Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / devtools / front_end / Linkifier.js
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  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 /**
32  * @interface
33  */
34 WebInspector.LinkifierFormatter = function()
35 {
36 }
37
38 WebInspector.LinkifierFormatter.prototype = {
39     /**
40      * @param {!Element} anchor
41      * @param {!WebInspector.UILocation} uiLocation
42      */
43     formatLiveAnchor: function(anchor, uiLocation) { }
44 }
45
46 /**
47  * @constructor
48  * @param {!WebInspector.LinkifierFormatter=} formatter
49  */
50 WebInspector.Linkifier = function(formatter)
51 {
52     this._formatter = formatter || new WebInspector.Linkifier.DefaultFormatter(WebInspector.Linkifier.MaxLengthForDisplayedURLs);
53     this._liveLocations = [];
54 }
55
56 /**
57  * @param {!WebInspector.Linkifier.LinkHandler} handler
58  */
59 WebInspector.Linkifier.setLinkHandler = function(handler)
60 {
61     WebInspector.Linkifier._linkHandler = handler;
62 }
63
64 /**
65  * @param {string} url
66  * @param {number=} lineNumber
67  * @return {boolean}
68  */
69 WebInspector.Linkifier.handleLink = function(url, lineNumber)
70 {
71     if (!WebInspector.Linkifier._linkHandler)
72         return false;
73     return WebInspector.Linkifier._linkHandler.handleLink(url, lineNumber)
74 }
75
76 /**
77  * @param {!Object} revealable
78  * @param {string} text
79  * @param {string=} fallbackHref
80  * @param {number=} fallbackLineNumber
81  * @param {string=} title
82  * @param {string=} classes
83  * @return {!Element}
84  */
85 WebInspector.Linkifier.linkifyUsingRevealer = function(revealable, text, fallbackHref, fallbackLineNumber, title, classes)
86 {
87     var a = document.createElement("a");
88     a.className = (classes || "") + " webkit-html-resource-link";
89     a.textContent = text.trimMiddle(WebInspector.Linkifier.MaxLengthForDisplayedURLs);
90     a.title = title || text;
91     if (fallbackHref) {
92         a.href = fallbackHref;
93         a.lineNumber = fallbackLineNumber;
94     }
95     /**
96      * @param {?Event} event
97      * @this {Object}
98      */
99     function clickHandler(event)
100     {
101         event.consume(true);
102         if (fallbackHref && WebInspector.Linkifier.handleLink(fallbackHref, fallbackLineNumber))
103             return;
104
105         WebInspector.Revealer.reveal(this);
106     }
107     a.addEventListener("click", clickHandler.bind(revealable), false);
108     return a;
109 }
110
111 WebInspector.Linkifier.prototype = {
112     /**
113      * @param {string} sourceURL
114      * @param {number} lineNumber
115      * @param {number=} columnNumber
116      * @param {string=} classes
117      * @return {?Element}
118      */
119     linkifyLocation: function(sourceURL, lineNumber, columnNumber, classes)
120     {
121         var rawLocation = WebInspector.debuggerModel.createRawLocationByURL(sourceURL, lineNumber, columnNumber || 0);
122         if (!rawLocation)
123             return WebInspector.linkifyResourceAsNode(sourceURL, lineNumber, classes);
124         return this.linkifyRawLocation(rawLocation, classes);
125     },
126
127     /**
128      * @param {!WebInspector.DebuggerModel.Location} rawLocation
129      * @param {string=} classes
130      * @return {?Element}
131      */
132     linkifyRawLocation: function(rawLocation, classes)
133     {
134         var script = WebInspector.debuggerModel.scriptForId(rawLocation.scriptId);
135         if (!script)
136             return null;
137         var anchor = this._createAnchor(classes);
138         var liveLocation = script.createLiveLocation(rawLocation, this._updateAnchor.bind(this, anchor));
139         this._liveLocations.push(liveLocation);
140         return anchor;
141     },
142
143     /**
144      * @param {?CSSAgent.StyleSheetId} styleSheetId
145      * @param {!WebInspector.CSSLocation} rawLocation
146      * @param {string=} classes
147      * @return {?Element}
148      */
149     linkifyCSSLocation: function(styleSheetId, rawLocation, classes)
150     {
151         var anchor = this._createAnchor(classes);
152         var liveLocation = WebInspector.cssModel.createLiveLocation(styleSheetId, rawLocation, this._updateAnchor.bind(this, anchor));
153         if (!liveLocation)
154             return null;
155         this._liveLocations.push(liveLocation);
156         return anchor;
157     },
158
159     /**
160      * @param {string=} classes
161      * @return {!Element}
162      */
163     _createAnchor: function(classes)
164     {
165         var anchor = document.createElement("a");
166         anchor.className = (classes || "") + " webkit-html-resource-link";
167
168         /**
169          * @param {?Event} event
170          */
171         function clickHandler(event)
172         {
173             event.consume(true);
174             if (!anchor.__uiLocation)
175                 return;
176             if (WebInspector.Linkifier.handleLink(anchor.__uiLocation.url(), anchor.__uiLocation.lineNumber))
177                 return;
178             WebInspector.Revealer.reveal(anchor.__uiLocation);
179         }
180         anchor.addEventListener("click", clickHandler, false);
181         return anchor;
182     },
183
184     reset: function()
185     {
186         for (var i = 0; i < this._liveLocations.length; ++i)
187             this._liveLocations[i].dispose();
188         this._liveLocations = [];
189     },
190
191     /**
192      * @param {!Element} anchor
193      * @param {!WebInspector.UILocation} uiLocation
194      */
195     _updateAnchor: function(anchor, uiLocation)
196     {
197         anchor.__uiLocation = uiLocation;
198         this._formatter.formatLiveAnchor(anchor, uiLocation);
199     }
200 }
201
202 /**
203  * @constructor
204  * @implements {WebInspector.LinkifierFormatter}
205  * @param {number=} maxLength
206  */
207 WebInspector.Linkifier.DefaultFormatter = function(maxLength)
208 {
209     this._maxLength = maxLength;
210 }
211
212 WebInspector.Linkifier.DefaultFormatter.prototype = {
213     /**
214      * @param {!Element} anchor
215      * @param {!WebInspector.UILocation} uiLocation
216      */
217     formatLiveAnchor: function(anchor, uiLocation)
218     {
219         var text = uiLocation.linkText();
220         if (this._maxLength)
221             text = text.trimMiddle(this._maxLength);
222         anchor.textContent = text;
223
224         var titleText = uiLocation.uiSourceCode.originURL();
225         if (typeof uiLocation.lineNumber === "number")
226             titleText += ":" + (uiLocation.lineNumber + 1);
227         anchor.title = titleText;
228     }
229 }
230
231 /**
232  * @constructor
233  * @extends {WebInspector.Linkifier.DefaultFormatter}
234  */
235 WebInspector.Linkifier.DefaultCSSFormatter = function()
236 {
237     WebInspector.Linkifier.DefaultFormatter.call(this, WebInspector.Linkifier.DefaultCSSFormatter.MaxLengthForDisplayedURLs);
238 }
239
240 WebInspector.Linkifier.DefaultCSSFormatter.MaxLengthForDisplayedURLs = 30;
241
242 WebInspector.Linkifier.DefaultCSSFormatter.prototype = {
243     /**
244      * @param {!Element} anchor
245      * @param {!WebInspector.UILocation} uiLocation
246      */
247     formatLiveAnchor: function(anchor, uiLocation)
248     {
249         WebInspector.Linkifier.DefaultFormatter.prototype.formatLiveAnchor.call(this, anchor, uiLocation);
250         anchor.classList.add("webkit-html-resource-link");
251         anchor.setAttribute("data-uncopyable", anchor.textContent);
252         anchor.textContent = "";
253     },
254     __proto__: WebInspector.Linkifier.DefaultFormatter.prototype
255 }
256
257 /**
258  * The maximum number of characters to display in a URL.
259  * @const
260  * @type {number}
261  */
262 WebInspector.Linkifier.MaxLengthForDisplayedURLs = 150;
263
264 /**
265  * @interface
266  */
267 WebInspector.Linkifier.LinkHandler = function()
268 {
269 }
270
271 WebInspector.Linkifier.LinkHandler.prototype = {
272     /**
273      * @param {string} url
274      * @param {number=} lineNumber
275      * @return {boolean}
276      */
277     handleLink: function(url, lineNumber) {}
278 }
279
280 /**
281  * @param {string} scriptId
282  * @param {number} lineNumber
283  * @param {number=} columnNumber
284  */
285 WebInspector.Linkifier.liveLocationText = function(scriptId, lineNumber, columnNumber)
286 {
287     var script = WebInspector.debuggerModel.scriptForId(scriptId);
288     if (!script)
289         return "";
290     var uiLocation = script.rawLocationToUILocation(lineNumber, columnNumber);
291     return uiLocation.linkText();
292 }