Upstream version 5.34.104.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     a.href = fallbackHref;
92     a.lineNumber = fallbackLineNumber;
93
94     /**
95      * @param {?Event} event
96      * @this {Object}
97      */
98     function clickHandler(event)
99     {
100         event.consume(true);
101         if (WebInspector.Linkifier.handleLink(fallbackHref, fallbackLineNumber))
102             return;
103
104         WebInspector.Revealer.reveal(this);
105     }
106     a.addEventListener("click", clickHandler.bind(revealable), false);
107     return a;
108 }
109
110 WebInspector.Linkifier.prototype = {
111     /**
112      * @param {string} sourceURL
113      * @param {number} lineNumber
114      * @param {number=} columnNumber
115      * @param {string=} classes
116      * @return {?Element}
117      */
118     linkifyLocation: function(sourceURL, lineNumber, columnNumber, classes)
119     {
120         var rawLocation = WebInspector.debuggerModel.createRawLocationByURL(sourceURL, lineNumber, columnNumber || 0);
121         if (!rawLocation)
122             return WebInspector.linkifyResourceAsNode(sourceURL, lineNumber, classes);
123         return this.linkifyRawLocation(rawLocation, classes);
124     },
125
126     /**
127      * @param {!WebInspector.DebuggerModel.Location} rawLocation
128      * @param {string=} classes
129      * @return {?Element}
130      */
131     linkifyRawLocation: function(rawLocation, classes)
132     {
133         var script = WebInspector.debuggerModel.scriptForId(rawLocation.scriptId);
134         if (!script)
135             return null;
136         var anchor = this._createAnchor(classes);
137         var liveLocation = script.createLiveLocation(rawLocation, this._updateAnchor.bind(this, anchor));
138         this._liveLocations.push(liveLocation);
139         return anchor;
140     },
141
142     /**
143      * @param {?CSSAgent.StyleSheetId} styleSheetId
144      * @param {!WebInspector.CSSLocation} rawLocation
145      * @param {string=} classes
146      * @return {?Element}
147      */
148     linkifyCSSLocation: function(styleSheetId, rawLocation, classes)
149     {
150         var anchor = this._createAnchor(classes);
151         var liveLocation = WebInspector.cssModel.createLiveLocation(styleSheetId, rawLocation, this._updateAnchor.bind(this, anchor));
152         if (!liveLocation)
153             return null;
154         this._liveLocations.push(liveLocation);
155         return anchor;
156     },
157
158     /**
159      * @param {string=} classes
160      * @return {!Element}
161      */
162     _createAnchor: function(classes)
163     {
164         var anchor = document.createElement("a");
165         anchor.className = (classes || "") + " webkit-html-resource-link";
166
167         /**
168          * @param {?Event} event
169          */
170         function clickHandler(event)
171         {
172             event.consume(true);
173             if (!anchor.__uiLocation)
174                 return;
175             if (WebInspector.Linkifier.handleLink(anchor.__uiLocation.url(), anchor.__uiLocation.lineNumber))
176                 return;
177             WebInspector.Revealer.reveal(anchor.__uiLocation);
178         }
179         anchor.addEventListener("click", clickHandler, false);
180         return anchor;
181     },
182
183     reset: function()
184     {
185         for (var i = 0; i < this._liveLocations.length; ++i)
186             this._liveLocations[i].dispose();
187         this._liveLocations = [];
188     },
189
190     /**
191      * @param {!Element} anchor
192      * @param {!WebInspector.UILocation} uiLocation
193      */
194     _updateAnchor: function(anchor, uiLocation)
195     {
196         anchor.__uiLocation = uiLocation;
197         this._formatter.formatLiveAnchor(anchor, uiLocation);
198     }
199 }
200
201 /**
202  * @constructor
203  * @implements {WebInspector.LinkifierFormatter}
204  * @param {number=} maxLength
205  */
206 WebInspector.Linkifier.DefaultFormatter = function(maxLength)
207 {
208     this._maxLength = maxLength;
209 }
210
211 WebInspector.Linkifier.DefaultFormatter.prototype = {
212     /**
213      * @param {!Element} anchor
214      * @param {!WebInspector.UILocation} uiLocation
215      */
216     formatLiveAnchor: function(anchor, uiLocation)
217     {
218         var text = uiLocation.linkText();
219         if (this._maxLength)
220             text = text.trimMiddle(this._maxLength);
221         anchor.textContent = text;
222
223         var titleText = uiLocation.uiSourceCode.originURL();
224         if (typeof uiLocation.lineNumber === "number")
225             titleText += ":" + (uiLocation.lineNumber + 1);
226         anchor.title = titleText;
227     }
228 }
229
230 /**
231  * @constructor
232  * @extends {WebInspector.Linkifier.DefaultFormatter}
233  */
234 WebInspector.Linkifier.DefaultCSSFormatter = function()
235 {
236     WebInspector.Linkifier.DefaultFormatter.call(this, WebInspector.Linkifier.DefaultCSSFormatter.MaxLengthForDisplayedURLs);
237 }
238
239 WebInspector.Linkifier.DefaultCSSFormatter.MaxLengthForDisplayedURLs = 30;
240
241 WebInspector.Linkifier.DefaultCSSFormatter.prototype = {
242     /**
243      * @param {!Element} anchor
244      * @param {!WebInspector.UILocation} uiLocation
245      */
246     formatLiveAnchor: function(anchor, uiLocation)
247     {
248         WebInspector.Linkifier.DefaultFormatter.prototype.formatLiveAnchor.call(this, anchor, uiLocation);
249         anchor.classList.add("webkit-html-resource-link");
250         anchor.setAttribute("data-uncopyable", anchor.textContent);
251         anchor.textContent = "";
252     },
253     __proto__: WebInspector.Linkifier.DefaultFormatter.prototype
254 }
255
256 /**
257  * The maximum number of characters to display in a URL.
258  * @const
259  * @type {number}
260  */
261 WebInspector.Linkifier.MaxLengthForDisplayedURLs = 150;
262
263 /**
264  * @interface
265  */
266 WebInspector.Linkifier.LinkHandler = function()
267 {
268 }
269
270 WebInspector.Linkifier.LinkHandler.prototype = {
271     /**
272      * @param {string} url
273      * @param {number=} lineNumber
274      * @return {boolean}
275      */
276     handleLink: function(url, lineNumber) {}
277 }