home *** CD-ROM | disk | FTP | other *** search
/ Computer Active Guide 2009 July / CAG7.ISO / Internetas / SafariSetup.exe / AppleApplicationSupport.msi / WebKit.resources_inspector_SourceView.js < prev    next >
Encoding:
Text File  |  2010-06-03  |  9.2 KB  |  284 lines

  1. /*
  2.  * Copyright (C) 2007, 2008 Apple 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
  6.  * are met:
  7.  *
  8.  * 1.  Redistributions of source code must retain the above copyright
  9.  *     notice, this list of conditions and the following disclaimer.
  10.  * 2.  Redistributions in binary form must reproduce the above copyright
  11.  *     notice, this list of conditions and the following disclaimer in the
  12.  *     documentation and/or other materials provided with the distribution.
  13.  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
  14.  *     its contributors may be used to endorse or promote products derived
  15.  *     from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
  18.  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20.  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
  21.  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22.  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  24.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. WebInspector.SourceView = function(resource)
  30. {
  31.     WebInspector.ResourceView.call(this, resource);
  32.  
  33.     this.element.addStyleClass("source");
  34.  
  35.     var canEditScripts = WebInspector.panels.scripts.canEditScripts() && resource.type === WebInspector.Resource.Type.Script;
  36.     this.sourceFrame = new WebInspector.SourceFrame(this.contentElement, this._addBreakpoint.bind(this), this._removeBreakpoint.bind(this), canEditScripts ? this._editLine.bind(this) : null);
  37.     resource.addEventListener("finished", this._resourceLoadingFinished, this);
  38.     this._frameNeedsSetup = true;
  39. }
  40.  
  41. // This is a map from resource.type to mime types
  42. // found in WebInspector.SourceTokenizer.Registry.
  43. WebInspector.SourceView.DefaultMIMETypeForResourceType = {
  44.     0: "text/html",
  45.     1: "text/css",
  46.     4: "text/javascript"
  47. }
  48.  
  49. WebInspector.SourceView.prototype = {
  50.     show: function(parentElement)
  51.     {
  52.         WebInspector.ResourceView.prototype.show.call(this, parentElement);
  53.         this.sourceFrame.visible = true;
  54.         this.resize();
  55.     },
  56.  
  57.     hide: function()
  58.     {
  59.         WebInspector.View.prototype.hide.call(this);
  60.         this.sourceFrame.visible = false;
  61.         this._currentSearchResultIndex = -1;
  62.     },
  63.  
  64.     resize: function()
  65.     {
  66.         if (this.sourceFrame)
  67.             this.sourceFrame.resize();
  68.     },
  69.  
  70.     setupSourceFrameIfNeeded: function()
  71.     {
  72.         if (!this._frameNeedsSetup)
  73.             return;
  74.  
  75.         this.attach();
  76.  
  77.         delete this._frameNeedsSetup;
  78.         WebInspector.getResourceContent(this.resource.identifier, this._contentLoaded.bind(this));
  79.     },
  80.  
  81.     hasContentTab: function()
  82.     {
  83.         return true;
  84.     },
  85.  
  86.     contentTabSelected: function()
  87.     {
  88.         this.setupSourceFrameIfNeeded();
  89.     },
  90.  
  91.     _contentLoaded: function(content)
  92.     {
  93.         var mimeType = this._canonicalMimeType(this.resource);
  94.         this.sourceFrame.setContent(mimeType, content, this.resource.url);
  95.         this._sourceFrameSetupFinished();
  96.     },
  97.  
  98.     _canonicalMimeType: function(resource)
  99.     {
  100.         return WebInspector.SourceView.DefaultMIMETypeForResourceType[resource.type] || resource.mimeType;
  101.     },
  102.  
  103.     _resourceLoadingFinished: function(event)
  104.     {
  105.         this._frameNeedsSetup = true;
  106.         this._sourceFrameSetup = false;
  107.         if (this.visible)
  108.             this.setupSourceFrameIfNeeded();
  109.         this.resource.removeEventListener("finished", this._resourceLoadingFinished, this);
  110.     },
  111.  
  112.     _addBreakpoint: function(line)
  113.     {
  114.         var sourceID = this._sourceIDForLine(line);
  115.         if (WebInspector.panels.scripts) {
  116.             var breakpoint = new WebInspector.Breakpoint(this.resource.url, line, sourceID);
  117.             WebInspector.panels.scripts.addBreakpoint(breakpoint);
  118.         }
  119.     },
  120.  
  121.     _removeBreakpoint: function(breakpoint)
  122.     {
  123.         if (WebInspector.panels.scripts)
  124.             WebInspector.panels.scripts.removeBreakpoint(breakpoint);
  125.     },
  126.  
  127.     _editLine: function(line, newContent)
  128.     {
  129.         var lines = [];
  130.         var textModel = this.sourceFrame.textModel;
  131.         for (var i = 0; i < textModel.linesCount; ++i) {
  132.             if (i === line)
  133.                 lines.push(newContent);
  134.             else
  135.                 lines.push(textModel.line(i));
  136.         }
  137.  
  138.         var linesCountToShift = newContent.split("\n").length - 1;
  139.         WebInspector.panels.scripts.editScriptSource(this._sourceIDForLine(line), lines.join("\n"), line, linesCountToShift, this._editLineComplete.bind(this));
  140.     },
  141.  
  142.     _editLineComplete: function(newBody)
  143.     {
  144.         this.sourceFrame.updateContent(newBody);
  145.     },
  146.  
  147.     _sourceIDForLine: function(line)
  148.     {
  149.         var sourceID = null;
  150.         var closestStartingLine = 0;
  151.         var scripts = this.resource.scripts;
  152.         for (var i = 0; i < scripts.length; ++i) {
  153.             var script = scripts[i];
  154.             if (script.startingLine <= line && script.startingLine >= closestStartingLine) {
  155.                 closestStartingLine = script.startingLine;
  156.                 sourceID = script.sourceID;
  157.             }
  158.         }
  159.         return sourceID;
  160.     },
  161.  
  162.     // The rest of the methods in this prototype need to be generic enough to work with a ScriptView.
  163.     // The ScriptView prototype pulls these methods into it's prototype to avoid duplicate code.
  164.  
  165.     searchCanceled: function()
  166.     {
  167.         this._currentSearchResultIndex = -1;
  168.         this._searchResults = [];
  169.         this.sourceFrame.clearMarkedRange();
  170.         delete this._delayedFindSearchMatches;
  171.     },
  172.  
  173.     performSearch: function(query, finishedCallback)
  174.     {
  175.         // Call searchCanceled since it will reset everything we need before doing a new search.
  176.         this.searchCanceled();
  177.  
  178.         this._searchFinishedCallback = finishedCallback;
  179.  
  180.         function findSearchMatches(query, finishedCallback)
  181.         {
  182.             this._searchResults = this.sourceFrame.findSearchMatches(query);
  183.             if (this._searchResults)
  184.                 finishedCallback(this, this._searchResults.length);
  185.         }
  186.  
  187.         if (!this._sourceFrameSetup) {
  188.             // The search is performed in _sourceFrameSetupFinished by calling _delayedFindSearchMatches.
  189.             this._delayedFindSearchMatches = findSearchMatches.bind(this, query, finishedCallback);
  190.             this.setupSourceFrameIfNeeded();
  191.             return;
  192.         }
  193.  
  194.         findSearchMatches.call(this, query, finishedCallback);
  195.     },
  196.  
  197.     jumpToFirstSearchResult: function()
  198.     {
  199.         if (!this._searchResults || !this._searchResults.length)
  200.             return;
  201.         this._currentSearchResultIndex = 0;
  202.         this._jumpToSearchResult(this._currentSearchResultIndex);
  203.     },
  204.  
  205.     jumpToLastSearchResult: function()
  206.     {
  207.         if (!this._searchResults || !this._searchResults.length)
  208.             return;
  209.         this._currentSearchResultIndex = (this._searchResults.length - 1);
  210.         this._jumpToSearchResult(this._currentSearchResultIndex);
  211.     },
  212.  
  213.     jumpToNextSearchResult: function()
  214.     {
  215.         if (!this._searchResults || !this._searchResults.length)
  216.             return;
  217.         if (++this._currentSearchResultIndex >= this._searchResults.length)
  218.             this._currentSearchResultIndex = 0;
  219.         this._jumpToSearchResult(this._currentSearchResultIndex);
  220.     },
  221.  
  222.     jumpToPreviousSearchResult: function()
  223.     {
  224.         if (!this._searchResults || !this._searchResults.length)
  225.             return;
  226.         if (--this._currentSearchResultIndex < 0)
  227.             this._currentSearchResultIndex = (this._searchResults.length - 1);
  228.         this._jumpToSearchResult(this._currentSearchResultIndex);
  229.     },
  230.  
  231.     showingFirstSearchResult: function()
  232.     {
  233.         return (this._currentSearchResultIndex === 0);
  234.     },
  235.  
  236.     showingLastSearchResult: function()
  237.     {
  238.         return (this._searchResults && this._currentSearchResultIndex === (this._searchResults.length - 1));
  239.     },
  240.  
  241.     revealLine: function(lineNumber)
  242.     {
  243.         this.setupSourceFrameIfNeeded();
  244.         this.sourceFrame.revealLine(lineNumber);
  245.     },
  246.  
  247.     highlightLine: function(lineNumber)
  248.     {
  249.         this.setupSourceFrameIfNeeded();
  250.         this.sourceFrame.highlightLine(lineNumber);
  251.     },
  252.  
  253.     addMessage: function(msg)
  254.     {
  255.         this.sourceFrame.addMessage(msg);
  256.     },
  257.  
  258.     clearMessages: function()
  259.     {
  260.         this.sourceFrame.clearMessages();
  261.     },
  262.  
  263.     _jumpToSearchResult: function(index)
  264.     {
  265.         var foundRange = this._searchResults[index];
  266.         if (!foundRange)
  267.             return;
  268.  
  269.         this.sourceFrame.markAndRevealRange(foundRange);
  270.     },
  271.  
  272.     _sourceFrameSetupFinished: function()
  273.     {
  274.         this._sourceFrameSetup = true;
  275.         this.resize();
  276.         if (this._delayedFindSearchMatches) {
  277.             this._delayedFindSearchMatches();
  278.             delete this._delayedFindSearchMatches;
  279.         }
  280.     }
  281. }
  282.  
  283. WebInspector.SourceView.prototype.__proto__ = WebInspector.ResourceView.prototype;
  284.