Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client Side Debugging #279

Merged
merged 17 commits into from
Oct 1, 2013
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 161 additions & 23 deletions dist/dust-core-1.2.5.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,94 @@ function getGlobal(){

(function(dust) {

if(!dust) {
if(window.console && window.console.error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will break in v8 and node where window is not defined.

in dustjs-helpers we just did:

/* make a safe version of console if it is not available
 * currently supporting:
 *   _console.log
 * */
var _console = (typeof console !== 'undefined')? console: {
  log: function(){
     /* a noop*/
   }
};

window.console.error('dust is not defined');
}
return;
}

dust.logger = {
// set the 'level' in the host environment equal to or more than the level of error you want to display.
// set 'syncronous' in the host environment to true if you want to manually print out errors in a batch using dust.logErrors()
// set 'forceLevel' in the host environment to an error level in order to only show errors of that level.
DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 4, synchronous: false,

methodMap: {0: 'debug', 1: 'info', 2: 'warn', 3: 'error'},

errorsList: [],

// can be overridden in the host environment
// log an error based on the level passed in and the current level set on this object
log: function(level, obj) {
if (dust.logger.level <= level) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggest adding this in a try/catch. logging should not generate errors.

if(dust.logger.forceLevel === undefined || dust.logger.forceLevel === level) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typeof dust.logger.forceLevel === 'undefined'

or

should we just define dust.logger.forceLevel = -1 by default.

var method = dust.logger.methodMap[level];
if (typeof window.console !== 'undefined' && window.console[method]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see note above.
_console[method](obj)

don't know if we need .call here

window.console[method].call(window.console, obj);
}
}
}
},

addError: function(level, obj) {
dust.logger.errorsList.push({level: level, obj:obj});
},

logErrors: function() {
var i, len;
if(console.group) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see above. if we shim out _console.group to be console.group || console.log || function(){/*a noop*/} and _console.groupEnd to be console.groupEnd or a noop then we avoid having to do this if check over and over.

console.group('dust errors');
}
for(i=0,len=dust.logger.errorsList.length; i<len; i++) {
dust.logger.log(dust.logger.errorsList[i].level, dust.logger.errorsList[i].obj);
}
if(console.groupEnd) {
console.groupEnd();
}
}
};

// if dust.logger.synchronous is set to true, only add the error instead of logging it.
dust.log = function(level, obj) { dust.logger.synchronous ? dust.logger.addError(level, obj) : dust.logger.log(level, obj); };

// use this to manually print out synchronlously printed errors.
dust.logErrors = function() { dust.logger.logErrors(); };

dust.helpers = {};

dust.cache = {};

dust.register = function(name, tmpl) {
if (!name) return;
if (!name) {
dust.log(2, 'template name is undefined');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should use the enums created dust.logger.WARN.

return;
}
if(typeof tmpl !== 'function') {
dust.log(2, 'template [' + name + '] cannot be resolved to a dust function');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nit-picky: Dust (the language is capitalized. dust the variable is not.

}
dust.cache[name] = tmpl;
};

dust.render = function(name, context, callback) {
var chunk = new Stub(callback).head;
dust.load(name, chunk, Context.wrap(context, name)).end();
var chunk = new Stub(callback).head,
loadedChunk = dust.load(name, chunk, Context.wrap(context, name));
// catch errors from dust.load
if(loadedChunk.error && loadedChunk.error.message) {
dust.log(2, loadedChunk.error.message);
}
loadedChunk.end();
};

dust.stream = function(name, context) {
var stream = new Stream();
dust.nextTick(function() {
dust.load(name, stream.head, Context.wrap(context, name)).end();
var loadedChunk = dust.load(name, stream.head, Context.wrap(context, name));
// catch errors from dust.load
if(loadedChunk.error && loadedChunk.error.message) {
dust.log(2, loadedChunk.error.message);
}
loadedChunk.end();
});
return stream;
};
Expand All @@ -47,7 +117,12 @@ dust.compileFn = function(source, name) {
return function(context, callback) {
var master = callback ? new Stub(callback) : new Stream();
dust.nextTick(function() {
tmpl(master.head, Context.wrap(context, name)).end();
if(typeof tmpl === 'function') {
tmpl(master.head, Context.wrap(context, name)).end();
}
else {
dust.log(2, 'template [' + name + '] cannot be resolved to a dust function');
}
});
return master;
};
Expand Down Expand Up @@ -75,11 +150,12 @@ dust.loadSource = function(source, path) {
return eval(source);
};

dust.prototype = Object.prototype;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why? the dust namespace is already pretty cluttered. this indirection doesn't by us much.

if (Array.isArray) {
dust.isArray = Array.isArray;
} else {
dust.isArray = function(arr) {
return Object.prototype.toString.call(arr) == "[object Array]";
return dust.prototype.toString.call(arr) === "[object Array]";
};
}

Expand All @@ -106,11 +182,14 @@ dust.filter = function(string, auto, filters) {
var name = filters[i];
if (name === "s") {
auto = null;
dust.log(0, 'using unescape filter on [' + string + ']');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure how useful the string is to a dev. Wouldn't they be more interested in the template name or line number?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't get at the current template name.

}
// fail silently for invalid filters
else if (typeof dust.filters[name] === 'function') {
string = dust.filters[name](string);
}
else {
dust.log(2, 'invalid filter [' + name + ']');
}
}
}
// by default always apply the h filter, unless asked to unescape with |s
Expand All @@ -125,8 +204,8 @@ dust.filters = {
j: function(value) { return dust.escapeJs(value); },
u: encodeURI,
uc: encodeURIComponent,
js: function(value) { if (!JSON) { return value; } return JSON.stringify(value); },
jp: function(value) { if (!JSON) { return value; } return JSON.parse(value); }
js: function(value) { if (!JSON) { dust.log(2, 'JSON is undefined. JSON stringify has not been used on [' + value + ']'); return value; } return JSON.stringify(value); },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure how useful the value is here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As stated above, can't get at the current template name, which would make it more useful.

jp: function(value) { if (!JSON) { dust.log(2, 'JSON is undefined. JSON parse has not been used on [' + value + ']'); return value; } return JSON.parse(value); }
};

function Context(stack, global, blocks) {
Expand All @@ -153,19 +232,36 @@ Context.prototype.get = function(key) {

while(ctx) {
if (ctx.isObject) {
value = ctx.head[key];
if(ctx.head) {
value = ctx.head[key];
}
else {
dust.log(2, 'context head is undefined for[' + key + ']');
}
if (!(value === undefined)) {
return value;
}
}
else {
dust.log(0, 'current context is not an object. Cannot find value for [{' + key + '}]');
}
dust.log(0, 'Looking for [{' + key + '}] up the context stack');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can potentially run many many times. not sure how useful the key is here. Not sure how this would affect perf.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be useful for debugging if we pair it with the template name somehow. It would only affect perf on pages with this option enabled. It would be turned off in a production environment.

ctx = ctx.tail;
}
dust.log(0, 'Looking for [{' + key + '}] in the globals');
return this.global ? this.global[key] : undefined;
};

Context.prototype.getPath = function(cur, down) {
var ctx = this.stack,
len = down.length;
len = down && dust.isArray(down) ? down.length : 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getpath calls are generated by the compiler which is written to guarantee an array is there. this might not be useful


if(!down) {
dust.log(1, 'array parameter in getPath is not defined');
}
if(!dust.isArray(down)) {
dust.log(1, 'array parameter in getPath is not an array');
}

if (cur && len === 0) return ctx.head;
ctx = ctx.head;
Expand All @@ -178,11 +274,25 @@ Context.prototype.getPath = function(cur, down) {
};

Context.prototype.push = function(head, idx, len) {
return new Context(new Stack(head, this.stack, idx, len), this.global, this.blocks);
var context = new Context(new Stack(head, this.stack, idx, len), this.global, this.blocks);
if(context) {
return context;
}
else {
dust.log(2, 'Head [' + head + '] could not be resolved to a context');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

head is an object. so you'll get ['object' 'object'] here. not sure how useful knowing the JSON value would be.

return {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not the same. the return value needs to be an instance of context.
you can use Context.wrap.

}
};

Context.prototype.rebase = function(head) {
return new Context(new Stack(head), this.global, this.blocks);
var context = new Context(new Stack(head), this.global, this.blocks);
if(context) {
return context;
}
else {
dust.log(2, 'Head [' + head + '] could not be resolved to a context');
return {};
}
};

Context.prototype.current = function() {
Expand All @@ -197,7 +307,10 @@ Context.prototype.getBlock = function(key, chk, ctx) {

var blocks = this.blocks;

if (!blocks) return;
if (!blocks) {
dust.log(1, 'no blocks defined for function getBlock');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should only need to be DEBUG. this is OK since blocks are not necesary

return;
}
var len = blocks.length, fn;
while (len--) {
fn = blocks[len][key];
Expand All @@ -223,7 +336,13 @@ Context.prototype.shiftBlocks = function(locals) {
function Stack(head, tail, idx, len) {
this.tail = tail;
this.isObject = !dust.isArray(head) && head && typeof head === "object";
this.head = head;
if(head !== undefined && head !== null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be shortened to head != null

this.head = head;
}
else {
dust.log(0, 'head was undefined. Defaulting to {}');
this.head = {};
}
this.index = idx;
this.of = len;
}
Expand All @@ -242,6 +361,7 @@ Stub.prototype.flush = function() {
this.out += chunk.data.join(""); //ie7 perf
} else if (chunk.error) {
this.callback(chunk.error);
dust.log(2, 'chunk error [' + chunk.error + '] thrown. Setting flush function to empty function.');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this stops rendering in a template in the middle of rendering. we should consider rewording this somehow.

this.flush = function() {};
return;
} else {
Expand All @@ -265,6 +385,7 @@ Stream.prototype.flush = function() {
this.emit('data', chunk.data.join("")); //ie7 perf
} else if (chunk.error) {
this.emit('error', chunk.error);
dust.log(2, 'chunk error [' + chunk.error + '] thrown. Setting flush function to empty function.');
this.flush = function() {};
return;
} else {
Expand All @@ -277,25 +398,39 @@ Stream.prototype.flush = function() {
};

Stream.prototype.emit = function(type, data) {
if (!this.events) return false;
if (!this.events) {
dust.log(1, 'no events to emit');
return false;
}
var handler = this.events[type];
if (!handler) return false;
if (!handler) {
dust.log(2, 'Event type [' + type + '] does not exist');
return false;
}
if (typeof handler == 'function') {
handler(data);
} else {
} else if (dust.isArray(handler)) {
var listeners = handler.slice(0);
for (var i = 0, l = listeners.length; i < l; i++) {
listeners[i](data);
}
}
else {
dust.log(0, 'handler [' + handler + '] is not of a type that is handled by emit');
}
};

Stream.prototype.on = function(type, callback) {
if (!this.events) {
this.events = {};
}
if (!this.events[type]) {
this.events[type] = callback;
dust.log(2, 'event type [' + type + '] does not exist. using just the specified callback.');
if(callback) {
this.events[type] = callback;
} else {
dust.log(2, 'callback for type [' + type + '] does not exist. listener not registered.');
}
} else if(typeof this.events[type] === 'function') {
this.events[type] = [this.events[type], callback];
} else {
Expand Down Expand Up @@ -385,6 +520,7 @@ Chunk.prototype.reference = function(elem, context, auto, filters) {
if (!dust.isEmpty(elem)) {
return this.write(dust.filter(elem, auto, filters));
} else {
dust.log(1, 'reference for element [' + elem + '] was not found. defaulting to chunk.');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can remove defaulting to chunk.

return this;
}
};
Expand Down Expand Up @@ -419,9 +555,7 @@ Chunk.prototype.section = function(elem, context, bodies, params) {
if (len > 0) {
// any custom helper can blow up the stack
// and store a flattened context, guard defensively
if(context.stack.head) {
context.stack.head['$len'] = len;
}
context.stack.head['$len'] = len;
for (var i=0; i<len; i++) {
if(context.stack.head) {
context.stack.head['$idx'] = i;
Expand Down Expand Up @@ -455,7 +589,8 @@ Chunk.prototype.section = function(elem, context, bodies, params) {
// undefined are all falsy
} else if (skip) {
return skip(this, context);
}
}
dust.log(2, 'can not handle the element [' + elem + '] given for the section tag');
return this;
};

Expand All @@ -468,6 +603,7 @@ Chunk.prototype.exists = function(elem, context, bodies) {
} else if (skip) {
return skip(this, context);
}
dust.log(0, 'not rendering body or skip');
return this;
};

Expand All @@ -480,6 +616,7 @@ Chunk.prototype.notexists = function(elem, context, bodies) {
} else if (skip) {
return skip(this, context);
}
dust.log(0, 'not rendering body or skip');
return this;
};

Expand Down Expand Up @@ -527,6 +664,7 @@ Chunk.prototype.helper = function(name, context, bodies, params) {
if( dust.helpers[name]){
return dust.helpers[name](this, context, bodies, params);
} else {
dust.log(3, 'invalid helper [' + name + ']');
return this;
}
};
Expand Down
Loading