Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(957)

Side by Side Diff: Source/devtools/front_end/sdk/Linkifier.js

Issue 471433004: DevTools: Split out the "workspace" and "bindings" modules from "sdk" (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Remove marker interfaces and WI.SourceMapping Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 * @implements {WebInspector.TargetManager.Observer}
49 * @param {!WebInspector.LinkifierFormatter=} formatter
50 */
51 WebInspector.Linkifier = function(formatter)
52 {
53 this._formatter = formatter || new WebInspector.Linkifier.DefaultFormatter(W ebInspector.Linkifier.MaxLengthForDisplayedURLs);
54 /** @type {!Map.<!WebInspector.Target, !Array.<{anchor: !Element, location: !WebInspector.LiveLocation}>>}*/
55 this._liveLocationsByTarget = new Map();
56 WebInspector.targetManager.observeTargets(this);
57 }
58
59 /**
60 * @param {!WebInspector.Linkifier.LinkHandler} handler
61 */
62 WebInspector.Linkifier.setLinkHandler = function(handler)
63 {
64 WebInspector.Linkifier._linkHandler = handler;
65 }
66
67 /**
68 * @param {string} url
69 * @param {number=} lineNumber
70 * @return {boolean}
71 */
72 WebInspector.Linkifier.handleLink = function(url, lineNumber)
73 {
74 if (!WebInspector.Linkifier._linkHandler)
75 return false;
76 return WebInspector.Linkifier._linkHandler.handleLink(url, lineNumber)
77 }
78
79 /**
80 * @param {!Object} revealable
81 * @param {string} text
82 * @param {string=} fallbackHref
83 * @param {number=} fallbackLineNumber
84 * @param {string=} title
85 * @param {string=} classes
86 * @return {!Element}
87 */
88 WebInspector.Linkifier.linkifyUsingRevealer = function(revealable, text, fallbac kHref, fallbackLineNumber, title, classes)
89 {
90 var a = document.createElement("a");
91 a.className = (classes || "") + " webkit-html-resource-link";
92 a.textContent = text.trimMiddle(WebInspector.Linkifier.MaxLengthForDisplayed URLs);
93 a.title = title || text;
94 if (fallbackHref) {
95 a.href = fallbackHref;
96 a.lineNumber = fallbackLineNumber;
97 }
98 /**
99 * @param {!Event} event
100 * @this {Object}
101 */
102 function clickHandler(event)
103 {
104 event.stopImmediatePropagation();
105 event.preventDefault();
106 if (fallbackHref && WebInspector.Linkifier.handleLink(fallbackHref, fall backLineNumber))
107 return;
108
109 WebInspector.Revealer.reveal(this);
110 }
111 a.addEventListener("click", clickHandler.bind(revealable), false);
112 return a;
113 }
114
115 WebInspector.Linkifier.prototype = {
116 /**
117 * @param {!WebInspector.Target} target
118 */
119 targetAdded: function(target)
120 {
121 this._liveLocationsByTarget.put(target, []);
122 },
123
124 /**
125 * @param {!WebInspector.Target} target
126 */
127 targetRemoved: function(target)
128 {
129 var liveLocations = this._liveLocationsByTarget.remove(target);
130 for (var i = 0; i < liveLocations.length; ++i) {
131 delete liveLocations[i].anchor.__uiLocation;
132 var anchor = liveLocations[i].anchor;
133 if (anchor.__fallbackAnchor) {
134 anchor.href = anchor.__fallbackAnchor.href;
135 anchor.lineNumber = anchor.__fallbackAnchor.lineNumber;
136 anchor.title = anchor.__fallbackAnchor.title;
137 anchor.className = anchor.__fallbackAnchor.className;
138 anchor.textContent = anchor.__fallbackAnchor.textContent;
139 }
140 liveLocations[i].location.dispose();
141 }
142 },
143
144 /**
145 * @param {?WebInspector.Target} target
146 * @param {?string} scriptId
147 * @param {string} sourceURL
148 * @param {number} lineNumber
149 * @param {number=} columnNumber
150 * @param {string=} classes
151 * @return {!Element}
152 */
153 linkifyScriptLocation: function(target, scriptId, sourceURL, lineNumber, col umnNumber, classes)
154 {
155 var rawLocation = target && !target.isDetached() ? target.debuggerModel. createRawLocationByScriptId(scriptId, sourceURL, lineNumber, columnNumber || 0) : null;
156 var fallbackAnchor = WebInspector.linkifyResourceAsNode(sourceURL, lineN umber, classes);
157 if (!rawLocation)
158 return fallbackAnchor;
159
160 var anchor = this._createAnchor(classes);
161 var liveLocation = WebInspector.debuggerWorkspaceBinding.createLiveLocat ion(rawLocation, this._updateAnchor.bind(this, anchor));
162 this._liveLocationsByTarget.get(rawLocation.target()).push({ anchor: anc hor, location: liveLocation });
163 anchor.__fallbackAnchor = fallbackAnchor;
164 return anchor;
165 },
166
167 /**
168 * @param {!WebInspector.DebuggerModel.Location} rawLocation
169 * @param {string} fallbackUrl
170 * @param {string=} classes
171 * @return {!Element}
172 */
173 linkifyRawLocation: function(rawLocation, fallbackUrl, classes)
174 {
175 return this.linkifyScriptLocation(rawLocation.target(), rawLocation.scri ptId, fallbackUrl, rawLocation.lineNumber, rawLocation.columnNumber, classes);
176 },
177
178 /**
179 * @param {?WebInspector.Target} target
180 * @param {!ConsoleAgent.CallFrame} callFrame
181 * @param {string=} classes
182 * @return {!Element}
183 */
184 linkifyConsoleCallFrame: function(target, callFrame, classes)
185 {
186 // FIXME(62725): console stack trace line/column numbers are one-based.
187 var lineNumber = callFrame.lineNumber ? callFrame.lineNumber - 1 : 0;
188 var columnNumber = callFrame.columnNumber ? callFrame.columnNumber - 1 : 0;
189 var anchor = this.linkifyScriptLocation(target, callFrame.scriptId, call Frame.url, lineNumber, columnNumber, classes);
190 if (WebInspector.BlackboxSupport.isBlackboxedURL(callFrame.url))
191 anchor.classList.add("webkit-html-blackbox-link");
192 return anchor;
193 },
194
195 /**
196 * @param {!WebInspector.CSSLocation} rawLocation
197 * @param {string=} classes
198 * @return {?Element}
199 */
200 linkifyCSSLocation: function(rawLocation, classes)
201 {
202 var anchor = this._createAnchor(classes);
203 var liveLocation = WebInspector.cssWorkspaceBinding.createLiveLocation(r awLocation, this._updateAnchor.bind(this, anchor));
204 if (!liveLocation)
205 return null;
206 this._liveLocationsByTarget.get(rawLocation.target()).push({ anchor: anc hor, location: liveLocation });
207 return anchor;
208 },
209
210 /**
211 * @param {!WebInspector.CSSMedia} media
212 * @return {?Element}
213 */
214 linkifyMedia: function(media)
215 {
216 var location = media.rawLocation();
217 if (location)
218 return this.linkifyCSSLocation(location);
219
220 // The "linkedStylesheet" case.
221 return WebInspector.linkifyResourceAsNode(media.sourceURL, undefined, "s ubtitle", media.sourceURL);
222 },
223
224 /**
225 * @param {string=} classes
226 * @return {!Element}
227 */
228 _createAnchor: function(classes)
229 {
230 var anchor = document.createElement("a");
231 anchor.className = (classes || "") + " webkit-html-resource-link";
232
233 /**
234 * @param {!Event} event
235 */
236 function clickHandler(event)
237 {
238 if (!anchor.__uiLocation)
239 return;
240 event.stopImmediatePropagation();
241 event.preventDefault();
242 if (WebInspector.Linkifier.handleLink(anchor.__uiLocation.uiSourceCo de.url, anchor.__uiLocation.lineNumber))
243 return;
244 WebInspector.Revealer.reveal(anchor.__uiLocation);
245 }
246 anchor.addEventListener("click", clickHandler, false);
247 return anchor;
248 },
249
250 reset: function()
251 {
252 var keys = this._liveLocationsByTarget.keys();
253 for (var i = 0; i < keys.length; ++i) {
254 var target = keys[i];
255 this.targetRemoved(target);
256 this.targetAdded(target);
257 }
258 },
259
260 /**
261 * @param {!Element} anchor
262 * @param {!WebInspector.UILocation} uiLocation
263 */
264 _updateAnchor: function(anchor, uiLocation)
265 {
266 anchor.__uiLocation = uiLocation;
267 this._formatter.formatLiveAnchor(anchor, uiLocation);
268 }
269 }
270
271 /**
272 * @constructor
273 * @implements {WebInspector.LinkifierFormatter}
274 * @param {number=} maxLength
275 */
276 WebInspector.Linkifier.DefaultFormatter = function(maxLength)
277 {
278 this._maxLength = maxLength;
279 }
280
281 WebInspector.Linkifier.DefaultFormatter.prototype = {
282 /**
283 * @param {!Element} anchor
284 * @param {!WebInspector.UILocation} uiLocation
285 */
286 formatLiveAnchor: function(anchor, uiLocation)
287 {
288 var text = uiLocation.linkText();
289 if (this._maxLength)
290 text = text.trimMiddle(this._maxLength);
291 anchor.textContent = text;
292
293 var titleText = uiLocation.uiSourceCode.originURL();
294 if (typeof uiLocation.lineNumber === "number")
295 titleText += ":" + (uiLocation.lineNumber + 1);
296 anchor.title = titleText;
297 }
298 }
299
300 /**
301 * @constructor
302 * @extends {WebInspector.Linkifier.DefaultFormatter}
303 */
304 WebInspector.Linkifier.DefaultCSSFormatter = function()
305 {
306 WebInspector.Linkifier.DefaultFormatter.call(this, WebInspector.Linkifier.De faultCSSFormatter.MaxLengthForDisplayedURLs);
307 }
308
309 WebInspector.Linkifier.DefaultCSSFormatter.MaxLengthForDisplayedURLs = 30;
310
311 WebInspector.Linkifier.DefaultCSSFormatter.prototype = {
312 /**
313 * @param {!Element} anchor
314 * @param {!WebInspector.UILocation} uiLocation
315 */
316 formatLiveAnchor: function(anchor, uiLocation)
317 {
318 WebInspector.Linkifier.DefaultFormatter.prototype.formatLiveAnchor.call( this, anchor, uiLocation);
319 anchor.classList.add("webkit-html-resource-link");
320 anchor.setAttribute("data-uncopyable", anchor.textContent);
321 anchor.textContent = "";
322 },
323 __proto__: WebInspector.Linkifier.DefaultFormatter.prototype
324 }
325
326 /**
327 * The maximum number of characters to display in a URL.
328 * @const
329 * @type {number}
330 */
331 WebInspector.Linkifier.MaxLengthForDisplayedURLs = 150;
332
333 /**
334 * @interface
335 */
336 WebInspector.Linkifier.LinkHandler = function()
337 {
338 }
339
340 WebInspector.Linkifier.LinkHandler.prototype = {
341 /**
342 * @param {string} url
343 * @param {number=} lineNumber
344 * @return {boolean}
345 */
346 handleLink: function(url, lineNumber) {}
347 }
348
349 /**
350 * @param {!WebInspector.Target} target
351 * @param {string} scriptId
352 * @param {number} lineNumber
353 * @param {number=} columnNumber
354 * @return {string}
355 */
356 WebInspector.Linkifier.liveLocationText = function(target, scriptId, lineNumber, columnNumber)
357 {
358 var script = target.debuggerModel.scriptForId(scriptId);
359 if (!script)
360 return "";
361 var location = /** @type {!WebInspector.DebuggerModel.Location} */ (target.d ebuggerModel.createRawLocation(script, lineNumber, columnNumber || 0));
362 var uiLocation = /** @type {!WebInspector.UILocation} */ (WebInspector.debug gerWorkspaceBinding.rawLocationToUILocation(location));
363 return uiLocation.linkText();
364 }
OLDNEW
« no previous file with comments | « Source/devtools/front_end/sdk/IsolatedFileSystemManager.js ('k') | Source/devtools/front_end/sdk/LiveEditSupport.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698