diff --git a/front/src/js/controllers/timelineCtrl.js b/front/src/js/controllers/timelineCtrl.js index ebe523e..f21046e 100644 --- a/front/src/js/controllers/timelineCtrl.js +++ b/front/src/js/controllers/timelineCtrl.js @@ -184,14 +184,6 @@ timelineCtrl.controller('TimelineCtrl', ['$scope', '$rootScope', '$routeParams', node.showDetails = !isOpen; }; - $scope.isStringOfObject = function(str) { - return typeof str === 'string' && str[0] === '{' && str[str.length - 1] === '}'; - }; - - $scope.isPureString = function(str) { - return typeof str === 'string' && str[0] !== '{' && str !== '(function)' && str !== '[Object]' && str !== '[Array]' && str !== 'true' && str !== 'false' && str !== 'undefined' && str !== 'unknown'; - }; - $scope.backToDashboard = function() { $location.path('/result/' + $scope.runId); diff --git a/front/src/js/directives/offendersDirectives.js b/front/src/js/directives/offendersDirectives.js index e430ddf..dd56eb5 100644 --- a/front/src/js/directives/offendersDirectives.js +++ b/front/src/js/directives/offendersDirectives.js @@ -1,129 +1,628 @@ -var offendersDirectives = angular.module('offendersDirectives', []); +(function() { + "use strict"; + var offendersDirectives = angular.module('offendersDirectives', []); -offendersDirectives.directive('domTree', function() { - return { - restrict: 'E', - scope: { - tree: '=' - }, - template: '
', - replace: true, - link: function(scope, element, attrs) { - - function recursiveHtmlBuilder(tree) { - var html = ''; - var keys = Object.keys(tree); - - keys.forEach(function(key) { - if (isNaN(tree[key])) { - html += '
' + key + '' + recursiveHtmlBuilder(tree[key]) + '
'; - } else if (tree[key] > 1) { - html += '
' + key + ' (x' + tree[key] + ')
'; - } else { - html += '
' + key + '
'; - } - }); + function getdomTreeHTML(tree) { + return '
' + getdomTreeInnerHTML(tree) + '
'; + } - return html; + function getdomTreeInnerHTML(tree) { + return recursiveHtmlBuilder(tree); + } + + function recursiveHtmlBuilder(tree) { + var html = ''; + var keys = Object.keys(tree); + + keys.forEach(function(key) { + if (isNaN(tree[key])) { + html += '
' + key + '' + recursiveHtmlBuilder(tree[key]) + '
'; + } else if (tree[key] > 1) { + html += '
' + key + ' (x' + tree[key] + ')
'; + } else { + html += '
' + key + '
'; + } + }); + + return html; + } + + offendersDirectives.directive('domTree', function() { + return { + restrict: 'E', + scope: { + tree: '=' + }, + template: '
', + replace: true, + link: function(scope, element) { + element.append(getdomTreeInnerHTML(scope.tree)); + } + }; + }); + + function getDomElementButtonHTML(obj) { + if (obj.tree) { + return '
' + getDomElementButtonInnerHTML(obj) + '
'; + } + + return '
' + getDomElementButtonInnerHTML(obj) + '
'; + } + + function getDomElementButtonInnerHTML(obj) { + if (obj.type === 'html' || + obj.type === 'body' || + obj.type === 'head' || + obj.type === 'window' || + obj.type === 'document' || + obj.type === 'fragment') { + return obj.type; + } + + if (obj.type === 'notAnElement') { + return 'Incorrect element'; + } + + var html = ''; + if (obj.type === 'domElement') { + html = 'DOM element ' + obj.element + ''; + } else if (obj.type === 'fragmentElement') { + html = 'Fragment element ' + obj.element + ''; + } else if (obj.type === 'createdElement') { + html = 'Created element ' + obj.element + ''; + } + + if (obj.tree) { + html += getdomTreeHTML(obj.tree); + } + + return html; + } + + offendersDirectives.directive('domElementButton', function() { + return { + restrict: 'E', + scope: { + obj: '=' + }, + template: '
', + replace: true, + link: function(scope, element) { + element.append(getDomElementButtonInnerHTML(scope.obj)); + } + }; + }); + + + function getJQueryContextButtonHTML(context) { + if (context.length === 0) { + return 'Empty jQuery object'; + } + + if (context.length === 1) { + return getDomElementButtonHTML(context.elements[0]); + } + + var html = context.length + ' elements (' + getDomElementButtonHTML(context.elements[0]) + ', ' + getDomElementButtonHTML(context.elements[1]); + if (context.length === 3) { + html += ', ' + getDomElementButtonHTML(context.elements[0]); + } else if (context.length > 3) { + html += ' and ' + (context.length - 2) + ' more...'; + } + return html + '}'; + } + + offendersDirectives.directive('timelineParams', function() { + + function isJQuery(node) { + return node.data.type.indexOf('jQuery ') === 0; + } + + function getNonJQueryHTML(node) { + var type = node.data.type; + + if (!node.data.callDetails) { + return ''; } - element.append(recursiveHtmlBuilder(scope.tree)); - } - }; -}); + var args = node.data.callDetails.arguments; + var ctxt = node.data.callDetails.context; -offendersDirectives.directive('domElementButton', function() { - return { - restrict: 'E', - scope: { - obj: '=' - }, - templateUrl: 'views/domElementButton.html', - replace: true - }; -}); -offendersDirectives.directive('jqueryContextButton', function() { - return { - restrict: 'E', - scope: { - context: '=' - }, - templateUrl: 'views/jqueryContextButton.html', - replace: true - }; -}); + switch (type) { + case 'getElementById': + case 'createElement': + return '' + args[0] + ''; -offendersDirectives.filter('shortenUrl', function() { - return function(url, maxLength) { - if (!maxLength) { - maxLength = 110; + case 'getElementsByClassName': + case 'getElementsByTagName': + case 'querySelector': + case 'querySelectorAll': + return '' + args[0] + ' on ' + getDomElementButtonHTML(ctxt.elements[0]); + + case 'appendChild': + return 'append ' + getDomElementButtonHTML(args[0]) + ' to ' + getDomElementButtonHTML(ctxt.elements[0]); + + case 'insertBefore': + return 'insert' + getDomElementButtonHTML(args[0]) + ' into ' + getDomElementButtonHTML(ctxt.elements[0]) + ' before ' + getDomElementButtonHTML(args[1]); + + case 'addEventListener': + return 'bind ' + args[0] + ' to ' + getDomElementButtonHTML(ctxt.elements[0]); + + case 'error': + return args[0]; + + default: + return ''; + } } - // Why dividing by 2.1? Because it adds a 5% margin. - var leftLength = Math.floor((maxLength - 5) / 2.1); - var rightLength = Math.ceil((maxLength - 5) / 2.1); + function getJQueryHTML(node) { + var type = node.data.type; + var args = node.data.callDetails.arguments; + var ctxt = node.data.callDetails.context; + + // escape HTML in args + for (var i = 0 ; i < 4 ; i ++) { + if (args[i]) { + args[i] = escapeHTML(args[i]); + } + } - return (url.length > maxLength) ? url.substr(0, leftLength) + ' ... ' + url.substr(-rightLength) : url; - }; -}); + if (type === 'jQuery loaded' || type === 'jQuery version change') { + return args[0]; + } -offendersDirectives.directive('urlLink', function() { - return { - restrict: 'E', - scope: { - url: '=', - maxLength: '=' - }, - template: '{{url | shortenUrl:maxLength}}', - replace: true - }; -}); + switch (type) { + case 'jQuery - onDOMReady': + case 'jQuery - windowOnLoad': + return '(function)'; -offendersDirectives.filter('encodeURIComponent', function() { - return window.encodeURIComponent; -}); + case 'jQuery - Sizzle call': + return '' + args[0] + ' on ' + getDomElementButtonHTML(ctxt.elements[0]); -offendersDirectives.directive('fileAndLine', function() { - return { - restrict: 'E', - scope: { - file: '=', - line: '=', - column: '=' - }, - template: '<inline CSS> @ {{line}}:{{column}}', - replace: true - }; -}); + case 'jQuery - find': + if (ctxt && ctxt.length === 1 && ctxt.elements[0].type !== 'document') { + return '' + args[0] + ' on ' + getJQueryContextButtonHTML(ctxt); + } else { + return '' + args[0] + ''; + } + break; -offendersDirectives.directive('fileAndLineButton', function() { - return { - restrict: 'E', - scope: { - file: '=', - line: '=', - column: '=' - }, - template: '
css file
', - replace: true - }; -}); + case 'jQuery - html': + if (args[0] !== undefined) { + return 'set content "' + args[0] + '" to ' + getJQueryContextButtonHTML(ctxt); + } else { + return 'get content from ' + getJQueryContextButtonHTML(ctxt); + } + break; -offendersDirectives.directive('offenderButton', function() { - return { - restrict: 'C', - link: function(scope, element, attrs) { + case 'jQuery - append': + return 'append ' + joinArgs(args) + ' to ' + getJQueryContextButtonHTML(ctxt); - element.bind('touchstart mouseenter', function(e) { - element.addClass('mouseOver'); - e.preventDefault(); - }); + case 'jQuery - appendTo': + return 'append' + getJQueryContextButtonHTML(ctxt) + ' to ' + args[0] + ''; - element.bind('touchend mouseleave click', function(e) { - element.removeClass('mouseOver'); - e.preventDefault(); + case 'jQuery - prepend': + return 'prepend ' + joinArgs(args) + ' to ' + getJQueryContextButtonHTML(ctxt); + + case 'jQuery - prependTo': + return 'prepend ' + getJQueryContextButtonHTML(ctxt) + ' to ' + args[0] + ''; + + case 'jQuery - before': + return 'insert ' + joinArgs(args) + ' before ' + getJQueryContextButtonHTML(ctxt); + + case 'jQuery - insertBefore': + return 'insert ' + getJQueryContextButtonHTML(ctxt) + ' before ' + args[0] + ''; + + case 'jQuery - after': + return 'insert ' + joinArgs(args) + ' after ' + getJQueryContextButtonHTML(ctxt); + + case 'jQuery - insertAfter': + return 'insert ' + getJQueryContextButtonHTML(ctxt) + ' after ' + args[0] + ''; + + case 'jQuery - remove': + case 'jQuery - detach': + if (args[0]) { + return getJQueryContextButtonHTML(ctxt) + ' filtered by ' + args[0] + ''; + } else { + return getJQueryContextButtonHTML(ctxt); + } + break; + + case 'jQuery - empty': + case 'jQuery - clone': + case 'jQuery - unwrap': + case 'jQuery - show': + case 'jQuery - hide': + case 'jQuery - animate': + case 'jQuery - fadeIn': + case 'jQuery - fadeOut': + case 'jQuery - fadeTo': + case 'jQuery - fadeToggle': + case 'jQuery - slideDown': + case 'jQuery - slideUp': + case 'jQuery - slideToggle': + return getJQueryContextButtonHTML(ctxt); + + case 'jQuery - replaceWith': + return 'replace ' + getJQueryContextButtonHTML(ctxt) + ' with ' + args[0] + ''; + + case 'jQuery - replaceAll': + return 'replace ' + args[0] + ' with ' + getJQueryContextButtonHTML(ctxt); + + case 'jQuery - text': + if (args[0]) { + return 'set text "' + args[0] + '" to ' + getJQueryContextButtonHTML(ctxt); + } else { + return 'get text from ' + getJQueryContextButtonHTML(ctxt); + } + break; + + case 'jQuery - wrap': + case 'jQuery - wrapAll': + return 'wrap ' + getJQueryContextButtonHTML(ctxt) + ' within ' + args[0] + ''; + + case 'jQuery - wrapInner': + return 'wrap the content of ' + getJQueryContextButtonHTML(ctxt) + ' within ' + args[0] + ''; + + case 'jQuery - css': + case 'jQuery - attr': + case 'jQuery - prop': + if (isStringOfObject(args[0])) { + return 'set ' + args[0] + ' on ' + getJQueryContextButtonHTML(ctxt); + } else if (args[1]) { + return 'set ' + args[0] + ' : ' + args[1] + ' on ' + getJQueryContextButtonHTML(ctxt); + } else { + return 'get ' + args[0] + ' from ' + getJQueryContextButtonHTML(ctxt); + } + break; + + case 'jQuery - offset': + case 'jQuery - height': + case 'jQuery - innerHeight': + case 'jQuery - outerHeight': + case 'jQuery - width': + case 'jQuery - innerWidth': + case 'jQuery - outerWidth': + case 'jQuery - scrollLeft': + case 'jQuery - scrollTop': + case 'jQuery - position': + if (args[0]) { + return 'set ' + args[0] + ' on ' + getJQueryContextButtonHTML(ctxt); + } else { + return 'get from ' + getJQueryContextButtonHTML(ctxt); + } + break; + + case 'jQuery - toggle': + if (args[0] === 'true') { + return getJQueryContextButtonHTML(ctxt) + ' to visible'; + } else if (args[0] === 'false') { + return getJQueryContextButtonHTML(ctxt) + ' to hidden'; + } else { + return getJQueryContextButtonHTML(ctxt); + } + break; + + case 'jQuery - on': + case 'jQuery - one': + if (args[1]) { + return 'bind ' + args[0] + ' on ' + getJQueryContextButtonHTML(ctxt) + '\'s children filtered by ' + args[1] + ''; + } else { + return 'bind ' + args[0] + ' on ' + getJQueryContextButtonHTML(ctxt); + } + break; + + case 'jQuery - off': + if (args[0]) { + if (args[1]) { + return 'unbind ' + args[0] + ' from ' + getJQueryContextButtonHTML(ctxt) + '\'s children filtered by ' + args[1] + ''; + } else { + return 'unbind ' + args[0] + ' from ' + getJQueryContextButtonHTML(ctxt); + } + } else { + return 'unbind all events'; + } + break; + + case 'jQuery - live': + case 'jQuery - bind': + return 'bind ' + args[0] + ' on ' + getJQueryContextButtonHTML(ctxt); + + case 'jQuery - die': + case 'jQuery - unbind': + if (args[0]) { + return 'unbind ' + args[0] + ' from ' + getJQueryContextButtonHTML(ctxt); + } else { + return 'unbind all events'; + } + break; + + case 'jQuery - delegate': + return 'bind ' + args[1] + ' on ' + getJQueryContextButtonHTML(ctxt) + '\'s children filtered by ' + args[0] + ''; + + case 'jQuery - undelegate': + if (args[0]) { + if (args[1]) { + return 'unbind ' + args[1] + ' from ' + getJQueryContextButtonHTML(ctxt) + '\'s children filtered by ' + args[0] + ''; + } else { + return 'unbind namespace ' + args[0] + ''; + } + } else { + return 'unbind all events'; + } + break; + + case 'jQuery - blur': + case 'jQuery - change': + case 'jQuery - click': + case 'jQuery - dblclick': + case 'jQuery - error': + case 'jQuery - focus': + case 'jQuery - focusin': + case 'jQuery - focusout': + case 'jQuery - hover': + case 'jQuery - keydown': + case 'jQuery - keypress': + case 'jQuery - keyup': + case 'jQuery - load': + case 'jQuery - mousedown': + case 'jQuery - mouseenter': + case 'jQuery - mouseleave': + case 'jQuery - mousemove': + case 'jQuery - mouseout': + case 'jQuery - mouseover': + case 'jQuery - mouseup': + case 'jQuery - resize': + case 'jQuery - scroll': + case 'jQuery - select': + case 'jQuery - submit': + case 'jQuery - unload': + return 'bind on ' + getJQueryContextButtonHTML(ctxt); + + case 'jQuery - removeAttr': + case 'jQuery - removeProp': + return 'remove ' + args[0] + ' from ' + getJQueryContextButtonHTML(ctxt); + + case 'jQuery - val': + if (args[0]) { + return 'set value ' + args[0] + ' to ' + getJQueryContextButtonHTML(ctxt); + } else { + return 'get value from ' + getJQueryContextButtonHTML(ctxt); + } + break; + + case 'jQuery - hasClass': + case 'jQuery - addClass': + case 'jQuery - removeClass': + return '' + args[0] + ' on ' + getJQueryContextButtonHTML(ctxt); + + case 'jQuery - toggleClass': + if (args[0]) { + if (args[1]) { + return 'toggle ' + args[0] + ' on ' + getJQueryContextButtonHTML(ctxt) + ' to ' + args[1] + ''; + } else { + return 'toggle ' + args[0] + ' on ' + getJQueryContextButtonHTML(ctxt); + } + } else { + return 'magic no-argument toggleClass'; + } + break; + + case 'jQuery - children': + if (args[0]) { + return 'of ' + getJQueryContextButtonHTML(ctxt) + ' filtered by ' + args[0] + ''; + } else { + return 'of ' + getJQueryContextButtonHTML(ctxt); + } + break; + + case 'jQuery - closest': + if (args[1]) { + return 'closest ' + args[0] + ' from ' + getJQueryContextButtonHTML(ctxt) + ' in context ' + args[1] + ''; + } else { + return 'closest ' + args[0] + ' from ' + getJQueryContextButtonHTML(ctxt); + } + break; + + case 'jQuery - next': + case 'jQuery - nextAll': + if (args[0]) { + return 'after ' + getJQueryContextButtonHTML(ctxt) + ' matching ' + args[0] + ''; + } else { + return 'after ' + getJQueryContextButtonHTML(ctxt); + } + break; + + case 'jQuery - nextUntil': + if (args[0]) { + if (args[1]) { + return 'after ' + getJQueryContextButtonHTML(ctxt) + ' until ' + args[0] + ' and matching ' + args[1] + ''; + } else { + return 'after ' + getJQueryContextButtonHTML(ctxt) + ' until ' + args[0] + ''; + } + } else { + return 'after ' + getJQueryContextButtonHTML(ctxt); + } + break; + + case 'jQuery - offsetParent': + return 'of ' + getJQueryContextButtonHTML(ctxt); + + case 'jQuery - prev': + case 'jQuery - prevAll': + if (args[0]) { + return 'before ' + getJQueryContextButtonHTML(ctxt) + ' matching ' + args[0] + ''; + } else { + return 'before ' + getJQueryContextButtonHTML(ctxt); + } + break; + + case 'jQuery - prevUntil': + if (args[0]) { + if (args[1]) { + return 'before ' + getJQueryContextButtonHTML(ctxt) + ' until ' + args[0] + ' and matching ' + args[1] + ''; + } else { + return 'before ' + getJQueryContextButtonHTML(ctxt) + ' until ' + args[0] + ''; + } + } else { + return 'before ' + getJQueryContextButtonHTML(ctxt); + } + break; + + case 'jQuery - parent': + case 'jQuery - parents': + if (args[0]) { + return 'of ' + getJQueryContextButtonHTML(ctxt) + ' matching ' + args[0] + ''; + } else { + return 'of ' + getJQueryContextButtonHTML(ctxt); + } + break; + + case 'jQuery - parentsUntil': + if (args[0]) { + if (args[1]) { + return 'of ' + getJQueryContextButtonHTML(ctxt) + ' until ' + args[0] + ' and matching ' + args[1] + ''; + } else { + return 'of ' + getJQueryContextButtonHTML(ctxt) + ' until ' + args[0] + ''; + } + } else { + return 'of ' + getJQueryContextButtonHTML(ctxt); + } + break; + + case 'jQuery - siblings': + if (args[0]) { + return 'near ' + getJQueryContextButtonHTML(ctxt) + ' matching ' + args[0] + ''; + } else { + return 'near ' + getJQueryContextButtonHTML(ctxt); + } + break; + + case 'jQuery - onDOMReady': + return '(function)'; + + default: + return ''; + } + } + + function escapeHTML(html) { + var entityMap = { + "&": "&", + "<": "<", + ">": ">", + '"': '"', + "'": ''', + "/": '/' + }; + + return String(html).replace(/[&<>"'\/]/g, function (s) { + return entityMap[s]; }); } - }; -}); \ No newline at end of file + + function joinArgs(args) { + var html = '' + args[0] + ''; + if (args[1]) { + html += ', ' + args[1] + ''; + if (args[2]) { + html += ', ' + args[2] + ''; + if (args[3]) { + html += ', and more...'; + } + } + } + return html; + } + + function getHTML(node) { + if (isJQuery(node)) { + return getJQueryHTML(node); + } else { + return getNonJQueryHTML(node); + } + } + + function isStringOfObject(str) { + return typeof str === 'string' && str[0] === '{' && str[str.length - 1] === '}'; + } + + function isPureString(str) { + return typeof str === 'string' && str[0] !== '{' && str !== '(function)' && str !== '[Object]' && str !== '[Array]' && str !== 'true' && str !== 'false' && str !== 'undefined' && str !== 'unknown'; + } + + return { + restrict: 'E', + scope: { + node: '=' + }, + template: '
', + replace: true, + link: function(scope, element) { + var html = getHTML(scope.node); + if (html) { + element.append(html); + } + } + }; + }); + + offendersDirectives.filter('shortenUrl', function() { + return function(url, maxLength) { + if (!maxLength) { + maxLength = 110; + } + + // Why dividing by 2.1? Because it adds a 5% margin. + var leftLength = Math.floor((maxLength - 5) / 2.1); + var rightLength = Math.ceil((maxLength - 5) / 2.1); + + return (url.length > maxLength) ? url.substr(0, leftLength) + ' ... ' + url.substr(-rightLength) : url; + }; + }); + + offendersDirectives.directive('urlLink', function() { + return { + restrict: 'E', + scope: { + url: '=', + maxLength: '=' + }, + template: '{{url | shortenUrl:maxLength}}', + replace: true + }; + }); + + offendersDirectives.filter('encodeURIComponent', function() { + return window.encodeURIComponent; + }); + + offendersDirectives.directive('fileAndLine', function() { + return { + restrict: 'E', + scope: { + file: '=', + line: '=', + column: '=' + }, + template: '<inline CSS> @ {{line}}:{{column}}', + replace: true + }; + }); + + offendersDirectives.directive('fileAndLineButton', function() { + return { + restrict: 'E', + scope: { + file: '=', + line: '=', + column: '=' + }, + template: '
css file
', + replace: true + }; + }); + +})(); \ No newline at end of file diff --git a/front/src/views/domElementButton.html b/front/src/views/domElementButton.html deleted file mode 100644 index 9b57ecb..0000000 --- a/front/src/views/domElementButton.html +++ /dev/null @@ -1,8 +0,0 @@ -
- {{::obj.type}} - DOM element {{::obj.element}} - Fragment element {{::obj.element}} - Created element {{::obj.element}} - Incorrect element - -
\ No newline at end of file diff --git a/front/src/views/jqueryContextButton.html b/front/src/views/jqueryContextButton.html deleted file mode 100644 index 7c334c0..0000000 --- a/front/src/views/jqueryContextButton.html +++ /dev/null @@ -1,9 +0,0 @@ - - Empty jQuery object - - - {{::context.length}} elements - (, - and {{::context.length - 2}} more...) - - \ No newline at end of file diff --git a/front/src/views/timeline.html b/front/src/views/timeline.html index bc9d157..ec251b2 100644 --- a/front/src/views/timeline.html +++ b/front/src/views/timeline.html @@ -75,7 +75,7 @@
Timestamp
-
- - {{::node.data.callDetails.arguments[0]}} - - - {{::node.data.callDetails.arguments[0]}} on - - - appended to - - - insert in before - - - {{::node.data.callDetails.arguments[0]}} bound to - + - - - {{::node.data.callDetails.arguments[0]}} - - - (function) - - - {{::node.data.callDetails.arguments[0]}} - on - - - {{::node.data.callDetails.arguments[0]}} - on - - - set content "{{::node.data.callDetails.arguments[0]}}" to - get content from - - - append {{::node.data.callDetails.arguments[0]}}, {{::node.data.callDetails.arguments[1]}}, {{::node.data.callDetails.arguments[2]}}, and more... to - - - append to {{::node.data.callDetails.arguments[0]}} - - - prepend {{::node.data.callDetails.arguments[0]}}, {{::node.data.callDetails.arguments[1]}}, {{::node.data.callDetails.arguments[2]}}, and more... to - - - prepend to {{::node.data.callDetails.arguments[0]}} - - - insert {{::node.data.callDetails.arguments[0]}}, {{::node.data.callDetails.arguments[1]}}, {{::node.data.callDetails.arguments[2]}}, and more... before - - - insert before {{::node.data.callDetails.arguments[0]}} - - - insert {{::node.data.callDetails.arguments[0]}}, {{::node.data.callDetails.arguments[1]}}, {{::node.data.callDetails.arguments[2]}}, and more... after - - - insert after {{::node.data.callDetails.arguments[0]}} - - - remove filtered by {{::node.data.callDetails.arguments[0]}} - - - detach filtered by {{::node.data.callDetails.arguments[0]}} - - - empty - - - clone - - - replace with {{::node.data.callDetails.arguments[0]}} - - - replace {{::node.data.callDetails.arguments[0]}} with - - - set text "{{::node.data.callDetails.arguments[0]}}" to - get text from - - - wrap with {{::node.data.callDetails.arguments[0]}} - - - wrap the content of with {{::node.data.callDetails.arguments[0]}} - - - unwrap - - - set {{::node.data.callDetails.arguments[0]}} to - - get {{::node.data.callDetails.arguments[0]}} from - set {{::node.data.callDetails.arguments[0]}} : {{::node.data.callDetails.arguments[1]}} to - - - - get from - set {{::node.data.callDetails.arguments[0]}} to - - - get from - - - - - - - to visible - to hidden - - - bind {{::node.data.callDetails.arguments[0]}} on 's children filtered by {{::node.data.callDetails.arguments[1]}} - - - - unbind {{::node.data.callDetails.arguments[0]}} from 's children filtered by {{::node.data.callDetails.arguments[1]}} - - - unbind all events - - - - bind {{::node.data.callDetails.arguments[0]}} on - - - - unbind {{::node.data.callDetails.arguments[0]}} from - - - unbind all events - - - - bind {{::node.data.callDetails.arguments[1]}} on 's children filtered by {{::node.data.callDetails.arguments[0]}} - - - - unbind {{::node.data.callDetails.arguments[1]}} from 's children filtered by {{::node.data.callDetails.arguments[0]}} - - - unbind namespace {{::node.data.callDetails.arguments[0]}} - - - unbind all events - - - - bind {{::node.data.callDetails.arguments[0]}} on - - - - unbind {{::node.data.callDetails.arguments[0]}} from - - - unbind all events - - - - bind on - - - remove {{::node.data.callDetails.arguments[0]}} from - - - - set value {{::node.data.callDetails.arguments[0]}} to - - - get value from - - - - {{::node.data.callDetails.arguments[0]}} on - - - magic no-argument toggleClass - toggle {{::node.data.callDetails.arguments[0]}} - on - to {{::node.data.callDetails.arguments[1]}} - - - of - filtered by {{::node.data.callDetails.arguments[0]}} - - - closest {{::node.data.callDetails.arguments[0]}} from - in context {{::node.data.callDetails.arguments[1]}} - - - after - matching {{::node.data.callDetails.arguments[0]}} - - - after - until {{::node.data.callDetails.arguments[0]}} - and matching {{::node.data.callDetails.arguments[1]}} - - - of - - - before - matching {{::node.data.callDetails.arguments[0]}} - - - before - until {{::node.data.callDetails.arguments[0]}} - and matching {{::node.data.callDetails.arguments[1]}} - - - of - matching {{::node.data.callDetails.arguments[0]}} - - - of - until {{::node.data.callDetails.arguments[0]}} - and matching {{::node.data.callDetails.arguments[1]}} - - - near - matching {{::node.data.callDetails.arguments[0]}} - -
-
-
{{::node.data.timestamp | number: 0}} ms
+
{{::node.data.timestamp | number: 0}} ms