18a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block/*
22daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * Copyright (C) 2011 Google Inc. All rights reserved.
3dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Copyright (C) 2010 Apple Inc. All rights reserved.
48a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block *
58a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * Redistribution and use in source and binary forms, with or without
68a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * modification, are permitted provided that the following conditions are
78a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * met:
88a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block *
98a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block *     * Redistributions of source code must retain the above copyright
108a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * notice, this list of conditions and the following disclaimer.
118a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block *     * Redistributions in binary form must reproduce the above
128a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * copyright notice, this list of conditions and the following disclaimer
138a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * in the documentation and/or other materials provided with the
148a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * distribution.
158a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block *     * Neither the name of Google Inc. nor the names of its
168a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * contributors may be used to endorse or promote products derived from
178a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * this software without specific prior written permission.
188a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block *
198a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
208a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
218a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
228a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
238a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
248a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
258a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
268a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
278a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
288a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
298a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
308a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block */
318a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochWebInspector.TextViewer = function(textModel, platform, url, delegate)
338a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{
342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    WebInspector.View.call(this);
352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
368a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    this._textModel = textModel;
372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this._textModel.changeListener = this._textChanged.bind(this);
382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    this._textModel.resetUndoStack();
392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    this._delegate = delegate;
408a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
418a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    this.element.className = "text-editor monospace";
42692e5dbf12901edacf14812a6fae25462920af42Steve Block
4381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    var enterTextChangeMode = this._enterInternalTextChangeMode.bind(this);
4481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    var exitTextChangeMode = this._exitInternalTextChangeMode.bind(this);
452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    var syncScrollListener = this._syncScroll.bind(this);
462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    var syncDecorationsForLineListener = this._syncDecorationsForLine.bind(this);
4781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    this._mainPanel = new WebInspector.TextEditorMainPanel(this._textModel, url, syncScrollListener, syncDecorationsForLineListener, enterTextChangeMode, exitTextChangeMode);
482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this._gutterPanel = new WebInspector.TextEditorGutterPanel(this._textModel, syncDecorationsForLineListener);
492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this.element.appendChild(this._mainPanel.element);
502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this.element.appendChild(this._gutterPanel.element);
512bde8e466a4451c7319e3a072d118917957d6554Steve Block
522bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Forward mouse wheel events from the unscrollable gutter to the main panel.
532bde8e466a4451c7319e3a072d118917957d6554Steve Block    this._gutterPanel.element.addEventListener("mousewheel", function(e) {
542bde8e466a4451c7319e3a072d118917957d6554Steve Block        this._mainPanel.element.dispatchEvent(e);
552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }.bind(this), false);
562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    this.element.addEventListener("dblclick", this._doubleClick.bind(this), true);
582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);
592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    this._registerShortcuts();
618a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block}
628a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
638a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve BlockWebInspector.TextViewer.prototype = {
648a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    set mimeType(mimeType)
658a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._mainPanel.mimeType = mimeType;
678a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
688a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
6981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    set readOnly(readOnly)
7081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (this._mainPanel.readOnly === readOnly)
722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;
7381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._mainPanel.readOnly = readOnly;
742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._delegate.readOnlyStateChanged(readOnly);
7581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
7681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
772bde8e466a4451c7319e3a072d118917957d6554Steve Block    get readOnly()
782bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
792bde8e466a4451c7319e3a072d118917957d6554Steve Block        return this._mainPanel.readOnly;
802bde8e466a4451c7319e3a072d118917957d6554Steve Block    },
812bde8e466a4451c7319e3a072d118917957d6554Steve Block
828a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    get textModel()
838a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
848a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return this._textModel;
858a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
868a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
878a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    revealLine: function(lineNumber)
888a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._mainPanel.revealLine(lineNumber);
908a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
918a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
928a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    addDecoration: function(lineNumber, decoration)
938a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._mainPanel.addDecoration(lineNumber, decoration);
952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._gutterPanel.addDecoration(lineNumber, decoration);
968a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
978a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
988a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    removeDecoration: function(lineNumber, decoration)
998a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
1002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._mainPanel.removeDecoration(lineNumber, decoration);
1012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._gutterPanel.removeDecoration(lineNumber, decoration);
1028a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
1038a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1048a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    markAndRevealRange: function(range)
1058a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
1062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._mainPanel.markAndRevealRange(range);
1078a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
1088a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1098a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    highlightLine: function(lineNumber)
1108a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
11154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        if (typeof lineNumber !== "number" || lineNumber < 0)
11254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block            return;
11354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
1142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._mainPanel.highlightLine(lineNumber);
1158a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
1168a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
117a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    clearLineHighlight: function()
118a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    {
1192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._mainPanel.clearLineHighlight();
120a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    },
121a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
122692e5dbf12901edacf14812a6fae25462920af42Steve Block    freeCachedElements: function()
123692e5dbf12901edacf14812a6fae25462920af42Steve Block    {
1242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._mainPanel.freeCachedElements();
1252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._gutterPanel.freeCachedElements();
1262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
1272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    get scrollTop()
1292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
1302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return this._mainPanel.element.scrollTop;
1312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
1322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    set scrollTop(scrollTop)
1342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
1352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._mainPanel.element.scrollTop = scrollTop;
1362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
1372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    get scrollLeft()
1392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
1402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return this._mainPanel.element.scrollLeft;
1412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
1422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    set scrollLeft(scrollLeft)
1442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
1452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._mainPanel.element.scrollLeft = scrollLeft;
1462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
1472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    beginUpdates: function()
1492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
1502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._mainPanel.beginUpdates();
1512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._gutterPanel.beginUpdates();
1522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
1532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    endUpdates: function()
1552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
1562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._mainPanel.endUpdates();
1572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._gutterPanel.endUpdates();
15881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._updatePanelOffsets();
1592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
1602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    resize: function()
1622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
1632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._mainPanel.resize();
1642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._gutterPanel.resize();
1652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._updatePanelOffsets();
1662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
1672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // WebInspector.TextModel listener
1692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _textChanged: function(oldRange, newRange, oldText, newText)
1702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
1712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (!this._internalTextChangeMode)
1722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            this._textModel.resetUndoStack();
1732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._mainPanel.textChanged(oldRange, newRange);
1742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._gutterPanel.textChanged(oldRange, newRange);
1752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._updatePanelOffsets();
17681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
17781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
17881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    _enterInternalTextChangeMode: function()
17981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
18081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._internalTextChangeMode = true;
1812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._delegate.startEditing();
18281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
18381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
18481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    _exitInternalTextChangeMode: function(oldRange, newRange)
18581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
18681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._internalTextChangeMode = false;
1872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._delegate.endEditing(oldRange, newRange);
1882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
1892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _updatePanelOffsets: function()
1912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
1922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        var lineNumbersWidth = this._gutterPanel.element.offsetWidth;
1932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (lineNumbersWidth)
1942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            this._mainPanel.element.style.setProperty("left", lineNumbersWidth + "px");
1952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        else
1962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            this._mainPanel.element.style.removeProperty("left"); // Use default value set in CSS.
1972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
1982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _syncScroll: function()
2002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
2012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        // Async call due to performance reasons.
2022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        setTimeout(function() {
2032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            var mainElement = this._mainPanel.element;
2042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            var gutterElement = this._gutterPanel.element;
2052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            // Handle horizontal scroll bar at the bottom of the main panel.
20681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this._gutterPanel.syncClientHeight(mainElement.clientHeight);
2072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            gutterElement.scrollTop = mainElement.scrollTop;
2082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }.bind(this), 0);
2092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
2102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _syncDecorationsForLine: function(lineNumber)
2122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
2132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (lineNumber >= this._textModel.linesCount)
2142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return;
2152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
21681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var mainChunk = this._mainPanel.chunkForLine(lineNumber);
2172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (mainChunk.linesCount === 1 && mainChunk.decorated) {
21881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            var gutterChunk = this._gutterPanel.makeLineAChunk(lineNumber);
21981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            var height = mainChunk.height;
22081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (height)
22181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                gutterChunk.element.style.setProperty("height", height + "px");
22281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            else
22381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                gutterChunk.element.style.removeProperty("height");
22481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        } else {
22581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            var gutterChunk = this._gutterPanel.chunkForLine(lineNumber);
22681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (gutterChunk.linesCount === 1)
22781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                gutterChunk.element.style.removeProperty("height");
22881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
2292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
2302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
2312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    _doubleClick: function(event)
2322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
2332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (!this.readOnly || this._commitEditingInProgress)
2342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;
2352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
2362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var lineRow = event.target.enclosingNodeOrSelfWithClass("webkit-line-content");
2372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (!lineRow)
2382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;  // Do not trigger editing from line numbers.
2392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
2402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (!this._delegate.isContentEditable())
2412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;
2422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
2432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this.readOnly = false;
2442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        window.getSelection().collapseToStart();
2452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
2462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
2472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    _registerShortcuts: function()
2482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
2492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var keys = WebInspector.KeyboardShortcut.Keys;
2502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var modifiers = WebInspector.KeyboardShortcut.Modifiers;
2512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
2522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._shortcuts = {};
2532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var commitEditing = this._commitEditing.bind(this);
2542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var cancelEditing = this._cancelEditing.bind(this);
2552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._shortcuts[WebInspector.KeyboardShortcut.makeKey("s", modifiers.CtrlOrMeta)] = commitEditing;
2562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Enter.code, modifiers.CtrlOrMeta)] = commitEditing;
2572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Esc.code)] = cancelEditing;
2582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
2592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var handleUndo = this._mainPanel.handleUndoRedo.bind(this._mainPanel, false);
2602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var handleRedo = this._mainPanel.handleUndoRedo.bind(this._mainPanel, true);
2612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._shortcuts[WebInspector.KeyboardShortcut.makeKey("z", modifiers.CtrlOrMeta)] = handleUndo;
2622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._shortcuts[WebInspector.KeyboardShortcut.makeKey("z", modifiers.Shift | modifiers.CtrlOrMeta)] = handleRedo;
2632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
2642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var handleTabKey = this._mainPanel.handleTabKeyPress.bind(this._mainPanel, false);
2652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var handleShiftTabKey = this._mainPanel.handleTabKeyPress.bind(this._mainPanel, true);
2662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Tab.code)] = handleTabKey;
2672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Tab.code, modifiers.Shift)] = handleShiftTabKey;
2682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
2692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
2702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    _handleKeyDown: function(e)
2712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
2722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(e);
2732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var handler = this._shortcuts[shortcutKey];
2742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (handler && handler.call(this)) {
2752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            e.preventDefault();
2762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            e.stopPropagation();
2772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }
2782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
2792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
2802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    _commitEditing: function()
2812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
2822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (this.readOnly)
2832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return false;
2842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
2852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this.readOnly = true;
2862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        function didCommitEditing(error)
2872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        {
2882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            this._commitEditingInProgress = false;
2892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (error)
2902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                this.readOnly = false;
2912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }
2922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._commitEditingInProgress = true;
2932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._delegate.commitEditing(didCommitEditing.bind(this));
2942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return true;
2952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
2962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
2972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    _cancelEditing: function()
2982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
2992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (this.readOnly)
3002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return false;
3012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
3022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this.readOnly = true;
3032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._delegate.cancelEditing();
3042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return true;
3052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
3062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
3072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochWebInspector.TextViewer.prototype.__proto__ = WebInspector.View.prototype;
3092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
3102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochWebInspector.TextViewerDelegate = function()
3112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
3122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
3132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
3142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochWebInspector.TextViewerDelegate.prototype = {
3152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    isContentEditable: function()
3162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
3172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // Should be implemented by subclasses.
3182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
3192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
3202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    readOnlyStateChanged: function(readOnly)
3212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
3222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // Should be implemented by subclasses.
3232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
3242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
3252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    startEditing: function()
3262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
3272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // Should be implemented by subclasses.
3282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
3292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
3302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    endEditing: function(oldRange, newRange)
3312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
3322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // Should be implemented by subclasses.
3332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
3342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
3352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    commitEditing: function()
3362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
3372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // Should be implemented by subclasses.
3382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
3392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
3402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    cancelEditing: function()
3412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
3422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // Should be implemented by subclasses.
3432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
3442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
3452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
3462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochWebInspector.TextViewerDelegate.prototype.__proto__ = WebInspector.Object.prototype;
3472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
3482fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockWebInspector.TextEditorChunkedPanel = function(textModel)
3492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
3502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this._textModel = textModel;
3512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this._defaultChunkSize = 50;
3532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this._paintCoalescingLevel = 0;
35481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    this._domUpdateCoalescingLevel = 0;
3552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
3562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3572fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockWebInspector.TextEditorChunkedPanel.prototype = {
3582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    get textModel()
3592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
3602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return this._textModel;
3612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
3622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    revealLine: function(lineNumber)
3642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
3652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (lineNumber >= this._textModel.linesCount)
3662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return;
3672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        var chunk = this.makeLineAChunk(lineNumber);
3692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        chunk.element.scrollIntoViewIfNeeded();
3702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
3712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    addDecoration: function(lineNumber, decoration)
3732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
3742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (lineNumber >= this._textModel.linesCount)
3752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;
3762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
3772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        var chunk = this.makeLineAChunk(lineNumber);
3782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        chunk.addDecoration(decoration);
3792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
3802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    removeDecoration: function(lineNumber, decoration)
3822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
3832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (lineNumber >= this._textModel.linesCount)
3842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;
3852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var chunk = this.chunkForLine(lineNumber);
3872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        chunk.removeDecoration(decoration);
388692e5dbf12901edacf14812a6fae25462920af42Steve Block    },
389692e5dbf12901edacf14812a6fae25462920af42Steve Block
3908a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    _buildChunks: function()
3918a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
39281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this.beginDomUpdates();
39381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
39481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._container.removeChildren();
3958a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
3968a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        this._textChunks = [];
3978a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        for (var i = 0; i < this._textModel.linesCount; i += this._defaultChunkSize) {
3982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            var chunk = this._createNewChunk(i, i + this._defaultChunkSize);
3998a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            this._textChunks.push(chunk);
40081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this._container.appendChild(chunk.element);
4018a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        }
402dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
4038a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        this._repaintAll();
40481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
40581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this.endDomUpdates();
4068a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
4078a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
4082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    makeLineAChunk: function(lineNumber)
4098a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
4108a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        var chunkNumber = this._chunkNumberForLine(lineNumber);
4118a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        var oldChunk = this._textChunks[chunkNumber];
41254cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
41354cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        if (!oldChunk) {
41454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block            console.error("No chunk for line number: " + lineNumber);
41554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block            return;
41654cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        }
41754cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block
4188a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        if (oldChunk.linesCount === 1)
4198a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            return oldChunk;
4208a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
4212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return this._splitChunkOnALine(lineNumber, chunkNumber);
4222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
4232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
4242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    _splitChunkOnALine: function(lineNumber, chunkNumber)
4252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
42681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this.beginDomUpdates();
42781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
4282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var oldChunk = this._textChunks[chunkNumber];
4298a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        var wasExpanded = oldChunk.expanded;
4308a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        oldChunk.expanded = false;
4318a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
4322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        var insertIndex = chunkNumber + 1;
4338a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
4348a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        // Prefix chunk.
4358a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        if (lineNumber > oldChunk.startLine) {
4362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            var prefixChunk = this._createNewChunk(oldChunk.startLine, lineNumber);
4378a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            this._textChunks.splice(insertIndex++, 0, prefixChunk);
43881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this._container.insertBefore(prefixChunk.element, oldChunk.element);
4398a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        }
4408a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
4418a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        // Line chunk.
4422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        var lineChunk = this._createNewChunk(lineNumber, lineNumber + 1);
4438a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        this._textChunks.splice(insertIndex++, 0, lineChunk);
44481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._container.insertBefore(lineChunk.element, oldChunk.element);
4458a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
4468a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        // Suffix chunk.
4478a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        if (oldChunk.startLine + oldChunk.linesCount > lineNumber + 1) {
4482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            var suffixChunk = this._createNewChunk(lineNumber + 1, oldChunk.startLine + oldChunk.linesCount);
4498a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            this._textChunks.splice(insertIndex, 0, suffixChunk);
45081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this._container.insertBefore(suffixChunk.element, oldChunk.element);
4518a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        }
4528a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
4538a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        // Remove enclosing chunk.
4542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._textChunks.splice(chunkNumber, 1);
45581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._container.removeChild(oldChunk.element);
4568a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
4578a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        if (wasExpanded) {
4588a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            if (prefixChunk)
4598a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block                prefixChunk.expanded = true;
4608a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            lineChunk.expanded = true;
4618a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            if (suffixChunk)
4628a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block                suffixChunk.expanded = true;
4638a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        }
4648a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
46581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this.endDomUpdates();
46681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
4678a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return lineChunk;
4688a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
4698a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
4702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _scroll: function()
4718a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
47281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // FIXME: Replace the "2" with the padding-left value from CSS.
47381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (this.element.scrollLeft <= 2)
47481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this.element.scrollLeft = 0;
47581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
4762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._scheduleRepaintAll();
4772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (this._syncScrollListener)
4782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            this._syncScrollListener();
4798a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
4808a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
4812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _scheduleRepaintAll: function()
4828a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
4832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (this._repaintAllTimer)
4842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            clearTimeout(this._repaintAllTimer);
4852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._repaintAllTimer = setTimeout(this._repaintAll.bind(this), 50);
4862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
4872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
4882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    beginUpdates: function()
4892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
4902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._paintCoalescingLevel++;
4912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
4922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
4932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    endUpdates: function()
4942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
4952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._paintCoalescingLevel--;
4962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (!this._paintCoalescingLevel)
4972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            this._repaintAll();
4982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
4992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
50081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    beginDomUpdates: function()
50181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
50281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._domUpdateCoalescingLevel++;
50381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
50481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
50581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    endDomUpdates: function()
50681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
50781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._domUpdateCoalescingLevel--;
50881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
50981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
5102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _chunkNumberForLine: function(lineNumber)
5112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
51281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        function compareLineNumbers(value, chunk)
51381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        {
51481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return value < chunk.startLine ? -1 : 1;
5152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
51681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var insertBefore = insertionIndexForObjectInListSortedByFunction(lineNumber, this._textChunks, compareLineNumbers);
51781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return insertBefore - 1;
5182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
5192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
52081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    chunkForLine: function(lineNumber)
5212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
5222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return this._textChunks[this._chunkNumberForLine(lineNumber)];
5232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
5242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
5252bde8e466a4451c7319e3a072d118917957d6554Steve Block    _findFirstVisibleChunkNumber: function(visibleFrom)
52681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
52781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        function compareOffsetTops(value, chunk)
52881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        {
52981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return value < chunk.offsetTop ? -1 : 1;
53081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
53181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var insertBefore = insertionIndexForObjectInListSortedByFunction(visibleFrom, this._textChunks, compareOffsetTops);
5322bde8e466a4451c7319e3a072d118917957d6554Steve Block        return insertBefore - 1;
5332bde8e466a4451c7319e3a072d118917957d6554Steve Block    },
53481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
5352bde8e466a4451c7319e3a072d118917957d6554Steve Block    _findVisibleChunks: function(visibleFrom, visibleTo)
5362bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
5372bde8e466a4451c7319e3a072d118917957d6554Steve Block        var from = this._findFirstVisibleChunkNumber(visibleFrom);
53881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        for (var to = from + 1; to < this._textChunks.length; ++to) {
53981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (this._textChunks[to].offsetTop >= visibleTo)
54081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                break;
54181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
54281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return { start: from, end: to };
54381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
54481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
5452bde8e466a4451c7319e3a072d118917957d6554Steve Block    _findFirstVisibleLineNumber: function(visibleFrom)
5462bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
5472bde8e466a4451c7319e3a072d118917957d6554Steve Block        var chunk = this._textChunks[this._findFirstVisibleChunkNumber(visibleFrom)];
5482bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!chunk.expanded)
5492bde8e466a4451c7319e3a072d118917957d6554Steve Block            return chunk.startLine;
5502bde8e466a4451c7319e3a072d118917957d6554Steve Block
5512bde8e466a4451c7319e3a072d118917957d6554Steve Block        var lineNumbers = [];
5522bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (var i = 0; i < chunk.linesCount; ++i) {
5532bde8e466a4451c7319e3a072d118917957d6554Steve Block            lineNumbers.push(chunk.startLine + i);
5542bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
5552bde8e466a4451c7319e3a072d118917957d6554Steve Block
5562bde8e466a4451c7319e3a072d118917957d6554Steve Block        function compareLineRowOffsetTops(value, lineNumber)
5572bde8e466a4451c7319e3a072d118917957d6554Steve Block        {
5582bde8e466a4451c7319e3a072d118917957d6554Steve Block            var lineRow = chunk.getExpandedLineRow(lineNumber);
5592bde8e466a4451c7319e3a072d118917957d6554Steve Block            return value < lineRow.offsetTop ? -1 : 1;
5602bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
5612bde8e466a4451c7319e3a072d118917957d6554Steve Block        var insertBefore = insertionIndexForObjectInListSortedByFunction(visibleFrom, lineNumbers, compareLineRowOffsetTops);
5622bde8e466a4451c7319e3a072d118917957d6554Steve Block        return lineNumbers[insertBefore - 1];
5632bde8e466a4451c7319e3a072d118917957d6554Steve Block    },
5642bde8e466a4451c7319e3a072d118917957d6554Steve Block
5652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _repaintAll: function()
5662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
5672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        delete this._repaintAllTimer;
5682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
56981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (this._paintCoalescingLevel || this._dirtyLines)
5702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return;
5712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
5722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        var visibleFrom = this.element.scrollTop;
5732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        var visibleTo = this.element.scrollTop + this.element.clientHeight;
5742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
57581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (visibleTo) {
57681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            var result = this._findVisibleChunks(visibleFrom, visibleTo);
57781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this._expandChunks(result.start, result.end);
5782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
5792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
5802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
5812bde8e466a4451c7319e3a072d118917957d6554Steve Block    _expandChunks: function(fromIndex, toIndex)
5822bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
5832bde8e466a4451c7319e3a072d118917957d6554Steve Block        // First collapse chunks to collect the DOM elements into a cache to reuse them later.
5842bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (var i = 0; i < fromIndex; ++i)
5852bde8e466a4451c7319e3a072d118917957d6554Steve Block            this._textChunks[i].expanded = false;
5862bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (var i = toIndex; i < this._textChunks.length; ++i)
5872bde8e466a4451c7319e3a072d118917957d6554Steve Block            this._textChunks[i].expanded = false;
5882bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (var i = fromIndex; i < toIndex; ++i)
5892bde8e466a4451c7319e3a072d118917957d6554Steve Block            this._textChunks[i].expanded = true;
5902bde8e466a4451c7319e3a072d118917957d6554Steve Block    },
5912bde8e466a4451c7319e3a072d118917957d6554Steve Block
5922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _totalHeight: function(firstElement, lastElement)
5932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
5942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        lastElement = (lastElement || firstElement).nextElementSibling;
5952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (lastElement)
5962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return lastElement.offsetTop - firstElement.offsetTop;
59781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
59881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var offsetParent = firstElement.offsetParent;
59981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (offsetParent && offsetParent.scrollHeight > offsetParent.clientHeight)
60081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return offsetParent.scrollHeight - firstElement.offsetTop;
60181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
60281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var total = 0;
60381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        while (firstElement && firstElement !== lastElement) {
60481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            total += firstElement.offsetHeight;
60581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            firstElement = firstElement.nextElementSibling;
60681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
60781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return total;
6082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
60981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
6102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    resize: function()
6112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
6122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._repaintAll();
6132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
6142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
6152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
6162fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockWebInspector.TextEditorGutterPanel = function(textModel, syncDecorationsForLineListener)
6172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
6182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    WebInspector.TextEditorChunkedPanel.call(this, textModel);
6192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
6202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this._syncDecorationsForLineListener = syncDecorationsForLineListener;
6212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
6222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this.element = document.createElement("div");
6232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this.element.className = "text-editor-lines";
6242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
62581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    this._container = document.createElement("div");
62681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    this._container.className = "inner-container";
62781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    this.element.appendChild(this._container);
62881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
6292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this.element.addEventListener("scroll", this._scroll.bind(this), false);
6302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
6312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this.freeCachedElements();
6322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this._buildChunks();
6332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
6342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
6352fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockWebInspector.TextEditorGutterPanel.prototype = {
6362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    freeCachedElements: function()
6372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
6382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._cachedRows = [];
6392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
6402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
6412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _createNewChunk: function(startLine, endLine)
6422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
6432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return new WebInspector.TextEditorGutterChunk(this, startLine, endLine);
6442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
6452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
64681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    textChanged: function(oldRange, newRange)
64781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
6482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this.beginDomUpdates();
64981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
65081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var linesDiff = newRange.linesCount - oldRange.linesCount;
65181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (linesDiff) {
65281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            // Remove old chunks (if needed).
65381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            for (var chunkNumber = this._textChunks.length - 1; chunkNumber >= 0 ; --chunkNumber) {
65481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                var chunk = this._textChunks[chunkNumber];
65581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (chunk.startLine + chunk.linesCount <= this._textModel.linesCount)
65681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    break;
65781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                chunk.expanded = false;
65881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                this._container.removeChild(chunk.element);
65981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
66081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this._textChunks.length = chunkNumber + 1;
66181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
66281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            // Add new chunks (if needed).
66381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            var totalLines = 0;
66481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (this._textChunks.length) {
66581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                var lastChunk = this._textChunks[this._textChunks.length - 1];
66681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                totalLines = lastChunk.startLine + lastChunk.linesCount;
66781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
66881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            for (var i = totalLines; i < this._textModel.linesCount; i += this._defaultChunkSize) {
66981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                var chunk = this._createNewChunk(i, i + this._defaultChunkSize);
67081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                this._textChunks.push(chunk);
67181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                this._container.appendChild(chunk.element);
67281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
67381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this._repaintAll();
67481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        } else {
67581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            // Decorations may have been removed, so we may have to sync those lines.
67681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            var chunkNumber = this._chunkNumberForLine(newRange.startLine);
67781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            var chunk = this._textChunks[chunkNumber];
67881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            while (chunk && chunk.startLine <= newRange.endLine) {
67981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (chunk.linesCount === 1)
68081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    this._syncDecorationsForLineListener(chunk.startLine);
68181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                chunk = this._textChunks[++chunkNumber];
68281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
68381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
6842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
6852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this.endDomUpdates();
68681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
68781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
68881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    syncClientHeight: function(clientHeight)
68981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
69081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (this.element.offsetHeight > clientHeight)
69181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this._container.style.setProperty("padding-bottom", (this.element.offsetHeight - clientHeight) + "px");
69281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        else
69381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this._container.style.removeProperty("padding-bottom");
6942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
6952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
6962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
6972fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockWebInspector.TextEditorGutterPanel.prototype.__proto__ = WebInspector.TextEditorChunkedPanel.prototype;
6982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
6992fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockWebInspector.TextEditorGutterChunk = function(textViewer, startLine, endLine)
7002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
7012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this._textViewer = textViewer;
7022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this._textModel = textViewer._textModel;
7032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this.startLine = startLine;
7052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    endLine = Math.min(this._textModel.linesCount, endLine);
7062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this.linesCount = endLine - startLine;
7072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this._expanded = false;
7092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this.element = document.createElement("div");
7112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this.element.lineNumber = startLine;
7122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this.element.className = "webkit-line-number";
7132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (this.linesCount === 1) {
7152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        // Single line chunks are typically created for decorations. Host line number in
7162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        // the sub-element in order to allow flexible border / margin management.
7172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        var innerSpan = document.createElement("span");
7182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        innerSpan.className = "webkit-line-number-inner";
7192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        innerSpan.textContent = startLine + 1;
7202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        var outerSpan = document.createElement("div");
7212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        outerSpan.className = "webkit-line-number-outer";
7222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        outerSpan.appendChild(innerSpan);
7232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this.element.appendChild(outerSpan);
7242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    } else {
7252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        var lineNumbers = [];
72681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        for (var i = startLine; i < endLine; ++i)
7272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            lineNumbers.push(i + 1);
7282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this.element.textContent = lineNumbers.join("\n");
7292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
7302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
7312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7322fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockWebInspector.TextEditorGutterChunk.prototype = {
7332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    addDecoration: function(decoration)
7342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
73581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._textViewer.beginDomUpdates();
73681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (typeof decoration === "string")
7372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            this.element.addStyleClass(decoration);
73881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._textViewer.endDomUpdates();
7392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
7402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    removeDecoration: function(decoration)
7422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
74381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._textViewer.beginDomUpdates();
74481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (typeof decoration === "string")
7452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            this.element.removeStyleClass(decoration);
74681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._textViewer.endDomUpdates();
7472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
7482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    get expanded()
7502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
7512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return this._expanded;
7522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
7532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    set expanded(expanded)
7552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
7562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (this.linesCount === 1)
7572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            this._textViewer._syncDecorationsForLineListener(this.startLine);
7582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (this._expanded === expanded)
7602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return;
7612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._expanded = expanded;
7632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (this.linesCount === 1)
7652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return;
7662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
76781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._textViewer.beginDomUpdates();
76881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
7692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (expanded) {
7702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            this._expandedLineRows = [];
7712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            var parentElement = this.element.parentElement;
7722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) {
7732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                var lineRow = this._createRow(i);
7742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                parentElement.insertBefore(lineRow, this.element);
7752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                this._expandedLineRows.push(lineRow);
7762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            }
7772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            parentElement.removeChild(this.element);
7782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        } else {
7792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            var elementInserted = false;
7802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            for (var i = 0; i < this._expandedLineRows.length; ++i) {
7812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                var lineRow = this._expandedLineRows[i];
7822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                var parentElement = lineRow.parentElement;
7832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                if (parentElement) {
7842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    if (!elementInserted) {
7852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        elementInserted = true;
7862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        parentElement.insertBefore(this.element, lineRow);
7872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    }
7882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    parentElement.removeChild(lineRow);
7892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                }
79081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                this._textViewer._cachedRows.push(lineRow);
7912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            }
7922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            delete this._expandedLineRows;
7932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
79481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
79581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._textViewer.endDomUpdates();
7962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
7972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    get height()
7992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
8002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (!this._expandedLineRows)
8012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return this._textViewer._totalHeight(this.element);
8022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return this._textViewer._totalHeight(this._expandedLineRows[0], this._expandedLineRows[this._expandedLineRows.length - 1]);
8032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
8042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
80581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    get offsetTop()
80681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
80781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return (this._expandedLineRows && this._expandedLineRows.length) ? this._expandedLineRows[0].offsetTop : this.element.offsetTop;
80881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
80981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
8102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _createRow: function(lineNumber)
8112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
8122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        var lineRow = this._textViewer._cachedRows.pop() || document.createElement("div");
8132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        lineRow.lineNumber = lineNumber;
8142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        lineRow.className = "webkit-line-number";
8152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        lineRow.textContent = lineNumber + 1;
8162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return lineRow;
8172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
8182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
8192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
82081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochWebInspector.TextEditorMainPanel = function(textModel, url, syncScrollListener, syncDecorationsForLineListener, enterTextChangeMode, exitTextChangeMode)
8212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
8222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    WebInspector.TextEditorChunkedPanel.call(this, textModel);
8232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
8242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this._syncScrollListener = syncScrollListener;
8252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this._syncDecorationsForLineListener = syncDecorationsForLineListener;
82681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    this._enterTextChangeMode = enterTextChangeMode;
82781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    this._exitTextChangeMode = exitTextChangeMode;
8282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
8292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this._url = url;
8302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this._highlighter = new WebInspector.TextEditorHighlighter(textModel, this._highlightDataReady.bind(this));
83181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    this._readOnly = true;
8322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
8332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this.element = document.createElement("div");
8342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this.element.className = "text-editor-contents";
8352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this.element.tabIndex = 0;
8362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
83781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    this._container = document.createElement("div");
83881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    this._container.className = "inner-container";
83981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    this._container.tabIndex = 0;
84081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    this.element.appendChild(this._container);
84181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
8422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this.element.addEventListener("scroll", this._scroll.bind(this), false);
8432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
84481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // In WebKit the DOMNodeRemoved event is fired AFTER the node is removed, thus it should be
84581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // attached to all DOM nodes that we want to track. Instead, we attach the DOMNodeRemoved
84681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // listeners only on the line rows, and use DOMSubtreeModified to track node removals inside
84781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // the line rows. For more info see: https://bugs.webkit.org/show_bug.cgi?id=55666
84881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    this._handleDOMUpdatesCallback = this._handleDOMUpdates.bind(this);
84981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    this._container.addEventListener("DOMCharacterDataModified", this._handleDOMUpdatesCallback, false);
85081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    this._container.addEventListener("DOMNodeInserted", this._handleDOMUpdatesCallback, false);
85181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    this._container.addEventListener("DOMSubtreeModified", this._handleDOMUpdatesCallback, false);
8522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
8532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this.freeCachedElements();
8542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this._buildChunks();
8552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
8562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
8572fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockWebInspector.TextEditorMainPanel.prototype = {
8582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    set mimeType(mimeType)
8592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
8602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._highlighter.mimeType = mimeType;
8612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
8622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
86381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    set readOnly(readOnly)
86481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
8652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (this._readOnly === readOnly)
8662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;
8672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
86881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this.beginDomUpdates();
86981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._readOnly = readOnly;
87081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (this._readOnly)
87181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this._container.removeStyleClass("text-editor-editable");
87281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        else
87381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this._container.addStyleClass("text-editor-editable");
87481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this.endDomUpdates();
87581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
87681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
8772bde8e466a4451c7319e3a072d118917957d6554Steve Block    get readOnly()
8782bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
8792bde8e466a4451c7319e3a072d118917957d6554Steve Block        return this._readOnly;
8802bde8e466a4451c7319e3a072d118917957d6554Steve Block    },
8812bde8e466a4451c7319e3a072d118917957d6554Steve Block
8822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    markAndRevealRange: function(range)
8832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
8842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (this._rangeToMark) {
8852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            var markedLine = this._rangeToMark.startLine;
8862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            delete this._rangeToMark;
8872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            // Remove the marked region immediately.
8882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (!this._dirtyLines) {
8892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                this.beginDomUpdates();
8902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                var chunk = this.chunkForLine(markedLine);
8912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                var wasExpanded = chunk.expanded;
8922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                chunk.expanded = false;
8932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                chunk.updateCollapsedLineRow();
8942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                chunk.expanded = wasExpanded;
8952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                this.endDomUpdates();
8962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            } else
8972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                this._paintLines(markedLine, markedLine + 1);
8982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
8992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
9002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (range) {
9012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            this._rangeToMark = range;
9022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            this.revealLine(range.startLine);
9032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            var chunk = this.makeLineAChunk(range.startLine);
9042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            this._paintLine(chunk.element);
9052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (this._markedRangeElement)
9062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                this._markedRangeElement.scrollIntoViewIfNeeded();
9072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
9082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        delete this._markedRangeElement;
9092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
9102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
9112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    highlightLine: function(lineNumber)
9122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
9132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this.clearLineHighlight();
9142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._highlightedLine = lineNumber;
9152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this.revealLine(lineNumber);
9162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this.addDecoration(lineNumber, "webkit-highlighted-line");
9172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
9182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
9192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    clearLineHighlight: function()
9202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
9212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (typeof this._highlightedLine === "number") {
9222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            this.removeDecoration(this._highlightedLine, "webkit-highlighted-line");
9232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            delete this._highlightedLine;
9242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
9252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
9262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
9272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    freeCachedElements: function()
9282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
9292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._cachedSpans = [];
9302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._cachedTextNodes = [];
9312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._cachedRows = [];
9328a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
9338a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
9342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    handleUndoRedo: function(redo)
9352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
9362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (this._readOnly || this._dirtyLines)
9372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return false;
9382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
9392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this.beginUpdates();
9402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._enterTextChangeMode();
9412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
9422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var callback = function(oldRange, newRange) {
9432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            this._exitTextChangeMode(oldRange, newRange);
9442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            this._enterTextChangeMode();
9452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }.bind(this);
9462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
9472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var range = redo ? this._textModel.redo(callback) : this._textModel.undo(callback);
9482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (range)
9492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            this._setCaretLocation(range.endLine, range.endColumn, true);
9502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
9512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._exitTextChangeMode(null, null);
9522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this.endUpdates();
9532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
9542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return true;
9552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
9562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
9572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    handleTabKeyPress: function(shiftKey)
9582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
9592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (this._readOnly || this._dirtyLines)
9602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return false;
9612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
9622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var selection = this._getSelection();
9632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (!selection)
9642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return false;
9652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
9662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (shiftKey)
9672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return true;
9682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
9692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this.beginUpdates();
9702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._enterTextChangeMode();
9712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
9722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var range = selection;
9732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (range.startLine > range.endLine || (range.startLine === range.endLine && range.startColumn > range.endColumn))
9742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            range = new WebInspector.TextRange(range.endLine, range.endColumn, range.startLine, range.startColumn);
9752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
9762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var newRange = this._setText(range, "\t");
9772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
9782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._exitTextChangeMode(range, newRange);
9792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this.endUpdates();
9802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
9812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._setCaretLocation(newRange.endLine, newRange.endColumn, true);
9822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return true;
9832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
9842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
9852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    _splitChunkOnALine: function(lineNumber, chunkNumber)
9862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
9872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var selection = this._getSelection();
9882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var chunk = WebInspector.TextEditorChunkedPanel.prototype._splitChunkOnALine.call(this, lineNumber, chunkNumber);
9892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._restoreSelection(selection);
9902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return chunk;
9912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
9922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
9932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _buildChunks: function()
9948a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
99581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        for (var i = 0; i < this._textModel.linesCount; ++i)
99681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this._textModel.removeAttribute(i, "highlight");
99781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
9982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        WebInspector.TextEditorChunkedPanel.prototype._buildChunks.call(this);
9998a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
10008a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
10012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _createNewChunk: function(startLine, endLine)
10028a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
10032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return new WebInspector.TextEditorMainChunk(this, startLine, endLine);
10048a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
10058a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
10062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _expandChunks: function(fromIndex, toIndex)
10078a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
10082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        var lastChunk = this._textChunks[toIndex - 1];
10092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        var lastVisibleLine = lastChunk.startLine + lastChunk.linesCount;
10108a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
10118a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        var selection = this._getSelection();
10128a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
10138a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        this._muteHighlightListener = true;
10148a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        this._highlighter.highlight(lastVisibleLine);
10158a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        delete this._muteHighlightListener;
10168a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
10172bde8e466a4451c7319e3a072d118917957d6554Steve Block        this._restorePaintLinesOperationsCredit();
10182bde8e466a4451c7319e3a072d118917957d6554Steve Block        WebInspector.TextEditorChunkedPanel.prototype._expandChunks.call(this, fromIndex, toIndex);
10192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._adjustPaintLinesOperationsRefreshValue();
10208a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
10218a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        this._restoreSelection(selection);
10228a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
10238a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
10248a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    _highlightDataReady: function(fromLine, toLine)
10258a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
10268a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        if (this._muteHighlightListener)
10278a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            return;
10282bde8e466a4451c7319e3a072d118917957d6554Steve Block        this._restorePaintLinesOperationsCredit();
10292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._paintLines(fromLine, toLine, true /*restoreSelection*/);
10302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
10318a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
10322bde8e466a4451c7319e3a072d118917957d6554Steve Block    _schedulePaintLines: function(startLine, endLine)
103381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
10342bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (startLine >= endLine)
10352bde8e466a4451c7319e3a072d118917957d6554Steve Block            return;
10362bde8e466a4451c7319e3a072d118917957d6554Steve Block
10372bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!this._scheduledPaintLines) {
10382bde8e466a4451c7319e3a072d118917957d6554Steve Block            this._scheduledPaintLines = [ { startLine: startLine, endLine: endLine } ];
10392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            this._paintScheduledLinesTimer = setTimeout(this._paintScheduledLines.bind(this), 0);
10402bde8e466a4451c7319e3a072d118917957d6554Steve Block        } else {
10412bde8e466a4451c7319e3a072d118917957d6554Steve Block            for (var i = 0; i < this._scheduledPaintLines.length; ++i) {
10422bde8e466a4451c7319e3a072d118917957d6554Steve Block                var chunk = this._scheduledPaintLines[i];
104381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (chunk.startLine <= endLine && chunk.endLine >= startLine) {
104481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    chunk.startLine = Math.min(chunk.startLine, startLine);
104581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    chunk.endLine = Math.max(chunk.endLine, endLine);
104681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    return;
104781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                }
10482bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (chunk.startLine > endLine) {
10492bde8e466a4451c7319e3a072d118917957d6554Steve Block                    this._scheduledPaintLines.splice(i, 0, { startLine: startLine, endLine: endLine });
10502bde8e466a4451c7319e3a072d118917957d6554Steve Block                    return;
10512bde8e466a4451c7319e3a072d118917957d6554Steve Block                }
105281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
10532bde8e466a4451c7319e3a072d118917957d6554Steve Block            this._scheduledPaintLines.push({ startLine: startLine, endLine: endLine });
105481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
105581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
105681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
10572bde8e466a4451c7319e3a072d118917957d6554Steve Block    _paintScheduledLines: function(skipRestoreSelection)
105881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
10592bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (this._paintScheduledLinesTimer)
10602bde8e466a4451c7319e3a072d118917957d6554Steve Block            clearTimeout(this._paintScheduledLinesTimer);
10612bde8e466a4451c7319e3a072d118917957d6554Steve Block        delete this._paintScheduledLinesTimer;
10622bde8e466a4451c7319e3a072d118917957d6554Steve Block
10632bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!this._scheduledPaintLines)
10642bde8e466a4451c7319e3a072d118917957d6554Steve Block            return;
10652bde8e466a4451c7319e3a072d118917957d6554Steve Block
10662bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Reschedule the timer if we can not paint the lines yet, or the user is scrolling.
10672bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (this._dirtyLines || this._repaintAllTimer) {
10682bde8e466a4451c7319e3a072d118917957d6554Steve Block            this._paintScheduledLinesTimer = setTimeout(this._paintScheduledLines.bind(this), 50);
106981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return;
107081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
10712bde8e466a4451c7319e3a072d118917957d6554Steve Block
10722bde8e466a4451c7319e3a072d118917957d6554Steve Block        var scheduledPaintLines = this._scheduledPaintLines;
10732bde8e466a4451c7319e3a072d118917957d6554Steve Block        delete this._scheduledPaintLines;
10742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
10752bde8e466a4451c7319e3a072d118917957d6554Steve Block        this._restorePaintLinesOperationsCredit();
10762bde8e466a4451c7319e3a072d118917957d6554Steve Block        this._paintLineChunks(scheduledPaintLines, !skipRestoreSelection);
10772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._adjustPaintLinesOperationsRefreshValue();
10782bde8e466a4451c7319e3a072d118917957d6554Steve Block    },
10792bde8e466a4451c7319e3a072d118917957d6554Steve Block
10802bde8e466a4451c7319e3a072d118917957d6554Steve Block    _restorePaintLinesOperationsCredit: function()
10812bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
10822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (!this._paintLinesOperationsRefreshValue)
10832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            this._paintLinesOperationsRefreshValue = 250;
10842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._paintLinesOperationsCredit = this._paintLinesOperationsRefreshValue;
10852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._paintLinesOperationsLastRefresh = Date.now();
10862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
10872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
10882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    _adjustPaintLinesOperationsRefreshValue: function()
10892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
10902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var operationsDone = this._paintLinesOperationsRefreshValue - this._paintLinesOperationsCredit;
10912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (operationsDone <= 0)
10922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;
10932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var timePast = Date.now() - this._paintLinesOperationsLastRefresh;
10942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (timePast <= 0)
10952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;
10962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // Make the synchronous CPU chunk for painting the lines 50 msec.
10972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var value = Math.floor(operationsDone / timePast * 50);
10982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._paintLinesOperationsRefreshValue = Number.constrain(value, 150, 1500);
109981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
110081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
11012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _paintLines: function(fromLine, toLine, restoreSelection)
11022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
11032bde8e466a4451c7319e3a072d118917957d6554Steve Block        this._paintLineChunks([ { startLine: fromLine, endLine: toLine } ], restoreSelection);
11042bde8e466a4451c7319e3a072d118917957d6554Steve Block    },
11052bde8e466a4451c7319e3a072d118917957d6554Steve Block
11062bde8e466a4451c7319e3a072d118917957d6554Steve Block    _paintLineChunks: function(lineChunks, restoreSelection)
11072bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
11082bde8e466a4451c7319e3a072d118917957d6554Steve Block        // First, paint visible lines, so that in case of long lines we should start highlighting
11092bde8e466a4451c7319e3a072d118917957d6554Steve Block        // the visible area immediately, instead of waiting for the lines above the visible area.
11102bde8e466a4451c7319e3a072d118917957d6554Steve Block        var visibleFrom = this.element.scrollTop;
11112bde8e466a4451c7319e3a072d118917957d6554Steve Block        var firstVisibleLineNumber = this._findFirstVisibleLineNumber(visibleFrom);
111281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
11132bde8e466a4451c7319e3a072d118917957d6554Steve Block        var chunk;
11148a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        var selection;
11152bde8e466a4451c7319e3a072d118917957d6554Steve Block        var invisibleLineRows = [];
11162bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (var i = 0; i < lineChunks.length; ++i) {
11172bde8e466a4451c7319e3a072d118917957d6554Steve Block            var lineChunk = lineChunks[i];
11182bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (this._dirtyLines || this._scheduledPaintLines) {
11192bde8e466a4451c7319e3a072d118917957d6554Steve Block                this._schedulePaintLines(lineChunk.startLine, lineChunk.endLine);
11208a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block                continue;
11212bde8e466a4451c7319e3a072d118917957d6554Steve Block            }
11222bde8e466a4451c7319e3a072d118917957d6554Steve Block            for (var lineNumber = lineChunk.startLine; lineNumber < lineChunk.endLine; ++lineNumber) {
11232bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (!chunk || lineNumber < chunk.startLine || lineNumber >= chunk.startLine + chunk.linesCount)
11242bde8e466a4451c7319e3a072d118917957d6554Steve Block                    chunk = this.chunkForLine(lineNumber);
11252bde8e466a4451c7319e3a072d118917957d6554Steve Block                var lineRow = chunk.getExpandedLineRow(lineNumber);
11262bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (!lineRow)
11272bde8e466a4451c7319e3a072d118917957d6554Steve Block                    continue;
11282bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (lineNumber < firstVisibleLineNumber) {
11292bde8e466a4451c7319e3a072d118917957d6554Steve Block                    invisibleLineRows.push(lineRow);
11302bde8e466a4451c7319e3a072d118917957d6554Steve Block                    continue;
11312bde8e466a4451c7319e3a072d118917957d6554Steve Block                }
11322bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (restoreSelection && !selection)
11332bde8e466a4451c7319e3a072d118917957d6554Steve Block                    selection = this._getSelection();
11342bde8e466a4451c7319e3a072d118917957d6554Steve Block                this._paintLine(lineRow);
11352bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (this._paintLinesOperationsCredit < 0) {
11362bde8e466a4451c7319e3a072d118917957d6554Steve Block                    this._schedulePaintLines(lineNumber + 1, lineChunk.endLine);
11372bde8e466a4451c7319e3a072d118917957d6554Steve Block                    break;
11382bde8e466a4451c7319e3a072d118917957d6554Steve Block                }
11392bde8e466a4451c7319e3a072d118917957d6554Steve Block            }
11402bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
11412bde8e466a4451c7319e3a072d118917957d6554Steve Block
11422bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (var i = 0; i < invisibleLineRows.length; ++i) {
11432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (restoreSelection && !selection)
11448a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block                selection = this._getSelection();
11452bde8e466a4451c7319e3a072d118917957d6554Steve Block            this._paintLine(invisibleLineRows[i]);
11468a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        }
11472bde8e466a4451c7319e3a072d118917957d6554Steve Block
11482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (restoreSelection)
11492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            this._restoreSelection(selection);
11508a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
11518a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
11522bde8e466a4451c7319e3a072d118917957d6554Steve Block    _paintLine: function(lineRow)
11538a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
11542bde8e466a4451c7319e3a072d118917957d6554Steve Block        var lineNumber = lineRow.lineNumber;
11552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (this._dirtyLines) {
11562bde8e466a4451c7319e3a072d118917957d6554Steve Block            this._schedulePaintLines(lineNumber, lineNumber + 1);
11578a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            return;
11588a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        }
11598a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
116081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this.beginDomUpdates();
116181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        try {
11622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (this._scheduledPaintLines || this._paintLinesOperationsCredit < 0) {
11632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                this._schedulePaintLines(lineNumber, lineNumber + 1);
116481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                return;
11658a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            }
116681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
11672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            var highlight = this._textModel.getAttribute(lineNumber, "highlight");
11682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (!highlight)
11692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                return;
11702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
117181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            lineRow.removeChildren();
117281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            var line = this._textModel.line(lineNumber);
117381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (!line)
117481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                lineRow.appendChild(document.createElement("br"));
117581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
117681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            var plainTextStart = -1;
117781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            for (var j = 0; j < line.length;) {
117881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (j > 1000) {
117981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    // This line is too long - do not waste cycles on minified js highlighting.
118081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    if (plainTextStart === -1)
118181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        plainTextStart = j;
118281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    break;
118381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                }
118481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                var attribute = highlight[j];
118581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (!attribute || !attribute.tokenType) {
118681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    if (plainTextStart === -1)
118781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        plainTextStart = j;
118881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    j++;
118981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                } else {
119081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    if (plainTextStart !== -1) {
119181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        this._appendTextNode(lineRow, line.substring(plainTextStart, j));
119281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                        plainTextStart = -1;
11932bde8e466a4451c7319e3a072d118917957d6554Steve Block                        --this._paintLinesOperationsCredit;
119481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    }
119581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    this._appendSpan(lineRow, line.substring(j, j + attribute.length), attribute.tokenType);
119681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    j += attribute.length;
11972bde8e466a4451c7319e3a072d118917957d6554Steve Block                    --this._paintLinesOperationsCredit;
11988a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block                }
11998a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            }
12002bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (plainTextStart !== -1) {
120181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                this._appendTextNode(lineRow, line.substring(plainTextStart, line.length));
12022bde8e466a4451c7319e3a072d118917957d6554Steve Block                --this._paintLinesOperationsCredit;
12032bde8e466a4451c7319e3a072d118917957d6554Steve Block            }
120481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (lineRow.decorationsElement)
120581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                lineRow.appendChild(lineRow.decorationsElement);
120681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        } finally {
12072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (this._rangeToMark && this._rangeToMark.startLine === lineNumber)
12082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                this._markedRangeElement = highlightSearchResult(lineRow, this._rangeToMark.startColumn, this._rangeToMark.endColumn - this._rangeToMark.startColumn);
120981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this.endDomUpdates();
12108a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        }
12118a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
12128a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
12132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _releaseLinesHighlight: function(lineRow)
1214692e5dbf12901edacf14812a6fae25462920af42Steve Block    {
12152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (!lineRow)
12162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return;
12172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if ("spans" in lineRow) {
12182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            var spans = lineRow.spans;
12192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            for (var j = 0; j < spans.length; ++j)
12202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                this._cachedSpans.push(spans[j]);
12212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            delete lineRow.spans;
1222692e5dbf12901edacf14812a6fae25462920af42Steve Block        }
12232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if ("textNodes" in lineRow) {
12242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            var textNodes = lineRow.textNodes;
12252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            for (var j = 0; j < textNodes.length; ++j)
12262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                this._cachedTextNodes.push(textNodes[j]);
12272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            delete lineRow.textNodes;
12282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
12292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        this._cachedRows.push(lineRow);
1230692e5dbf12901edacf14812a6fae25462920af42Steve Block    },
1231692e5dbf12901edacf14812a6fae25462920af42Steve Block
12328a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    _getSelection: function()
12338a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
12348a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        var selection = window.getSelection();
12352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (!selection.rangeCount)
12368a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            return null;
12378a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        var selectionRange = selection.getRangeAt(0);
12385af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        // Selection may be outside of the viewer.
123981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (!this._container.isAncestor(selectionRange.startContainer) || !this._container.isAncestor(selectionRange.endContainer))
12405af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            return null;
12418a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        var start = this._selectionToPosition(selectionRange.startContainer, selectionRange.startOffset);
12422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        var end = selectionRange.collapsed ? start : this._selectionToPosition(selectionRange.endContainer, selectionRange.endOffset);
12432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (selection.anchorNode === selectionRange.startContainer && selection.anchorOffset === selectionRange.startOffset)
12442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return new WebInspector.TextRange(start.line, start.column, end.line, end.column);
12452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        else
12462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return new WebInspector.TextRange(end.line, end.column, start.line, start.column);
12478a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
12488a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
12492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    _restoreSelection: function(range, scrollIntoView)
12508a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
12518a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        if (!range)
12528a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            return;
12532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        var start = this._positionToSelection(range.startLine, range.startColumn);
12542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        var end = range.isEmpty() ? start : this._positionToSelection(range.endLine, range.endColumn);
12552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        window.getSelection().setBaseAndExtent(start.container, start.offset, end.container, end.offset);
12562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
12572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (scrollIntoView) {
12582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            for (var node = end.container; node; node = node.parentElement) {
12592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                if (node.scrollIntoViewIfNeeded) {
12602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    node.scrollIntoViewIfNeeded();
12612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    break;
12622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                }
12632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            }
12642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }
12652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
12662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
12672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    _setCaretLocation: function(line, column, scrollIntoView)
12682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
12692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var range = new WebInspector.TextRange(line, column, line, column);
12702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._restoreSelection(range, scrollIntoView);
12718a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
12728a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
12738a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    _selectionToPosition: function(container, offset)
12748a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
127581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (container === this._container && offset === 0)
12768a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            return { line: 0, column: 0 };
127781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (container === this._container && offset === 1)
12788a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            return { line: this._textModel.linesCount - 1, column: this._textModel.lineLength(this._textModel.linesCount - 1) };
12798a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
12802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var lineRow = this._enclosingLineRowOrSelf(container);
12818a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        var lineNumber = lineRow.lineNumber;
12822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (container === lineRow && offset === 0)
12838a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            return { line: lineNumber, column: 0 };
12848a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
12852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        // This may be chunk and chunks may contain \n.
12868a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        var column = 0;
12872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var node = lineRow.nodeType === Node.TEXT_NODE ? lineRow : lineRow.traverseNextTextNode(lineRow);
1288ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        while (node && node !== container) {
12892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            var text = node.textContent;
12902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            for (var i = 0; i < text.length; ++i) {
12912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                if (text.charAt(i) === "\n") {
12922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    lineNumber++;
12932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    column = 0;
12942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                } else
12952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    column++;
12962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            }
12972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            node = node.traverseNextTextNode(lineRow);
1298ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1299ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
1300ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (node === container && offset) {
1301ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            var text = node.textContent;
13028a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            for (var i = 0; i < offset; ++i) {
13038a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block                if (text.charAt(i) === "\n") {
13048a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block                    lineNumber++;
13058a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block                    column = 0;
13068a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block                } else
1307ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block                    column++;
13088a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            }
13098a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        }
1310ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return { line: lineNumber, column: column };
13118a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
13128a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
13132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _positionToSelection: function(line, column)
13142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
131581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var chunk = this.chunkForLine(line);
13162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // One-lined collapsed chunks may still stay highlighted.
13172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var lineRow = chunk.linesCount === 1 ? chunk.element : chunk.getExpandedLineRow(line);
13182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (lineRow)
13192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            var rangeBoundary = lineRow.rangeBoundaryForOffset(column);
13202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        else {
13212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            var offset = column;
13222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            for (var i = chunk.startLine; i < line; ++i)
13232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                offset += this._textModel.lineLength(i) + 1; // \n
13242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            lineRow = chunk.element;
13252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (lineRow.firstChild)
13262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                var rangeBoundary = { container: lineRow.firstChild, offset: offset };
13272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            else
13282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                var rangeBoundary = { container: lineRow, offset: 0 };
13292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
13302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return rangeBoundary;
13312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
13322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
13332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    _enclosingLineRowOrSelf: function(element)
13342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
13352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var lineRow = element.enclosingNodeOrSelfWithClass("webkit-line-content");
13362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (lineRow)
13372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return lineRow;
13382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        for (var lineRow = element; lineRow; lineRow = lineRow.parentElement) {
13392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (lineRow.parentElement === this._container)
13402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                return lineRow;
13412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }
13422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return null;
13432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
13442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1345692e5dbf12901edacf14812a6fae25462920af42Steve Block    _appendSpan: function(element, content, className)
13468a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
1347692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (className === "html-resource-link" || className === "html-external-link") {
1348692e5dbf12901edacf14812a6fae25462920af42Steve Block            element.appendChild(this._createLink(content, className === "html-external-link"));
1349692e5dbf12901edacf14812a6fae25462920af42Steve Block            return;
1350692e5dbf12901edacf14812a6fae25462920af42Steve Block        }
13518a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
1352692e5dbf12901edacf14812a6fae25462920af42Steve Block        var span = this._cachedSpans.pop() || document.createElement("span");
13538a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        span.className = "webkit-" + className;
1354692e5dbf12901edacf14812a6fae25462920af42Steve Block        span.textContent = content;
1355692e5dbf12901edacf14812a6fae25462920af42Steve Block        element.appendChild(span);
1356692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (!("spans" in element))
1357692e5dbf12901edacf14812a6fae25462920af42Steve Block            element.spans = [];
1358692e5dbf12901edacf14812a6fae25462920af42Steve Block        element.spans.push(span);
1359692e5dbf12901edacf14812a6fae25462920af42Steve Block    },
1360692e5dbf12901edacf14812a6fae25462920af42Steve Block
1361692e5dbf12901edacf14812a6fae25462920af42Steve Block    _appendTextNode: function(element, text)
1362692e5dbf12901edacf14812a6fae25462920af42Steve Block    {
1363692e5dbf12901edacf14812a6fae25462920af42Steve Block        var textNode = this._cachedTextNodes.pop();
13642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (textNode)
1365692e5dbf12901edacf14812a6fae25462920af42Steve Block            textNode.nodeValue = text;
13662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        else
1367692e5dbf12901edacf14812a6fae25462920af42Steve Block            textNode = document.createTextNode(text);
1368692e5dbf12901edacf14812a6fae25462920af42Steve Block        element.appendChild(textNode);
1369692e5dbf12901edacf14812a6fae25462920af42Steve Block        if (!("textNodes" in element))
1370692e5dbf12901edacf14812a6fae25462920af42Steve Block            element.textNodes = [];
1371692e5dbf12901edacf14812a6fae25462920af42Steve Block        element.textNodes.push(textNode);
13728a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
13738a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
13748a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    _createLink: function(content, isExternal)
13758a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
13768a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        var quote = content.charAt(0);
13778a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        if (content.length > 1 && (quote === "\"" ||   quote === "'"))
13788a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            content = content.substring(1, content.length - 1);
13798a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        else
13808a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            quote = null;
13818a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
13828a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        var a = WebInspector.linkifyURLAsNode(this._rewriteHref(content), content, null, isExternal);
13838a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        var span = document.createElement("span");
13848a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        span.className = "webkit-html-attribute-value";
13858a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        if (quote)
13868a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            span.appendChild(document.createTextNode(quote));
13878a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        span.appendChild(a);
13888a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        if (quote)
13898a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            span.appendChild(document.createTextNode(quote));
13908a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return span;
13918a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
13928a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
13938a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    _rewriteHref: function(hrefValue, isExternal)
13948a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
13958a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        if (!this._url || !hrefValue || hrefValue.indexOf("://") > 0)
13968a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            return hrefValue;
13978a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return WebInspector.completeURL(this._url, hrefValue);
13988a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
13998a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
14002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    _handleDOMUpdates: function(e)
14018a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
140281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (this._domUpdateCoalescingLevel)
140381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return;
140481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
14052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        var target = e.target;
140681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (target === this._container)
140781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return;
140881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
14092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var lineRow = this._enclosingLineRowOrSelf(target);
141081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (!lineRow)
14112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return;
141281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
141381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (lineRow.decorationsElement && (lineRow.decorationsElement === target || lineRow.decorationsElement.isAncestor(target))) {
141481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (this._syncDecorationsForLineListener)
14152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                this._syncDecorationsForLineListener(lineRow.lineNumber);
141681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return;
141781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
141881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
141981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (this._readOnly)
142081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return;
142181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
14222bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (target === lineRow && e.type === "DOMNodeInserted") {
14232bde8e466a4451c7319e3a072d118917957d6554Steve Block            // Ensure that the newly inserted line row has no lineNumber.
14242bde8e466a4451c7319e3a072d118917957d6554Steve Block            delete lineRow.lineNumber;
14252bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
14262bde8e466a4451c7319e3a072d118917957d6554Steve Block
14272bde8e466a4451c7319e3a072d118917957d6554Steve Block        var startLine = 0;
14282bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (var row = lineRow; row; row = row.previousSibling) {
14292bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (typeof row.lineNumber === "number") {
14302bde8e466a4451c7319e3a072d118917957d6554Steve Block                startLine = row.lineNumber;
14312bde8e466a4451c7319e3a072d118917957d6554Steve Block                break;
14322bde8e466a4451c7319e3a072d118917957d6554Steve Block            }
14332bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
14342bde8e466a4451c7319e3a072d118917957d6554Steve Block
14352bde8e466a4451c7319e3a072d118917957d6554Steve Block        var endLine = startLine + 1;
14362bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (var row = lineRow.nextSibling; row; row = row.nextSibling) {
14372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (typeof row.lineNumber === "number" && row.lineNumber > startLine) {
14382bde8e466a4451c7319e3a072d118917957d6554Steve Block                endLine = row.lineNumber;
14392bde8e466a4451c7319e3a072d118917957d6554Steve Block                break;
14402bde8e466a4451c7319e3a072d118917957d6554Steve Block            }
14412bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
14422bde8e466a4451c7319e3a072d118917957d6554Steve Block
14432bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (target === lineRow && e.type === "DOMNodeRemoved") {
14442bde8e466a4451c7319e3a072d118917957d6554Steve Block            // Now this will no longer be valid.
14452bde8e466a4451c7319e3a072d118917957d6554Steve Block            delete lineRow.lineNumber;
14462bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
14472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
144881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (this._dirtyLines) {
14492bde8e466a4451c7319e3a072d118917957d6554Steve Block            this._dirtyLines.start = Math.min(this._dirtyLines.start, startLine);
14502bde8e466a4451c7319e3a072d118917957d6554Steve Block            this._dirtyLines.end = Math.max(this._dirtyLines.end, endLine);
145181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        } else {
14522bde8e466a4451c7319e3a072d118917957d6554Steve Block            this._dirtyLines = { start: startLine, end: endLine };
145381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            setTimeout(this._applyDomUpdates.bind(this), 0);
145481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            // Remove marked ranges, if any.
145581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this.markAndRevealRange(null);
145681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
145781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
145881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
145981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    _applyDomUpdates: function()
146081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
146181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (!this._dirtyLines)
146281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return;
146381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
146481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // Check if the editor had been set readOnly by the moment when this async callback got executed.
146581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (this._readOnly) {
146681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            delete this._dirtyLines;
146781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return;
146881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
146981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
147081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // This is a "foreign" call outside of this class. Should be before we delete the dirty lines flag.
147181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._enterTextChangeMode();
147281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
147381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var dirtyLines = this._dirtyLines;
147481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        delete this._dirtyLines;
147581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
147681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var firstChunkNumber = this._chunkNumberForLine(dirtyLines.start);
147781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var startLine = this._textChunks[firstChunkNumber].startLine;
147881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var endLine = this._textModel.linesCount;
147981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
148081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // Collect lines.
148181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var firstLineRow;
148281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (firstChunkNumber) {
148381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            var chunk = this._textChunks[firstChunkNumber - 1];
148481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            firstLineRow = chunk.expanded ? chunk.getExpandedLineRow(chunk.startLine + chunk.linesCount - 1) : chunk.element;
148581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            firstLineRow = firstLineRow.nextSibling;
148681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        } else
148781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            firstLineRow = this._container.firstChild;
148881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
148981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var lines = [];
149081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        for (var lineRow = firstLineRow; lineRow; lineRow = lineRow.nextSibling) {
149181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (typeof lineRow.lineNumber === "number" && lineRow.lineNumber >= dirtyLines.end) {
149281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                endLine = lineRow.lineNumber;
149381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                break;
149481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
149581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            // Update with the newest lineNumber, so that the call to the _getSelection method below should work.
149681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            lineRow.lineNumber = startLine + lines.length;
149781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this._collectLinesFromDiv(lines, lineRow);
149881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
149981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
15002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // Try to decrease the range being replaced, if possible.
150181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var startOffset = 0;
150281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        while (startLine < dirtyLines.start && startOffset < lines.length) {
150381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (this._textModel.line(startLine) !== lines[startOffset])
150481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                break;
150581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            ++startOffset;
150681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            ++startLine;
150781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
150881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
150981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var endOffset = lines.length;
151081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        while (endLine > dirtyLines.end && endOffset > startOffset) {
151181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (this._textModel.line(endLine - 1) !== lines[endOffset - 1])
151281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                break;
151381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            --endOffset;
151481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            --endLine;
151581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
151681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
151781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        lines = lines.slice(startOffset, endOffset);
151881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
15192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // Try to decrease the range being replaced by column offsets, if possible.
15202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var startColumn = 0;
15212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var endColumn = this._textModel.lineLength(endLine - 1);
15222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (lines.length > 0) {
15232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            var line1 = this._textModel.line(startLine);
15242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            var line2 = lines[0];
15252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            while (line1[startColumn] && line1[startColumn] === line2[startColumn])
15262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                ++startColumn;
15272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            lines[0] = line2.substring(startColumn);
15282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
15292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            var line1 = this._textModel.line(endLine - 1);
15302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            var line2 = lines[lines.length - 1];
15312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            for (var i = 0; i < endColumn && i < line2.length; ++i) {
15322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                if (startLine === endLine - 1 && endColumn - i <= startColumn)
15332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    break;
15342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                if (line1[endColumn - i - 1] !== line2[line2.length - i - 1])
15352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    break;
15362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            }
15372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (i) {
15382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                endColumn -= i;
15392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                lines[lines.length - 1] = line2.substring(0, line2.length - i);
15402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            }
15412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }
15422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
154381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var selection = this._getSelection();
154481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
15452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (lines.length === 0 && endLine < this._textModel.linesCount)
154681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            var oldRange = new WebInspector.TextRange(startLine, 0, endLine, 0);
15472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        else if (lines.length === 0 && startLine > 0)
15482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            var oldRange = new WebInspector.TextRange(startLine - 1, this._textModel.lineLength(startLine - 1), endLine - 1, this._textModel.lineLength(endLine - 1));
15492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        else
15502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            var oldRange = new WebInspector.TextRange(startLine, startColumn, endLine - 1, endColumn);
15512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
15522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var newRange = this._setText(oldRange, lines.join("\n"));
15532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
15542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._paintScheduledLines(true);
15552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._restoreSelection(selection);
15562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
15572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._exitTextChangeMode(oldRange, newRange);
15582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
155981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
15602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    textChanged: function(oldRange, newRange)
15612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
156281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this.beginDomUpdates();
156381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._removeDecorationsInRange(oldRange);
156481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._updateChunksForRanges(oldRange, newRange);
156581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._updateHighlightsForRange(newRange);
156681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this.endDomUpdates();
15672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    },
156881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
15692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    _setText: function(range, text)
15702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
15712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (this._lastEditedRange && (!text || text.indexOf("\n") !== -1 || this._lastEditedRange.endLine !== range.startLine || this._lastEditedRange.endColumn !== range.startColumn))
15722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            this._textModel.markUndoableState();
157381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
15742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var newRange = this._textModel.setText(range, text);
15752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        this._lastEditedRange = newRange;
15762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
15772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return newRange;
157881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
157981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
158081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    _removeDecorationsInRange: function(range)
158181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
158281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        for (var i = this._chunkNumberForLine(range.startLine); i < this._textChunks.length; ++i) {
158381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            var chunk = this._textChunks[i];
158481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (chunk.startLine > range.endLine)
158581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                break;
158681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            chunk.removeAllDecorations();
158781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
158881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
158981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
159081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    _updateChunksForRanges: function(oldRange, newRange)
159181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
159281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // Update the chunks in range: firstChunkNumber <= index <= lastChunkNumber
159381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var firstChunkNumber = this._chunkNumberForLine(oldRange.startLine);
159481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var lastChunkNumber = firstChunkNumber;
159581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        while (lastChunkNumber + 1 < this._textChunks.length) {
159681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (this._textChunks[lastChunkNumber + 1].startLine > oldRange.endLine)
159781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                break;
159881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            ++lastChunkNumber;
159981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
160081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
160181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var startLine = this._textChunks[firstChunkNumber].startLine;
160281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var linesCount = this._textChunks[lastChunkNumber].startLine + this._textChunks[lastChunkNumber].linesCount - startLine;
160381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var linesDiff = newRange.linesCount - oldRange.linesCount;
160481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        linesCount += linesDiff;
160581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
160681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (linesDiff) {
160781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            // Lines shifted, update the line numbers of the chunks below.
160881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            for (var chunkNumber = lastChunkNumber + 1; chunkNumber < this._textChunks.length; ++chunkNumber)
160981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                this._textChunks[chunkNumber].startLine += linesDiff;
161081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
161181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
161281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var firstLineRow;
161381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (firstChunkNumber) {
161481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            var chunk = this._textChunks[firstChunkNumber - 1];
161581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            firstLineRow = chunk.expanded ? chunk.getExpandedLineRow(chunk.startLine + chunk.linesCount - 1) : chunk.element;
161681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            firstLineRow = firstLineRow.nextSibling;
161781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        } else
161881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            firstLineRow = this._container.firstChild;
161981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
162081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // Most frequent case: a chunk remained the same.
162181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        for (var chunkNumber = firstChunkNumber; chunkNumber <= lastChunkNumber; ++chunkNumber) {
162281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            var chunk = this._textChunks[chunkNumber];
16232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (chunk.startLine + chunk.linesCount > this._textModel.linesCount)
16242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                break;
162581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            var lineNumber = chunk.startLine;
162681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            for (var lineRow = firstLineRow; lineRow && lineNumber < chunk.startLine + chunk.linesCount; lineRow = lineRow.nextSibling) {
162781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (lineRow.lineNumber !== lineNumber || lineRow !== chunk.getExpandedLineRow(lineNumber) || lineRow.textContent !== this._textModel.line(lineNumber) || !lineRow.firstChild)
162881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    break;
162981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                ++lineNumber;
163081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
163181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (lineNumber < chunk.startLine + chunk.linesCount)
163281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                break;
163381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            chunk.updateCollapsedLineRow();
163481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            ++firstChunkNumber;
163581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            firstLineRow = lineRow;
163681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            startLine += chunk.linesCount;
163781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            linesCount -= chunk.linesCount;
163881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
163981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
164081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (firstChunkNumber > lastChunkNumber && linesCount === 0)
164181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return;
164281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
164381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // Maybe merge with the next chunk, so that we should not create 1-sized chunks when appending new lines one by one.
164481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var chunk = this._textChunks[lastChunkNumber + 1];
164581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var linesInLastChunk = linesCount % this._defaultChunkSize;
164681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (chunk && !chunk.decorated && linesInLastChunk > 0 && linesInLastChunk + chunk.linesCount <= this._defaultChunkSize) {
164781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            ++lastChunkNumber;
164881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            linesCount += chunk.linesCount;
164981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
165081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
165181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var scrollTop = this.element.scrollTop;
165281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var scrollLeft = this.element.scrollLeft;
165381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
165481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // Delete all DOM elements that were either controlled by the old chunks, or have just been inserted.
165581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var firstUnmodifiedLineRow = null;
165681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var chunk = this._textChunks[lastChunkNumber + 1];
165781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (chunk) {
165881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            firstUnmodifiedLineRow = chunk.expanded ? chunk.getExpandedLineRow(chunk.startLine) : chunk.element;
16592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
166081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        while (firstLineRow && firstLineRow !== firstUnmodifiedLineRow) {
166181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            var lineRow = firstLineRow;
166281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            firstLineRow = firstLineRow.nextSibling;
166381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this._container.removeChild(lineRow);
166481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
166581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
166681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // Replace old chunks with the new ones.
166781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        for (var chunkNumber = firstChunkNumber; linesCount > 0; ++chunkNumber) {
166881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            var chunkLinesCount = Math.min(this._defaultChunkSize, linesCount);
166981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            var newChunk = this._createNewChunk(startLine, startLine + chunkLinesCount);
167081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this._container.insertBefore(newChunk.element, firstUnmodifiedLineRow);
167181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
167281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (chunkNumber <= lastChunkNumber)
167381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                this._textChunks[chunkNumber] = newChunk;
167481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            else
167581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                this._textChunks.splice(chunkNumber, 0, newChunk);
167681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            startLine += chunkLinesCount;
167781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            linesCount -= chunkLinesCount;
167881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
167981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (chunkNumber <= lastChunkNumber)
168081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this._textChunks.splice(chunkNumber, lastChunkNumber - chunkNumber + 1);
168181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
168281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this.element.scrollTop = scrollTop;
168381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this.element.scrollLeft = scrollLeft;
168481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
168581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
168681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    _updateHighlightsForRange: function(range)
168781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
168881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var visibleFrom = this.element.scrollTop;
168981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var visibleTo = this.element.scrollTop + this.element.clientHeight;
169081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
169181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var result = this._findVisibleChunks(visibleFrom, visibleTo);
169281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var chunk = this._textChunks[result.end - 1];
169381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var lastVisibleLine = chunk.startLine + chunk.linesCount;
169481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
16952bde8e466a4451c7319e3a072d118917957d6554Steve Block        lastVisibleLine = Math.max(lastVisibleLine, range.endLine + 1);
16962bde8e466a4451c7319e3a072d118917957d6554Steve Block        lastVisibleLine = Math.min(lastVisibleLine, this._textModel.linesCount);
169781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
169881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var updated = this._highlighter.updateHighlight(range.startLine, lastVisibleLine);
169981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (!updated) {
170081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            // Highlights for the chunks below are invalid, so just collapse them.
170181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            for (var i = this._chunkNumberForLine(range.startLine); i < this._textChunks.length; ++i)
170281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                this._textChunks[i].expanded = false;
170381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
170481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
170581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._repaintAll();
170681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
170781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
170881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    _collectLinesFromDiv: function(lines, element)
170981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
171081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var textContents = [];
17112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        var node = element.nodeType === Node.TEXT_NODE ? element : element.traverseNextNode(element);
171281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        while (node) {
171381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (element.decorationsElement === node) {
171481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                node = node.nextSibling;
171581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                continue;
171681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
171781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (node.nodeName.toLowerCase() === "br")
171881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                textContents.push("\n");
171981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            else if (node.nodeType === Node.TEXT_NODE)
172081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                textContents.push(node.textContent);
172181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            node = node.traverseNextNode(element);
172281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
172381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
172481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var textContent = textContents.join("");
172581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // The last \n (if any) does not "count" in a DIV.
172681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        textContent = textContent.replace(/\n$/, "");
172781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
172881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        textContents = textContent.split("\n");
172981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        for (var i = 0; i < textContents.length; ++i)
173081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            lines.push(textContents[i]);
17318a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    }
17328a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block}
17338a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
17342fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockWebInspector.TextEditorMainPanel.prototype.__proto__ = WebInspector.TextEditorChunkedPanel.prototype;
1735692e5dbf12901edacf14812a6fae25462920af42Steve Block
17362fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockWebInspector.TextEditorMainChunk = function(textViewer, startLine, endLine)
17378a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{
1738692e5dbf12901edacf14812a6fae25462920af42Steve Block    this._textViewer = textViewer;
1739692e5dbf12901edacf14812a6fae25462920af42Steve Block    this._textModel = textViewer._textModel;
17402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
17412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this.element = document.createElement("div");
17428a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    this.element.lineNumber = startLine;
17432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    this.element.className = "webkit-line-content";
174481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    this.element.addEventListener("DOMNodeRemoved", this._textViewer._handleDOMUpdatesCallback, false);
17458a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
174681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    this._startLine = startLine;
17478a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    endLine = Math.min(this._textModel.linesCount, endLine);
17488a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    this.linesCount = endLine - startLine;
17498a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
17508a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    this._expanded = false;
17518a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
175281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    this.updateCollapsedLineRow();
17538a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block}
17548a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
17552fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockWebInspector.TextEditorMainChunk.prototype = {
17568a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    addDecoration: function(decoration)
17578a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
175881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._textViewer.beginDomUpdates();
175981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (typeof decoration === "string")
17608a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            this.element.addStyleClass(decoration);
176181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        else {
176281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (!this.element.decorationsElement) {
176381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                this.element.decorationsElement = document.createElement("div");
176481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                this.element.decorationsElement.className = "webkit-line-decorations";
176581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                this.element.appendChild(this.element.decorationsElement);
176681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
176781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this.element.decorationsElement.appendChild(decoration);
17688a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        }
176981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._textViewer.endDomUpdates();
17708a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
17718a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
17728a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    removeDecoration: function(decoration)
17738a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
177481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._textViewer.beginDomUpdates();
177581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (typeof decoration === "string")
17768a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            this.element.removeStyleClass(decoration);
177781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        else if (this.element.decorationsElement)
177881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this.element.decorationsElement.removeChild(decoration);
177981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._textViewer.endDomUpdates();
178081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
178181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
178281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    removeAllDecorations: function()
178381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
178481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._textViewer.beginDomUpdates();
178581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this.element.className = "webkit-line-content";
178681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (this.element.decorationsElement) {
178781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this.element.removeChild(this.element.decorationsElement);
178881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            delete this.element.decorationsElement;
178981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
179081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._textViewer.endDomUpdates();
179181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
179281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
179381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    get decorated()
179481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
179581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return this.element.className !== "webkit-line-content" || !!(this.element.decorationsElement && this.element.decorationsElement.firstChild);
179681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
179781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
179881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    get startLine()
179981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
180081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return this._startLine;
180181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
180281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
180381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    set startLine(startLine)
180481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
180581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._startLine = startLine;
180681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this.element.lineNumber = startLine;
180781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (this._expandedLineRows) {
180881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            for (var i = 0; i < this._expandedLineRows.length; ++i)
180981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                this._expandedLineRows[i].lineNumber = startLine + i;
18108a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        }
18118a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
18128a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
18138a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    get expanded()
18148a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
18158a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        return this._expanded;
18168a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
18178a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
18188a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    set expanded(expanded)
18198a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
18208a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        if (this._expanded === expanded)
18218a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            return;
18228a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
18238a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        this._expanded = expanded;
18248a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
18258a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        if (this.linesCount === 1) {
18268a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            if (expanded)
18272bde8e466a4451c7319e3a072d118917957d6554Steve Block                this._textViewer._paintLine(this.element);
18288a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            return;
18298a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        }
18308a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
183181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._textViewer.beginDomUpdates();
183281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
18338a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        if (expanded) {
18342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            this._expandedLineRows = [];
18358a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            var parentElement = this.element.parentElement;
18368a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) {
1837692e5dbf12901edacf14812a6fae25462920af42Steve Block                var lineRow = this._createRow(i);
18388a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block                parentElement.insertBefore(lineRow, this.element);
18392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                this._expandedLineRows.push(lineRow);
18408a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            }
18418a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            parentElement.removeChild(this.element);
18422bde8e466a4451c7319e3a072d118917957d6554Steve Block            this._textViewer._paintLines(this.startLine, this.startLine + this.linesCount);
18438a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        } else {
18442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            var elementInserted = false;
18452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            for (var i = 0; i < this._expandedLineRows.length; ++i) {
18462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                var lineRow = this._expandedLineRows[i];
18472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                var parentElement = lineRow.parentElement;
18482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                if (parentElement) {
18492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    if (!elementInserted) {
18502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        elementInserted = true;
18512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        parentElement.insertBefore(this.element, lineRow);
18522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    }
18532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    parentElement.removeChild(lineRow);
18542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                }
185581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                this._textViewer._releaseLinesHighlight(lineRow);
18568a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            }
18572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            delete this._expandedLineRows;
18588a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        }
185981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
186081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this._textViewer.endDomUpdates();
18618a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
18628a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
18638a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    get height()
18648a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
18652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (!this._expandedLineRows)
18662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return this._textViewer._totalHeight(this.element);
18672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return this._textViewer._totalHeight(this._expandedLineRows[0], this._expandedLineRows[this._expandedLineRows.length - 1]);
18688a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    },
18698a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
187081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    get offsetTop()
187181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
187281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return (this._expandedLineRows && this._expandedLineRows.length) ? this._expandedLineRows[0].offsetTop : this.element.offsetTop;
187381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
187481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
1875692e5dbf12901edacf14812a6fae25462920af42Steve Block    _createRow: function(lineNumber)
18768a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    {
18772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        var lineRow = this._textViewer._cachedRows.pop() || document.createElement("div");
1878692e5dbf12901edacf14812a6fae25462920af42Steve Block        lineRow.lineNumber = lineNumber;
18792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        lineRow.className = "webkit-line-content";
188081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        lineRow.addEventListener("DOMNodeRemoved", this._textViewer._handleDOMUpdatesCallback, false);
18812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        lineRow.textContent = this._textModel.line(lineNumber);
18822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (!lineRow.textContent)
18832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            lineRow.appendChild(document.createElement("br"));
1884692e5dbf12901edacf14812a6fae25462920af42Steve Block        return lineRow;
18852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    },
18862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
18872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    getExpandedLineRow: function(lineNumber)
18882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    {
18892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (!this._expanded || lineNumber < this.startLine || lineNumber >= this.startLine + this.linesCount)
18902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return null;
18912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (!this._expandedLineRows)
18922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            return this.element;
18932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return this._expandedLineRows[lineNumber - this.startLine];
189481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    },
189581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
189681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    updateCollapsedLineRow: function()
189781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    {
189881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (this.linesCount === 1 && this._expanded)
189981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return;
190081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
190181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        var lines = [];
190281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        for (var i = this.startLine; i < this.startLine + this.linesCount; ++i)
190381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            lines.push(this._textModel.line(i));
190481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
190581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this.element.removeChildren();
190681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        this.element.textContent = lines.join("\n");
190781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
190881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // The last empty line will get swallowed otherwise.
190981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (!lines[lines.length - 1])
191081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            this.element.appendChild(document.createElement("br"));
19118a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    }
19128a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block}
1913