|
153 | 153 | { |
154 | 154 | this._onMessage(JSON.stringify({ |
155 | 155 | time: 7, |
156 | | - level: "GENERAL", |
| 156 | + level: "ERROR", |
157 | 157 | message: ["I am a message with an %o object", {foo:"bar", blah:true}], |
158 | 158 | stack: [ |
159 | 159 | { |
|
168 | 168 | }, |
169 | 169 | { |
170 | 170 | function: "this.testStack", |
171 | | - file: "http://localhost:8080/assets/js/../../../src/springroll/remote/RemoteTrace.js", |
172 | | - lineLocation: "154:10" |
| 171 | + file: "http://andrew.cloudkid.net/Tools/SpringRollStudio/src/springroll/remote/RemoteTrace.js", |
| 172 | + lineLocation: "152:18" |
173 | 173 | } |
174 | 174 | ] |
175 | 175 | })); |
|
218 | 218 | }; |
219 | 219 | } |
220 | 220 |
|
| 221 | + //block object toggles from affecting stack visibility toggles |
221 | 222 | output.on("click", ".message", function(e) |
222 | 223 | { |
223 | 224 | var target = $(e.target); |
224 | | - //block object toggles from affecting stack visibility toggles |
| 225 | + //only need to block object toggles, as they are part of the message |
225 | 226 | if(target.hasClass("objectToggle") || target.parent().hasClass("objectToggle")) |
226 | 227 | { |
227 | 228 | //stop the event |
|
232 | 233 | $(targetId).collapse("toggle"); |
233 | 234 | } |
234 | 235 | }); |
| 236 | + |
| 237 | + //http://sunlightjs.com/docs.html |
| 238 | + |
| 239 | + //get clicks on any link to a page in the stack view |
| 240 | + output.on("click", ".stackLink", function(e) |
| 241 | + { |
| 242 | + //TODO: Remove |
| 243 | + if(RELEASE) |
| 244 | + return; |
| 245 | + var target = $(e.target); |
| 246 | + var location = target.data("location"); |
| 247 | + var colonIndex = location.indexOf(":"); |
| 248 | + var line = parseInt(colonIndex > 0 ? location.substring(0, colonIndex) : location), |
| 249 | + column = colonIndex > 0 ? parseInt(location.substring(colonIndex + 1)) : 0; |
| 250 | + $.ajax({ |
| 251 | + url : target.data("file"), |
| 252 | + dataType: "text", |
| 253 | + success : function (data) { |
| 254 | + //make a text box to display the JS file |
| 255 | + //TODO: Actual location for this |
| 256 | + //Note: Sunlight makes a <div> with a class of "sunlight-container" where |
| 257 | + //the pre created by this code is placed |
| 258 | + $("#frame").prepend($("<pre class='sunlight-highlight-javascript' contentEditable='true'></pre>").text(data)); |
| 259 | + //format Javascript syntax |
| 260 | + Sunlight.highlightAll(); |
| 261 | + var codeBlock = $(".sunlight-javascript"); |
| 262 | + //select the line/column |
| 263 | + //figure out how many characters in that line/column is |
| 264 | + var text = codeBlock.text(), |
| 265 | + characterCount = 0, |
| 266 | + lastNewLine = 0; |
| 267 | + for(var lineIndex = 1; lineIndex < line; ++lineIndex) |
| 268 | + { |
| 269 | + //get the newline character at the end of line #lineIndex |
| 270 | + lastNewLine = text.indexOf("\n", lastNewLine + 1); |
| 271 | + characterCount = lastNewLine; |
| 272 | + } |
| 273 | + characterCount += column; |
| 274 | + |
| 275 | + //figure out which node has the character we are looking for |
| 276 | + //the parsed document is filled with <span> elements for syntax |
| 277 | + //highlighting |
| 278 | + var childNodes = codeBlock[0].childNodes; |
| 279 | + for(var i = 0, length = childNodes.length; i < length; ++i) |
| 280 | + { |
| 281 | + var node = childNodes[i]; |
| 282 | + //anything that's not a text node is a span with text inside |
| 283 | + if(node.nodeType != 3) |
| 284 | + node = node.childNodes[0]; |
| 285 | + //get the amount of text inside the text node |
| 286 | + characterCount -= node.length; |
| 287 | + //if we've run out of our character count, that's the node that we want |
| 288 | + if(characterCount <= 0) |
| 289 | + { |
| 290 | + var scroller = $(".sunlight-code-container"); |
| 291 | + //get the position of the text node relative to the scroller |
| 292 | + //the text has to be wrapped in a span first, as TextNodes don't |
| 293 | + //have offsetTop |
| 294 | + var nodePos = $(node).wrap("<span></span>").parent().offset().top - |
| 295 | + codeBlock.offset().top; |
| 296 | + //center the text in the scrolling window |
| 297 | + scroller.scrollTop(Math.max(nodePos - scroller.height() * 0.5, 0)); |
| 298 | + //remove the text wrapping that we added |
| 299 | + $(node).unwrap(); |
| 300 | + |
| 301 | + //put the text caret in the correct location |
| 302 | + var range = document.createRange(), |
| 303 | + sel = window.getSelection(); |
| 304 | + range.setStart(node, -characterCount + 1); |
| 305 | + range.collapse(true); |
| 306 | + sel.removeAllRanges(); |
| 307 | + sel.addRange(range); |
| 308 | + break; |
| 309 | + } |
| 310 | + } |
| 311 | + } |
| 312 | + }); |
| 313 | + }); |
235 | 314 | }; |
236 | 315 |
|
237 | 316 | // Reference to the prototype |
|
577 | 656 | stackLinkText = stackLinkText.substring(stackLinkText.lastIndexOf("/") + 1); |
578 | 657 | stackLinkText += ":" + stack[i].lineLocation; |
579 | 658 | var line = $("<div class='line'></div>"); |
| 659 | + var stackLink = $("<span class='stackLink'></span>") |
| 660 | + .text(stackLinkText) |
| 661 | + .attr("data-file", stack[i].file) |
| 662 | + .attr("data-location", stack[i].lineLocation); |
580 | 663 | line.text(stack[i].function) |
581 | | - .append($("<span class='stackLink'></span>").text(stackLinkText)); |
| 664 | + .append(stackLink); |
582 | 665 | group.append(line); |
583 | 666 | } |
584 | 667 | log.append(group); |
|
0 commit comments