<commit_before>'use strict';

var _ = require('lodash');

var AND_TOKEN = 'AND',
	OR_TOKEN = 'OR',
	OPEN_PAREN_TOKEN = '(',
	CLOSE_PAREN_TOKEN = ')';

var TOKEN_REGEXP = /\s+AND\s+|\s+OR\s+|\s?\(\s?|\s?\)\s?/;
/****************************************************\
		Rules
\****************************************************/

function EmptyRule () {

}

EmptyRule.prototype.match = function(tagList) {
	return true;
};

EmptyRule.prototype.equalTo = function(emptyRule) {
	return emptyRule instanceof EmptyRule;
};

EmptyRule.prototype.toString = function() {
	return '';
};

function TagRule (tag) {
	this._value = tag;
}

TagRule.prototype.match = function(tagList) {
    // APEP this match can cause problems - TODO update this to be full word
	return tagList.indexOf(this._value) !== -1 ? true : false;
};

TagRule.prototype.equalTo = function(tagRule) {
	return tagRule instanceof TagRule && this._value === tagRule._value;
};

TagRule.prototype.toString = function() {
	return this._value;
};

function AndRule (leftRule, rightRule) {
	this._left = leftRule;
	this._right = rightRule;
}

AndRule.prototype.match = function(tagList) {
	return this._left.match(tagList) && this._right.match(tagList);
};

AndRule.prototype.equalTo = function(andRule) {
	return andRule instanceof AndRule &&
		this._left.equalTo(andRule._left) &&
		this._right.equalTo(andRule._right);
};

AndRule.prototype.toString = function() {
	return this._left.toString() + ' AND ' + this._right.toString();
};

function OrRule (leftRule, rightRule) {
	this._left = leftRule;
	this._right = rightRule;
}

OrRule.prototype.match = function(tagList) {
	return this._left.match(tagList) || this._right.match(tagList);
};

OrRule.prototype.equalTo = function(orRule) {
	return orRule instanceof OrRule &&
		this._left.equalTo(orRule._left) &&
		this._right.equalTo(orRule._right);
};

OrRule.prototype.toString = function() {
	return this._left.toString() + ' OR ' + this._right.toString();
};

function ParethesisRule (rule) {
	this._rule = rule;
}

ParethesisRule.prototype.match = function(tagList) {
	return this._rule.match(tagList);
};

ParethesisRule.prototype.equalTo = function(rule) {
	return rule instanceof ParethesisRule &&
		this._rule.equalTo(rule._rule);
};

ParethesisRule.prototype.toString = function() {
	return '(' + this._rule.toString() + ')';
};

/****************************************************\
        TagMatcher
\****************************************************/

function TagMatcher (query) {
	this._query = parseQuery(tokenizeQuery(query || ''));
}

TagMatcher.prototype.toString = function() {
	return this._query.toString();
};

function parseQuery (tokens) {

	// catch the easy case first, single tag
	if (tokens.length === 0) {
		return new EmptyRule();
	} else if (tokens.length === 1) {
		var toke = tokens[0];
		if (toke instanceof ParethesisRule) {
			return toke;
		} else {
			return new TagRule(tokens[0]);
		}
	} else {
		// first look for wrapped parenthesis
		// process all sets of parenthesis before continuing
		var openParenIndex = tokens.indexOf(OPEN_PAREN_TOKEN);
		while (openParenIndex !== -1) {
			// find the matching closer
			var closePos = openParenIndex,
				counter = 1;

			while (counter > 0 && closePos < tokens.length) {
				var token = tokens[++closePos];
				if (token === OPEN_PAREN_TOKEN) {
					counter++;
				} else if (token === CLOSE_PAREN_TOKEN) {
					counter--;
				}
			}

			if (counter > 0) {
				throw 'Unfound closing parenthesis in tokens ' + tokens;
			}

			var pre = tokens.slice(0, openParenIndex);
			var rule = new ParethesisRule(parseQuery(tokens.slice(openParenIndex + 1, closePos)));
			var post = tokens.slice(closePos + 1);

			tokens = [].concat(pre, rule, post);
			openParenIndex = tokens.indexOf(OPEN_PAREN_TOKEN);

		}

		// then look for OR
		var leftTokens, rightTokens;
		var orIndex = tokens.indexOf(OR_TOKEN);
		if (orIndex !== -1) {
			leftTokens = tokens.slice(0, orIndex);
			rightTokens = tokens.slice(orIndex + 1);
			return new OrRule(parseQuery(leftTokens), parseQuery(rightTokens));
		} else {
			// look for AND
			var andIndex = tokens.indexOf(AND_TOKEN);
			if (andIndex !== -1) {
				leftTokens = tokens.slice(0, andIndex);
				rightTokens = tokens.slice(andIndex + 1);
				return new AndRule(parseQuery(leftTokens), parseQuery(rightTokens));
			} else {
				// all done, nothing else to check, just return our one rule now
				return tokens[0];
			}
		}
	}
}

function tokenizeQuery (query) {
	var tokens = [];
	query = query.replace(/,/g, ' OR ').trim();

	var match,
		matchString = query;
	while (matchString !== '') {
		match = TOKEN_REGEXP.exec(matchString);

		if (! match) {
			tokens.push(matchString.trim());
			break;
		} else {
			// first break off the tags prior to the token
			if (match.index !== 0) {
				var tagToke = matchString.substring(0, match.index).trim();
				tokens.push(tagToke);
			}

			// now put on the matched token
			tokens.push(match[0].trim());

			// advance the startIndex
			// add a space on the front to add back the space that went missing from the match
			var offset = match.index + match[0].length;
			if (matchString.charAt(offset-1) === ' ') {
				offset--;
			}

			matchString = matchString.substring(offset);
		}

	}

	return tokens;
}

TagMatcher.prototype.match = function(tagList) {
	return this._query.match(tagList);
};

TagMatcher.prototype.equalTo = function(tagMatcher) {
	return this._query.equalTo(tagMatcher._query);
};

module.exports = TagMatcher;
<commit_msg>Resolve the tag matcher to only search full words.<commit_after>'use strict';

var _ = require('lodash');

var AND_TOKEN = 'AND',
	OR_TOKEN = 'OR',
	OPEN_PAREN_TOKEN = '(',
	CLOSE_PAREN_TOKEN = ')';

var TOKEN_REGEXP = /\s+AND\s+|\s+OR\s+|\s?\(\s?|\s?\)\s?/;
/****************************************************\
		Rules
\****************************************************/

function EmptyRule () {

}

EmptyRule.prototype.match = function(tagList) {
	return true;
};

EmptyRule.prototype.equalTo = function(emptyRule) {
	return emptyRule instanceof EmptyRule;
};

EmptyRule.prototype.toString = function() {
	return '';
};

function TagRule (tag) {
	this._value = tag;
}

TagRule.prototype.match = function(tagList) {
    var self = this;

    // APEP Split the tag list using the delimiter we've enforced on the user
    var matches = _.filter(tagList.split(","), function(tag) {
        // APEP we can then compare each tag to find a match - trim is something we may or may not want
        return tag.trim() === self._value;
    });

    return matches.length > 0;
};

TagRule.prototype.equalTo = function(tagRule) {
	return tagRule instanceof TagRule && this._value === tagRule._value;
};

TagRule.prototype.toString = function() {
	return this._value;
};

function AndRule (leftRule, rightRule) {
	this._left = leftRule;
	this._right = rightRule;
}

AndRule.prototype.match = function(tagList) {
	return this._left.match(tagList) && this._right.match(tagList);
};

AndRule.prototype.equalTo = function(andRule) {
	return andRule instanceof AndRule &&
		this._left.equalTo(andRule._left) &&
		this._right.equalTo(andRule._right);
};

AndRule.prototype.toString = function() {
	return this._left.toString() + ' AND ' + this._right.toString();
};

function OrRule (leftRule, rightRule) {
	this._left = leftRule;
	this._right = rightRule;
}

OrRule.prototype.match = function(tagList) {
	return this._left.match(tagList) || this._right.match(tagList);
};

OrRule.prototype.equalTo = function(orRule) {
	return orRule instanceof OrRule &&
		this._left.equalTo(orRule._left) &&
		this._right.equalTo(orRule._right);
};

OrRule.prototype.toString = function() {
	return this._left.toString() + ' OR ' + this._right.toString();
};

function ParethesisRule (rule) {
	this._rule = rule;
}

ParethesisRule.prototype.match = function(tagList) {
	return this._rule.match(tagList);
};

ParethesisRule.prototype.equalTo = function(rule) {
	return rule instanceof ParethesisRule &&
		this._rule.equalTo(rule._rule);
};

ParethesisRule.prototype.toString = function() {
	return '(' + this._rule.toString() + ')';
};

/****************************************************\
        TagMatcher
\****************************************************/

function TagMatcher (query) {
	this._query = parseQuery(tokenizeQuery(query || ''));
}

TagMatcher.prototype.toString = function() {
	return this._query.toString();
};

function parseQuery (tokens) {

	// catch the easy case first, single tag
	if (tokens.length === 0) {
		return new EmptyRule();
	} else if (tokens.length === 1) {
		var toke = tokens[0];
		if (toke instanceof ParethesisRule) {
			return toke;
		} else {
			return new TagRule(tokens[0]);
		}
	} else {
		// first look for wrapped parenthesis
		// process all sets of parenthesis before continuing
		var openParenIndex = tokens.indexOf(OPEN_PAREN_TOKEN);
		while (openParenIndex !== -1) {
			// find the matching closer
			var closePos = openParenIndex,
				counter = 1;

			while (counter > 0 && closePos < tokens.length) {
				var token = tokens[++closePos];
				if (token === OPEN_PAREN_TOKEN) {
					counter++;
				} else if (token === CLOSE_PAREN_TOKEN) {
					counter--;
				}
			}

			if (counter > 0) {
				throw 'Unfound closing parenthesis in tokens ' + tokens;
			}

			var pre = tokens.slice(0, openParenIndex);
			var rule = new ParethesisRule(parseQuery(tokens.slice(openParenIndex + 1, closePos)));
			var post = tokens.slice(closePos + 1);

			tokens = [].concat(pre, rule, post);
			openParenIndex = tokens.indexOf(OPEN_PAREN_TOKEN);

		}

		// then look for OR
		var leftTokens, rightTokens;
		var orIndex = tokens.indexOf(OR_TOKEN);
		if (orIndex !== -1) {
			leftTokens = tokens.slice(0, orIndex);
			rightTokens = tokens.slice(orIndex + 1);
			return new OrRule(parseQuery(leftTokens), parseQuery(rightTokens));
		} else {
			// look for AND
			var andIndex = tokens.indexOf(AND_TOKEN);
			if (andIndex !== -1) {
				leftTokens = tokens.slice(0, andIndex);
				rightTokens = tokens.slice(andIndex + 1);
				return new AndRule(parseQuery(leftTokens), parseQuery(rightTokens));
			} else {
				// all done, nothing else to check, just return our one rule now
				return tokens[0];
			}
		}
	}
}

function tokenizeQuery (query) {
	var tokens = [];
	query = query.replace(/,/g, ' OR ').trim();

	var match,
		matchString = query;
	while (matchString !== '') {
		match = TOKEN_REGEXP.exec(matchString);

		if (! match) {
			tokens.push(matchString.trim());
			break;
		} else {
			// first break off the tags prior to the token
			if (match.index !== 0) {
				var tagToke = matchString.substring(0, match.index).trim();
				tokens.push(tagToke);
			}

			// now put on the matched token
			tokens.push(match[0].trim());

			// advance the startIndex
			// add a space on the front to add back the space that went missing from the match
			var offset = match.index + match[0].length;
			if (matchString.charAt(offset-1) === ' ') {
				offset--;
			}

			matchString = matchString.substring(offset);
		}

	}

	return tokens;
}

TagMatcher.prototype.match = function(tagList) {
	return this._query.match(tagList);
};

TagMatcher.prototype.equalTo = function(tagMatcher) {
	return this._query.equalTo(tagMatcher._query);
};

module.exports = TagMatcher;
<|endoftext|>


<commit_before>/**
* Game.js
*
* @description :: TODO: You might write a short summary of how this model works and what it represents here.
* @docs        :: http://sailsjs.org/#!documentation/models
*/

var S = require('string');

module.exports = {

  attributes: {

    game_id: {
      type: 'string',
      unique: true
    },

    date: {
      type: 'datetime'
    },

    home_team: {
      type: 'string'
    },

    home_score: {
      type: 'string'
    },

    visiting_team: {
      type: 'string'
    },

    visiting_score: {
      type: 'string'
    },

    winning_team: {
      type: 'string'
    },

    losing_team: {
      type: 'string'
    }

  },

  map: function (a, res, model) {
    "use strict";
    var self = this;

    var promise = new Promise(function (resolve, reject) {

      var obj = {
        game_id: model.filename,
        date: model.date_of_game,
        home_team: model.match_up.substr(model.match_up.indexOf(' at ')+4, model.match_up.length),
        home_score: model.score.substr(model.score.lastIndexOf('-')+1, model.score.length),
        visiting_team: model.match_up.substr(0, model.match_up.indexOf(' at ')),
        visiting_score: model.score.substr(model.match_up.indexOf(': ')-2, model.match_up.indexOf(': ')+2),
        winning_team: "",
        losing_team: ""
      }

      obj.home_score = self.determineHomeScore(obj, model);
      obj.visiting_score = self.determineVisitingScore(obj, model);
      obj.winning_team = self.determineWinner(obj);
      obj.losing_team = self.determineLoser(obj);

      res.model = obj;
      resolve(res);
    });
    return promise;
  },

  determineHomeScore: function (obj, model) {
    "use strict";

    // home score
    // model.match_up.substr(model.match_up.indexOf(' at ')+4, model.match_up.length)

    try {
      var winner = model.score.substr(0, model.score.indexOf('WIN')-1);

      // sails.log.info(winner);

      if (S(obj.home_team.toLowerCase()).contains(winner.toLowerCase())) {
        return model.score.substr(model.match_up.indexOf(': ')-2, model.match_up.indexOf(': ')+2);
      } else {
        return model.score.substr(model.match_up.indexOf(': '), model.match_up.indexOf(': ')+4);
        // return model.match_up.substr(model.match_up.indexOf(' at ')+4, model.match_up.length);
      }
    } catch (error) {
      sails.log.error(error);
    }

    // visiting score
    // model.score.substr(model.match_up.indexOf(': ')-2, model.match_up.indexOf(': ')+2),
  },

  determineVisitingScore: function (obj, model) {
    "use strict";

    try {
      var winner = model.score.substr(0, model.score.indexOf('WIN')-1);

      // sails.log.info(winner);

      if (S(obj.visiting_team.toLowerCase()).contains(winner.toLowerCase())) {
        return model.score.substr(model.match_up.indexOf(': ')-2, model.match_up.indexOf(': ')+2);
      } else {
        return model.score.substr(model.match_up.indexOf(': '), model.match_up.indexOf(': ')+4);
      }
    } catch (error) {
      sails.log.error(error);
    }
  },

  determineWinner: function (obj) {
    "use strict";

    if (obj.home_score > obj.visiting_score) {
      return obj.home_team;
    } else {
      return obj.visiting_team;
    }

  },

  determineLoser: function (obj) {
    "use strict";

    if (obj.home_score > obj.visiting_score) {
      return obj.visiting_team;
    } else {
      return obj.home_team;
    }

  },

  // path: function () {
  //   "use strict";
  //   return '/games';
  // },

  load: function (parser) {
    'use strict'

    // startup
    return parser.getScores(parser.getDirectoryContentNames("input/recaps"));
  },

  populate: function (callback, data) {
    "use strict";
    Game.findOrCreate({ game_id: data.model.game_id }, data.model)
      .then(function (data) {
        "use strict";
        // sails.log.debug("found: " + data.game_id );
        callback();
      })
      .catch(function (error) {
        sails.log.error(error.details);
      });

  }
};

<commit_msg>fixed bug with home and visiting score<commit_after>/**
* Game.js
*
* @description :: TODO: You might write a short summary of how this model works and what it represents here.
* @docs        :: http://sailsjs.org/#!documentation/models
*/

var S = require('string');

module.exports = {

  attributes: {

    game_id: {
      type: 'string',
      unique: true
    },

    date: {
      type: 'datetime'
    },

    home_team: {
      type: 'string'
    },

    home_score: {
      type: 'string'
    },

    visiting_team: {
      type: 'string'
    },

    visiting_score: {
      type: 'string'
    },

    winning_team: {
      type: 'string'
    },

    losing_team: {
      type: 'string'
    }

  },

  map: function (a, res, model) {
    "use strict";
    var self = this;

    var promise = new Promise(function (resolve, reject) {

      var obj = {
        game_id: model.filename,
        date: model.date_of_game,
        home_team: model.match_up.substr(model.match_up.indexOf(' at ')+4, model.match_up.length),
        home_score: model.score.substr(model.score.lastIndexOf('-')+1, model.score.length),
        visiting_team: model.match_up.substr(0, model.match_up.indexOf(' at ')),
        visiting_score: model.score.substr(model.match_up.indexOf(': ')-2, model.match_up.indexOf(': ')+2),
        winning_team: "",
        losing_team: ""
      }

      obj.home_score = self.determineHomeScore(obj, model);
      obj.visiting_score = self.determineVisitingScore(obj, model);
      obj.winning_team = self.determineWinner(obj);
      obj.losing_team = self.determineLoser(obj);

      res.model = obj;
      resolve(res);
    });
    return promise;
  },

  determineHomeScore: function (obj, model) {
    "use strict";

    // home score
    // model.match_up.substr(model.match_up.indexOf(' at ')+4, model.match_up.length)

    try {
      var winner = model.score.substr(0, model.score.indexOf('WIN')-1);

      // sails.log.info(winner);

      if (S(obj.home_team.toLowerCase()).contains(winner.toLowerCase())) {
        return model.score.substring(model.score.indexOf(': ')+2, model.score.lastIndexOf('-'));
      } else {
        return model.score.substring(model.score.lastIndexOf('-')+1, model.score.length);
      }
    } catch (error) {
      sails.log.error(error);
    }

    // visiting score
    // model.score.substr(model.match_up.indexOf(': ')-2, model.match_up.indexOf(': ')+2),
  },

  determineVisitingScore: function (obj, model) {
    "use strict";

    try {
      var winner = model.score.substr(0, model.score.indexOf('WIN')-1);

      // sails.log.info(winner);

      if (S(obj.visiting_team.toLowerCase()).contains(winner.toLowerCase())) {
        return model.score.substring(model.score.indexOf(': ')+2, model.score.lastIndexOf('-'));
      } else {
        return model.score.substring(model.score.lastIndexOf('-')+1, model.score.length);
      }
    } catch (error) {
      sails.log.error(error);
    }
  },

  determineWinner: function (obj) {
    "use strict";

    if (obj.home_score > obj.visiting_score) {
      return obj.home_team;
    } else {
      return obj.visiting_team;
    }

  },

  determineLoser: function (obj) {
    "use strict";

    if (obj.home_score > obj.visiting_score) {
      return obj.visiting_team;
    } else {
      return obj.home_team;
    }

  },

  // path: function () {
  //   "use strict";
  //   return '/games';
  // },

  load: function (parser) {
    'use strict'

    // startup
    return parser.getScores(parser.getDirectoryContentNames("input/recaps"));
  },

  populate: function (callback, data) {
    "use strict";
    Game.findOrCreate({ game_id: data.model.game_id }, data.model)
      .then(function (data) {
        "use strict";
        // sails.log.debug("found: " + data.game_id );
        callback();
      })
      .catch(function (error) {
        sails.log.error(error.details);
      });

  }
};

<|endoftext|>


<commit_before>
openerp.base.data = function(openerp) {

openerp.base.DataGroup =  openerp.base.Controller.extend( /** @lends openerp.base.DataGroup# */{
    /**
     * Management interface between views and the collection of selected OpenERP
     * records (represents the view's state?)
     *
     * @constructs
     * @extends openerp.base.Controller
     * @param {openerp.base.Session} session Current OpenERP session
     */
    init: function(session) {
        this._super(session, null);
    }
});

openerp.base.DataSet =  openerp.base.Controller.extend( /** @lends openerp.base.DataSet# */{
    /**
     * DateaManagement interface between views and the collection of selected
     * OpenERP records (represents the view's state?)
     *
     * @constructs
     * @extends openerp.base.Controller
     *
     * @param {openerp.base.Session} session current OpenERP session
     * @param {String} model the OpenERP model this dataset will manage
     */
    init: function(session, model) {
        this._super(session);
        this.model = model;
        this.context = {};
        this.index = 0;
        this.count = 0;
    },
    start: function() {
    },
    previous: function () {
        this.index -= 1;
        if (this.index < 0) {
            this.index = this.count - 1;
        }
        return this;
    },
    next: function () {
        this.index += 1;
        if (this.index >= this.count) {
            this.index = 0;
        }
        return this;
    },
    /**
     * Read records.
     */
    read_ids: function (ids, fields, callback) {
        var self = this;
        this.rpc('/base/dataset/get', {
            model: this.model,
            ids: ids,
            fields: fields
        }, callback);
    },
    /**
     * Read a slice of the records represented by this DataSet, based on its
     * domain and context.
     *
     * @param {Number} [offset=0] The index from which selected records should be returned
     * @param {Number} [limit=null] The maximum number of records to return
     */
    read_slice: function (fields, offset, limit, callback) {
    },
    /**
     * Read the indexed record.
     */
    read_index: function (fields, callback) {
        if (_.isEmpty(this.ids)) {
            callback([]);
        } else {
            fields = fields || false;
            this.read_ids([this.ids[this.index]], fields, function(records) {
                callback(records[0]);
            });
        }
    },
    default_get: function(fields, callback) {
        this.rpc('/base/dataset/default_get', {
            model: this.model,
            fields: fields,
            context: this.context
        }, callback);
    },
    create: function() {
    },
    write: function (id, data, callback) {
        this.rpc('/base/dataset/save', {
            model: this.model,
            id: id,
            data: data,
            context: this.context
        }, callback);
    },
    unlink: function() {
    },
    call: function (method, ids, args, callback) {
        ids = ids || [];
        args = args || [];
        this.rpc('/base/dataset/call', {
            model: this.model,
            method: method,
            ids: ids,
            args: args
        }, callback);
    },
});

openerp.base.DataSetStatic =  openerp.base.DataSet.extend({
    init: function(session, model) {
        this._super(session, model);
        // all local records
        this.ids = [];
        this.count = 0;
    },
    read_slice: function (fields, offset, limit, callback) {
        this.read_ids(this.ids.slice(offset, offset + limit));
    },
});

openerp.base.DataSetSearch =  openerp.base.DataSet.extend({
    init: function(session, model) {
        this._super(session, model);
        this.domain = [];
        this.sort = [];
        this.offset = 0;
        // subset records[offset:offset+limit]
        // is it necessary ?
        this.ids = [];
    },
    read_slice: function (fields, offset, limit, callback) {
        var self = this;
        offset = offset || 0;
        // cached search, not sure it's a good idea
        if(this.offset <= offset) {
            var start = offset - this.offset;
            if(this.ids.length - start >= limit) {
                // TODO: check if this could work do only read if possible
                // return read_ids(ids.slice(start,start+limit),fields,callback)
            }
        }
        this.rpc('/base/dataset/search_read', {
            model: this.model,
            fields: fields,
            domain: this.domain,
            context: this.context,
            sort: this.sort,
            offset: offset,
            limit: limit
        }, function (records) {
            self.offset = offset;
            self.count = records.length;    // TODO: get real count
            for (var i=0; i < records.length; i++ ) {
                self.ids.push(records[i].id);
            }
            callback(records);
        });
    },
});

};

// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
<commit_msg>[ADD] return deffered in dataset<commit_after>
openerp.base.data = function(openerp) {

openerp.base.DataGroup =  openerp.base.Controller.extend( /** @lends openerp.base.DataGroup# */{
    /**
     * Management interface between views and the collection of selected OpenERP
     * records (represents the view's state?)
     *
     * @constructs
     * @extends openerp.base.Controller
     * @param {openerp.base.Session} session Current OpenERP session
     */
    init: function(session) {
        this._super(session, null);
    }
});

openerp.base.DataSet =  openerp.base.Controller.extend( /** @lends openerp.base.DataSet# */{
    /**
     * DateaManagement interface between views and the collection of selected
     * OpenERP records (represents the view's state?)
     *
     * @constructs
     * @extends openerp.base.Controller
     *
     * @param {openerp.base.Session} session current OpenERP session
     * @param {String} model the OpenERP model this dataset will manage
     */
    init: function(session, model) {
        this._super(session);
        this.model = model;
        this.context = {};
        this.index = 0;
        this.count = 0;
    },
    start: function() {
    },
    previous: function () {
        this.index -= 1;
        if (this.index < 0) {
            this.index = this.count - 1;
        }
        return this;
    },
    next: function () {
        this.index += 1;
        if (this.index >= this.count) {
            this.index = 0;
        }
        return this;
    },
    /**
     * Read records.
     */
    read_ids: function (ids, fields, callback) {
        var self = this;
        this.rpc('/base/dataset/get', {
            model: this.model,
            ids: ids,
            fields: fields
        }, callback);
    },
    /**
     * Read a slice of the records represented by this DataSet, based on its
     * domain and context.
     *
     * @param {Number} [offset=0] The index from which selected records should be returned
     * @param {Number} [limit=null] The maximum number of records to return
     */
    read_slice: function (fields, offset, limit, callback) {
    },
    /**
     * Read the indexed record.
     */
    read_index: function (fields, callback) {
        if (_.isEmpty(this.ids)) {
            callback([]);
        } else {
            fields = fields || false;
            this.read_ids([this.ids[this.index]], fields, function(records) {
                callback(records[0]);
            });
        }
    },
    default_get: function(fields, callback) {
        return this.rpc('/base/dataset/default_get', {
            model: this.model,
            fields: fields,
            context: this.context
        }, callback);
    },
    create: function() {
    },
    write: function (id, data, callback) {
        return this.rpc('/base/dataset/save', {
            model: this.model,
            id: id,
            data: data,
            context: this.context
        }, callback);
    },
    unlink: function() {
    },
    call: function (method, ids, args, callback) {
        ids = ids || [];
        args = args || [];
        return this.rpc('/base/dataset/call', {
            model: this.model,
            method: method,
            ids: ids,
            args: args
        }, callback);
    },
});

openerp.base.DataSetStatic =  openerp.base.DataSet.extend({
    init: function(session, model) {
        this._super(session, model);
        // all local records
        this.ids = [];
        this.count = 0;
    },
    read_slice: function (fields, offset, limit, callback) {
        this.read_ids(this.ids.slice(offset, offset + limit));
    },
});

openerp.base.DataSetSearch =  openerp.base.DataSet.extend({
    init: function(session, model) {
        this._super(session, model);
        this.domain = [];
        this.sort = [];
        this.offset = 0;
        // subset records[offset:offset+limit]
        // is it necessary ?
        this.ids = [];
    },
    read_slice: function (fields, offset, limit, callback) {
        var self = this;
        offset = offset || 0;
        // cached search, not sure it's a good idea
        if(this.offset <= offset) {
            var start = offset - this.offset;
            if(this.ids.length - start >= limit) {
                // TODO: check if this could work do only read if possible
                // return read_ids(ids.slice(start,start+limit),fields,callback)
            }
        }
        this.rpc('/base/dataset/search_read', {
            model: this.model,
            fields: fields,
            domain: this.domain,
            context: this.context,
            sort: this.sort,
            offset: offset,
            limit: limit
        }, function (records) {
            self.offset = offset;
            self.count = records.length;    // TODO: get real count
            for (var i=0; i < records.length; i++ ) {
                self.ids.push(records[i].id);
            }
            callback(records);
        });
    },
});

};

// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
<|endoftext|>


<commit_before>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2012, Ajax.org B.V.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ajax.org B.V. nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***** END LICENSE BLOCK ***** */

// [WIP]

define(function(require, exports, module) {
"use strict";
var TokenIterator = require("../token_iterator").TokenIterator;

function is(token, type) {
    return token.type.lastIndexOf(type + ".xml") > -1;
}

// do not indent after singleton tags or <html>
exports.singletonTags = ["area", "base", "br", "col", "command", "embed", "hr", "html", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr"];

// insert a line break after block level tags
exports.blockTags = ["article", "aside", "blockquote", "body", "div", "dl", "fieldset", "footer", "form", "head", "header", "html", "nav", "ol", "p", "script", "section", "style", "table", "tbody", "tfoot", "thead", "ul"];

exports.beautify = function(session) {
    var iterator = new TokenIterator(session, 0, 0);
    var token = iterator.getCurrentToken();
    var tabString = session.getTabString();
    var singletonTags = exports.singletonTags;
    var blockTags = exports.blockTags;
    var nextToken;
    var breakBefore = false;
    var spaceBefore = false;
    var spaceAfter = false;
    var code = "";
    var value = "";
    var tagName = "";
    var depth = 0;
    var lastDepth = 0;
    var lastIndent = 0;
    var indent = 0;
    var unindent = false;
    var roundDepth = 0;
    var onCaseLine = false;
    var row;
    var curRow = 0;
    var rowsToAdd = 0;
    var rowTokens = [];
    var abort = false;
    var i;
    var indentNextLine = false;
    var inTag = false;
    var inCSS = false;
    var inBlock = false;
    var inCase = false;

    var trimNext = function() {
        if (nextToken && nextToken.value && nextToken.type !== 'string.regexp')
            nextToken.value = nextToken.value.trim();
    };

    var trimLine = function() {
        code = code.replace(/ +$/, "");
    };

    var trimCode = function() {
        code = code.trimRight();
        breakBefore = false;
    };

    while (token !== null) {
        curRow = iterator.getCurrentTokenRow();
        rowTokens = iterator.$rowTokens;
        nextToken = iterator.stepForward();

        if (typeof token !== "undefined") {
            value = token.value;
            unindent = false;

            // mode
            inCSS = (tagName === "style" || session.$modeId === "ace/mode/css");

            // in tag
            if (is(token, "tag-open")) {
                inTag = true;

                // are we in a block tag
                if (nextToken)
                    inBlock = (blockTags.indexOf(nextToken.value) !== -1);

                // html indentation
                if (value === "</") {
                    // line break before closing tag unless we just had one
                    if (inBlock && !breakBefore && rowsToAdd < 1)
                        rowsToAdd++;

                    if (inCSS)
                        rowsToAdd = 1;

                    unindent = true;
                    inBlock = false;
                }
            } else if (is(token, "tag-close")) {
                inTag = false;
            // comments
            } else if (is(token, "comment.start")) {
                inBlock = true;
            } else if (is(token, "comment.end")) {
                inBlock = false;
            }

            // line break before }
            if (!inTag && !rowsToAdd && token.type === "paren.rparen" && token.value.substr(0, 1) === "}") {
                rowsToAdd++;
            }

            // switch case
            onCaseLine = false;
            if (token.type === "keyword" && value.match(/^(case|default)$/)) {
                onCaseLine = true;
                inCase = true;
            } else if (token.type === "keyword" && value === "break")
                inCase = false;

            // add rows
            if (curRow !== row) {
                rowsToAdd = curRow;

                if (row)
                    rowsToAdd -= row;
            }

            if (rowsToAdd) {
                trimCode();
                for (; rowsToAdd > 0; rowsToAdd--)
                    code += "\n";

                breakBefore = true;

                // trim value if not in a comment or string
                if (!is(token, "comment") && !token.type.match(/^(comment|string)$/))
                   value = value.trimLeft();
            }

            if (value) {
                // whitespace
                if (token.type === "keyword" && value.match(/^(if|else|elseif|for|while|switch)$/)) {
                    trimNext();
                    spaceAfter = true;

                    // space before else, elseif
                    if (value.match(/^(else|elseif)$/)) {
                        if (code.match(/\}[\s]*$/)) {
                            trimCode();
                            spaceBefore = true;
                        }
                    }
                // trim value after opening paren
                } else if (token.type === "paren.lparen") {
                    trimNext();

                    // whitespace after {
                    if (value.substr(-1) === "{") {
                        spaceAfter = true;
                        indentNextLine = false;

                        if(!inTag)
                            rowsToAdd = 1;
                    }

                    // ensure curly brace is preceeded by whitespace
                    if (value.substr(0, 1) === "{") {
                        spaceBefore = true;

                        // collapse square and curly brackets together
                        if (code.substr(-1) !== '[' && code.trimRight().substr(-1) === '[') {
                            trimCode();
                            spaceBefore = false;
                        } else if (code.trimRight().substr(-1) === ')') {
                            trimCode();
                        } else {
                            trimLine();
                        }
                    }
                // remove space before closing paren
                } else if (token.type === "paren.rparen") {
                    unindent = true;

                    // ensure curly brace is preceeded by whitespace
                    if (value.substr(0, 1) === "}") {
                        if (code.trimRight().substr(-1) === '{') {
                            trimCode();
                        } else {
                            spaceBefore = true;

                            if (inCSS)
                                rowsToAdd+=2;
                        }
                    }

                    // collapse square and curly brackets together
                    if (value.substr(0, 1) === "]") {
                        if (code.substr(-1) !== '}' && code.trimRight().substr(-1) === '}') {
                            spaceBefore = false;
                            indent++;
                            trimCode();
                        }
                    }

                    // collapse round brackets together
                    if (value.substr(0, 1) === ")") {
                        if (code.substr(-1) !== '(' && code.trimRight().substr(-1) === '(') {
                            spaceBefore = false;
                            indent++;
                            trimCode();
                        }
                    }

                    trimLine();
                // add spaces around conditional operators
                } else if ((token.type === "keyword.operator" || token.type === "keyword") && value.match(/^(=|==|===|!=|!==|&&|\|\||and|or|xor|\+=|.=|>|>=|<|<=|=>)$/)) {
                    trimCode();
                    trimNext();
                    spaceBefore = true;
                    spaceAfter = true;
                // remove space before semicolon
                } else if (token.type === "punctuation.operator" && value === ';') {
                    trimCode();
                    trimNext();
                    spaceAfter = true;

                    if (inCSS)
                        rowsToAdd++;
                // space after colon or comma
                } else if (token.type === "punctuation.operator" && value.match(/^(:|,)$/)) {
                    trimCode();
                    trimNext();
                    spaceAfter = true;
                    breakBefore = false;
                // ensure space before php closing tag
                } else if (token.type === "support.php_tag" && value === "?>" && !breakBefore) {
                    trimCode();
                    spaceBefore = true;
                // remove excess space before HTML attribute
                } else if (is(token, "attribute-name") && code.substr(-1).match(/^\s$/)) {
                    spaceBefore = true;
                // remove space around attribute equals
                } else if (is(token, "attribute-equals")) {
                    trimLine();
                    trimNext();
                // remove space before HTML closing tag
                } else if (is(token, "tag-close")) {
                    trimLine();
                    if(value === "/>")
                        spaceBefore = true;
                }

                // add indent to code unless multiline string or comment
                if (breakBefore && !(token.type.match(/^(comment)$/) && !value.substr(0, 1).match(/^[/#]$/)) && !(token.type.match(/^(string)$/) && !value.substr(0, 1).match(/^['"]$/))) {

                    indent = lastIndent;

                    if(depth > lastDepth)
                        indent++;
                    else if(depth < lastDepth)
                        indent = depth;

                    lastDepth = depth;
                    lastIndent = indent;

                    if(unindent)
                        indent--;

                    if (inCase && !onCaseLine)
                        indent++;

                    if (indentNextLine && !roundDepth) {
                        indent++;
                        indentNextLine = false;
                    }

                    for (i = 0; i < indent; i++)
                        code += tabString;
                }

                // indent one line after if or else
                if (token.type === "paren.lparen") {
                    roundDepth += (value.match(/\(/g) || []).length;
                    depth += value.length;
                }

                if (token.type === "keyword" && value.match(/^(if|else|elseif|for|while)$/)) {
                    indentNextLine = true;
                    roundDepth = 0;
                } else if (!roundDepth && value.trim() && token.type !== "comment")
                    indentNextLine = false;

                if (token.type === "paren.rparen") {
                    roundDepth -= (value.match(/\)/g) || []).length;
                    depth -= value.length;
                }

                // add to code
                if (spaceBefore && !breakBefore) {
                    trimLine();
                    if (code.substr(-1) !== "\n")
                        code += " ";
                }

                code += value;

                if (spaceAfter)
                    code += " ";

                breakBefore = false;
                spaceBefore = false;
                spaceAfter = false;

                // line break after block tag or doctype
                if ((is(token, "tag-close") && (inBlock || blockTags.indexOf(tagName) !== -1)) || (is(token, "doctype") && value === ">")) {
                    // undo linebreak if tag is immediately closed
                    if (inBlock && nextToken && nextToken.value === "</")
                        rowsToAdd = -1;
                    else
                        rowsToAdd = 1;
                }

                // html indentation
                if (is(token, "tag-open") && value === "</") {
                    depth--;
                // indent after opening tag
                } else if (is(token, "tag-open") && value === "<" && singletonTags.indexOf(nextToken.value) === -1) {
                    depth++;
                // remove indent if unknown singleton
                } else if (is(token, "tag-name")) {
                    tagName = value;
                } else if (is(token, "tag-close") && value === "/>" && singletonTags.indexOf(tagName) === -1){
                    depth--;
                }

                row = curRow;
            }
        }

        token = nextToken;
    }

    code = code.trim();
    session.doc.setValue(code);
};

exports.commands = [{
    name: "beautify",
    exec: function(editor) {
        exports.beautify(editor.session);
    },
    bindKey: "Ctrl-Shift-B"
}];

});
<commit_msg>refactor indent handling<commit_after>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2012, Ajax.org B.V.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ajax.org B.V. nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***** END LICENSE BLOCK ***** */

// [WIP]

define(function(require, exports, module) {
"use strict";
var TokenIterator = require("../token_iterator").TokenIterator;

function is(token, type) {
    return token.type.lastIndexOf(type + ".xml") > -1;
}

// do not indent after singleton tags or <html>
exports.singletonTags = ["area", "base", "br", "col", "command", "embed", "hr", "html", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr"];

// insert a line break after block level tags
exports.blockTags = ["article", "aside", "blockquote", "body", "div", "dl", "fieldset", "footer", "form", "head", "header", "html", "nav", "ol", "p", "script", "section", "style", "table", "tbody", "tfoot", "thead", "ul"];

exports.beautify = function(session) {
    var iterator = new TokenIterator(session, 0, 0);
    var token = iterator.getCurrentToken();
    var tabString = session.getTabString();
    var singletonTags = exports.singletonTags;
    var blockTags = exports.blockTags;
    var nextToken;
    var breakBefore = false;
    var spaceBefore = false;
    var spaceAfter = false;
    var code = "";
    var value = "";
    var tagName = "";
    var depth = 0;
    var lastDepth = 0;
    var lastIndent = 0;
    var indent = 0;
    var unindent = false;
    var roundDepth = 0;
    var onCaseLine = false;
    var row;
    var curRow = 0;
    var rowsToAdd = 0;
    var rowTokens = [];
    var abort = false;
    var i;
    var indentNextLine = false;
    var inTag = false;
    var inCSS = false;
    var inBlock = false;
    var inCase = false;
    var levels = {0: 0};

    var trimNext = function() {
        if (nextToken && nextToken.value && nextToken.type !== 'string.regexp')
            nextToken.value = nextToken.value.trim();
    };

    var trimLine = function() {
        code = code.replace(/ +$/, "");
    };

    var trimCode = function() {
        code = code.trimRight();
        breakBefore = false;
    };

    while (token !== null) {
        curRow = iterator.getCurrentTokenRow();
        rowTokens = iterator.$rowTokens;
        nextToken = iterator.stepForward();

        if (typeof token !== "undefined") {
            value = token.value;
            unindent = false;

            // mode
            inCSS = (tagName === "style" || session.$modeId === "ace/mode/css");

            // in tag
            if (is(token, "tag-open")) {
                inTag = true;

                // are we in a block tag
                if (nextToken)
                    inBlock = (blockTags.indexOf(nextToken.value) !== -1);

                // html indentation
                if (value === "</") {
                    // line break before closing tag unless we just had one
                    if (inBlock && !breakBefore && rowsToAdd < 1)
                        rowsToAdd++;

                    if (inCSS)
                        rowsToAdd = 1;

                    unindent = true;
                    inBlock = false;
                }
            } else if (is(token, "tag-close")) {
                inTag = false;
            // comments
            } else if (is(token, "comment.start")) {
                inBlock = true;
            } else if (is(token, "comment.end")) {
                inBlock = false;
            }

            // line break before }
            if (!inTag && !rowsToAdd && token.type === "paren.rparen" && token.value.substr(0, 1) === "}") {
                rowsToAdd++;
            }

            // switch case
            onCaseLine = false;
            if (token.type === "keyword" && value.match(/^(case|default)$/)) {
                onCaseLine = true;
                inCase = true;
            } else if (token.type === "keyword" && value === "break")
                inCase = false;

            // add rows
            if (curRow !== row) {
                rowsToAdd = curRow;

                if (row)
                    rowsToAdd -= row;
            }

            if (rowsToAdd) {
                trimCode();
                for (; rowsToAdd > 0; rowsToAdd--)
                    code += "\n";

                breakBefore = true;

                // trim value if not in a comment or string
                if (!is(token, "comment") && !token.type.match(/^(comment|string)$/))
                   value = value.trimLeft();
            }

            if (value) {
                // whitespace
                if (token.type === "keyword" && value.match(/^(if|else|elseif|for|while|switch)$/)) {
                    trimNext();
                    spaceAfter = true;

                    // space before else, elseif
                    if (value.match(/^(else|elseif)$/)) {
                        if (code.match(/\}[\s]*$/)) {
                            trimCode();
                            spaceBefore = true;
                        }
                    }
                // trim value after opening paren
                } else if (token.type === "paren.lparen") {
                    trimNext();

                    // whitespace after {
                    if (value.substr(-1) === "{") {
                        spaceAfter = true;
                        indentNextLine = false;

                        if(!inTag)
                            rowsToAdd = 1;
                    }

                    // ensure curly brace is preceeded by whitespace
                    if (value.substr(0, 1) === "{") {
                        spaceBefore = true;

                        // collapse square and curly brackets together
                        if (code.substr(-1) !== '[' && code.trimRight().substr(-1) === '[') {
                            trimCode();
                            spaceBefore = false;
                        } else if (code.trimRight().substr(-1) === ')') {
                            trimCode();
                        } else {
                            trimLine();
                        }
                    }
                // remove space before closing paren
                } else if (token.type === "paren.rparen") {
                    unindent = true;

                    // ensure curly brace is preceeded by whitespace
                    if (value.substr(0, 1) === "}") {
                        if (code.trimRight().substr(-1) === '{') {
                            trimCode();
                        } else {
                            spaceBefore = true;

                            if (inCSS)
                                rowsToAdd+=2;
                        }
                    }

                    // collapse square and curly brackets together
                    if (value.substr(0, 1) === "]") {
                        if (code.substr(-1) !== '}' && code.trimRight().substr(-1) === '}') {
                            spaceBefore = false;
                            indent++;
                            trimCode();
                        }
                    }

                    // collapse round brackets together
                    if (value.substr(0, 1) === ")") {
                        if (code.substr(-1) !== '(' && code.trimRight().substr(-1) === '(') {
                            spaceBefore = false;
                            indent++;
                            trimCode();
                        }
                    }

                    trimLine();
                // add spaces around conditional operators
                } else if ((token.type === "keyword.operator" || token.type === "keyword") && value.match(/^(=|==|===|!=|!==|&&|\|\||and|or|xor|\+=|.=|>|>=|<|<=|=>)$/)) {
                    trimCode();
                    trimNext();
                    spaceBefore = true;
                    spaceAfter = true;
                // remove space before semicolon
                } else if (token.type === "punctuation.operator" && value === ';') {
                    trimCode();
                    trimNext();
                    spaceAfter = true;

                    if (inCSS)
                        rowsToAdd++;
                // space after colon or comma
                } else if (token.type === "punctuation.operator" && value.match(/^(:|,)$/)) {
                    trimCode();
                    trimNext();
                    spaceAfter = true;
                    breakBefore = false;
                // ensure space before php closing tag
                } else if (token.type === "support.php_tag" && value === "?>" && !breakBefore) {
                    trimCode();
                    spaceBefore = true;
                // remove excess space before HTML attribute
                } else if (is(token, "attribute-name") && code.substr(-1).match(/^\s$/)) {
                    spaceBefore = true;
                // remove space around attribute equals
                } else if (is(token, "attribute-equals")) {
                    trimLine();
                    trimNext();
                // remove space before HTML closing tag
                } else if (is(token, "tag-close")) {
                    trimLine();
                    if(value === "/>")
                        spaceBefore = true;
                }

                // add indent to code unless multiline string or comment
                if (breakBefore && !(token.type.match(/^(comment)$/) && !value.substr(0, 1).match(/^[/#]$/)) && !(token.type.match(/^(string)$/) && !value.substr(0, 1).match(/^['"]$/))) {

                    indent = lastIndent;

                    if(depth > lastDepth) {
                        indent++;

                        for (i=depth; i > lastDepth; i--)
                            levels[i] = indent;
                    } else if(depth < lastDepth)
                        indent = levels[depth];

                    lastDepth = depth;
                    lastIndent = indent;

                    if(unindent)
                        indent--;

                    if (inCase && !onCaseLine)
                        indent++;

                    if (indentNextLine && !roundDepth) {
                        indent++;
                        indentNextLine = false;
                    }

                    for (i = 0; i < indent; i++)
                        code += tabString;
                }

                // indent one line after if or else
                if (token.type === "paren.lparen") {
                    roundDepth += (value.match(/\(/g) || []).length;
                    depth += value.length;
                }

                if (token.type === "keyword" && value.match(/^(if|else|elseif|for|while)$/)) {
                    indentNextLine = true;
                    roundDepth = 0;
                } else if (!roundDepth && value.trim() && token.type !== "comment")
                    indentNextLine = false;

                if (token.type === "paren.rparen") {
                    roundDepth -= (value.match(/\)/g) || []).length;
                    depth -= value.length;
                }

                // add to code
                if (spaceBefore && !breakBefore) {
                    trimLine();
                    if (code.substr(-1) !== "\n")
                        code += " ";
                }

                code += value;

                if (spaceAfter)
                    code += " ";

                breakBefore = false;
                spaceBefore = false;
                spaceAfter = false;

                // line break after block tag or doctype
                if ((is(token, "tag-close") && (inBlock || blockTags.indexOf(tagName) !== -1)) || (is(token, "doctype") && value === ">")) {
                    // undo linebreak if tag is immediately closed
                    if (inBlock && nextToken && nextToken.value === "</")
                        rowsToAdd = -1;
                    else
                        rowsToAdd = 1;
                }

                // html indentation
                if (is(token, "tag-open") && value === "</") {
                    depth--;
                // indent after opening tag
                } else if (is(token, "tag-open") && value === "<" && singletonTags.indexOf(nextToken.value) === -1) {
                    depth++;
                // remove indent if unknown singleton
                } else if (is(token, "tag-name")) {
                    tagName = value;
                } else if (is(token, "tag-close") && value === "/>" && singletonTags.indexOf(tagName) === -1){
                    depth--;
                }

                row = curRow;
            }
        }

        token = nextToken;
    }

    code = code.trim();
    session.doc.setValue(code);
};

exports.commands = [{
    name: "beautify",
    exec: function(editor) {
        exports.beautify(editor.session);
    },
    bindKey: "Ctrl-Shift-B"
}];

});
<|endoftext|>


<commit_before>var jsdom = require('jsdom'),
    fs = require('fs'),
    assert = require('chai').assert,
    file = fs.readFileSync('index.html').toString();

describe('Your HTML Page', function() {
  var window;
  before(function(next) {
    jsdom.env(
      file,
      ["http://code.jquery.com/jquery.js"],
      function (err, w) {
        if(err) { next(err); }
        window = w;
        next();
      }
    );
  });

  it('should have a title that\'s a child of the head element @title', function() {
    assert.equal(window.$('head > title').length, 1, 'Make sure to create a `title` element.');
  });

  it('should have a title that contains your name @title', function() {
    assert.notEqual(window.$('head > title').text(), '', 'Make sure to set the content of the `title` element to your name.');
  });

  it('should have an h1 element that\'s a child of the body element @h1', function() {
    assert.isAtLeast(window.$('body > h1').length, 1, "Make sure to create an `h1` element that's a child of the `body` element.");
  });

  it('should have content in the h1 element @h1', function() {
    assert.equal(window.$('body > h1').text(), 'Hello, Pluralsight!', "Make sure to set the content of your `h1` element to 'Hello, Pluralsight!'.");
  });

  it('should have a ul that\'s a child of the body element @ul', function() {
    assert.isAtLeast(window.$('body > ul').length, 1, "Make sure to create a `ul` element that's a child of the `body` element.");
  });

  it('should have at least 2 li elements that are children of the ul element @ul', function() {
    assert.isAtLeast(window.$('body > ul > li').length, 2, "Make sure to create at least 2 `li` elements that are children of the `ul` element.");
  });

  it('should have content for each of the `li` elements. @li', function() {
    assert.isAtLeast(window.$('body > ul > li').length, 2, "Make sure you have at least 2 `li` elements with things you want to learn.");

    var message = "Make sure that each `li` element contains some text describing one thing you want to learn."
    assert.notEqual(window.$('body > ul > li:first').text(), '', message);
    assert.notEqual(window.$('body > ul > li:last').text(), '', message);
  });
});
<commit_msg>Allow h1 task to use spacing around required text<commit_after>var jsdom = require('jsdom'),
    fs = require('fs'),
    assert = require('chai').assert,
    file = fs.readFileSync('index.html').toString();

describe('Your HTML Page', function() {
  var window;
  before(function(next) {
    jsdom.env(
      file,
      ["http://code.jquery.com/jquery.js"],
      function (err, w) {
        if(err) { next(err); }
        window = w;
        next();
      }
    );
  });

  it('should have a title that\'s a child of the head element @title', function() {
    assert.equal(window.$('head > title').length, 1, 'Make sure to create a `title` element.');
  });

  it('should have a title that contains your name @title', function() {
    assert.notEqual(window.$('head > title').text(), '', 'Make sure to set the content of the `title` element to your name.');
  });

  it('should have an h1 element that\'s a child of the body element @h1', function() {
    assert.isAtLeast(window.$('body > h1').length, 1, "Make sure to create an `h1` element that's a child of the `body` element.");
  });

  it('should have content in the h1 element @h1', function() {
    assert.equal(window.$('body > h1').text().trim(), 'Hello, Pluralsight!', "Make sure to set the content of your `h1` element to 'Hello, Pluralsight!'.");
  });

  it('should have a ul that\'s a child of the body element @ul', function() {
    assert.isAtLeast(window.$('body > ul').length, 1, "Make sure to create a `ul` element that's a child of the `body` element.");
  });

  it('should have at least 2 li elements that are children of the ul element @ul', function() {
    assert.isAtLeast(window.$('body > ul > li').length, 2, "Make sure to create at least 2 `li` elements that are children of the `ul` element.");
  });

  it('should have content for each of the `li` elements. @li', function() {
    assert.isAtLeast(window.$('body > ul > li').length, 2, "Make sure you have at least 2 `li` elements with things you want to learn.");

    var message = "Make sure that each `li` element contains some text describing one thing you want to learn."
    assert.notEqual(window.$('body > ul > li:first').text(), '', message);
    assert.notEqual(window.$('body > ul > li:last').text(), '', message);
  });
});
<|endoftext|>


<commit_before>/**
 * @author Serhii Maksymchuk from Ubrainians for imCode
 * 13.08.18
 */
define(
    'imcms-text-editor-utils',
    [
        'tinymce', 'imcms-texts-rest-api', 'imcms-events', 'jquery', 'imcms-modal-window-builder',
        'imcms-text-editor-types', 'imcms-html-filtering-policies', 'imcms-i18n-texts'
    ],
    function (tinyMCE, textsRestApi, events, $, modal, editorTypes, filteringPolicies, texts) {

        texts = texts.editors.text;

        const ACTIVE_EDIT_AREA_CLASS = 'imcms-editor-area--active';
        const ACTIVE_EDIT_AREA_CLASS_$ = '.' + ACTIVE_EDIT_AREA_CLASS;

        let activeEditor;

        let blurEnabled = true;

        events.on('disable text editor blur', () => {
            blurEnabled = false;
        });
        events.on('enable text editor blur', () => {
            blurEnabled = true;
        });

        function getActiveTextEditor() {
            return activeEditor || tinyMCE.activeEditor;
        }

        function setActiveTextEditor(activeTextEditor) {
            if (activeEditor && (activeTextEditor !== activeEditor) && activeEditor.triggerBlur) {
                activeEditor.triggerBlur();
            }

            activeEditor = activeTextEditor;
        }

        function saveContent(editor, onSaved, withFilter) {
            const textDTO = $(editor.$()).data();
            textDTO.text = editor.getContent();

            if (!withFilter) {
                textDTO.htmlFilteringPolicy = filteringPolicies.allowAll;
            }

            switch (textDTO.type) {
                case editorTypes.html:
                case editorTypes.htmlFromEditor: {
                    textDTO.text = textDTO.text.replace(/</g, '<').replace(/>/g, '>');
                    if (textDTO.type === editorTypes.htmlFromEditor) textDTO.type = editorTypes.html;
                    break;
                }
                case editorTypes.text:
                case editorTypes.textFromEditor: {
                    textDTO.text = textDTO.text.replace(/</g, '<').replace(/>/g, '>');
                    if (textDTO.type === editorTypes.textFromEditor) textDTO.type = editorTypes.text;
                }
            }

            textsRestApi.create(textDTO)
                .done(receivedTextDTO => {
                    events.trigger('imcms-version-modified');
                    editor.startContent = editor.getContent();
                    editor.setDirty(false);

                    onSaved && onSaved.call && onSaved.call(null, receivedTextDTO);
                })
                .fail(() => modal.buildErrorWindow(texts.error.createFailed));
        }

        function setEditorFocus(activeTextEditor) {
            $(activeTextEditor.$()).focus(function () {
                setActiveTextEditor(activeTextEditor);

                $(ACTIVE_EDIT_AREA_CLASS_$).removeClass(ACTIVE_EDIT_AREA_CLASS)
                    .find('.mce-edit-focus')
                    .removeClass('mce-edit-focus');

                $(this).closest('.imcms-editor-area--text').addClass(ACTIVE_EDIT_AREA_CLASS);
            });
        }

        function onEditorBlur(editor) {
            if (!blurEnabled || !editor.isDirty()) {
                return;
            }

            modal.buildModalWindow(texts.confirmSave, confirmed => {
                if (!confirmed) {
                    editor.setContent(editor.startContent);
                } else {
                    saveContent(editor);
                }
            });
        }

        function showEditButton($editor) {
            $editor.parents('.imcms-editor-area--text')
                .find('.imcms-control--edit.imcms-control--text')
                .css('display', 'block');
        }

        function filterContent(content, filteringPolicy, onFiltered) {
            const textDTO = {
                text: content,
                htmlFilteringPolicy: filteringPolicy,
            };

            textsRestApi.filter(textDTO)
                .done(receivedTextDTO => {
                    onFiltered && onFiltered(receivedTextDTO);
                })
                .fail(() => modal.buildErrorWindow(texts.error.filterFailed));
        }

        return {
            ACTIVE_EDIT_AREA_CLASS: ACTIVE_EDIT_AREA_CLASS,
            ACTIVE_EDIT_AREA_CLASS_$: ACTIVE_EDIT_AREA_CLASS_$,
            getActiveTextEditor: getActiveTextEditor,
            setActiveTextEditor: setActiveTextEditor,
            saveContent: saveContent,
            setEditorFocus: setEditorFocus,
            onEditorBlur: onEditorBlur,
            showEditButton: showEditButton,
            filterContent,
        };
    }
);
<commit_msg>Issue IMCMS-483: Improve the text-editor - Add errors handling to filter request;<commit_after>/**
 * @author Serhii Maksymchuk from Ubrainians for imCode
 * 13.08.18
 */
define(
    'imcms-text-editor-utils',
    [
        'tinymce', 'imcms-texts-rest-api', 'imcms-events', 'jquery', 'imcms-modal-window-builder',
        'imcms-text-editor-types', 'imcms-html-filtering-policies', 'imcms-i18n-texts'
    ],
    function (tinyMCE, textsRestApi, events, $, modal, editorTypes, filteringPolicies, texts) {

        texts = texts.editors.text;

        const ACTIVE_EDIT_AREA_CLASS = 'imcms-editor-area--active';
        const ACTIVE_EDIT_AREA_CLASS_$ = '.' + ACTIVE_EDIT_AREA_CLASS;

        let activeEditor;

        let blurEnabled = true;

        events.on('disable text editor blur', () => {
            blurEnabled = false;
        });
        events.on('enable text editor blur', () => {
            blurEnabled = true;
        });

        function getActiveTextEditor() {
            return activeEditor || tinyMCE.activeEditor;
        }

        function setActiveTextEditor(activeTextEditor) {
            if (activeEditor && (activeTextEditor !== activeEditor) && activeEditor.triggerBlur) {
                activeEditor.triggerBlur();
            }

            activeEditor = activeTextEditor;
        }

        function saveContent(editor, onSaved, withFilter) {
            const textDTO = $(editor.$()).data();
            textDTO.text = editor.getContent();

            if (!withFilter) {
                textDTO.htmlFilteringPolicy = filteringPolicies.allowAll;
            }

            switch (textDTO.type) {
                case editorTypes.html:
                case editorTypes.htmlFromEditor: {
                    textDTO.text = textDTO.text.replace(/</g, '<').replace(/>/g, '>');
                    if (textDTO.type === editorTypes.htmlFromEditor) textDTO.type = editorTypes.html;
                    break;
                }
                case editorTypes.text:
                case editorTypes.textFromEditor: {
                    textDTO.text = textDTO.text.replace(/</g, '<').replace(/>/g, '>');
                    if (textDTO.type === editorTypes.textFromEditor) textDTO.type = editorTypes.text;
                }
            }

            textsRestApi.create(textDTO)
                .done(receivedTextDTO => {
                    events.trigger('imcms-version-modified');
                    editor.startContent = editor.getContent();
                    editor.setDirty(false);

                    onSaved && onSaved.call && onSaved.call(null, receivedTextDTO);
                })
                .fail(() => modal.buildErrorWindow(texts.error.createFailed));
        }

        function setEditorFocus(activeTextEditor) {
            $(activeTextEditor.$()).focus(function () {
                setActiveTextEditor(activeTextEditor);

                $(ACTIVE_EDIT_AREA_CLASS_$).removeClass(ACTIVE_EDIT_AREA_CLASS)
                    .find('.mce-edit-focus')
                    .removeClass('mce-edit-focus');

                $(this).closest('.imcms-editor-area--text').addClass(ACTIVE_EDIT_AREA_CLASS);
            });
        }

        function onEditorBlur(editor) {
            if (!blurEnabled || !editor.isDirty()) {
                return;
            }

            modal.buildModalWindow(texts.confirmSave, confirmed => {
                if (!confirmed) {
                    editor.setContent(editor.startContent);
                } else {
                    saveContent(editor);
                }
            });
        }

        function showEditButton($editor) {
            $editor.parents('.imcms-editor-area--text')
                .find('.imcms-control--edit.imcms-control--text')
                .css('display', 'block');
        }

        function filterContent(content, filteringPolicy, onSuccess, onFail) {
            const textDTO = {
                text: content,
                htmlFilteringPolicy: filteringPolicy,
            };

            textsRestApi.filter(textDTO)
                .done(receivedTextDTO => {
                    onSuccess && onSuccess(receivedTextDTO);
                })
                .fail(() => {
                    onFail && onFail();
                    modal.buildErrorWindow(texts.error.filterFailed)
                });
        }

        return {
            ACTIVE_EDIT_AREA_CLASS: ACTIVE_EDIT_AREA_CLASS,
            ACTIVE_EDIT_AREA_CLASS_$: ACTIVE_EDIT_AREA_CLASS_$,
            getActiveTextEditor: getActiveTextEditor,
            setActiveTextEditor: setActiveTextEditor,
            saveContent: saveContent,
            setEditorFocus: setEditorFocus,
            onEditorBlur: onEditorBlur,
            showEditButton: showEditButton,
            filterContent,
        };
    }
);
<|endoftext|>


<commit_before>angular.module('ODataResources').
factory('$odataExpandPredicate', ['$odataPredicate', '$odataBinaryOperation', '$odataOrderByStatement', function (ODataPredicate, ODataBinaryOperation, ODataOrderByStatement) {

    var ODataExpandPredicate = function (tableName, context) {
        if (tableName === undefined) {
            throw "ExpandPredicate should be passed a table name but got undefined.";
        }

        if (context === undefined) {
            throw "ExpandPredicate should be passed a context but got undefined.";
        }

        this.name = tableName;
        this.expandables = []; // To maintain recursion compatibility with base OdataResourceProvider
        this.options = {
            select: [],
            filter: [],
            orderby: [],
            expand: this.expandables,
        };
        this.context = context;
    };

    ODataExpandPredicate.prototype.filter = function(operand1, operand2, operand3) {
        if (operand1 === undefined) throw "The first parameter is undefined. Did you forget to invoke the method as a constructor by adding the 'new' keyword?";

        var predicate;

        if (angular.isFunction(operand1.execute) && operand2 === undefined) {
            predicate = operand1;
        } else {
            predicate = new ODataBinaryOperation(operand1, operand2, operand3);
        }

        this.options.filter.push(predicate);

        return this;
    };

    ODataExpandPredicate.prototype.select = function (propertyName) {
        if (propertyName === undefined) {
            throw "ExpandPredicate.select should be passed a property name but got undefined.";
        }

        if (!angular.isArray(propertyName))
            propertyName = propertyName.split(',');

        function checkArray(i, value) {
            return value === propertyName[i];
        }

        for (var i = 0; i < propertyName.length; i++) {
            if (!this.options.select.some(checkArray.bind(this, i)))
                this.options.select.push(propertyName[i]);
        }
        return this;
    };

    ODataExpandPredicate.prototype.orderBy = function (arg1, arg2) {
        this.options.orderby.push((new ODataOrderByStatement(arg1, arg2)).execute());
        return this;
    };

    ODataExpandPredicate.prototype.expand = function (tableName) {
        if (tableName === undefined) {
            throw "ExpandPredicate.expand should be passed a table name but got undefined.";
        }
        return new ODataExpandPredicate(tableName, this).finish();
    };

    ODataExpandPredicate.prototype.expandPredicate = function (tableName) {
        if (tableName === undefined) {
            throw "ExpandPredicate.expandPredicate should be passed a table name but got undefined.";
        }
        return new ODataExpandPredicate(tableName, this);
    };

    ODataExpandPredicate.prototype.build = function () {
        var query = this.name;
        var sub = [];
        for (var option in this.options) {
            if (this.options[option].length) {
                if (option === 'filter') {
                    sub.push("$filter=" + ODataPredicate.and(this.options.filter).execute(this.isv4, true));
                } else {
                    sub.push("$" + option + "=" + this.options[option].join(','));
                }
            }
        }
        if (sub.length) {
            query += "(" + sub.join(';') + ")";
        }
        return query;
    };

    ODataExpandPredicate.prototype.finish = function () {
        var query = this.build();
        this.context.expandables.push(query);
        return this.context;
    };

    return ODataExpandPredicate;
}]);<commit_msg>Correction for OData v4<commit_after>angular.module('ODataResources').
factory('$odataExpandPredicate', ['$odataPredicate', '$odataBinaryOperation', '$odataOrderByStatement', function (ODataPredicate, ODataBinaryOperation, ODataOrderByStatement) {

    var ODataExpandPredicate = function (tableName, context) {
        if (tableName === undefined) {
            throw "ExpandPredicate should be passed a table name but got undefined.";
        }

        if (context === undefined) {
            throw "ExpandPredicate should be passed a context but got undefined.";
        }

        this.name = tableName;
        this.expandables = []; // To maintain recursion compatibility with base OdataResourceProvider
        this.options = {
            select: [],
            filter: [],
            orderby: [],
            expand: this.expandables,
        };
        this.context = context;
    };

    ODataExpandPredicate.prototype.filter = function(operand1, operand2, operand3) {
        if (operand1 === undefined) throw "The first parameter is undefined. Did you forget to invoke the method as a constructor by adding the 'new' keyword?";

        var predicate;

        if (angular.isFunction(operand1.execute) && operand2 === undefined) {
            predicate = operand1;
        } else {
            predicate = new ODataBinaryOperation(operand1, operand2, operand3);
        }

        this.options.filter.push(predicate);

        return this;
    };

    ODataExpandPredicate.prototype.select = function (propertyName) {
        if (propertyName === undefined) {
            throw "ExpandPredicate.select should be passed a property name but got undefined.";
        }

        if (!angular.isArray(propertyName))
            propertyName = propertyName.split(',');

        function checkArray(i, value) {
            return value === propertyName[i];
        }

        for (var i = 0; i < propertyName.length; i++) {
            if (!this.options.select.some(checkArray.bind(this, i)))
                this.options.select.push(propertyName[i]);
        }
        return this;
    };

    ODataExpandPredicate.prototype.orderBy = function (arg1, arg2) {
        this.options.orderby.push((new ODataOrderByStatement(arg1, arg2)).execute());
        return this;
    };

    ODataExpandPredicate.prototype.expand = function (tableName) {
        if (tableName === undefined) {
            throw "ExpandPredicate.expand should be passed a table name but got undefined.";
        }
        return new ODataExpandPredicate(tableName, this).finish();
    };

    ODataExpandPredicate.prototype.expandPredicate = function (tableName) {
        if (tableName === undefined) {
            throw "ExpandPredicate.expandPredicate should be passed a table name but got undefined.";
        }
        return new ODataExpandPredicate(tableName, this);
    };

    ODataExpandPredicate.prototype.build = function () {
        var query = this.name;
        var sub = [];
        for (var option in this.options) {
            if (this.options[option].length) {
                if (option === 'filter') {
                    sub.push("$filter=" + ODataPredicate.and(this.options.filter).execute(this.context.isv4, true));
                } else {
                    sub.push("$" + option + "=" + this.options[option].join(','));
                }
            }
        }
        if (sub.length) {
            query += "(" + sub.join(';') + ")";
        }
        return query;
    };

    ODataExpandPredicate.prototype.finish = function () {
        var query = this.build();
        this.context.expandables.push(query);
        return this.context;
    };

    return ODataExpandPredicate;
}]);
<|endoftext|>


<commit_before>const SparqlClient = require('sparql-client')
const $ = require('jquery')
const magnificPopup = require('magnific-popup')

// <-------------- Variables ---------------->
var endpoint = 'http://dbpedia.org/sparql'
var client = new SparqlClient(endpoint)
var sights = []
var markers = []
var infoWindows = []
var centerLat, centerLng
var buildingsOverall = {}

// <------------- onload ----------------------->
$(document).ready(function(){

  // sets the lat and lng of the current user

  $('#sightlist').on('click', 'li', function() {
    showDetails(this.dataset.id)
  })

  $("#sightlist, #showhidelist").hide()

  $("#showhidelist").click(function() {
    $('#sightlist').slideToggle( "slow", function() {})
  })
})

window.map.addListener("idle",function(){
  var bounds = window.map.getBounds();
  var top = bounds.H.j
  var left = bounds.j.j
  var bottom = bounds.H.H
  var right = bounds.j.H

//Get radius from coordinate data of Map Borders
  var height = Math.abs(top-bottom)
  var width = Math.abs(right-left)

// dont make request if zoomfactor is too big
  if (width<3&&height<3)
  getSightsInProximity(window.map.getCenter().lng(), window.map.getCenter().lat(), height/2, width/2)
})

// eventhandler for input field
  $( 'form' ).submit(function( event ) {
    var city = $('#inputfield').val()
    city = city.charAt(0).toUpperCase() + city.slice(1)
    $('#cityname').html(city)
    $('#inputfield').val('')
    $('#cityerror').html('')
    $('#sightlabel').html('')
    $('#sightabstract').html('')
    $('#sightthumb').attr("src", '')
    getSightsByCity(city)
    event.preventDefault()
  })

// view results
  function showResults(object) {
    $('#sightlist').html("")

     $("#showhidelist").show()

    if(sights.length == 0) {
      $('#cityerror').html("We are terribly sorry, we were not able to find any sights matching your city. ")
    }
    else {
      for (var i = 0; i < sights.length; i++) {
        var val = sights[i].Label.value
        $('#sightlist').append('
' + val + '
')
      }
    }
    // add popup functionality after li are appended
    $('.detail-popup').magnificPopup({
      type:'inline',
      midClick: true // Allow opening popup on middle mouse click. Always set it to true if you don't provide alternative source in href.
    })
  }

// show details per sight
  function showDetails(id) {
    $('#sightlabel').html(sights[id].Label.value)
    $('#sightabstract').html(sights[id].Abstract.value)
    $('#sightthumb').attr("src", sights[id].Thumbnail.value)
  }

  // <------------ User Location --------------->
  function getLocation() {
    if (navigator.geolocation) {
        return navigator.geolocation.getCurrentPosition(setCoords);
    } else {
      console.log("Geolocation is not supported by this browser.")
    }
  }

  function setCoords(position) {
    centerLat = position.coords.latitude
    centerLng = position.coords.longitude

    // centers the map at the current position of the user
    map.setCenter({lat: centerLat, lng: centerLng})
    map.addListener('click', function() {
      closeInfowindows()
    })
  }

  function addMarkers() {
    clearMarkers()
    for (var i = 0; i < sights.length; i++) {
      addDelayedMarkers(sights[i], i * 50)
    }
  }

  function clearMarkers() {
    for (var i = 0; i < markers.length; i++) {
      markers[i].setMap(null)
    }
  }

  function closeInfowindows() {
    for (var i = 0; i < infoWindows.length; i++) {
      infoWindows[i].close()
    }
  }

  function addDelayedMarkers(sight, delay) {
    var string = ''
    if(sight.Thumbnail.value != '') string += ''
    string += '
' + sight.Label.value + '
'

    window.setTimeout(function() {
      var marker = new google.maps.Marker({
        position: {lat: parseFloat(sight.Lat.value), lng: parseFloat(sight.Long.value)},
        map: map,
        title: sight.Label.value,
        animation: google.maps.Animation.DROP
      })
      marker.info = new google.maps.InfoWindow({
        content: string
      })
      infoWindows.push(marker.info)
      google.maps.event.addListener(marker, 'click', function() {
        closeInfowindows()
        marker.info.open(map, marker)
      })
      markers.push(marker)
    }, delay)
  }

  // runs a query against the DB with given params
  function queryDB(query) {
    client.query(query, function (error, results) {
      if (error) {
        console.log(error)
      } else {
        console.log(results.results.bindings)
        sights = results.results.bindings
        showResults()
        $('html, body').stop().animate({
          scrollTop: $(document).height()
        }, 1500)
        addMarkers()
        var mean = getLocationMean()
        console.log("lat: " + mean.lat + " long: " + mean.long);
        map.setCenter({lat: mean.lat, lng: mean.long})
      }
    })
  }

  function addProximityMarkers(buildings, delay){
    //clearMarkers()
    if (buildingsOverall.length>2000)
    {
      clearMarkers()
      buildingsOverall = {}
    }

    for (var i = 0; i < buildings.length; i++) {

      if (!(buildingsOverall[buildings[i].name.value]))
      {
        buildingsOverall[buildings[i].name.value] = buildings[i];
        addDelayedProximityMarkers(buildings[i], i * 50)
      }
    }
  }

  function addDelayedProximityMarkers(building, delay) {

    var string = ''
    if(building.thumbnail.value != '') string += ''
    string += '
' + building.name.value + '
'

    window.setTimeout(function() {
      var marker = new google.maps.Marker({
        position: {lat: parseFloat(building.lat.value), lng: parseFloat(building.long.value)},
        map: map,
        title: building.name.value,
        animation: google.maps.Animation.DROP
      })
      marker.info = new google.maps.InfoWindow({
        content: string
      })
      infoWindows.push(marker.info)
      google.maps.event.addListener(marker, 'click', function() {
        closeInfowindows()
        marker.info.open(map, marker)
      })
      markers.push(marker)
    }, delay)
  }

  function queryInProximity(query) {
    client.query(query, function (error, results) {
      if (error) {
        console.log(error)
      } else {

        var buildings = results.results.bindings
        console.log(buildings)
        addProximityMarkers(buildings)
        }
    })
  }

  function getLocationMean() {
    var mean = {
      lat: 0,
      long: 0
    }

    for (var i = 0; i < sights.length; i++) {
      mean.lat += parseFloat(sights[i].Lat.value)
      mean.long += parseFloat(sights[i].Long.value)
    }

    mean.lat = mean.lat / sights.length
    mean.long = mean.long / sights.length
    return mean
  }

  function stringify(city) {
    var str = city.split(' ')

    for (var i = 0; i < str.length; i++) {
      str[i] = str[i].charAt(0).toUpperCase() + str[i].slice(1)
    }

    return str.join('_')
  }

  function getSightsInProximity(long, lat, height, width) {
     var query = `PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT * WHERE
{
?s a dbo:ArchitecturalStructure .
FILTER NOT EXISTS { ?s a dbo:Station } .
FILTER NOT EXISTS { ?s a dbo:RailwayLine } .
?s rdfs:label ?name .
FILTER langMatches(lang(?name), 'en').
?s dbo:thumbnail ?thumbnail .
?s geo:lat ?lat .
?s geo:long ?long . FILTER ( ?long > ${long} - ${width} && ?long < ${long} +  ${width} && ?lat > ${lat} -  ${height} && ?lat < ${lat} +  ${height}) }
LIMIT 10000`;
    queryInProximity(query)
   //   console.log(query)
  }

  function getSightsByCity(city) {
    city = stringify(city)

    var query = "PREFIX dcterms:  <http://purl.org/dc/terms/>\
                  PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\
                  SELECT DISTINCT (str(?label) as ?Label) (str(?lat) as ?Lat) (str(?long) as ?Long) (str(?thumbnail) as ?Thumbnail) (?abstract as ?Abstract)\
                  WHERE { \
                    ?sight dct:subject <http://dbpedia.org/resource/Category:Visitor_attractions_in_" + city + "> .\
                  FILTER langMatches(lang(?label), 'en').\
                  FILTER langMatches(lang(?abstract), 'en').\
                    ?sight rdfs:label ?label .\
                    ?sight geo:lat ?lat .\
                    ?sight geo:long ?long .\
                    ?sight dbo:thumbnail ?thumbnail .\
                    ?sight dbo:abstract ?abstract \
                  }\
                  ORDER BY ASC(?Label)"
    queryDB(query)

  }
<commit_msg>edited query to avoid multiple datasets<commit_after>const SparqlClient = require('sparql-client')
const $ = require('jquery')
const magnificPopup = require('magnific-popup')

// <-------------- Variables ---------------->
var endpoint = 'http://dbpedia.org/sparql'
var client = new SparqlClient(endpoint)
var sights = []
var markers = []
var infoWindows = []
var centerLat, centerLng
var buildingsOverall = {}

// <------------- onload ----------------------->
$(document).ready(function(){

  // sets the lat and lng of the current user

  $('#sightlist').on('click', 'li', function() {
    showDetails(this.dataset.id)
  })

  $("#sightlist, #showhidelist").hide()

  $("#showhidelist").click(function() {
    $('#sightlist').slideToggle( "slow", function() {})
  })
})

window.map.addListener("idle",function(){
  var bounds = window.map.getBounds();
  var top = bounds.H.j
  var left = bounds.j.j
  var bottom = bounds.H.H
  var right = bounds.j.H

//Get radius from coordinate data of Map Borders
  var height = Math.abs(top-bottom)
  var width = Math.abs(right-left)

// dont make request if zoomfactor is too big
  if (width<3&&height<3)
  getSightsInProximity(window.map.getCenter().lng(), window.map.getCenter().lat(), height/2, width/2)
})

// eventhandler for input field
  $( 'form' ).submit(function( event ) {
    var city = $('#inputfield').val()
    city = city.charAt(0).toUpperCase() + city.slice(1)
    $('#cityname').html(city)
    $('#inputfield').val('')
    $('#cityerror').html('')
    $('#sightlabel').html('')
    $('#sightabstract').html('')
    $('#sightthumb').attr("src", '')
    getSightsByCity(city)
    event.preventDefault()
  })

// view results
  function showResults(object) {
    $('#sightlist').html("")

     $("#showhidelist").show()

    if(sights.length == 0) {
      $('#cityerror').html("We are terribly sorry, we were not able to find any sights matching your city. ")
    }
    else {
      for (var i = 0; i < sights.length; i++) {
        var val = sights[i].Label.value
        $('#sightlist').append('
' + val + '
')
      }
    }
    // add popup functionality after li are appended
    $('.detail-popup').magnificPopup({
      type:'inline',
      midClick: true // Allow opening popup on middle mouse click. Always set it to true if you don't provide alternative source in href.
    })
  }

// show details per sight
  function showDetails(id) {
    $('#sightlabel').html(sights[id].Label.value)
    $('#sightabstract').html(sights[id].Abstract.value)
    $('#sightthumb').attr("src", sights[id].Thumbnail.value)
  }

  // <------------ User Location --------------->
  function getLocation() {
    if (navigator.geolocation) {
        return navigator.geolocation.getCurrentPosition(setCoords);
    } else {
      console.log("Geolocation is not supported by this browser.")
    }
  }

  function setCoords(position) {
    centerLat = position.coords.latitude
    centerLng = position.coords.longitude

    // centers the map at the current position of the user
    map.setCenter({lat: centerLat, lng: centerLng})
    map.addListener('click', function() {
      closeInfowindows()
    })
  }

  function addMarkers() {
    clearMarkers()
    for (var i = 0; i < sights.length; i++) {
      addDelayedMarkers(sights[i], i * 50)
    }
  }

  function clearMarkers() {
    for (var i = 0; i < markers.length; i++) {
      markers[i].setMap(null)
    }
  }

  function closeInfowindows() {
    for (var i = 0; i < infoWindows.length; i++) {
      infoWindows[i].close()
    }
  }

  function addDelayedMarkers(sight, delay) {
    var string = ''
    if(sight.Thumbnail.value != '') string += ''
    string += '
' + sight.Label.value + '
'

    window.setTimeout(function() {
      var marker = new google.maps.Marker({
        position: {lat: parseFloat(sight.Lat.value), lng: parseFloat(sight.Long.value)},
        map: map,
        title: sight.Label.value,
        animation: google.maps.Animation.DROP
      })
      marker.info = new google.maps.InfoWindow({
        content: string
      })
      infoWindows.push(marker.info)
      google.maps.event.addListener(marker, 'click', function() {
        closeInfowindows()
        marker.info.open(map, marker)
      })
      markers.push(marker)
    }, delay)
  }

  // runs a query against the DB with given params
  function queryDB(query) {
    client.query(query, function (error, results) {
      if (error) {
        console.log(error)
      } else {
        console.log(results.results.bindings)
        sights = results.results.bindings
        showResults()
        $('html, body').stop().animate({
          scrollTop: $(document).height()
        }, 1500)
        addMarkers()
        var mean = getLocationMean()
        console.log("lat: " + mean.lat + " long: " + mean.long);
        map.setCenter({lat: mean.lat, lng: mean.long})
      }
    })
  }

  function addProximityMarkers(buildings, delay){
    //clearMarkers()
    if (buildingsOverall.length>2000)
    {
      clearMarkers()
      buildingsOverall = {}
    }

    for (var i = 0; i < buildings.length; i++) {

      if (!(buildingsOverall[buildings[i].name.value]))
      {
        buildingsOverall[buildings[i].name.value] = buildings[i];
        addDelayedProximityMarkers(buildings[i], i * 50)
      }
    }
  }

  function addDelayedProximityMarkers(building, delay) {

    var string = ''
    if(building.thumbnail.value != '') string += ''
    string += '
' + building.name.value + '
'

    window.setTimeout(function() {
      var marker = new google.maps.Marker({
        position: {lat: parseFloat(building.lat.value), lng: parseFloat(building.long.value)},
        map: map,
        title: building.name.value,
        animation: google.maps.Animation.DROP
      })
      marker.info = new google.maps.InfoWindow({
        content: string
      })
      infoWindows.push(marker.info)
      google.maps.event.addListener(marker, 'click', function() {
        closeInfowindows()
        marker.info.open(map, marker)
      })
      markers.push(marker)
    }, delay)
  }

  function queryInProximity(query) {
    client.query(query, function (error, results) {
      if (error) {
        console.log(error)
      } else {

        var buildings = results.results.bindings
        console.log(buildings)
        addProximityMarkers(buildings)
        }
    })
  }

  function getLocationMean() {
    var mean = {
      lat: 0,
      long: 0
    }

    for (var i = 0; i < sights.length; i++) {
      mean.lat += parseFloat(sights[i].Lat.value)
      mean.long += parseFloat(sights[i].Long.value)
    }

    mean.lat = mean.lat / sights.length
    mean.long = mean.long / sights.length
    return mean
  }

  function stringify(city) {
    var str = city.split(' ')

    for (var i = 0; i < str.length; i++) {
      str[i] = str[i].charAt(0).toUpperCase() + str[i].slice(1)
    }

    return str.join('_')
  }

  function getSightsInProximity(long, lat, height, width) {
     var query = `PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
					PREFIX dbo: <http://dbpedia.org/ontology/>
					PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
					SELECT * WHERE
					{
					?s a dbo:ArchitecturalStructure .
					FILTER NOT EXISTS { ?s a dbo:Station } .
					FILTER NOT EXISTS { ?s a dbo:RailwayLine } .
					?s rdfs:label ?name .
					FILTER langMatches(lang(?name), 'en').
					?s dbo:thumbnail ?thumbnail .
					?s geo:lat ?lat .
					?s geo:long ?long . FILTER ( ?long > ${long} - ${width} && ?long < ${long} +  ${width} && ?lat > ${lat} -  ${height} && ?lat < ${lat} +  ${height}) }
					LIMIT 10000`;
    queryInProximity(query)
   //   console.log(query)
  }

  function getSightsByCity(city) {
    city = stringify(city)

    var query = `PREFIX dcterms:  <http://purl.org/dc/terms/>
                  PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
                  SELECT DISTINCT (str(?label) as ?Label) (str(SAMPLE(?lat)) as ?Lat) (str(SAMPLE(?long)) as ?Long) (str(SAMPLE(?thumbnail)) as ?Thumbnail) (?abstract as ?Abstract)
                  WHERE {
                    ?sight dct:subject <http://dbpedia.org/resource/Category:Visitor_attractions_in_${city}> .
                  FILTER langMatches(lang(?label), 'en').
                    ?sight rdfs:label ?label .
                    ?sight geo:lat ?lat .
                    ?sight geo:long ?long .
                    ?sight dbo:thumbnail ?thumbnail .
                  FILTER langMatches(lang(?abstract), 'en').
                    ?sight dbo:abstract ?abstract
                  }
                  ORDER BY ASC(?Label)`
    queryDB(query)

  }
<|endoftext|>