|
@@ -93,511 +93,6 @@
|
|
};
|
|
};
|
|
});
|
|
});
|
|
|
|
|
|
-
|
|
|
|
- function getJQueryContextButtonHTML(context, onASingleLine) {
|
|
|
|
- if (context.length === 0) {
|
|
|
|
- return '<span class="offenderButton">Empty jQuery object</span>';
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (context.length === 1) {
|
|
|
|
- return getDomElementButtonHTML(context.elements[0], onASingleLine);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- var html = context.length + ' elements (' + getDomElementButtonHTML(context.elements[0], onASingleLine) + ', ' + getDomElementButtonHTML(context.elements[1], onASingleLine);
|
|
|
|
- if (context.length === 3) {
|
|
|
|
- html += ', ' + getDomElementButtonHTML(context.elements[0], onASingleLine);
|
|
|
|
- } else if (context.length > 3) {
|
|
|
|
- html += ' and ' + (context.length - 2) + ' more...';
|
|
|
|
- }
|
|
|
|
- return html + ')';
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function isJQuery(node) {
|
|
|
|
- return node.data.type.indexOf('jQuery ') === 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function getNonJQueryHTML(node, onASingleLine) {
|
|
|
|
- var type = node.data.type;
|
|
|
|
-
|
|
|
|
- if (node.windowPerformance) {
|
|
|
|
- switch (type) {
|
|
|
|
- case 'documentScroll':
|
|
|
|
- return '(triggering the scroll event on <b>document</b>)';
|
|
|
|
-
|
|
|
|
- case 'windowScroll':
|
|
|
|
- return '(triggering the scroll event on <b>window</b>)';
|
|
|
|
-
|
|
|
|
- case 'window.onscroll':
|
|
|
|
- return '(calling the <b>window.onscroll</b> function)';
|
|
|
|
-
|
|
|
|
- default:
|
|
|
|
- return '';
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (!node.data.callDetails) {
|
|
|
|
- return '';
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- var args = node.data.callDetails.arguments;
|
|
|
|
- var ctxt = node.data.callDetails.context;
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- switch (type) {
|
|
|
|
- case 'getElementById':
|
|
|
|
- case 'createElement':
|
|
|
|
- return '<b>' + args[0] + '</b>';
|
|
|
|
-
|
|
|
|
- case 'getElementsByClassName':
|
|
|
|
- case 'getElementsByTagName':
|
|
|
|
- case 'querySelector':
|
|
|
|
- case 'querySelectorAll':
|
|
|
|
- return '<b>' + args[0] + '</b> on ' + getDomElementButtonHTML(ctxt.elements[0], onASingleLine);
|
|
|
|
-
|
|
|
|
- case 'appendChild':
|
|
|
|
- return 'append ' + getDomElementButtonHTML(args[0], onASingleLine) + ' to ' + getDomElementButtonHTML(ctxt.elements[0], onASingleLine);
|
|
|
|
-
|
|
|
|
- case 'insertBefore':
|
|
|
|
- return 'insert ' + getDomElementButtonHTML(args[0], onASingleLine) + ' into ' + getDomElementButtonHTML(ctxt.elements[0], onASingleLine) + ' before ' + getDomElementButtonHTML(args[1], onASingleLine);
|
|
|
|
-
|
|
|
|
- case 'addEventListener':
|
|
|
|
- return 'bind <b>' + args[0] + '</b> to ' + getDomElementButtonHTML(ctxt.elements[0], onASingleLine);
|
|
|
|
-
|
|
|
|
- case 'getComputedStyle':
|
|
|
|
- return getDomElementButtonHTML(args[0], onASingleLine) + (args[1] || '');
|
|
|
|
-
|
|
|
|
- case 'error':
|
|
|
|
- return args[0];
|
|
|
|
-
|
|
|
|
- case 'jQuery - onDOMReady':
|
|
|
|
- return '(function)';
|
|
|
|
-
|
|
|
|
- case 'documentScroll':
|
|
|
|
- return 'The scroll event just triggered on document';
|
|
|
|
-
|
|
|
|
- case 'windowScroll':
|
|
|
|
- return 'The scroll event just triggered on window';
|
|
|
|
-
|
|
|
|
- case 'window.onscroll':
|
|
|
|
- return 'The window.onscroll function just got called';
|
|
|
|
-
|
|
|
|
- default:
|
|
|
|
- return '';
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function getJQueryHTML(node, onASingleLine) {
|
|
|
|
- var type = node.data.type;
|
|
|
|
- var unescapedArgs = node.data.callDetails.arguments;
|
|
|
|
- var args = [];
|
|
|
|
- var ctxt = node.data.callDetails.context;
|
|
|
|
-
|
|
|
|
- // escape HTML in args
|
|
|
|
- for (var i = 0 ; i < 4 ; i ++) {
|
|
|
|
- if (unescapedArgs[i] !== undefined) {
|
|
|
|
- args[i] = escapeHTML(unescapedArgs[i]);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (type === 'jQuery loaded' || type === 'jQuery version change') {
|
|
|
|
- return args[0];
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- switch (type) {
|
|
|
|
- case 'jQuery - onDOMReady':
|
|
|
|
- case 'jQuery - windowOnLoad':
|
|
|
|
- return '(function)';
|
|
|
|
-
|
|
|
|
- case 'jQuery - Sizzle call':
|
|
|
|
- return '<b>' + args[0] + '</b> on ' + getDomElementButtonHTML(ctxt.elements[0], onASingleLine);
|
|
|
|
-
|
|
|
|
- case 'jQuery - find':
|
|
|
|
- if (ctxt && ctxt.length === 1 && ctxt.elements[0].type !== 'document') {
|
|
|
|
- return '<b>' + args[0] + '</b> on ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- } else {
|
|
|
|
- return '<b>' + args[0] + '</b>';
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - html':
|
|
|
|
- if (args[0] !== undefined) {
|
|
|
|
- return 'set content "<b>' + args[0] + '</b>" to ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- } else {
|
|
|
|
- return 'get content from ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - append':
|
|
|
|
- return 'append ' + joinArgs(args) + ' to ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
-
|
|
|
|
- case 'jQuery - appendTo':
|
|
|
|
- return 'append ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' to <b>' + args[0] + '</b>';
|
|
|
|
-
|
|
|
|
- case 'jQuery - prepend':
|
|
|
|
- return 'prepend ' + joinArgs(args) + ' to ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
-
|
|
|
|
- case 'jQuery - prependTo':
|
|
|
|
- return 'prepend ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' to <b>' + args[0] + '</b>';
|
|
|
|
-
|
|
|
|
- case 'jQuery - before':
|
|
|
|
- return 'insert ' + joinArgs(args) + ' before ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
-
|
|
|
|
- case 'jQuery - insertBefore':
|
|
|
|
- return 'insert ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' before <b>' + args[0] + '</b>';
|
|
|
|
-
|
|
|
|
- case 'jQuery - after':
|
|
|
|
- return 'insert ' + joinArgs(args) + ' after ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
-
|
|
|
|
- case 'jQuery - insertAfter':
|
|
|
|
- return 'insert ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' after <b>' + args[0] + '</b>';
|
|
|
|
-
|
|
|
|
- case 'jQuery - remove':
|
|
|
|
- case 'jQuery - detach':
|
|
|
|
- if (args[0]) {
|
|
|
|
- return getJQueryContextButtonHTML(ctxt, onASingleLine) + ' filtered by <b>' + args[0] + '</b>';
|
|
|
|
- } else {
|
|
|
|
- return getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- 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, onASingleLine);
|
|
|
|
-
|
|
|
|
- case 'jQuery - replaceWith':
|
|
|
|
- return 'replace ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' with <b>' + args[0] + '</b>';
|
|
|
|
-
|
|
|
|
- case 'jQuery - replaceAll':
|
|
|
|
- return 'replace <b>' + args[0] + '</b> with ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
-
|
|
|
|
- case 'jQuery - text':
|
|
|
|
- if (args[0] !== undefined) {
|
|
|
|
- return 'set text "<b>' + args[0] + '</b>" to ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- } else {
|
|
|
|
- return 'get text from ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - wrap':
|
|
|
|
- case 'jQuery - wrapAll':
|
|
|
|
- return 'wrap ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' within <b>' + args[0] + '</b>';
|
|
|
|
-
|
|
|
|
- case 'jQuery - wrapInner':
|
|
|
|
- return 'wrap the content of ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' within <b>' + args[0] + '</b>';
|
|
|
|
-
|
|
|
|
- case 'jQuery - css':
|
|
|
|
- case 'jQuery - attr':
|
|
|
|
- case 'jQuery - prop':
|
|
|
|
- if (isStringOfObject(args[0])) {
|
|
|
|
- return 'set <b>' + args[0] + '</b> on ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- } else if (args[1]) {
|
|
|
|
- return 'set <b>' + args[0] + '</b> : <b>' + args[1] + '</b> on ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- } else {
|
|
|
|
- return 'get <b>' + args[0] + '</b> from ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - offset':
|
|
|
|
- case 'jQuery - height':
|
|
|
|
- case 'jQuery - innerHeight':
|
|
|
|
- case 'jQuery - width':
|
|
|
|
- case 'jQuery - innerWidth':
|
|
|
|
- case 'jQuery - scrollLeft':
|
|
|
|
- case 'jQuery - scrollTop':
|
|
|
|
- case 'jQuery - position':
|
|
|
|
- if (args[0]) {
|
|
|
|
- return 'set <b>' + args[0] + '</b> on ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- } else {
|
|
|
|
- return 'get from ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - outerHeight':
|
|
|
|
- case 'jQuery - outerWidth':
|
|
|
|
- if (args[0] && args[0] !== 'true') {
|
|
|
|
- return 'set <b>' + args[0] + '</b> on ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- } else if (args[0] === 'true') {
|
|
|
|
- return 'get from ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' (with include margins option)';
|
|
|
|
- } else {
|
|
|
|
- return 'get from ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - toggle':
|
|
|
|
- if (args[0] === 'true') {
|
|
|
|
- return getJQueryContextButtonHTML(ctxt, onASingleLine) + ' to visible';
|
|
|
|
- } else if (args[0] === 'false') {
|
|
|
|
- return getJQueryContextButtonHTML(ctxt, onASingleLine) + ' to hidden';
|
|
|
|
- } else {
|
|
|
|
- return getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - on':
|
|
|
|
- case 'jQuery - one':
|
|
|
|
- if (isStringOfObject(args[0])) {
|
|
|
|
- return '<b>' + args[0].replace(/"\(function\)"/g, '(function)') + '</b>';
|
|
|
|
- } else if (args[1] && isPureString(args[1])) {
|
|
|
|
- return 'bind <b>' + args[0] + '</b> on ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + '\'s children filtered by <b>' + args[1] + '</b>';
|
|
|
|
- } else {
|
|
|
|
- return 'bind <b>' + args[0] + '</b> on ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - off':
|
|
|
|
- if (args[0]) {
|
|
|
|
- if (args[1]) {
|
|
|
|
- return 'unbind <b>' + args[0] + '</b> from ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + '\'s children filtered by <b>' + args[1] + '</b>';
|
|
|
|
- } else {
|
|
|
|
- return 'unbind <b>' + args[0] + '</b> from ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- return 'unbind all events';
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - live':
|
|
|
|
- case 'jQuery - bind':
|
|
|
|
- return 'bind <b>' + args[0] + '</b> on ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
-
|
|
|
|
- case 'jQuery - die':
|
|
|
|
- case 'jQuery - unbind':
|
|
|
|
- if (args[0]) {
|
|
|
|
- return 'unbind <b>' + args[0] + '</b> from ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- } else {
|
|
|
|
- return 'unbind all events';
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - delegate':
|
|
|
|
- return 'bind <b>' + args[1] + '</b> on ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + '\'s children filtered by <b>' + args[0] + '</b>';
|
|
|
|
-
|
|
|
|
- case 'jQuery - undelegate':
|
|
|
|
- if (args[0]) {
|
|
|
|
- if (args[1]) {
|
|
|
|
- return 'unbind <b>' + args[1] + '</b> from ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + '\'s children filtered by <b>' + args[0] + '</b>';
|
|
|
|
- } else {
|
|
|
|
- return 'unbind namespace <b>' + args[0] + '</b>';
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- return 'unbind all events';
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - blur':
|
|
|
|
- case 'jQuery - change':
|
|
|
|
- case 'jQuery - click':
|
|
|
|
- case 'jQuery - dblclick':
|
|
|
|
- case 'jQuery - focus':
|
|
|
|
- case 'jQuery - keydown':
|
|
|
|
- case 'jQuery - keypress':
|
|
|
|
- case 'jQuery - keyup':
|
|
|
|
- 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':
|
|
|
|
- if (args[0]) {
|
|
|
|
- return 'bind on ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- } else {
|
|
|
|
- return 'triggered on ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - error':
|
|
|
|
- case 'jQuery - focusin':
|
|
|
|
- case 'jQuery - focusout':
|
|
|
|
- case 'jQuery - hover':
|
|
|
|
- case 'jQuery - load':
|
|
|
|
- case 'jQuery - unload':
|
|
|
|
- return 'bind on ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
-
|
|
|
|
- case 'jQuery - removeAttr':
|
|
|
|
- case 'jQuery - removeProp':
|
|
|
|
- return 'remove <b>' + args[0] + '</b> from ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
-
|
|
|
|
- case 'jQuery - val':
|
|
|
|
- if (args[0]) {
|
|
|
|
- return 'set value <b>' + args[0] + '</b> to ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- } else {
|
|
|
|
- return 'get value from ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - hasClass':
|
|
|
|
- case 'jQuery - addClass':
|
|
|
|
- case 'jQuery - removeClass':
|
|
|
|
- return '<b>' + args[0] + '</b> on ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
-
|
|
|
|
- case 'jQuery - toggleClass':
|
|
|
|
- if (args[0]) {
|
|
|
|
- if (args[1]) {
|
|
|
|
- return 'toggle <b>' + args[0] + '</b> on ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' to <b>' + args[1] + '</b>';
|
|
|
|
- } else {
|
|
|
|
- return 'toggle <b>' + args[0] + '</b> on ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- return 'magic no-argument toggleClass';
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - children':
|
|
|
|
- if (args[0]) {
|
|
|
|
- return 'of ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' filtered by <b>' + args[0] + '</b>';
|
|
|
|
- } else {
|
|
|
|
- return 'of ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - closest':
|
|
|
|
- if (args[1]) {
|
|
|
|
- return 'closest <b>' + args[0] + '</b> from ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' in context <b>' + args[1] + '</b>';
|
|
|
|
- } else {
|
|
|
|
- return 'closest <b>' + args[0] + '</b> from ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - next':
|
|
|
|
- case 'jQuery - nextAll':
|
|
|
|
- if (args[0]) {
|
|
|
|
- return 'after ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' matching <b>' + args[0] + '</b>';
|
|
|
|
- } else {
|
|
|
|
- return 'after ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - nextUntil':
|
|
|
|
- if (args[0]) {
|
|
|
|
- if (args[1]) {
|
|
|
|
- return 'after ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' until <b>' + args[0] + '</b> and matching <b>' + args[1] + '</b>';
|
|
|
|
- } else {
|
|
|
|
- return 'after ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' until <b>' + args[0] + '</b>';
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- return 'after ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - offsetParent':
|
|
|
|
- return 'of ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
-
|
|
|
|
- case 'jQuery - prev':
|
|
|
|
- case 'jQuery - prevAll':
|
|
|
|
- if (args[0]) {
|
|
|
|
- return 'before ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' matching <b>' + args[0] + '</b>';
|
|
|
|
- } else {
|
|
|
|
- return 'before ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - prevUntil':
|
|
|
|
- if (args[0]) {
|
|
|
|
- if (args[1]) {
|
|
|
|
- return 'before ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' until <b>' + args[0] + '</b> and matching <b>' + args[1] + '</b>';
|
|
|
|
- } else {
|
|
|
|
- return 'before ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' until <b>' + args[0] + '</b>';
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- return 'before ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - parent':
|
|
|
|
- case 'jQuery - parents':
|
|
|
|
- if (args[0]) {
|
|
|
|
- return 'of ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' matching <b>' + args[0] + '</b>';
|
|
|
|
- } else {
|
|
|
|
- return 'of ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - parentsUntil':
|
|
|
|
- if (args[0]) {
|
|
|
|
- if (args[1]) {
|
|
|
|
- return 'of ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' until <b>' + args[0] + '</b> and matching <b>' + args[1] + '</b>';
|
|
|
|
- } else {
|
|
|
|
- return 'of ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' until <b>' + args[0] + '</b>';
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- return 'of ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 'jQuery - siblings':
|
|
|
|
- if (args[0]) {
|
|
|
|
- return 'near ' + getJQueryContextButtonHTML(ctxt, onASingleLine) + ' matching <b>' + args[0] + '</b>';
|
|
|
|
- } else {
|
|
|
|
- return 'near ' + getJQueryContextButtonHTML(ctxt, onASingleLine);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- default:
|
|
|
|
- return '';
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function escapeHTML(html) {
|
|
|
|
- var entityMap = {
|
|
|
|
- "&": "&",
|
|
|
|
- "<": "<",
|
|
|
|
- ">": ">",
|
|
|
|
- '"': '"',
|
|
|
|
- "'": ''',
|
|
|
|
- "/": '/'
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- return String(html).replace(/[&<>"'\/]/g, function (s) {
|
|
|
|
- return entityMap[s];
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function joinArgs(args) {
|
|
|
|
- var html = '<b>' + args[0] + '</b>';
|
|
|
|
- if (args[1]) {
|
|
|
|
- html += ', <b>' + args[1] + '</b>';
|
|
|
|
- if (args[2]) {
|
|
|
|
- html += ', <b>' + args[2] + '</b>';
|
|
|
|
- if (args[3]) {
|
|
|
|
- html += ', and more...';
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return html;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- 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';
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function getTimelineParamsHTML(node, onASingleLine) {
|
|
|
|
- if (isJQuery(node)) {
|
|
|
|
- return getJQueryHTML(node, onASingleLine);
|
|
|
|
- } else {
|
|
|
|
- return getNonJQueryHTML(node, onASingleLine);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
function getBacktraceHTML(backtrace) {
|
|
function getBacktraceHTML(backtrace) {
|
|
var html = '';
|
|
var html = '';
|
|
var parsedBacktrace = parseBacktrace(backtrace);
|
|
var parsedBacktrace = parseBacktrace(backtrace);
|
|
@@ -687,145 +182,6 @@
|
|
return out;
|
|
return out;
|
|
}
|
|
}
|
|
|
|
|
|
- function getTimelineDetailsHTML(node) {
|
|
|
|
- var html = '';
|
|
|
|
-
|
|
|
|
- if (node.data.type != 'jQuery loaded' && node.data.type != 'jQuery version change' && !node.windowPerformance) {
|
|
|
|
- if (node.warning || node.error) {
|
|
|
|
- html += '<div class="icon-warning"></div>';
|
|
|
|
- } else {
|
|
|
|
- html += '<div class="icon-question"></div>';
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- html += '<div class="detailsOverlay">';
|
|
|
|
- html += '<div class="closeBtn">✖</div>';
|
|
|
|
-
|
|
|
|
- if (node.data.callDetails.context && node.data.callDetails.context.length === 0) {
|
|
|
|
- html += '<h4>Called on 0 jQuery element</h4><p class="advice">Useless function call, as the jQuery object is empty.</p>';
|
|
|
|
- } else if (node.eventNotDelegated) {
|
|
|
|
- html += '<p class="advice">This binding should use Event Delegation instead of binding each element one by one.</p>';
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (node.data.resultsNumber === 0) {
|
|
|
|
- html += '<p class="advice">The query returned 0 results. Could it be unused or dead code?</p>';
|
|
|
|
- } else if (node.data.resultsNumber > 0) {
|
|
|
|
- html += '<p>The query returned ' + node.data.resultsNumber + ' ' + (node.data.resultsNumber > 1 ? 'results' : 'result') + '.</p>';
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (node.data.backtrace) {
|
|
|
|
- html += '<h4>Backtrace</h4>';
|
|
|
|
- html += '<div class="table">';
|
|
|
|
- html += getBacktraceHTML(node.data.backtrace);
|
|
|
|
- html += '</div>';
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- html += '</div>';
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return html;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- offendersDirectives.directive('profilerLine', ['$filter', function($filter) {
|
|
|
|
-
|
|
|
|
- var numberWithCommas = $filter('number');
|
|
|
|
-
|
|
|
|
- function getProfilerLineHTML(index, node) {
|
|
|
|
- return '<div class="index">' + (index + 1) + '</div>' +
|
|
|
|
- '<div class="type">' + node.data.type + (node.children ? '<div class="children">' + recursiveChildrenHTML(node) + '</div>' : '') + '</div>' +
|
|
|
|
- '<div class="value">' + getTimelineParamsHTML(node, false) + '</div>' +
|
|
|
|
- '<div class="details">' + getTimelineDetailsHTML(node) + '</div>' +
|
|
|
|
- '<div class="startTime ' + node.data.loadingStep + '">' + numberWithCommas(node.data.timestamp, 0) + ' ms</div>';
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function recursiveChildrenHTML(node) {
|
|
|
|
- var html = '';
|
|
|
|
-
|
|
|
|
- if (node.children) {
|
|
|
|
- node.children.forEach(function(child) {
|
|
|
|
- html += '<div class="child"><span>' + child.data.type + '<div class="childArgs">' + getTimelineParamsHTML(child, true) + '</div></span>' + recursiveChildrenHTML(child) + '</div>';
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return html;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function onDetailsClick(row) {
|
|
|
|
- // Close if it's already open
|
|
|
|
- if (row.classList.contains('showDetails')) {
|
|
|
|
- closeDetails(row);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Close any other open details overlay
|
|
|
|
- var openOnes = document.getElementsByClassName('showDetails');
|
|
|
|
- if (openOnes.length > 0) {
|
|
|
|
- openOnes[0].classList.remove('showDetails');
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Make it appear
|
|
|
|
- row.classList.add('showDetails');
|
|
|
|
-
|
|
|
|
- // Bind the close button
|
|
|
|
- row.querySelector('.closeBtn').addEventListener('click', function() {
|
|
|
|
- closeDetails(row);
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function closeDetails(row) {
|
|
|
|
- row.classList.remove('showDetails');
|
|
|
|
-
|
|
|
|
- // Unbind the close button
|
|
|
|
- row.querySelector('.closeBtn').removeEventListener('click', closeDetails);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return {
|
|
|
|
- restrict: 'E',
|
|
|
|
- scope: {
|
|
|
|
- index: '=',
|
|
|
|
- node: '='
|
|
|
|
- },
|
|
|
|
- template: '<div></div>',
|
|
|
|
- replace: true,
|
|
|
|
- link: function(scope, element) {
|
|
|
|
-
|
|
|
|
- if (scope.node.error) {
|
|
|
|
- element.addClass('jsError');
|
|
|
|
- } else if (scope.node.windowPerformance) {
|
|
|
|
- element.addClass('windowPerformance');
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- element.append(getProfilerLineHTML(scope.index, scope.node));
|
|
|
|
- element[0].id = 'line_' + scope.index;
|
|
|
|
-
|
|
|
|
- if (scope.node.warning) {
|
|
|
|
- element[0].classList.add('warning');
|
|
|
|
-
|
|
|
|
- if (scope.node.queryWithoutResults) {
|
|
|
|
- element[0].classList.add('queryWithoutResults');
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (scope.node.jQueryCallOnEmptyObject) {
|
|
|
|
- element[0].classList.add('jQueryCallOnEmptyObject');
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (scope.node.eventNotDelegated) {
|
|
|
|
- element[0].classList.add('eventNotDelegated');
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- // Bind click on the details icon
|
|
|
|
- var detailsIcon = element[0].querySelector('.details div');
|
|
|
|
- if (detailsIcon) {
|
|
|
|
- detailsIcon.addEventListener('click', function() {
|
|
|
|
- onDetailsClick(this.parentNode.parentNode);
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
- }]);
|
|
|
|
-
|
|
|
|
function shortenUrl(url, maxLength) {
|
|
function shortenUrl(url, maxLength) {
|
|
if (!maxLength) {
|
|
if (!maxLength) {
|
|
maxLength = 110;
|
|
maxLength = 110;
|