Home | History | Annotate | Download | only in sources
      1 /*
      2  * Copyright (C) 2012 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  * 1. Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *
     11  * 2. Redistributions in binary form must reproduce the above
     12  * copyright notice, this list of conditions and the following disclaimer
     13  * in the documentation and/or other materials provided with the
     14  * distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
     17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
     20  * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 /**
     30  * @constructor
     31  * @extends {WebInspector.SourceFrame}
     32  * @param {!WebInspector.UISourceCode} uiSourceCode
     33  */
     34 WebInspector.UISourceCodeFrame = function(uiSourceCode)
     35 {
     36     this._uiSourceCode = uiSourceCode;
     37     WebInspector.SourceFrame.call(this, this._uiSourceCode);
     38     WebInspector.settings.textEditorAutocompletion.addChangeListener(this._enableAutocompletionIfNeeded, this);
     39     this._enableAutocompletionIfNeeded();
     40 
     41     this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._onWorkingCopyChanged, this);
     42     this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyCommitted, this);
     43     this._updateStyle();
     44 }
     45 
     46 WebInspector.UISourceCodeFrame.prototype = {
     47     /**
     48      * @return {!WebInspector.UISourceCode}
     49      */
     50     uiSourceCode: function()
     51     {
     52         return this._uiSourceCode;
     53     },
     54 
     55     _enableAutocompletionIfNeeded: function()
     56     {
     57         this.textEditor.setCompletionDictionary(WebInspector.settings.textEditorAutocompletion.get() ? new WebInspector.SampleCompletionDictionary() : null);
     58     },
     59 
     60     wasShown: function()
     61     {
     62         WebInspector.SourceFrame.prototype.wasShown.call(this);
     63         this._boundWindowFocused = this._windowFocused.bind(this);
     64         window.addEventListener("focus", this._boundWindowFocused, false);
     65         this._checkContentUpdated();
     66     },
     67 
     68     willHide: function()
     69     {
     70         WebInspector.SourceFrame.prototype.willHide.call(this);
     71         window.removeEventListener("focus", this._boundWindowFocused, false);
     72         delete this._boundWindowFocused;
     73         this._uiSourceCode.removeWorkingCopyGetter();
     74     },
     75 
     76     /**
     77      * @return {boolean}
     78      */
     79     canEditSource: function()
     80     {
     81         var projectType = this._uiSourceCode.project().type();
     82         if (projectType === WebInspector.projectTypes.Debugger || projectType === WebInspector.projectTypes.Formatter)
     83             return false;
     84         if (projectType === WebInspector.projectTypes.Network && this._uiSourceCode.contentType() === WebInspector.resourceTypes.Document)
     85             return false;
     86         return true;
     87     },
     88 
     89     _windowFocused: function(event)
     90     {
     91         this._checkContentUpdated();
     92     },
     93 
     94     _checkContentUpdated: function()
     95     {
     96         if (!this.loaded || !this.isShowing())
     97             return;
     98         this._uiSourceCode.checkContentUpdated();
     99     },
    100 
    101     commitEditing: function()
    102     {
    103         if (!this._uiSourceCode.isDirty())
    104             return;
    105 
    106         this._muteSourceCodeEvents = true;
    107         this._uiSourceCode.commitWorkingCopy(this._didEditContent.bind(this));
    108         delete this._muteSourceCodeEvents;
    109     },
    110 
    111     onTextChanged: function(oldRange, newRange)
    112     {
    113         WebInspector.SourceFrame.prototype.onTextChanged.call(this, oldRange, newRange);
    114         if (this._isSettingContent)
    115             return;
    116         this._muteSourceCodeEvents = true;
    117         if (this._textEditor.isClean())
    118             this._uiSourceCode.resetWorkingCopy();
    119         else
    120             this._uiSourceCode.setWorkingCopyGetter(this._textEditor.text.bind(this._textEditor));
    121         delete this._muteSourceCodeEvents;
    122     },
    123 
    124     _didEditContent: function(error)
    125     {
    126         if (error) {
    127             WebInspector.messageSink.addErrorMessage(error, true);
    128             return;
    129         }
    130     },
    131 
    132     /**
    133      * @param {!WebInspector.Event} event
    134      */
    135     _onWorkingCopyChanged: function(event)
    136     {
    137         if (this._muteSourceCodeEvents)
    138             return;
    139         this._innerSetContent(this._uiSourceCode.workingCopy());
    140         this.onUISourceCodeContentChanged();
    141     },
    142 
    143     /**
    144      * @param {!WebInspector.Event} event
    145      */
    146     _onWorkingCopyCommitted: function(event)
    147     {
    148         if (!this._muteSourceCodeEvents) {
    149             this._innerSetContent(this._uiSourceCode.workingCopy());
    150             this.onUISourceCodeContentChanged();
    151         }
    152         this._textEditor.markClean();
    153         this._updateStyle();
    154     },
    155 
    156     _updateStyle: function()
    157     {
    158         this.element.classList.toggle("source-frame-unsaved-committed-changes", this._uiSourceCode.hasUnsavedCommittedChanges());
    159     },
    160 
    161     onUISourceCodeContentChanged: function()
    162     {
    163     },
    164 
    165     /**
    166      * @param {string} content
    167      */
    168     _innerSetContent: function(content)
    169     {
    170         this._isSettingContent = true;
    171         this.setContent(content);
    172         delete this._isSettingContent;
    173     },
    174 
    175     populateTextAreaContextMenu: function(contextMenu, lineNumber)
    176     {
    177         WebInspector.SourceFrame.prototype.populateTextAreaContextMenu.call(this, contextMenu, lineNumber);
    178         contextMenu.appendApplicableItems(this._uiSourceCode);
    179         contextMenu.appendSeparator();
    180     },
    181 
    182     dispose: function()
    183     {
    184         WebInspector.settings.textEditorAutocompletion.removeChangeListener(this._enableAutocompletionIfNeeded, this);
    185         this._textEditor.dispose();
    186         this.detach();
    187     },
    188 
    189     __proto__: WebInspector.SourceFrame.prototype
    190 }
    191