mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
create dom trace debug tool
This commit is contained in:
238
js/ext/angular/test/dom-trace.js
vendored
Normal file
238
js/ext/angular/test/dom-trace.js
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
|
||||
(function(){
|
||||
|
||||
function logMutation(m) {
|
||||
if(m.type == 'attributes') {
|
||||
attributeMutation(m);
|
||||
} else if(m.type == 'childList') {
|
||||
childListMutation(m);
|
||||
} else if(m.type == 'characterData') {
|
||||
characterDataMutation(m);
|
||||
} else if(m.type == 'subtree') {
|
||||
attributeMutation(m);
|
||||
} else {
|
||||
console.debug(m);
|
||||
}
|
||||
}
|
||||
|
||||
function attributeMutation(m) {
|
||||
// target's attributes are to be observed.
|
||||
if(m.attributeName == 'class') {
|
||||
var msgs = [];
|
||||
|
||||
msgs.push( 'Class, ' + createElementId(m.target) );
|
||||
|
||||
if(m.oldValue !== m.target.className) {
|
||||
var exisitingClasses = (m.oldValue ? m.oldValue.split(' ') : []);
|
||||
var currentClasses = m.target.className.split(' ');
|
||||
var addedClasses = [];
|
||||
var removedClasses = [];
|
||||
|
||||
for(var x=0; x<currentClasses.length; x++) {
|
||||
if(currentClasses[x]=='' || ignoreClassName(currentClasses[x])) continue;
|
||||
var addedCSS = currentClasses[x];
|
||||
|
||||
for(var y=0; y<exisitingClasses.length; y++) {
|
||||
if(currentClasses[x] == exisitingClasses[y]) {
|
||||
addedCSS = null;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if(addedCSS) addedClasses.push(addedCSS);
|
||||
}
|
||||
|
||||
for(var x=0; x<exisitingClasses.length; x++) {
|
||||
if(exisitingClasses[x]=='' || ignoreClassName(exisitingClasses[x])) continue;
|
||||
var removedCSS=exisitingClasses[x];
|
||||
|
||||
for(var y=0; y<currentClasses.length; y++) {
|
||||
if(currentClasses[x] == exisitingClasses[y]) {
|
||||
removedCSS = null;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if(removedCSS) removedClasses.push(removedCSS);
|
||||
}
|
||||
|
||||
if(addedClasses.length) {
|
||||
msgs.push('Added ' + addedClasses);
|
||||
}
|
||||
if(removedClasses.length) {
|
||||
msgs.push('Removed ' + removedClasses);
|
||||
}
|
||||
if(addedClasses.length || removedClasses.length) {
|
||||
log(m, msgs, 'magenta');
|
||||
}
|
||||
|
||||
} else {
|
||||
msgs.push('className never changed!')
|
||||
log(m, msgs, 'maroon');
|
||||
}
|
||||
|
||||
} else if(m.attributeName == 'style') {
|
||||
var msgs = [];
|
||||
|
||||
msgs.push( 'Style, ' + createElementId(m.target) );
|
||||
if(m.oldValue) msgs.push( 'from ' + m.oldValue );
|
||||
|
||||
if(msgs.length) {
|
||||
log(m, msgs, 'blue');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function childListMutation(m) {
|
||||
// children are to be observed.
|
||||
var msgs = [];
|
||||
for(var x=0; x<m.addedNodes.length; x++) {
|
||||
if(m.addedNodes[x].nodeType !== 3) {
|
||||
msgs.push('Child List');
|
||||
msgs.push( 'Add: ' + createElementId(m.target) );
|
||||
msgs.push( 'Parent: ' + createElementId(m.target.parentElement) );
|
||||
}
|
||||
}
|
||||
if(msgs.length) {
|
||||
log(m, msgs, 'orange');
|
||||
}
|
||||
|
||||
msgs = [];
|
||||
for(var x=0; x<m.removedNodes.length; x++) {
|
||||
if(m.removedNodes[x].nodeType !== 3) {
|
||||
msgs.push('Child List');
|
||||
msgs.push( 'Remove: ' + createElementId(m.target) );
|
||||
msgs.push( 'Parent: ' + createElementId(m.target.parentElement) );
|
||||
}
|
||||
}
|
||||
if(msgs.length) {
|
||||
log(m, msgs, 'orangered');
|
||||
}
|
||||
}
|
||||
|
||||
function characterDataMutation(m) {
|
||||
// target's data are to be observed
|
||||
|
||||
}
|
||||
|
||||
function createElementId(el) {
|
||||
var id;
|
||||
if(!el) {
|
||||
id = 'null'
|
||||
} else if(el.tagName) {
|
||||
var id = el.tagName.toLowerCase();
|
||||
var classes = el.className.split(' ');
|
||||
for(var x=0; x<classes.length; x++) {
|
||||
if(!ignoreClassName(classes[x])) {
|
||||
id += '.' + classes[x];
|
||||
}
|
||||
}
|
||||
if(el.id.length) id += '#' + el.id;
|
||||
|
||||
var href = el.getAttribute('href');
|
||||
if(href) {
|
||||
href = href.split('/');
|
||||
id += '[href=' + href[href.length -1] + ']';
|
||||
}
|
||||
|
||||
var ngClick = el.getAttribute('ng-click');
|
||||
if(ngClick) {
|
||||
id += '[ng-click=' + ngClick + ']';
|
||||
}
|
||||
} else {
|
||||
id = el.nodeName;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
function ignoreClassName(className) {
|
||||
if(!className.length) return true;
|
||||
for(var x=0; x<ignoreClassNames.length; x++) {
|
||||
if(className === ignoreClassNames[x]) return true;
|
||||
}
|
||||
}
|
||||
|
||||
function log(m, msgs, color) {
|
||||
totalManipulations++;
|
||||
|
||||
if(m.target && !m.target.domTraceId) {
|
||||
m.target.domTraceId = idInc;
|
||||
idInc++;
|
||||
}
|
||||
|
||||
msgs.unshift( 'ID ' + m.target.domTraceId );
|
||||
|
||||
var d = new Date();
|
||||
msgs.unshift( d.getSeconds() + '.' + d.getMilliseconds() );
|
||||
|
||||
var msg = msgs.join(', ');
|
||||
console.log("%c" + msg,
|
||||
"color:" + color);
|
||||
|
||||
clearTimeout(timeId)
|
||||
timeId = setTimeout(function(){
|
||||
console.log('Manipulations:', totalManipulations)
|
||||
totalManipulations = 0;
|
||||
}, 1200);
|
||||
}
|
||||
|
||||
var timeId;
|
||||
|
||||
window.domTrace = {
|
||||
|
||||
observe: function(selector){
|
||||
if (!selector) selector = 'body';
|
||||
var el = document.querySelector(selector);
|
||||
if(!el) return console.error(selector, 'not found');
|
||||
|
||||
console.debug('Dom Trace, observe:', selector);
|
||||
|
||||
var observer = new MutationObserver(function(mutations) {
|
||||
mutations.forEach(logMutation);
|
||||
});
|
||||
|
||||
observer.observe(el, {
|
||||
attributes: true,
|
||||
childList: false,
|
||||
characterData: true,
|
||||
subtree: true,
|
||||
attributeOldValue: true,
|
||||
characterDataOldValue: true,
|
||||
attributeFilter: true
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
|
||||
|
||||
var logColors = {
|
||||
attributesClass: 'purple',
|
||||
attributesStyle: 'magenta',
|
||||
childListAdd: 'orange',
|
||||
childListRemove: 'orangered',
|
||||
characterData: 'blue',
|
||||
subtree: 'green',
|
||||
attributeOldValue: 'maroon',
|
||||
characterDataOldValue: 'brown',
|
||||
attributeFilter: 'darkblue'
|
||||
};
|
||||
|
||||
var ignoreClassNames = [
|
||||
'ng-isolate-scope',
|
||||
'ng-scope',
|
||||
'ng-binding',
|
||||
'ng-bind-html'
|
||||
];
|
||||
|
||||
var idInc = 0;
|
||||
var totalManipulations = 0;
|
||||
|
||||
document.addEventListener('keyup', function(e){
|
||||
if(e.keyCode === 27) {
|
||||
console.clear();
|
||||
totalManipulations = 0;
|
||||
}
|
||||
}, false);
|
||||
|
||||
})(window);
|
||||
@@ -12,6 +12,7 @@
|
||||
<script src="../../../../dist/js/angular/angular-sanitize.js"></script>
|
||||
<script src="../../../../dist/js/angular-ui/angular-ui-router.js"></script>
|
||||
<script src="../../../../dist/js/ionic-angular.js"></script>
|
||||
<script src="dom-trace.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -379,6 +380,8 @@
|
||||
|
||||
});
|
||||
|
||||
domTrace.observe();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user