Improve arguments reading in timeline

This commit is contained in:
Gaël Métais
2015-03-08 23:13:09 +01:00
parent 3e0e31a5fe
commit 121a8b11b8
13 changed files with 313 additions and 27 deletions
+1
View File
@@ -109,6 +109,7 @@
border-bottom-left-radius: 0.4em;
border-bottom-right-radius: 0.4em;
border-top: 1px solid #999;
z-index: 2;
}
.offenders .offenderButton .domTree {
text-align: left;
+1 -1
View File
@@ -268,7 +268,7 @@ input.textFilter {
background: #fff;
border: 2px solid #f1c40f;
border-radius: 0.5em;
z-index: 1;
z-index: 2;
}
@media screen and (max-width: 1024px) {
.detailsOverlay {
+9
View File
@@ -187,6 +187,15 @@ 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);
};
+11 -2
View File
@@ -43,6 +43,17 @@ offendersDirectives.directive('domElementButton', function() {
};
});
offendersDirectives.directive('jqueryContextButton', function() {
return {
restrict: 'E',
scope: {
context: '='
},
templateUrl: 'views/jqueryContextButton.html',
replace: true
};
});
offendersDirectives.filter('shortenUrl', function() {
return function(url, maxLength) {
if (!maxLength) {
@@ -104,8 +115,6 @@ offendersDirectives.directive('offenderButton', function() {
restrict: 'C',
link: function(scope, element, attrs) {
console.log('initializing touchstart');
element.bind('touchstart mouseenter', function(e) {
element.addClass('mouseOver');
e.preventDefault();
+1
View File
@@ -120,6 +120,7 @@
border-bottom-left-radius: 0.4em;
border-bottom-right-radius: 0.4em;
border-top: 1px solid #999;
z-index: 2;
}
.domTree {
+1 -1
View File
@@ -309,7 +309,7 @@ input.textFilter {
background: #fff;
border: 2px solid #f1c40f;
border-radius: 0.5em;
z-index: 1;
z-index: 2;
}
@media screen and (max-width: 1024px) {
.detailsOverlay {
+1
View File
@@ -3,5 +3,6 @@
<span ng-if="obj.type == 'domElement'">DOM element <b>{{obj.element}}</b></span>
<span ng-if="obj.type == 'fragmentElement'">Fragment element <b>{{obj.element}}</b></span>
<span ng-if="obj.type == 'createdElement'">Created element <b>{{obj.element}}</b></span>
<span ng-if="obj.type == 'notAnElement'">Incorrect element</span>
<dom-tree ng-if="obj.tree" tree="obj.tree"></dom-tree>
</div>
+9
View File
@@ -0,0 +1,9 @@
<span>
<span ng-if="context.length == 0" class="offenderButton">Empty jQuery object</span>
<span ng-if="context.length == 1"><dom-element-button obj="context.elements[0]"></dom-element-button></span>
<span ng-if="context.length > 1">
{{context.length}} elements
(<dom-element-button obj="context.elements[0]"></dom-element-button>, <dom-element-button obj="context.elements[1]"></dom-element-button>
<span ng-if="context.length > 2">and {{context.length - 2}} more...</span>)
</span>
</span>
+234 -9
View File
@@ -93,10 +93,237 @@
</div>
<div class="value">
{{node.data.callDetails.arguments[0]}}
<span ng-if="node.data.callDetails.arguments.length > 1"> : {{node.data.callDetails.arguments[1]}}</span>
<span ng-if="node.data.callDetails.arguments.length > 2"> : {{node.data.callDetails.arguments[2]}}</span>
<span ng-if="node.data.callDetails.arguments.length > 3"> : {{node.data.callDetails.arguments[3]}}</span>
<span ng-if="node.data.type == 'getElementById' || node.data.type == 'createElement'">
<b>{{node.data.callDetails.arguments[0]}}</b>
</span>
<span ng-if="node.data.type == 'getElementsByClassName' || node.data.type == 'getElementsByTagName' || node.data.type == 'querySelector' || node.data.type == 'querySelectorAll'" class="offenders">
<b>{{node.data.callDetails.arguments[0]}}</b> on <dom-element-button obj="node.data.callDetails.context.elements[0]"></dom-element-button>
</span>
<span ng-if="node.data.type == 'appendChild'" class="offenders">
<dom-element-button obj="node.data.callDetails.arguments[0]"></dom-element-button> appended to <dom-element-button obj="node.data.callDetails.context.elements[0]"></dom-element-button>
</span>
<span ng-if="node.data.type == 'insertBefore'" class="offenders">
insert <dom-element-button obj="node.data.callDetails.arguments[0]"></dom-element-button> in <dom-element-button obj="node.data.callDetails.context.elements[0]"></dom-element-button> before <dom-element-button obj="node.data.callDetails.arguments[1]"></dom-element-button>
</span>
<span ng-if="node.data.type == 'createTextNode' || node.data.type == 'createDocumentFragment'">
</span>
<span ng-if="node.data.type == 'addEventListener'" class="offenders">
<b>{{node.data.callDetails.arguments[0]}}</b> bound to <dom-element-button obj="node.data.callDetails.context.elements[0]"></dom-element-button>
</span>
<span ng-if="node.data.type == 'jQuery loaded' || node.data.type == 'jQuery version change'">
{{node.data.callDetails.arguments[0]}}
</span>
<span ng-if="node.data.type == 'jQuery - onDOMReady' || node.data.type == 'jQuery - windowOnLoad'">
(function)
</span>
<span ng-if="node.data.type == 'jQuery - Sizzle call'" class="offenders">
<b>{{node.data.callDetails.arguments[0]}}</b>
<span ng-if="node.data.callDetails.context.elements[0].type != 'document'"> on <dom-element-button obj="node.data.callDetails.context.elements[0]"></dom-element-button></span>
</span>
<span ng-if="node.data.type == 'jQuery - find'" class="offenders">
<b>{{node.data.callDetails.arguments[0]}}</b>
<span ng-if="node.data.callDetails.context"> on <dom-element-button obj="node.data.callDetails.context.elements[0]"></dom-element-button></span>
</span>
<span ng-if="node.data.type == 'jQuery - html'" class="offenders">
<span ng-if="node.data.callDetails.arguments[0] != undefined">set content "<b>{{node.data.callDetails.arguments[0]}}</b>" to <jquery-context-button context="node.data.callDetails.context"></jquery-context-button></span>
<span ng-if="node.data.callDetails.arguments[0] == undefined">get content from <jquery-context-button context="node.data.callDetails.context"></jquery-context-button></span>
</span>
<span ng-if="node.data.type == 'jQuery - append'" class="offenders">
append <b>{{node.data.callDetails.arguments[0]}}</b><span ng-if="node.data.callDetails.arguments[1]">, <b>{{node.data.callDetails.arguments[1]}}</b></span><span ng-if="node.data.callDetails.arguments[2]">, <b>{{node.data.callDetails.arguments[2]}}</b></span><span ng-if="node.data.callDetails.arguments[3]">, <b>and more...</b></span> to <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
<span ng-if="node.data.type == 'jQuery - appendTo'" class="offenders">
append <jquery-context-button context="node.data.callDetails.context"></jquery-context-button> to {{node.data.callDetails.arguments[0]}}
</span>
<span ng-if="node.data.type == 'jQuery - prepend'" class="offenders">
prepend <b>{{node.data.callDetails.arguments[0]}}</b><span ng-if="node.data.callDetails.arguments[1]">, <b>{{node.data.callDetails.arguments[1]}}</b></span><span ng-if="node.data.callDetails.arguments[2]">, <b>{{node.data.callDetails.arguments[2]}}</b></span><span ng-if="node.data.callDetails.arguments[3]">, <b>and more...</b></span> to <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
<span ng-if="node.data.type == 'jQuery - prependTo'" class="offenders">
prepend <jquery-context-button context="node.data.callDetails.context"></jquery-context-button> to {{node.data.callDetails.arguments[0]}}
</span>
<span ng-if="node.data.type == 'jQuery - before'" class="offenders">
insert <b>{{node.data.callDetails.arguments[0]}}</b><span ng-if="node.data.callDetails.arguments[1]">, <b>{{node.data.callDetails.arguments[1]}}</b></span><span ng-if="node.data.callDetails.arguments[2]">, <b>{{node.data.callDetails.arguments[2]}}</b></span><span ng-if="node.data.callDetails.arguments[3]">, <b>and more...</b></span> before <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
<span ng-if="node.data.type == 'jQuery - insertBefore'" class="offenders">
insert <jquery-context-button context="node.data.callDetails.context"></jquery-context-button> before {{node.data.callDetails.arguments[0]}}
</span>
<span ng-if="node.data.type == 'jQuery - after'" class="offenders">
insert <b>{{node.data.callDetails.arguments[0]}}</b><span ng-if="node.data.callDetails.arguments[1]">, <b>{{node.data.callDetails.arguments[1]}}</b></span><span ng-if="node.data.callDetails.arguments[2]">, <b>{{node.data.callDetails.arguments[2]}}</b></span><span ng-if="node.data.callDetails.arguments[3]">, <b>and more...</b></span> after <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
<span ng-if="node.data.type == 'jQuery - insertAfter'" class="offenders">
insert <jquery-context-button context="node.data.callDetails.context"></jquery-context-button> after {{node.data.callDetails.arguments[0]}}
</span>
<span ng-if="node.data.type == 'jQuery - remove'" class="offenders">
remove <jquery-context-button context="node.data.callDetails.context"></jquery-context-button><span ng-if="node.data.callDetails.arguments[0] != undefined"> filtered by <b>{{node.data.callDetails.arguments[0]}}</b></span>
</span>
<span ng-if="node.data.type == 'jQuery - detach'" class="offenders">
detach <jquery-context-button context="node.data.callDetails.context"></jquery-context-button><span ng-if="node.data.callDetails.arguments[0] != undefined"> filtered by <b>{{node.data.callDetails.arguments[0]}}</b></span>
</span>
<span ng-if="node.data.type == 'jQuery - empty'" class="offenders">
empty <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
<span ng-if="node.data.type == 'jQuery - clone'" class="offenders">
clone <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
<span ng-if="node.data.type == 'jQuery - replaceWith'" class="offenders">
replace <jquery-context-button context="node.data.callDetails.context"></jquery-context-button> with <b>{{node.data.callDetails.arguments[0]}}</b>
</span>
<span ng-if="node.data.type == 'jQuery - replaceAll'" class="offenders">
replace <b>{{node.data.callDetails.arguments[0]}}</b> with <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
<span ng-if="node.data.type == 'jQuery - text'" class="offenders">
<span ng-if="node.data.callDetails.arguments[0] != undefined">set text "<b>{{node.data.callDetails.arguments[0]}}</b>" to <jquery-context-button context="node.data.callDetails.context"></jquery-context-button></span>
<span ng-if="node.data.callDetails.arguments[0] == undefined">get text from <jquery-context-button context="node.data.callDetails.context"></jquery-context-button></span>
</span>
<span ng-if="node.data.type == 'jQuery - wrap' || node.data.type == 'jQuery - wrapAll'" class="offenders">
wrap <jquery-context-button context="node.data.callDetails.context"></jquery-context-button> with <b>{{node.data.callDetails.arguments[0]}}</b>
</span>
<span ng-if="node.data.type == 'jQuery - wrapInner'" class="offenders">
wrap the content of <jquery-context-button context="node.data.callDetails.context"></jquery-context-button> with <b>{{node.data.callDetails.arguments[0]}}</b>
</span>
<span ng-if="node.data.type == 'jQuery - unwrap'" class="offenders">
unwrap <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
<span ng-if="node.data.type == 'jQuery - css' || node.data.type == 'jQuery - attr' || node.data.type == 'jQuery - prop'" class="offenders">
<span ng-if="isStringOfObject(node.data.callDetails.arguments[0])">set <b>{{node.data.callDetails.arguments[0]}}</b> to <jquery-context-button context="node.data.callDetails.context"></jquery-context-button></span>
<span ng-if="!isStringOfObject(node.data.callDetails.arguments[0])">
<span ng-if="node.data.callDetails.arguments[1] == undefined">get <b>{{node.data.callDetails.arguments[0]}}</b> from <jquery-context-button context="node.data.callDetails.context"></jquery-context-button></span>
<span ng-if="node.data.callDetails.arguments[1] != undefined">set <b>{{node.data.callDetails.arguments[0]}}</b> : <b>{{node.data.callDetails.arguments[1]}}</b> to <jquery-context-button context="node.data.callDetails.context"></jquery-context-button></span>
</span>
</span>
<span ng-if="node.data.type == 'jQuery - offset' || node.data.type == 'jQuery - height' || node.data.type == 'jQuery - innerHeight' || node.data.type == 'jQuery - outerHeight' || node.data.type == 'jQuery - width' || node.data.type == 'jQuery - innerWidth' || node.data.type == 'jQuery - outerWidth' || node.data.type == 'jQuery - scrollLeft' || node.data.type == 'jQuery - scrollTop'" class="offenders">
<span ng-if="node.data.callDetails.arguments[0] == undefined">get from <jquery-context-button context="node.data.callDetails.context"></jquery-context-button></span>
<span ng-if="node.data.callDetails.arguments[0] != undefined">set <b>{{node.data.callDetails.arguments[0]}}</b> to <jquery-context-button context="node.data.callDetails.context"></jquery-context-button></span>
</span>
<span ng-if="node.data.type == 'jQuery - position'" class="offenders">
get from <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
<span ng-if="node.data.type == 'jQuery - show' || node.data.type == 'jQuery - hide' || node.data.type == 'jQuery - animate' || node.data.type == 'jQuery - fadeIn' || node.data.type == 'jQuery - fadeOut' || node.data.type == 'jQuery - fadeTo' || node.data.type == 'jQuery - fadeToggle' || node.data.type == 'jQuery - slideDown' || node.data.type == 'jQuery - slideUp' || node.data.type == 'jQuery - slideToggle'" class="offenders">
<jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
<span ng-if="node.data.type == 'jQuery - toggle'" class="offenders">
<jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
<span ng-if="node.data.callDetails.arguments[0] == 'true'"> to visible</span>
<span ng-if="node.data.callDetails.arguments[0] == 'false'"> to hidden</span>
</span>
<span ng-if="node.data.type == 'jQuery - on' || node.data.type == 'jQuery - one'" class="offenders">
bind <b>{{node.data.callDetails.arguments[0]}}</b> on <jquery-context-button context="node.data.callDetails.context"></jquery-context-button><span ng-if="isPureString(node.data.callDetails.arguments[1])">'s children filtered by <b>{{node.data.callDetails.arguments[1]}}</b></span>
</span>
<span ng-if="node.data.type == 'jQuery - off'" class="offenders">
<span ng-if="node.data.callDetails.arguments[0]">
unbind <b>{{node.data.callDetails.arguments[0]}}</b> from <jquery-context-button context="node.data.callDetails.context"></jquery-context-button><span ng-if="isPureString(node.data.callDetails.arguments[1])">'s children filtered by <b>{{node.data.callDetails.arguments[1]}}</b></span>
</span>
<span ng-if="!node.data.callDetails.arguments[0]">
unbind all events
</span>
</span>
<span ng-if="node.data.type == 'jQuery - live'" class="offenders">
bind <b>{{node.data.callDetails.arguments[0]}}</b> on <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
<span ng-if="node.data.type == 'jQuery - die'" class="offenders">
<span ng-if="node.data.callDetails.arguments[0]">
unbind <b>{{node.data.callDetails.arguments[0]}}</b> from <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
<span ng-if="!node.data.callDetails.arguments[0]">
unbind all events
</span>
</span>
<span ng-if="node.data.type == 'jQuery - delegate'" class="offenders">
bind <b>{{node.data.callDetails.arguments[1]}}</b> on <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>'s children filtered by <b>{{node.data.callDetails.arguments[0]}}</b>
</span>
<span ng-if="node.data.type == 'jQuery - undelegate'" class="offenders">
<span ng-if="node.data.callDetails.arguments[1]">
unbind <b>{{node.data.callDetails.arguments[1]}}</b> from <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>'s children filtered by <b>{{node.data.callDetails.arguments[0]}}</b>
</span>
<span ng-if="node.data.callDetails.arguments[0] && !node.data.callDetails.arguments[1]">
unbind namespace <b>{{node.data.callDetails.arguments[0]}}</b>
</span>
<span ng-if="!node.data.callDetails.arguments[0]">
unbind all events
</span>
</span>
<span ng-if="node.data.type == 'jQuery - bind'" class="offenders">
bind <b>{{node.data.callDetails.arguments[0]}}</b> on <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
<span ng-if="node.data.type == 'jQuery - unbind'" class="offenders">
<span ng-if="node.data.callDetails.arguments[0]">
unbind <b>{{node.data.callDetails.arguments[0]}}</b> from <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
<span ng-if="!node.data.callDetails.arguments[0]">
unbind all events
</span>
</span>
<span ng-if="node.data.type == 'jQuery - blur' || node.data.type == 'jQuery - change' || node.data.type == 'jQuery - click' || node.data.type == 'jQuery - dblclick' || node.data.type == 'jQuery - error' || node.data.type == 'jQuery - focus' || node.data.type == 'jQuery - focusin' || node.data.type == 'jQuery - focusout' || node.data.type == 'jQuery - hover' || node.data.type == 'jQuery - keydown' || node.data.type == 'jQuery - keypress' || node.data.type == 'jQuery - keyup' || node.data.type == 'jQuery - load' || node.data.type == 'jQuery - mousedown' || node.data.type == 'jQuery - mouseenter' || node.data.type == 'jQuery - mouseleave' || node.data.type == 'jQuery - mousemove' || node.data.type == 'jQuery - mouseout' || node.data.type == 'jQuery - mouseover' || node.data.type == 'jQuery - mouseup' || node.data.type == 'jQuery - resize' || node.data.type == 'jQuery - scroll' || node.data.type == 'jQuery - select' || node.data.type == 'jQuery - submit' || node.data.type == 'jQuery - unload'" class="offenders">
bind on <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
<span ng-if="node.data.type == 'jQuery - removeAttr' || node.data.type == 'jQuery - removeProp'" class="offenders">
remove <b>{{node.data.callDetails.arguments[0]}}</b> from <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
<span ng-if="node.data.type == 'jQuery - val'" class="offenders">
<span ng-if="node.data.callDetails.arguments[0]">
set value <b>{{node.data.callDetails.arguments[0]}}</b> to <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
<span ng-if="!node.data.callDetails.arguments[0]">
get value from <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
</span>
<span ng-if="node.data.type == 'jQuery - hasClass' || node.data.type == 'jQuery - addClass' || node.data.type == 'jQuery - removeClass'" class="offenders">
<b>{{node.data.callDetails.arguments[0]}}</b> on <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
<span ng-if="node.data.type == 'jQuery - toggleClass'" class="offenders">
<span ng-if="!node.data.callDetails.arguments[0]">magic no-argument toggleClass</span>
<span ng-if="node.data.callDetails.arguments[0]">toggle <b>{{node.data.callDetails.arguments[0]}}</b></span>
on <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
<span ng-if="node.data.callDetails.arguments[1]">to <b>{{node.data.callDetails.arguments[1]}}</b></span>
</span>
<span ng-if="node.data.type == 'jQuery - children'" class="offenders">
of <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
<span ng-if="node.data.callDetails.arguments[0]">filtered by <b>{{node.data.callDetails.arguments[0]}}</b></span>
</span>
<span ng-if="node.data.type == 'jQuery - closest'" class="offenders">
closest <b>{{node.data.callDetails.arguments[0]}}</b> from <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
<span ng-if="node.data.callDetails.arguments[1]">in context <b>{{node.data.callDetails.arguments[1]}}</b></span>
</span>
<span ng-if="node.data.type == 'jQuery - next' || node.data.type == 'jQuery - nextAll'" class="offenders">
after <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
<span ng-if="node.data.callDetails.arguments[0]">matching <b>{{node.data.callDetails.arguments[0]}}</b></span>
</span>
<span ng-if="node.data.type == 'jQuery - nextUntil'" class="offenders">
after <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
<span ng-if="node.data.callDetails.arguments[0]">until <b>{{node.data.callDetails.arguments[0]}}</b></span>
<span ng-if="node.data.callDetails.arguments[1]">and matching <b>{{node.data.callDetails.arguments[1]}}</b></span>
</span>
<span ng-if="node.data.type == 'jQuery - offsetParent'" class="offenders">
of <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
</span>
<span ng-if="node.data.type == 'jQuery - prev' || node.data.type == 'jQuery - prevAll'" class="offenders">
before <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
<span ng-if="node.data.callDetails.arguments[0]">matching <b>{{node.data.callDetails.arguments[0]}}</b></span>
</span>
<span ng-if="node.data.type == 'jQuery - prevUntil'" class="offenders">
before <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
<span ng-if="node.data.callDetails.arguments[0]">until <b>{{node.data.callDetails.arguments[0]}}</b></span>
<span ng-if="node.data.callDetails.arguments[1]">and matching <b>{{node.data.callDetails.arguments[1]}}</b></span>
</span>
<span ng-if="node.data.type == 'jQuery - parent' || node.data.type == 'jQuery - parents'" class="offenders">
of <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
<span ng-if="node.data.callDetails.arguments[0]">matching <b>{{node.data.callDetails.arguments[0]}}</b></span>
</span>
<span ng-if="node.data.type == 'jQuery - parentsUntil'" class="offenders">
of <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
<span ng-if="node.data.callDetails.arguments[0]">until <b>{{node.data.callDetails.arguments[0]}}</b></span>
<span ng-if="node.data.callDetails.arguments[1]">and matching <b>{{node.data.callDetails.arguments[1]}}</b></span>
</span>
<span ng-if="node.data.type == 'jQuery - siblings'" class="offenders">
near <jquery-context-button context="node.data.callDetails.context"></jquery-context-button>
<span ng-if="node.data.callDetails.arguments[0]">matching <b>{{node.data.callDetails.arguments[0]}}</b></span>
</span>
</div>
<div class="details">
@@ -107,11 +334,6 @@
<div class="detailsOverlay" ng-if="node.showDetails">
<div class="closeBtn" ng-click="onNodeDetailsClick(node)"></div>
<div ng-if="node.data.callDetails.context.domElement">
<h4>Called on DOM element</h4>
<div>{{node.data.callDetails.context.domElement}}</div>
</div>
<div ng-if="node.data.callDetails.context.length === 0">
<h4>Called on 0 jQuery element</h4>
<p class="advice">Useless function call, as the jQuery object is empty.</p>
@@ -133,6 +355,9 @@
<p class="advice" ng-if="node.data.resultsNumber === 0">
The query returned 0 results. Could it be unused or dead code?
</p>
<p ng-if="node.data.resultsNumber > 0">
The query returned <ng-pluralize count="node.data.resultsNumber" when="{'one': '1 result', 'other': '{} results'}"></ng-pluralize>.
</p>
<div ng-if="node.parsedBacktrace">
<h4>Backtrace</h4>
+9
View File
@@ -32,6 +32,15 @@ var OffendersHelpers = function() {
};
this.domPathToDomElementObj = function(domPath) {
if (typeof domPath === 'boolean') {
return {
// Not a normal element path
type: 'notAnElement',
element: domPath
};
}
var domArray = this.domPathToArray(domPath);
var domTree = this.listOfDomArraysToTree([this.domPathToArray(domPath)]);
+10 -2
View File
@@ -51,9 +51,17 @@ var jsExecutionTransformer = function() {
// Change the list of dom paths into a tree
treeRecursiveParser(node, function(node) {
if (node.data.callDetails && node.data.callDetails.context && node.data.callDetails.context.length > 0) {
var domArrays = node.data.callDetails.context.elements.map(offendersHelpers.domPathToArray);
node.data.callDetails.context.elements = offendersHelpers.listOfDomArraysToTree(domArrays);
node.data.callDetails.context.elements = node.data.callDetails.context.elements.map(offendersHelpers.domPathToDomElementObj, offendersHelpers);
}
if (node.data.type === 'appendChild' || node.data.type === 'insertBefore') {
node.data.callDetails.arguments[0] = offendersHelpers.domPathToDomElementObj(node.data.callDetails.arguments[0]);
}
if (node.data.type === 'insertBefore') {
node.data.callDetails.arguments[1] = offendersHelpers.domPathToDomElementObj(node.data.callDetails.arguments[1]);
}
});
});
@@ -247,11 +247,12 @@ exports.module = function(phantomas) {
});
}
function insertBeforeSpyBefore(child) {
function insertBeforeSpyBefore(child, refElement) {
/*jshint validthis: true */
var context = phantomas.getDOMPath(this);
var appended = phantomas.getDOMPath(child);
var referent = phantomas.getDOMPath(refElement);
appendChild(child, this, context, appended);
phantomas.enterContext({
@@ -261,7 +262,10 @@ exports.module = function(phantomas) {
length: 1,
elements: [context]
},
arguments: [appended]
arguments: [
appended,
referent
]
},
backtrace: phantomas.getBacktrace()
});
@@ -116,8 +116,9 @@ exports.module = function(phantomas) {
'addClass',
'removeClass',
'toggleClass',
];
// Tree traversal
var jQueryTraversalFunctions = [
'children',
'closest',
'find',
@@ -134,9 +135,11 @@ exports.module = function(phantomas) {
'siblings'
];
jQueryFunctions = jQueryFunctions.concat(jQueryTraversalFunctions);
// spy calls to jQuery functions
phantomas.once('init', function() {
phantomas.evaluate(function(jQueryFunctions) {
phantomas.evaluate(function(jQueryFunctions, jQueryTraversalFunctions) {
(function(phantomas) {
var jQuery;
var oldJQuery;
@@ -219,10 +222,6 @@ exports.module = function(phantomas) {
phantomas.enterContext({
type: 'jQuery - find',
callDetails: {
context: {
length: 1,
elements: ['#document']
},
arguments: [selector]
},
backtrace: phantomas.getBacktrace()
@@ -234,8 +233,7 @@ exports.module = function(phantomas) {
var data = phantomas.getContextData();
if (data.type === 'jQuery - find' &&
data.callDetails.context.elements.length === 1 &&
data.callDetails.context.elements[0] === '#document' &&
!data.callDetails.context &&
data.callDetails.arguments.length === 1 &&
/^#([\w\-]*)$/.exec(data.callDetails.arguments[0]) !== null) {
@@ -284,6 +282,11 @@ exports.module = function(phantomas) {
args = [].slice.call(arguments);
args.forEach(function(arg, index) {
if (arg instanceof Array) {
arg = '[Array]';
}
if (arg instanceof Object) {
if (arg instanceof jQuery || (arg.jquery && arg.jquery.length > 0)) {
@@ -354,12 +357,19 @@ exports.module = function(phantomas) {
});
}, function(result) {
phantomas.leaveContext();
if (jQueryTraversalFunctions.indexOf(functionName) >= 0) {
var moreData = {
resultsNumber : (result && result.length) ? result.length : 0
};
phantomas.leaveContext(moreData);
} else {
phantomas.leaveContext();
}
}) || phantomas.log('jQuery: can not track jQuery - ' + functionName + ' (this version of jQuery doesn\'t support it)');
});
});
})(window.__phantomas);
}, jQueryFunctions);
}, jQueryFunctions, jQueryTraversalFunctions);
});