Implemented a javascript code style

This commit is contained in:
Stefan Zermatten
2015-04-22 12:44:25 +02:00
parent dce20375b5
commit fada0f5136
113 changed files with 1614 additions and 1650 deletions

View File

@@ -1,7 +1,7 @@
getMod = function(score){
return Math.floor((score-10)/2);
}
return Math.floor((score - 10) / 2);
};
signedString = function(number){
return number >= 0? "+" + number : "" + number;
}
return number >= 0 ? "+" + number : "" + number;
};

View File

@@ -1,17 +1,17 @@
roll = function (n, d){
if(!isNaN(n)){
roll = function(n, d){
if (!isNaN(n)){
//first digit is a number
if(d === undefined){
if (d === undefined){
d = n;
n = 1;
}
if(n > 500){
if (n > 500){
console.log(n + " > 500, cannot lift that many dice to roll them");
return;
}
var result = {sum: 0, rolls: []};
for (var i = 0; i < n; i++){
var roll = Math.floor(Random.fraction() * d + 1)
var roll = Math.floor(Random.fraction() * d + 1);
result.sum += roll;
result.rolls.push(roll);
}
@@ -19,26 +19,26 @@ roll = function (n, d){
}
console.log("rolling dice failed for inputs: ", n, d);
return {sum: 0, rolls: []};
}
};
rollDropLow = function(n, d, drop){
var r = roll(n,d)
r.rolls.sort(function(a, b){return a-b}); //sort ascending
var r = roll(n, d);
r.rolls.sort(function(a, b){return a - b;}); //sort ascending
r.rolls.splice(0, drop); //remove the lowest elements
r.sum = 0;
for (var i = 0, l = r.rolls.length; i , l ; i++){
sum += r.rolls[i];
}
return r;
}
};
rollDropHigh = function(n, d, drop){
var r = roll(n,d)
r.rolls.sort(function(a, b){return b-a}); //sort descending
var r = roll(n, d);
r.rolls.sort(function(a, b){return b - a;}); //sort descending
r.rolls.splice(0, drop); //remove the highest elements
r.sum = 0;
for (var i = 0, l = r.rolls.length; i , l ; i++){
sum += r.rolls[i];
}
return r;
}
};

View File

@@ -1,62 +1,69 @@
//evaluates a calculation string
evaluate = function(charId, string){
if(!string) return string;
if (!string) return string;
var char = Characters.findOne(charId, {fields: {_id: 1}});
string = string.replace(/\b[a-z]+\b/gi, function(sub){
//fields
if(Schemas.Character.schema(sub)){
return char.fieldValue(sub)
if (Schemas.Character.schema(sub)){
return char.fieldValue(sub);
}
//ability modifiers
var abilityMods = ["STRENGTHMOD", "DEXTERITYMOD", "CONSTITUTIONMOD", "INTELLIGENCEMOD", "WISDOMMOD", "CHARISMAMOD"]
if( _.contains(abilityMods, sub.toUpperCase()) ){
var slice = sub.slice(0, - 3);
var abilityMods = [
"STRENGTHMOD",
"DEXTERITYMOD",
"CONSTITUTIONMOD",
"INTELLIGENCEMOD",
"WISDOMMOD",
"CHARISMAMOD",
];
if (_.contains(abilityMods, sub.toUpperCase())){
var slice = sub.slice(0, -3);
return char.abilityMod(slice);
}
//class levels
if(/\w+levels?\b/gi.test(sub)){
if (/\w+levels?\b/gi.test(sub)){
//strip out "level"
var className = sub.replace(/levels?\b/gi, "");
var cls = Classes.findOne({charId: charId, name: className});
return cls && cls.level;
}
//character level
if(sub.toUpperCase() === "LEVEL"){
if (sub.toUpperCase() === "LEVEL"){
return char.level();
}
return sub;
});
try{
try {
var result = math.eval(string);
return result;
} catch(e){
} catch (e){
console.log("Failed to evaluate ", string);
return string;
}
}
};
//takes a string with {calculations} and returns it with the results
//takes a string with {calculations} and returns it with the results
//of the calculations returned in place
evaluateString = function(charId, string){
//define brackets as curly brackets around anything that isn't a curly bracket
if(!string) return string;
if (!string) return string;
var brackets = /\{[^\{\}]*\}/g;
var result = string.replace(brackets, function(exp){
var exp = exp.replace(/(\{|\})/g, "") //remove curly brackets
exp = exp.replace(/(\{|\})/g, ""); //remove curly brackets
return evaluate(charId, exp);
});
return result;
}
};
//returns the value of the effect if it exists,
//returns the value of the effect if it exists,
//otherwise returns the result of the calculation if it exists,
//otherwise returns 0
evaluateEffect = function(charId, effect){
if(_.isFinite(effect.value)){
if (_.isFinite(effect.value)){
return effect.value;
} else if(_.isString(effect.calculation)){
} else if (_.isString(effect.calculation)){
return +evaluate(charId, effect.calculation);
} else {
return 0;
}
}
};

View File

@@ -1,31 +1,35 @@
var childSchema = new SimpleSchema({
parent: { type: Object },
'parent.collection': { type: String },
'parent.id': { type: String, regEx: SimpleSchema.RegEx.Id },
'parent.group': { type: String, optional: true},
'removedWith': { optional: true, type: String, regEx: SimpleSchema.RegEx.Id },
parent: {type: Object},
"parent.collection": {type: String},
"parent.id": {type: String, regEx: SimpleSchema.RegEx.Id},
"parent.group": {type: String, optional: true},
"removedWith": {
optional: true,
type: String,
regEx: SimpleSchema.RegEx.Id,
},
});
var joinWithDefaultKeys = function(keys){
var defaultKeys = [
'charId',
"charId",
];
return _.union(keys, defaultKeys);
};
var limitModifierToKeys = function(modifier, keys){
if(!modifier) return;
modifier = _.pick(modifier, ['$set', '$unset']);
if(modifier.$set) modifier.$set = _.pick(modifier.$set, keys);
if(modifier.$unset) modifier.$unset = _.pick(modifier.$unset, keys);
if(_.isEmpty(modifier.$set)) delete modifier.$set;
if(_.isEmpty(modifier.$unset)) delete modifier.$unset;
if (!modifier) return;
modifier = _.pick(modifier, ["$set", "$unset"]);
if (modifier.$set) modifier.$set = _.pick(modifier.$set, keys);
if (modifier.$unset) modifier.$unset = _.pick(modifier.$unset, keys);
if (_.isEmpty(modifier.$set)) delete modifier.$set;
if (_.isEmpty(modifier.$unset)) delete modifier.$unset;
return modifier;
};
var getParent = function(doc){
if(!doc || !doc.parent) return;
var parentCol = Meteor.isClient?
if (!doc || !doc.parent) return;
var parentCol = Meteor.isClient ?
window[doc.parent.collection] : global[doc.parent.collection];
if (parentCol)
return parentCol.findOne(doc.parent.id, {removed: true});
@@ -33,9 +37,12 @@ var getParent = function(doc){
var inheritParentProperties = function(doc, collection){
var parent = getParent(doc);
if(!parent) throw new Meteor.Error('Parenting Error', 'Document\'s parent does not exist');
if (!parent) throw new Meteor.Error(
"Parenting Error",
"Document's parent does not exist"
);
var handMeDowns = _.pick(parent, collection.inheritedKeys);
if(_.isEmpty(handMeDowns)) return;
if (_.isEmpty(handMeDowns)) return;
collection.update(doc._id, {$set: handMeDowns});
};
@@ -43,16 +50,18 @@ var childCollections = [];
makeChild = function(collection, inheritedKeys){
inheritedKeys = inheritedKeys || [];
if(inheritedKeys) collection.inheritedKeys = joinWithDefaultKeys(inheritedKeys);
if (inheritedKeys) {
collection.inheritedKeys = joinWithDefaultKeys(inheritedKeys);
}
collection.helpers({
//returns the parent even if it's removed
getParent: function(){
return getParent(this);
},
getParentCollection: function(){
return Meteor.isClient?
return Meteor.isClient ?
window[this.parent.collection] : global[this.parent.collection];
}
},
});
//when created, inherit parent properties
@@ -62,17 +71,19 @@ makeChild = function(collection, inheritedKeys){
collection.before.update(function(userId, doc, fieldNames, modifier, options){
//if we are restoring this asset, unmark that it was removed with its parent, we no longer care
if( modifier && modifier.$unset && modifier.$unset.removed){
if (modifier && modifier.$unset && modifier.$unset.removed) {
modifier.$unset.removedWith = "";
}
});
if(Meteor.isClient) collection.after.update(function (userId, doc, fieldNames, modifier, options) {
if(modifier && modifier.$set && modifier.$set.parent){
//when we change parents, inherit its properties
inheritParentProperties(doc, collection);
}
});
if (Meteor.isClient) {
collection.after.update(function(userId, doc, fieldNames, modifier, options) {
if (modifier && modifier.$set && modifier.$set.parent){
//when we change parents, inherit its properties
inheritParentProperties(doc, collection);
}
});
}
collection.softRemoveNode = collection.softRemoveNode || function(id){
collection.softRemove(id);
@@ -91,47 +102,55 @@ makeParent = function(collection, donatedKeys){
donatedKeys = joinWithDefaultKeys(donatedKeys);
var collectionName = collection._collection.name;
//after changing, push the changes to all children
if(Meteor.isClient) collection.after.update(function (userId, doc, fieldNames, modifier, options) {
modifier = limitModifierToKeys(modifier, donatedKeys);
doc = _.pick(doc, ['_id','charId']);
if(!modifier) return;
Meteor.call('updateChildren', doc, modifier, true);
});
if (Meteor.isClient) {
collection.after.update(function(userId, doc, fieldNames, modifier, options) {
modifier = limitModifierToKeys(modifier, donatedKeys);
doc = _.pick(doc, ["_id", "charId"]);
if (!modifier) return;
Meteor.call("updateChildren", doc, modifier, true);
});
}
collection.softRemoveNode = function(id){
Meteor.call('softRemoveNode', collectionName, id);
Meteor.call("softRemoveNode", collectionName, id);
};
collection.restoreNode = function(id){
Meteor.call('restoreNode', collectionName, id);
Meteor.call("restoreNode", collectionName, id);
};
if(Meteor.isServer) collection.after.remove(function (userId, doc) {
if (Meteor.isServer) collection.after.remove(function(userId, doc) {
_.each(childCollections, function(collection){
collection.remove(
{'parent.id': doc._id}
{"parent.id": doc._id}
);
});
});
};
var checkPermission = function(userId, charId){
var char = Characters.findOne( charId, { fields: {owner: 1, writers: 1} } );
if(!char)
throw new Meteor.Error('Access Denied, no charId',
'Character '+charId+' does not exist');
var char = Characters.findOne(charId, {fields: {owner: 1, writers: 1}});
if (!char)
throw new Meteor.Error("Access Denied, no charId",
"Character " + charId + " does not exist");
if (!userId)
throw new Meteor.Error('Access Denied, no userId',
'No UserId set when trying to update character asset.');
throw new Meteor.Error("Access Denied, no userId",
"No UserId set when trying to update character asset.");
if (char.owner !== userId && !_.contains(char.writers, userId))
throw new Meteor.Error('Access Denied, not permitted',
'Not permitted to update assets of this character.');
throw new Meteor.Error("Access Denied, not permitted",
"Not permitted to update assets of this character.");
return true;
};
var cascadeSoftRemove = function(id, removedWithId){
_.each(childCollections, function(treeCollection){
treeCollection.update({"parent.id": id}, {$set: {removed: true, removedWith: removedWithId}}, {multi: true});
treeCollection.update(
{"parent.id": id},
{$set: {
removed: true,
removedWith: removedWithId,
}},
{multi: true}
);
treeCollection.find({"parent.id": id}).forEach(function(doc){
cascadeSoftRemove(doc._id, removedWithId);
});
@@ -159,37 +178,40 @@ Meteor.methods({
var collection = Mongo.Collection.get(collectionName);
collection.restore(id);
_.each(childCollections, function(treeCollection){
treeCollection.update({removedWith: id, removed: true}, { $unset: {removed: true, removedWith: ""} }, {multi: true});
treeCollection.update(
{removedWith: id, removed: true},
{$unset: {removed: true, removedWith: ""}},
{multi: true}
);
});
},
updateChildren: function (parent, modifier, limitToInheritance) {
updateChildren: function(parent, modifier, limitToInheritance) {
check(parent, {_id: String, charId: String});
check(modifier, Object);
checkPermission(this.userId, parent.charId);
var selector = {'parent.id': parent._id};
var selector = {"parent.id": parent._id};
_.each(childCollections, function(collection){
var thisModifier;
if(limitToInheritance){
if (limitToInheritance){
thisModifier = limitModifierToKeys(modifier, collection.inheritedKeys);
} else{
} else {
thisModifier = _.clone(modifier);
}
if(_.isEmpty(thisModifier)) return;
collection.update( selector, thisModifier, {multi: true, removed: true});
if (_.isEmpty(thisModifier)) return;
collection.update(selector, thisModifier, {multi: true, removed: true});
});
},
cloneChildren: function (objectId, newParent){
cloneChildren: function(objectId, newParent){
check(objectId, String);
check(newParent, {id: String, collection: String});
_.each(childCollections, function(collection){
var keys = collection.simpleSchema().objectKeys();
collection.find({'parent.id': objectId}).forEach(function(doc){
var newDoc = _.pick( doc, keys);
collection.find({"parent.id": objectId}).forEach(function(doc){
var newDoc = _.pick(doc, keys);
newDoc.parent = newParent;
collection.insert(newDoc);
});
});
}
},
});

View File

@@ -7,7 +7,12 @@ canEditCharacter = function(charId, userId){
canViewCharacter = function(charId, userId){
userId = userId || Meteor.userId();
var char = Characters.findOne(charId, {fields: {owner: 1, writers: 1, readers: 1}});
var char = Characters.findOne(
charId,
{fields: {owner: 1, writers: 1, readers: 1}}
);
if (!char) return false;
return (userId === char.owner || _.contains(char.writers, userId) || _.contains(char.readers, userId));
return userId === char.owner ||
_.contains(char.writers, userId) ||
_.contains(char.readers, userId);
};

View File

@@ -1,18 +0,0 @@
placeCaretAtEnd = function(el) {
el = el.get(0); //jquery element -> DOM element
el.focus();
if (typeof window.getSelection != "undefined"
&& typeof document.createRange != "undefined") {
var range = document.createRange();
range.selectNodeContents(el);
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (typeof document.body.createTextRange != "undefined") {
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.collapse(false);
textRange.select();
}
}

View File

@@ -6,7 +6,7 @@ pointBuyCost = {
"12": 4,
"13": 5,
"14": 7,
"15": 9
"15": 9,
};
var getPointBuyEffect = function(stat, value, pointsUsed, charId){
@@ -24,21 +24,21 @@ var getPointBuyEffect = function(stat, value, pointsUsed, charId){
charId: charId,
stat: stat,
operation: "base",
}
},
};
};
var checkPermission = function(userId, charId){
var char = Characters.findOne( charId, { fields: {owner: 1, writers: 1} } );
if(!char)
throw new Meteor.Error('Access Denied',
'Character '+charId+' does not exist');
var char = Characters.findOne(charId, {fields: {owner: 1, writers: 1}});
if (!char)
throw new Meteor.Error("Access Denied",
"Character " + charId + " does not exist");
if (!userId)
throw new Meteor.Error('Access Denied',
'No UserId set when trying to update character asset.');
throw new Meteor.Error("Access Denied",
"No UserId set when trying to update character asset.");
if (char.owner !== userId && !_.contains(char.writers, userId))
throw new Meteor.Error('Access Denied',
'Not permitted to update assets of this character.');
throw new Meteor.Error("Access Denied",
"Not permitted to update assets of this character.");
return true;
};
@@ -50,7 +50,7 @@ Meteor.methods({
constitution: Number,
intelligence: Number,
wisdom: Number,
charisma: Number
charisma: Number,
});
check(charId, String);
checkPermission(this.userId, charId);

View File

@@ -1,49 +0,0 @@
// turns dot notation strings into keys of root
// argument formats:
// 157, object -> 157
// "some.number", object -> object.some.number
// "some.function", object -> object.some.function()
// "some.function arg1 arg2", object -> object.some.function(arg1, arg2)
pop = function(input, root){
if(typeof(input) === "string"){
//we need root for this part
if(root === undefined) return;
//this is a likely to fail if the string is malformed
try{
//split over spaces
var parts = input.split(" ");
//for each word
for (var i = 0; i < parts.length; i++){
//split over dots
var str = parts[i].split(".");
//start at root
parts[i] = root;
//for each word between dots
for (var j = 0; j < str.length; j++){
parts[i] = parts[i][str[j]];
}
}
//pull the first word out, might be a function
var func = parts.splice(0, 1)[0];
//if it's a function, apply the arguments to it
if(_.isFunction(func)) return +func.apply(root, parts);
//if it's a number, return it
if(!isNaN(func)) return +func;
} catch (err) {
//TODO pokemon catch statement is bad
//"gotta catch em all"
console.log(err);
return;
}
}
return +input;
}

View File

@@ -1,6 +1,10 @@
preventLoop = function(inputFunction){
if(!_.isFunction(inputFunction)) throw new Meteor.Error("Not a function",
"preventLoop can only take a function as an argument");
if (!_.isFunction(inputFunction)){
throw new Meteor.Error(
"Not a function",
"preventLoop can only take a function as an argument"
);
}
//store a private array of arguments we have been given without returning
//if we try to visit the same argument twice before resolving its value
//we are in a dependency loop and need to GTFO
@@ -8,20 +12,20 @@ preventLoop = function(inputFunction){
return function(argument){
var value;
//we're still evaluating this attribute, must be in a loop
if(_.contains(visitedArgs, argument)) {
if (_.contains(visitedArgs, argument)) {
console.warn("dependency loop detected");
return NaN;
} else{
} else {
//push this skill to the list of visited skills
//we can't visit it again unless it returns first
visitedArgs.push(argument);
}
try{
try {
value = inputFunction.call(this, argument);
} finally{
//this argument returns or fails, pull it from the array
visitedArgs = _.without(visitedArgs, argument);
}
return value;
}
};
};

View File

@@ -1,7 +1,9 @@
Meteor.methods({
"getUserId": function(username){
if(!username) return;
var user = Meteor.users.findOne({$or: [{username: username}, {"emails.address": username}]});
if (!username) return;
var user = Meteor.users.findOne(
{$or: [{username: username}, {"emails.address": username}]}
);
return user && user._id;
}
});

View File

@@ -11,4 +11,4 @@ updatePolymerInputs = function(self){
el.valueChanged();
});
});
};
};