<commit_before>/*! see LICENCE for Simplified BSD Licence */
/*jslint browser:true, indent:2*/
/*global define, require*/ // Require.JS

define(function () {
  'use strict';

  return {
    /**
     * @param {String} name This is the name of the desired resource module.
     * @param {Function} req Provides a "require" to load other modules.
     * @param {Function} load Pass the module's result to this function.
     * @param {Object} config Provides the optimizer's configuration.
     */
    load: function (name, req, load) { // , config
      // TODO: check config.isBuild\
      // TODO: call load.fromText() if necessary to eval JavaScript text
      req([name], function (result) {
        if (result && typeof result === 'object' &&
            typeof result.then === 'function') {
          result.fail(function () {
            load.error.apply(this, arguments);
          });
          result.then(function () {
            load.apply(this, arguments);
          });
        } else {
          load(result);
        }
      });
    }/*,
    write: function () {
      // TODO: what needs to be done for write() ??
    }, */
/*        pluginBuilder: function () {
      // TODO: what needs to be done for pluginBuilder() ??
    } */
    /*
     * Note: we explicitly do NOT implement normalize(), as the simpler
     * default implementation is sufficient for current use cases.
     */
  };
});
<commit_msg>Since we're "leaving the promise world", we should terminate the continuation chain with a done function. Otherwise exceptions from the AMD module that requires the promise module won't be visible.<commit_after>/*! see LICENCE for Simplified BSD Licence */
/*jslint browser:true, indent:2*/
/*global define, require*/ // Require.JS

define(function () {
  'use strict';

  return {
    /**
     * @param {String} name This is the name of the desired resource module.
     * @param {Function} req Provides a "require" to load other modules.
     * @param {Function} load Pass the module's result to this function.
     * @param {Object} config Provides the optimizer's configuration.
     */
    load: function (name, req, load) { // , config
      // TODO: check config.isBuild\
      // TODO: call load.fromText() if necessary to eval JavaScript text
      req([name], function (result) {
        if (result && typeof result === 'object' &&
            typeof result.then === 'function') {
          result.fail(function () {
            load.error.apply(this, arguments);
          });
          result.done(function () {
            load.apply(this, arguments);
          });
        } else {
          load(result);
        }
      });
    }/*,
    write: function () {
      // TODO: what needs to be done for write() ??
    }, */
/*        pluginBuilder: function () {
      // TODO: what needs to be done for pluginBuilder() ??
    } */
    /*
     * Note: we explicitly do NOT implement normalize(), as the simpler
     * default implementation is sufficient for current use cases.
     */
  };
});
<|endoftext|>


<commit_before>var _ = require('underscore');

var messages = [
  {
    lat: 45.783028,
    long: 4.881148,
    text: 'INSA !',
    id: 1,
    is_full: true,
    timestamp: 1391591648
  },
  {
    lat: 45.782167,
    long: 4.872093,
    text: 'Bâtiment IF',
    id: 2,
    is_full: true,
    timestamp: 1391591750
  },
  {
    lat: 45.783753,
    long: 4.872651,
    text: 'Bâtiment TC',
    id: 3,
    is_full: true,
    timestamp: 1391591750
  },
];

exports.get_previews = function(lat, long){
  if(lat === undefined || long === undefined){
    return null;
  }else{
    return messages;
   }
}

exports.get_message = function(id){
  if(id !== undefined)
    return _.where(messages, {id: parseInt(id)});
  else
    return null;
}

exports.post_message = function(body){
  body['id'] = messages.length+1;
  body['timestamp'] = Math.floor(new Date().getTime()/1000);
  messages.push(body);
  return body;
}
<commit_msg>màj du mock<commit_after>var _ = require('underscore');

var messages = [
  {
    lat: 45.783028,
    long: 4.881148,
    text: 'INSA !',
    id: 1,
    is_full: true,
    timestamp: 1391591648
  },
  {
    lat: 45.782167,
    long: 4.872093,
    text: 'Bâtiment IF',
    id: 2,
    is_full: true,
    timestamp: 1391591750
  },
  {
    lat: 45.783753,
    long: 4.872651,
    text: 'Bâtiment TC',
    id: 3,
    is_full: true,
    timestamp: 1391591750
  },
];

exports.get_previews = function(lat, long){
  if(lat === undefined || long === undefined){
    return null;
  }else{
    return messages;
   }
}

exports.get_message = function(id){
  if(id !== undefined){
    var msg = _.where(messages, {id: parseInt(id)});
    return msg.length !== 0 ? msg:null;
  }
  else{
    return null;
  }
}

exports.post_message = function(body){
  body['id'] = messages.length+1;
  body['timestamp'] = Math.floor(new Date().getTime()/1000);
  messages.push(body);
  return body;
}
<|endoftext|>


<commit_before>"use strict";

var inflection = require("inflection");

var log = require("./log");

module.exports = {

	string: null,

	convert: function(string, destination) {
		if (this["to_" + destination]) {
			return this.from(string)["to_" + destination]();
		} else {
			this.error(destination);
		}
	},

	error: function(error) {
		log.error("Case \"" + error + "\" is not supported.");
	},

	from: function(string) {
		var self = this;
		this.string = inflection.underscore(string.replace(/-/g, "_").replace(/[A-Z]{2,}/g, function(match) {
			return self.upper_case_first(match.toLowerCase());
		})).replace(/_{2,}/g, "_");
		return this;
	},

	to_camel: function() {
		return inflection.camelize(this.string, true);
	},

	to_pascal: function() {
		return inflection.camelize(this.string);
	},

	to_screaming_snake: function() {
		return this.string.toUpperCase();
	},

	to_snake: function() {
		return this.string;
	},

	to_spinal: function() {
		return inflection.dasherize(this.string);
	},

	to_train: function() {
		var self = this;
		return self.upper_case_first(inflection.dasherize(this.string).replace(/-[a-z]/g, function(match) {
			return "-" + self.upper_case_first(match.slice(1));
		}));
	},

	upper_case_first: function(string) {
		return string.charAt(0).toUpperCase() + string.slice(1);
	}

};
<commit_msg>Improved support for non-standard case names<commit_after>"use strict";

var inflection = require("inflection");

var log = require("./log");

module.exports = {

	string: null,

	convert: function(string, destination) {
		destination = this.from(destination).to_snake();
		if (this["to_" + destination]) {
			return this.from(string)["to_" + destination]();
		} else {
			this.error(destination);
		}
	},

	error: function(error) {
		log.error("Case \"" + error + "\" is not supported.");
	},

	from: function(string) {
		var self = this;
		this.string = inflection.underscore(string.replace(/-/g, "_").replace(/[A-Z]{2,}/g, function(match) {
			return self.upper_case_first(match.toLowerCase());
		})).replace(/_{2,}/g, "_");
		return this;
	},

	to_camel: function() {
		return inflection.camelize(this.string, true);
	},

	to_pascal: function() {
		return inflection.camelize(this.string);
	},

	to_screaming_snake: function() {
		return this.string.toUpperCase();
	},

	to_snake: function() {
		return this.string;
	},

	to_spinal: function() {
		return inflection.dasherize(this.string);
	},

	to_train: function() {
		var self = this;
		return self.upper_case_first(inflection.dasherize(this.string).replace(/-[a-z]/g, function(match) {
			return "-" + self.upper_case_first(match.slice(1));
		}));
	},

	upper_case_first: function(string) {
		return string.charAt(0).toUpperCase() + string.slice(1);
	}

};
<|endoftext|>


<commit_before>/*
    newT
        a JavaScript template library

    authors:  jeffrey tierney | https://twitter.com/jeffreytierney
              gregory tomlinson | https://twitter.com/gregory80

    project home: https://github.com/jeffreytierney/newT
    license: (see author)

    Usage:

        Create a new 'newT' -- a JS represention of DOM Template w/ event capabilities

            newT.save("id_name", function( data ) {
                // use the () for multiline return of DOM elements via newT.
                // the second param is the 'contents' of the element
                // this sample is a simple string derived from data when newT.render() is called
                return (
                    newT.div({clss : "my_css_class"}, data.foo)
                )
            });

        Converter syntax for Element CSS Class Attribute: "clss"

        Render DOM Elements
            @param string "id_name" template name
            @param (any) the data to pass to the method used in the second parameter of newT.save("name", func);
            newT.render("id_name", { foo : "hello world bars" } );

        Render DOM with options and scope

            newT.render("id_name", {}, {
                scope : obj_scope || this
                data : { } // will be overriden completely - not extended
                preData : func // execute w/ scope passed in
                pre : func // excuted w/ scope passed in
            })

        On Script Load
            On script load, the newT (or temp name is assigned) is initialized.
                This single instance allows convience referrals to complex structures through the
                newT iterface

        Use with innerHTML
            newT.renderToString("id_name", {
                foo : "I come back as a string, no a DOM node"
            });

        Iteration
            newT.each(["one", "two"], function( data, idx ) {
                console.log("data", data);
                console.log("index position", idx);
            })

        Innards:
            newT.templates.global will provide current "templates"

*/

(function (temp) {
  // Default global var name will be newT
  // can be overridden by passing something different
  // into the self executing wrapper function
  temp = temp || "newT";

  // internally refer to it as T for brevity sake
  var T = function(options) {
    this.init(options || {});
  }, regex_pattern=/\<[^\>]+\>|\&[^ ]+;/,
  el_cache = {};
  slice = Array.prototype.slice;

  T.prototype = {
    constructor: T.prototype.constructor,
    version : "1.1.1.1",
    init: function(options) {
      this.options = {
        if_attr: "when",
        local_safe: "_safe",
        safe_mode: false
      };
      for(var opt in options) { this.options[opt] = options[opt]; }
      this.templates = {};
      this.__createMethods();
      return this;
    },
    // simple function to save the passed in template
    save: function(name, template) {
      var name_parts = name.split("."),
          ns = "global";
      name = name_parts[0];
      if(name_parts.length > 1) {
        ns = name_parts[1];
      }
      if(!this.templates.hasOwnProperty(ns)) { this.templates[ns] = {}; }
      this.templates[ns][name] = template;
      return this;
    },
    // create the elements for the template
    // and if an exisiting root el was passed in, append it to that root
    // either way, return the newly created element(s)
    render: function(name, data, opts) {
      var name_parts = name.split("."),
          ns = "global",
          new_el,
          ret,
          _new_el, i;
      name = name_parts[0];
      if(name_parts.length > 1) {
        ns = name_parts[1];
      }

      opts = opts || {};
      opts.scope = opts.scope || null;
      opts.data = data;

      // if a preprocessing function is specified in the options, call it
      // use either the specified scope, or the default of null (set earlier)
      // params
      if (opts.preData) { opts.data = opts.preData.call(opts.scope, opts.data); }
      if (opts.pre) { ret = opts.pre.call(opts.scope, opts.data); }

      this.cur_options = opts;

      new_el = this.templates[ns][name](opts.data, opts._i, opts._idx);
      if(typeof new_el === "object" && new_el.length > 0) {
        _new_el=new_el;
        new_el=document.createDocumentFragment();
        for(i in _new_el) {
            new_el.appendChild( _new_el[i] );
        }
      }

      if(opts.el) {
        opts.el.appendChild(new_el);
      }

      // if a posprocessing function is specified in the options, call it
      // use either the specified scope, or the default of null (set earlier)
      if (opts.post) { opts.post.call(opts.scope, new_el, opts.data); }

      this.cur_options = null;
      delete opts;
      return new_el;
    },
    renderToString: function(name, data, opts) {
      opts = opts || {};
      delete opts.el;

      var el = document.createElement("div");
      el.appendChild(this.render(name, data, opts));

      return el.innerHTML;

    },
    // function to iterate over a collection and render a previously saved template
    // for each item in the collection
    // uses a document fragment to collect each element and pass it back
    eachRender: function(data, template_name, opts) {
      // dont set cur_options here because that happens in render
      opts = opts || {};
      if(!this.checkRender(opts)) { return ""; }
      var frag = document.createDocumentFragment(), idx=0, i;
      opts.el = frag;
      for(i in data) {
        if(data.hasOwnProperty(i)) {
          opts["_i"] = i;
          opts["_idx"] = idx++;
          this.render(template_name, data[i], opts);
        }
      }
      delete opts;
      return frag;
    },
    // more free form iterator function that allows passing an ad-hoc
    // rendering function to be evaluated for each item in the collection
    // uses a document fragment to collect each element and pass it back
    each: function(data, func, opts) {
      opts = opts || {};
      if(!this.checkRender(opts)) { return ""; }
      this.cur_options = opts;
      var frag = document.createDocumentFragment(), child, idx=0, i;
      for(i in data) {
        if(data.hasOwnProperty(i)) {
          child = func(data[i], i, idx);
          if(child) {
            frag.appendChild(child);
          }
          idx+=1;
        }
      }
      this.cur_options = null;
      return frag;
    },
    checkRender: function(opts) {
      if(this.options.if_attr in opts && !opts[this.options.if_attr]) { return false; }
      return true;
    },
    // function that gets called in initializing the class... loops through
    // list of allowed html elements, and creates a helper function on the prototype
    // to allow easy creation of that element simply by calling its name as a function
    __createMethods: function() {
      //var el_list = "a abbr acronym address applet area b base basefont bdo bgsound big blockquote body br button caption center cite code col colgroup comment custom dd del dfn dir div dl dt em embed fieldset font form frame frameset head h1 h2 h3 h4 h5 h6 hn hr html i iframe img input input ins isindex kbd label legend li link listing map marquee menu meta nobr noframes noscript object ol optgroup option p param plaintext pre q rt ruby s samp script select small span strike strong style sub sup table tbody td textarea tfoot th thead title tr tt u ul var wbr xml xmp video audio";
      var el_list = "a abbr address area article aside audio b base bdi bdo blockquote body br button canvas caption cite code col colgroup command datalist dd del details device dfn div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header hgroup hr html i iframe img input ins kbd keygen label legend li link map mark menu meta meter nav noscript object ol optgroup option output p param pre progress q rp rt ruby s samp script section select small source span strong style sub summary sup table tbody td textarea tfoot th thead time title tr track ul var video wbr",
          els = el_list.split(" "),
          prefix = this.options.prefix || "", _this = this;

      // extra helper for just grouping a bunch together without a specific parent
      els.push("frag");

      this.addEls(els, true);

      return this;
    },
    _createEl: function(type) {
      if (type in el_cache && el_cache[type].cloneNode) { return el_cache[type].cloneNode();}
      el_cache[type] = document.createElement(type);
      return el_cache[type].cloneNode();
    },
    // generic version of the function used to build the element specific creation functions
    // type -> name of element to create
    // attributes (optional) -> object with key/value pairs for attributes to be added to the element
    //                          to avoid silliness with using class as an object key
    //                          you must use "clss" to set class.  yuck
    // content (optional) -> arbitrarily many pieces of content to be added within the element
    //                       can be strings, domElements, or anything that evaluates to either of those
    element: function(type, attributes, content) {
      var args = slice.call(arguments, 1),
          el = (type==="frag" ? document.createDocumentFragment() : this._createEl(type));
      if(args.length) {
        content = args;
      }
      else {
        return el;
      }

      if (args[0] && args[0].toString() === "[object Object]") {
        attributes = content.shift();
      }
      else {
        attributes = null;
      }

      if(attributes) {
        // when is not an attribute... but can accept a test case that can be used for conditional rendering
        // if it evaluates to true, the node will be rendered... if not, rendering will be short-circuited and an empty string will be returned
        // when is now just the default value for if_attr... this can be overridden using setOption()
        var _local_safe_mode;
        if(!this.checkRender(attributes)){ el = null; return "";}
        delete attributes[this.options.if_attr];

        if(this.options.local_safe in attributes) {
          _local_safe_mode = !!attributes[this.options.local_safe];
          delete attributes[this.options.local_safe];
        }

        for(attr in attributes) {
          switch(attr.toLowerCase()) {
            case "clss":
            case "classname":
              el.className = (attributes[attr].join ? attributes[attr].join(" ") : attributes[attr]);
              break;
            case "style":
              el.cssText = el.style.cssText = attributes[attr];
              break;
            default:
              if(attr.charAt(0) === "_") {
                var attr_name = attr.substring(1);
                if(attributes[attr]) {
                  el.setAttribute(attr_name, attr_name);
                }
              }
              else{
                el.setAttribute(attr, attributes[attr]);
              }
          }
        }
      }

      var c;
      for(var i=0, len=content.length; i<len; i++) {
        // if the content is a string, create a Text Node to hold it and append
        // unless (for now) there are html tags or entities in it... then just innerHTML it
        c = content[i];
        switch(typeof c) {
            case "string":
                this.addText(el, c, _local_safe_mode);
            break;

            case "number":
                el.appendChild(document.createTextNode(c));
            break;
            case "function":
                var result = c();
                if(typeof result == "string") {
                  this.addText(el, result, _local_safe_mode);
                }
                else {
                  el.appendChild(result);
                }
            break;
            case "undefined":
                break;
            default:
                try{ el.appendChild(c); } catch(ex) { el.appendChild(document.createTextNode(c)); }
            break;

        }
      }
      return el;
    },
    addText: function(el, text, _local_safe_mode) {
      if(!this.isSafeMode(_local_safe_mode) && text.match(regex_pattern)) {
        el.innerHTML = text;
      }
      else {
        el.appendChild(document.createTextNode(text));
      }
      return this;
    },
    setOption: function(key, val){
      if (typeof key === "object") {
        for (var _key in key) { this.options[_key] = key[_key]; }
      }
      else {
        this.options[key] = val;
      }
      return this;
    },
    // when safe mode is set to on, any strings
    safeMode: function(on) {
      if(typeof on == "undefined") { on = true; }
      this.options["safe_mode"] = !!on;
      return this;
    },
    isSafeMode: function(_local_safe_mode) {
      if(typeof _local_safe_mode != "undefined") { return !!_local_safe_mode; }
      if (this.cur_options && "safe_mode" in this.cur_options) { return !!this.cur_options.safe_mode; }
      return !!this.options.safe_mode
    },
    // If you want another separate instance of newT, perhaps to keep its own template management
    // call newT.clone() and it will return another freshly initialized copy (with a clear templates object)
    clone: function() {
      return new T();
    },
    // want to write plugin elements that can do more than just render dom elements?
    // such as dom elements that have some extra processing or ajax requests related to their rendering
    // extend the core newT prototype with this method.
    extend: function(name, func, force, local) {
      if(local) {
        if(!this.hasOwnProperty(name) || force) {
          this[name] = func;
          return true;
        }
      }
      else {
        if(!(name in T.prototype) || force) {
          T.prototype[name] = func;
          return true;
        }
      }
      return false;
    },
    addEls: function(els, force, local) {
      if(typeof els === "string") { els = els.split(" "); }
      var _this = this, args, p_elem=T.prototype.element;
      for(var i=0, len=els.length; i<len; i++) (function(el) {
        _this.extend(el, function() {
              args = slice.call(arguments);
              args.unshift(el);
              return p_elem.apply(_this, args);
        }, force, local);
      })(els[i]);

      delete _this;

      return this;
    },
    noConflict: function(new_name) {
      new_name = new_name || "__newT";
      try{delete window[_last_name];}catch(ex){window[_last_name] = undefined;}
      window[temp] = _old_newt;
      window[new_name] = _temp;
      _last_name = new_name;
      return this;
    }
  }
  var _old_newt = window[temp], _temp, _last_name = temp;
  window[temp] = _temp = new T();
})();
<commit_msg>firefox needs a deep param for clone node so pass false<commit_after>/*
    newT
        a JavaScript template library

    authors:  jeffrey tierney | https://twitter.com/jeffreytierney
              gregory tomlinson | https://twitter.com/gregory80

    project home: https://github.com/jeffreytierney/newT
    license: (see author)

    Usage:

        Create a new 'newT' -- a JS represention of DOM Template w/ event capabilities

            newT.save("id_name", function( data ) {
                // use the () for multiline return of DOM elements via newT.
                // the second param is the 'contents' of the element
                // this sample is a simple string derived from data when newT.render() is called
                return (
                    newT.div({clss : "my_css_class"}, data.foo)
                )
            });

        Converter syntax for Element CSS Class Attribute: "clss"

        Render DOM Elements
            @param string "id_name" template name
            @param (any) the data to pass to the method used in the second parameter of newT.save("name", func);
            newT.render("id_name", { foo : "hello world bars" } );

        Render DOM with options and scope

            newT.render("id_name", {}, {
                scope : obj_scope || this
                data : { } // will be overriden completely - not extended
                preData : func // execute w/ scope passed in
                pre : func // excuted w/ scope passed in
            })

        On Script Load
            On script load, the newT (or temp name is assigned) is initialized.
                This single instance allows convience referrals to complex structures through the
                newT iterface

        Use with innerHTML
            newT.renderToString("id_name", {
                foo : "I come back as a string, no a DOM node"
            });

        Iteration
            newT.each(["one", "two"], function( data, idx ) {
                console.log("data", data);
                console.log("index position", idx);
            })

        Innards:
            newT.templates.global will provide current "templates"

*/

(function (temp) {
  // Default global var name will be newT
  // can be overridden by passing something different
  // into the self executing wrapper function
  temp = temp || "newT";

  // internally refer to it as T for brevity sake
  var T = function(options) {
    this.init(options || {});
  }, regex_pattern=/\<[^\>]+\>|\&[^ ]+;/,
  el_cache = {},
  slice = Array.prototype.slice;

  T.prototype = {
    constructor: T.prototype.constructor,
    version : "1.1.1.1",
    init: function(options) {
      this.options = {
        if_attr: "when",
        local_safe: "_safe",
        safe_mode: false
      };
      for(var opt in options) { this.options[opt] = options[opt]; }
      this.templates = {};
      this.__createMethods();
      return this;
    },
    // simple function to save the passed in template
    save: function(name, template) {
      var name_parts = name.split("."),
          ns = "global";
      name = name_parts[0];
      if(name_parts.length > 1) {
        ns = name_parts[1];
      }
      if(!this.templates.hasOwnProperty(ns)) { this.templates[ns] = {}; }
      this.templates[ns][name] = template;
      return this;
    },
    // create the elements for the template
    // and if an exisiting root el was passed in, append it to that root
    // either way, return the newly created element(s)
    render: function(name, data, opts) {
      var name_parts = name.split("."),
          ns = "global",
          new_el,
          ret,
          _new_el, i;
      name = name_parts[0];
      if(name_parts.length > 1) {
        ns = name_parts[1];
      }

      opts = opts || {};
      opts.scope = opts.scope || null;
      opts.data = data;

      // if a preprocessing function is specified in the options, call it
      // use either the specified scope, or the default of null (set earlier)
      // params
      if (opts.preData) { opts.data = opts.preData.call(opts.scope, opts.data); }
      if (opts.pre) { ret = opts.pre.call(opts.scope, opts.data); }

      this.cur_options = opts;

      new_el = this.templates[ns][name](opts.data, opts._i, opts._idx);
      if(typeof new_el === "object" && new_el.length > 0) {
        _new_el=new_el;
        new_el=document.createDocumentFragment();
        for(i in _new_el) {
            new_el.appendChild( _new_el[i] );
        }
      }

      if(opts.el) {
        opts.el.appendChild(new_el);
      }

      // if a posprocessing function is specified in the options, call it
      // use either the specified scope, or the default of null (set earlier)
      if (opts.post) { opts.post.call(opts.scope, new_el, opts.data); }

      this.cur_options = null;
      delete opts;
      return new_el;
    },
    renderToString: function(name, data, opts) {
      opts = opts || {};
      delete opts.el;

      var el = document.createElement("div");
      el.appendChild(this.render(name, data, opts));

      return el.innerHTML;

    },
    // function to iterate over a collection and render a previously saved template
    // for each item in the collection
    // uses a document fragment to collect each element and pass it back
    eachRender: function(data, template_name, opts) {
      // dont set cur_options here because that happens in render
      opts = opts || {};
      if(!this.checkRender(opts)) { return ""; }
      var frag = document.createDocumentFragment(), idx=0, i;
      opts.el = frag;
      for(i in data) {
        if(data.hasOwnProperty(i)) {
          opts["_i"] = i;
          opts["_idx"] = idx++;
          this.render(template_name, data[i], opts);
        }
      }
      delete opts;
      return frag;
    },
    // more free form iterator function that allows passing an ad-hoc
    // rendering function to be evaluated for each item in the collection
    // uses a document fragment to collect each element and pass it back
    each: function(data, func, opts) {
      opts = opts || {};
      if(!this.checkRender(opts)) { return ""; }
      this.cur_options = opts;
      var frag = document.createDocumentFragment(), child, idx=0, i;
      for(i in data) {
        if(data.hasOwnProperty(i)) {
          child = func(data[i], i, idx);
          if(child) {
            frag.appendChild(child);
          }
          idx+=1;
        }
      }
      this.cur_options = null;
      return frag;
    },
    checkRender: function(opts) {
      if(this.options.if_attr in opts && !opts[this.options.if_attr]) { return false; }
      return true;
    },
    // function that gets called in initializing the class... loops through
    // list of allowed html elements, and creates a helper function on the prototype
    // to allow easy creation of that element simply by calling its name as a function
    __createMethods: function() {
      //var el_list = "a abbr acronym address applet area b base basefont bdo bgsound big blockquote body br button caption center cite code col colgroup comment custom dd del dfn dir div dl dt em embed fieldset font form frame frameset head h1 h2 h3 h4 h5 h6 hn hr html i iframe img input input ins isindex kbd label legend li link listing map marquee menu meta nobr noframes noscript object ol optgroup option p param plaintext pre q rt ruby s samp script select small span strike strong style sub sup table tbody td textarea tfoot th thead title tr tt u ul var wbr xml xmp video audio";
      var el_list = "a abbr address area article aside audio b base bdi bdo blockquote body br button canvas caption cite code col colgroup command datalist dd del details device dfn div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header hgroup hr html i iframe img input ins kbd keygen label legend li link map mark menu meta meter nav noscript object ol optgroup option output p param pre progress q rp rt ruby s samp script section select small source span strong style sub summary sup table tbody td textarea tfoot th thead time title tr track ul var video wbr",
          els = el_list.split(" "),
          prefix = this.options.prefix || "", _this = this;

      // extra helper for just grouping a bunch together without a specific parent
      els.push("frag");

      this.addEls(els, true);

      return this;
    },
    _createEl: function(type) {
      if (type in el_cache && el_cache[type].cloneNode) { return el_cache[type].cloneNode(false);}
      el_cache[type] = document.createElement(type);
      return el_cache[type].cloneNode(false);
    },
    // generic version of the function used to build the element specific creation functions
    // type -> name of element to create
    // attributes (optional) -> object with key/value pairs for attributes to be added to the element
    //                          to avoid silliness with using class as an object key
    //                          you must use "clss" to set class.  yuck
    // content (optional) -> arbitrarily many pieces of content to be added within the element
    //                       can be strings, domElements, or anything that evaluates to either of those
    element: function(type, attributes, content) {
      var args = slice.call(arguments, 1),
          el = (type==="frag" ? document.createDocumentFragment() : this._createEl(type));
      if(args.length) {
        content = args;
      }
      else {
        return el;
      }

      if (args[0] && args[0].toString() === "[object Object]") {
        attributes = content.shift();
      }
      else {
        attributes = null;
      }

      if(attributes) {
        // when is not an attribute... but can accept a test case that can be used for conditional rendering
        // if it evaluates to true, the node will be rendered... if not, rendering will be short-circuited and an empty string will be returned
        // when is now just the default value for if_attr... this can be overridden using setOption()
        var _local_safe_mode;
        if(!this.checkRender(attributes)){ el = null; return "";}
        delete attributes[this.options.if_attr];

        if(this.options.local_safe in attributes) {
          _local_safe_mode = !!attributes[this.options.local_safe];
          delete attributes[this.options.local_safe];
        }

        for(attr in attributes) {
          switch(attr.toLowerCase()) {
            case "clss":
            case "classname":
              el.className = (attributes[attr].join ? attributes[attr].join(" ") : attributes[attr]);
              break;
            case "style":
              el.cssText = el.style.cssText = attributes[attr];
              break;
            default:
              if(attr.charAt(0) === "_") {
                var attr_name = attr.substring(1);
                if(attributes[attr]) {
                  el.setAttribute(attr_name, attr_name);
                }
              }
              else{
                el.setAttribute(attr, attributes[attr]);
              }
          }
        }
      }

      var c;
      for(var i=0, len=content.length; i<len; i++) {
        // if the content is a string, create a Text Node to hold it and append
        // unless (for now) there are html tags or entities in it... then just innerHTML it
        c = content[i];
        switch(typeof c) {
            case "string":
                this.addText(el, c, _local_safe_mode);
            break;

            case "number":
                el.appendChild(document.createTextNode(c));
            break;
            case "function":
                var result = c();
                if(typeof result == "string") {
                  this.addText(el, result, _local_safe_mode);
                }
                else {
                  el.appendChild(result);
                }
            break;
            case "undefined":
                break;
            default:
                try{ el.appendChild(c); } catch(ex) { el.appendChild(document.createTextNode(c)); }
            break;

        }
      }
      return el;
    },
    addText: function(el, text, _local_safe_mode) {
      if(!this.isSafeMode(_local_safe_mode) && text.match(regex_pattern)) {
        el.innerHTML = text;
      }
      else {
        el.appendChild(document.createTextNode(text));
      }
      return this;
    },
    setOption: function(key, val){
      if (typeof key === "object") {
        for (var _key in key) { this.options[_key] = key[_key]; }
      }
      else {
        this.options[key] = val;
      }
      return this;
    },
    // when safe mode is set to on, any strings
    safeMode: function(on) {
      if(typeof on == "undefined") { on = true; }
      this.options["safe_mode"] = !!on;
      return this;
    },
    isSafeMode: function(_local_safe_mode) {
      if(typeof _local_safe_mode != "undefined") { return !!_local_safe_mode; }
      if (this.cur_options && "safe_mode" in this.cur_options) { return !!this.cur_options.safe_mode; }
      return !!this.options.safe_mode
    },
    // If you want another separate instance of newT, perhaps to keep its own template management
    // call newT.clone() and it will return another freshly initialized copy (with a clear templates object)
    clone: function() {
      return new T();
    },
    // want to write plugin elements that can do more than just render dom elements?
    // such as dom elements that have some extra processing or ajax requests related to their rendering
    // extend the core newT prototype with this method.
    extend: function(name, func, force, local) {
      if(local) {
        if(!this.hasOwnProperty(name) || force) {
          this[name] = func;
          return true;
        }
      }
      else {
        if(!(name in T.prototype) || force) {
          T.prototype[name] = func;
          return true;
        }
      }
      return false;
    },
    addEls: function(els, force, local) {
      if(typeof els === "string") { els = els.split(" "); }
      var _this = this, args, p_elem=T.prototype.element;
      for(var i=0, len=els.length; i<len; i++) (function(el) {
        _this.extend(el, function() {
              args = slice.call(arguments);
              args.unshift(el);
              return p_elem.apply(_this, args);
        }, force, local);
      })(els[i]);

      delete _this;

      return this;
    },
    noConflict: function(new_name) {
      new_name = new_name || "__newT";
      try{delete window[_last_name];}catch(ex){window[_last_name] = undefined;}
      window[temp] = _old_newt;
      window[new_name] = _temp;
      _last_name = new_name;
      return this;
    }
  }
  var _old_newt = window[temp], _temp, _last_name = temp;
  window[temp] = _temp = new T();
})();
<|endoftext|>


<commit_before>var region = require('caniuse-lite/dist/unpacker/region').default
var path = require('path')
var fs = require('fs')

var BrowserslistError = require('./error')

var IS_SECTION = /^\s*\[(.+)\]\s*$/
var CONFIG_PATTERN = /^browserslist-config-/
var SCOPED_CONFIG__PATTERN = /@[^./]+\/browserslist-config(-|$)/
var TIME_TO_UPDATE_CANIUSE = 6 * 30 * 24 * 60 * 60 * 1000
var FORMAT = 'Browserslist config should be a string or an array ' +
             'of strings with browser queries'

var dataTimeChecked = false
var filenessCache = { }
var configCache = { }

function checkExtend (name) {
  var use = ' Use `dangerousExtend` option to disable.'
  if (!CONFIG_PATTERN.test(name) && !SCOPED_CONFIG__PATTERN.test(name)) {
    throw new BrowserslistError(
      'Browserslist config needs `browserslist-config-` prefix. ' + use)
  }
  if (name.indexOf('.') !== -1) {
    throw new BrowserslistError(
      '`.` not allowed in Browserslist config name. ' + use)
  }
  if (name.indexOf('node_modules') !== -1) {
    throw new BrowserslistError(
      '`node_modules` not allowed in Browserslist config.' + use)
  }
}

function isFile (file) {
  if (file in filenessCache) {
    return filenessCache[file]
  }
  var result = fs.existsSync(file) && fs.statSync(file).isFile()
  if (!process.env.BROWSERSLIST_DISABLE_CACHE) {
    filenessCache[file] = result
  }
  return result
}

function eachParent (file, callback) {
  var loc = path.resolve(file)
  do {
    var result = callback(loc)
    if (typeof result !== 'undefined') return result
  } while (loc !== (loc = path.dirname(loc)))
  return undefined
}

function check (section) {
  if (Array.isArray(section)) {
    for (var i = 0; i < section.length; i++) {
      if (typeof section[i] !== 'string') {
        throw new BrowserslistError(FORMAT)
      }
    }
  } else if (typeof section !== 'string') {
    throw new BrowserslistError(FORMAT)
  }
}

function pickEnv (config, opts) {
  if (typeof config !== 'object') return config

  var name
  if (typeof opts.env === 'string') {
    name = opts.env
  } else if (process.env.BROWSERSLIST_ENV) {
    name = process.env.BROWSERSLIST_ENV
  } else if (process.env.NODE_ENV) {
    name = process.env.NODE_ENV
  } else {
    name = 'production'
  }

  return config[name] || config.defaults
}

function parsePackage (file) {
  var config = JSON.parse(fs.readFileSync(file))
  if (config.browserlist && !config.browserslist) {
    throw new BrowserslistError(
      '`browserlist` key instead of `browserslist` in ' + file)
  }
  var list = config.browserslist
  if (Array.isArray(list)) {
    list = { defaults: list }
  }

  for (var i in list) {
    check(list[i])
  }

  return list
}

function latestReleaseTime (agents) {
  var latest = 0
  for (var name in agents) {
    var dates = agents[name].releaseDate || { }
    for (var key in dates) {
      if (latest < dates[key]) {
        latest = dates[key]
      }
    }
  }
  return latest * 1000
}

module.exports = {
  loadQueries: function loadQueries (context, name) {
    if (!context.dangerousExtend) checkExtend(name)
    // eslint-disable-next-line security/detect-non-literal-require
    var queries = require(require.resolve(name, { paths: ['.'] }))
    if (!Array.isArray(queries)) {
      throw new BrowserslistError(
        '`' + name + '` config exports not an array of queries')
    }
    return queries
  },

  getStat: function getStat (opts) {
    var stats
    if (opts.stats) {
      stats = opts.stats
    } else if (process.env.BROWSERSLIST_STATS) {
      stats = process.env.BROWSERSLIST_STATS
    } else if (opts.path && path.resolve && fs.existsSync) {
      stats = eachParent(opts.path, function (dir) {
        var file = path.join(dir, 'browserslist-stats.json')
        return isFile(file) ? file : undefined
      })
    }

    if (typeof stats === 'string') {
      try {
        stats = JSON.parse(fs.readFileSync(stats))
      } catch (e) {
        throw new BrowserslistError('Can\'t read ' + stats)
      }
    }

    if (stats && 'dataByBrowser' in stats) {
      stats = stats.dataByBrowser
    }

    return stats
  },

  loadConfig: function loadConfig (opts) {
    if (process.env.BROWSERSLIST) {
      return process.env.BROWSERSLIST
    } else if (opts.config || process.env.BROWSERSLIST_CONFIG) {
      var file = opts.config || process.env.BROWSERSLIST_CONFIG
      if (path.basename(file) === 'package.json') {
        return pickEnv(parsePackage(file), opts)
      } else {
        return pickEnv(module.exports.readConfig(file), opts)
      }
    } else if (opts.path) {
      return pickEnv(module.exports.findConfig(opts.path), opts)
    } else {
      return undefined
    }
  },

  loadCountry: function loadCountry (usage, country) {
    var code = country.replace(/[^\w-]/g, '')
    if (!usage[code]) {
      // eslint-disable-next-line security/detect-non-literal-require
      var compressed = require('caniuse-lite/data/regions/' + code + '.js')
      var data = region(compressed)
      usage[country] = { }
      for (var i in data) {
        for (var j in data[i]) {
          usage[country][i + ' ' + j] = data[i][j]
        }
      }
    }
  },

  parseConfig: function parseConfig (string) {
    var result = { defaults: [] }
    var sections = ['defaults']

    string.toString()
      .replace(/#[^\n]*/g, '')
      .split(/\n|,/)
      .map(function (line) {
        return line.trim()
      })
      .filter(function (line) {
        return line !== ''
      })
      .forEach(function (line) {
        if (IS_SECTION.test(line)) {
          sections = line.match(IS_SECTION)[1].trim().split(' ')
          sections.forEach(function (section) {
            if (result[section]) {
              throw new BrowserslistError(
                'Duplicate section ' + section + ' in Browserslist config')
            }
            result[section] = []
          })
        } else {
          sections.forEach(function (section) {
            result[section].push(line)
          })
        }
      })

    return result
  },

  readConfig: function readConfig (file) {
    if (!isFile(file)) {
      throw new BrowserslistError('Can\'t read ' + file + ' config')
    }
    return module.exports.parseConfig(fs.readFileSync(file))
  },

  findConfig: function findConfig (from) {
    from = path.resolve(from)

    var cacheKey = isFile(from) ? path.dirname(from) : from
    if (cacheKey in configCache) {
      return configCache[cacheKey]
    }

    var resolved = eachParent(from, function (dir) {
      var config = path.join(dir, 'browserslist')
      var pkg = path.join(dir, 'package.json')
      var rc = path.join(dir, '.browserslistrc')

      var pkgBrowserslist
      if (isFile(pkg)) {
        try {
          pkgBrowserslist = parsePackage(pkg)
        } catch (e) {
          if (e.name === 'BrowserslistError') throw e
          console.warn(
            '[Browserslist] Could not parse ' + pkg + '. Ignoring it.')
        }
      }

      if (isFile(config) && pkgBrowserslist) {
        throw new BrowserslistError(
          dir + ' contains both browserslist and package.json with browsers')
      } else if (isFile(rc) && pkgBrowserslist) {
        throw new BrowserslistError(
          dir + ' contains both .browserslistrc and package.json with browsers')
      } else if (isFile(config) && isFile(rc)) {
        throw new BrowserslistError(
          dir + ' contains both .browserslistrc and browserslist')
      } else if (isFile(config)) {
        return module.exports.readConfig(config)
      } else if (isFile(rc)) {
        return module.exports.readConfig(rc)
      } else {
        return pkgBrowserslist
      }
    })
    if (!process.env.BROWSERSLIST_DISABLE_CACHE) {
      configCache[cacheKey] = resolved
    }
    return resolved
  },

  clearCaches: function clearCaches () {
    dataTimeChecked = false
    filenessCache = { }
    configCache = { }
  },

  oldDataWarning: function oldDataWarning (agentsObj) {
    if (dataTimeChecked) return
    dataTimeChecked = true

    var latest = latestReleaseTime(agentsObj)
    var halfYearAgo = Date.now() - TIME_TO_UPDATE_CANIUSE

    if (latest !== 0 && latest < halfYearAgo) {
      var command = 'npm update'
      eachParent(__filename, function (dir) {
        var pckg = path.join(dir, 'package.json')
        var yarnLock = path.join(dir, 'yarn.lock')
        if (isFile(pckg) && isFile(yarnLock)) {
          command = 'yarn upgrade'
        }
      })
      console.warn(
        'Browserslist: caniuse-lite is outdated. ' +
        'Please run next command `' + command + ' caniuse-lite browserslist`')
    }
  },

  currentNode: function currentNode () {
    return 'node ' + process.versions.node
  }
}
<commit_msg>Update node.js (#285)<commit_after>var region = require('caniuse-lite/dist/unpacker/region').default
var path = require('path')
var fs = require('fs')

var BrowserslistError = require('./error')

var IS_SECTION = /^\s*\[(.+)\]\s*$/
var CONFIG_PATTERN = /^browserslist-config-/
var SCOPED_CONFIG__PATTERN = /@[^./]+\/browserslist-config(-|$|\/)/
var TIME_TO_UPDATE_CANIUSE = 6 * 30 * 24 * 60 * 60 * 1000
var FORMAT = 'Browserslist config should be a string or an array ' +
             'of strings with browser queries'

var dataTimeChecked = false
var filenessCache = { }
var configCache = { }

function checkExtend (name) {
  var use = ' Use `dangerousExtend` option to disable.'
  if (!CONFIG_PATTERN.test(name) && !SCOPED_CONFIG__PATTERN.test(name)) {
    throw new BrowserslistError(
      'Browserslist config needs `browserslist-config-` prefix. ' + use)
  }
  if (name.indexOf('.') !== -1) {
    throw new BrowserslistError(
      '`.` not allowed in Browserslist config name. ' + use)
  }
  if (name.indexOf('node_modules') !== -1) {
    throw new BrowserslistError(
      '`node_modules` not allowed in Browserslist config.' + use)
  }
}

function isFile (file) {
  if (file in filenessCache) {
    return filenessCache[file]
  }
  var result = fs.existsSync(file) && fs.statSync(file).isFile()
  if (!process.env.BROWSERSLIST_DISABLE_CACHE) {
    filenessCache[file] = result
  }
  return result
}

function eachParent (file, callback) {
  var loc = path.resolve(file)
  do {
    var result = callback(loc)
    if (typeof result !== 'undefined') return result
  } while (loc !== (loc = path.dirname(loc)))
  return undefined
}

function check (section) {
  if (Array.isArray(section)) {
    for (var i = 0; i < section.length; i++) {
      if (typeof section[i] !== 'string') {
        throw new BrowserslistError(FORMAT)
      }
    }
  } else if (typeof section !== 'string') {
    throw new BrowserslistError(FORMAT)
  }
}

function pickEnv (config, opts) {
  if (typeof config !== 'object') return config

  var name
  if (typeof opts.env === 'string') {
    name = opts.env
  } else if (process.env.BROWSERSLIST_ENV) {
    name = process.env.BROWSERSLIST_ENV
  } else if (process.env.NODE_ENV) {
    name = process.env.NODE_ENV
  } else {
    name = 'production'
  }

  return config[name] || config.defaults
}

function parsePackage (file) {
  var config = JSON.parse(fs.readFileSync(file))
  if (config.browserlist && !config.browserslist) {
    throw new BrowserslistError(
      '`browserlist` key instead of `browserslist` in ' + file)
  }
  var list = config.browserslist
  if (Array.isArray(list)) {
    list = { defaults: list }
  }

  for (var i in list) {
    check(list[i])
  }

  return list
}

function latestReleaseTime (agents) {
  var latest = 0
  for (var name in agents) {
    var dates = agents[name].releaseDate || { }
    for (var key in dates) {
      if (latest < dates[key]) {
        latest = dates[key]
      }
    }
  }
  return latest * 1000
}

module.exports = {
  loadQueries: function loadQueries (context, name) {
    if (!context.dangerousExtend) checkExtend(name)
    // eslint-disable-next-line security/detect-non-literal-require
    var queries = require(require.resolve(name, { paths: ['.'] }))
    if (!Array.isArray(queries)) {
      throw new BrowserslistError(
        '`' + name + '` config exports not an array of queries')
    }
    return queries
  },

  getStat: function getStat (opts) {
    var stats
    if (opts.stats) {
      stats = opts.stats
    } else if (process.env.BROWSERSLIST_STATS) {
      stats = process.env.BROWSERSLIST_STATS
    } else if (opts.path && path.resolve && fs.existsSync) {
      stats = eachParent(opts.path, function (dir) {
        var file = path.join(dir, 'browserslist-stats.json')
        return isFile(file) ? file : undefined
      })
    }

    if (typeof stats === 'string') {
      try {
        stats = JSON.parse(fs.readFileSync(stats))
      } catch (e) {
        throw new BrowserslistError('Can\'t read ' + stats)
      }
    }

    if (stats && 'dataByBrowser' in stats) {
      stats = stats.dataByBrowser
    }

    return stats
  },

  loadConfig: function loadConfig (opts) {
    if (process.env.BROWSERSLIST) {
      return process.env.BROWSERSLIST
    } else if (opts.config || process.env.BROWSERSLIST_CONFIG) {
      var file = opts.config || process.env.BROWSERSLIST_CONFIG
      if (path.basename(file) === 'package.json') {
        return pickEnv(parsePackage(file), opts)
      } else {
        return pickEnv(module.exports.readConfig(file), opts)
      }
    } else if (opts.path) {
      return pickEnv(module.exports.findConfig(opts.path), opts)
    } else {
      return undefined
    }
  },

  loadCountry: function loadCountry (usage, country) {
    var code = country.replace(/[^\w-]/g, '')
    if (!usage[code]) {
      // eslint-disable-next-line security/detect-non-literal-require
      var compressed = require('caniuse-lite/data/regions/' + code + '.js')
      var data = region(compressed)
      usage[country] = { }
      for (var i in data) {
        for (var j in data[i]) {
          usage[country][i + ' ' + j] = data[i][j]
        }
      }
    }
  },

  parseConfig: function parseConfig (string) {
    var result = { defaults: [] }
    var sections = ['defaults']

    string.toString()
      .replace(/#[^\n]*/g, '')
      .split(/\n|,/)
      .map(function (line) {
        return line.trim()
      })
      .filter(function (line) {
        return line !== ''
      })
      .forEach(function (line) {
        if (IS_SECTION.test(line)) {
          sections = line.match(IS_SECTION)[1].trim().split(' ')
          sections.forEach(function (section) {
            if (result[section]) {
              throw new BrowserslistError(
                'Duplicate section ' + section + ' in Browserslist config')
            }
            result[section] = []
          })
        } else {
          sections.forEach(function (section) {
            result[section].push(line)
          })
        }
      })

    return result
  },

  readConfig: function readConfig (file) {
    if (!isFile(file)) {
      throw new BrowserslistError('Can\'t read ' + file + ' config')
    }
    return module.exports.parseConfig(fs.readFileSync(file))
  },

  findConfig: function findConfig (from) {
    from = path.resolve(from)

    var cacheKey = isFile(from) ? path.dirname(from) : from
    if (cacheKey in configCache) {
      return configCache[cacheKey]
    }

    var resolved = eachParent(from, function (dir) {
      var config = path.join(dir, 'browserslist')
      var pkg = path.join(dir, 'package.json')
      var rc = path.join(dir, '.browserslistrc')

      var pkgBrowserslist
      if (isFile(pkg)) {
        try {
          pkgBrowserslist = parsePackage(pkg)
        } catch (e) {
          if (e.name === 'BrowserslistError') throw e
          console.warn(
            '[Browserslist] Could not parse ' + pkg + '. Ignoring it.')
        }
      }

      if (isFile(config) && pkgBrowserslist) {
        throw new BrowserslistError(
          dir + ' contains both browserslist and package.json with browsers')
      } else if (isFile(rc) && pkgBrowserslist) {
        throw new BrowserslistError(
          dir + ' contains both .browserslistrc and package.json with browsers')
      } else if (isFile(config) && isFile(rc)) {
        throw new BrowserslistError(
          dir + ' contains both .browserslistrc and browserslist')
      } else if (isFile(config)) {
        return module.exports.readConfig(config)
      } else if (isFile(rc)) {
        return module.exports.readConfig(rc)
      } else {
        return pkgBrowserslist
      }
    })
    if (!process.env.BROWSERSLIST_DISABLE_CACHE) {
      configCache[cacheKey] = resolved
    }
    return resolved
  },

  clearCaches: function clearCaches () {
    dataTimeChecked = false
    filenessCache = { }
    configCache = { }
  },

  oldDataWarning: function oldDataWarning (agentsObj) {
    if (dataTimeChecked) return
    dataTimeChecked = true

    var latest = latestReleaseTime(agentsObj)
    var halfYearAgo = Date.now() - TIME_TO_UPDATE_CANIUSE

    if (latest !== 0 && latest < halfYearAgo) {
      var command = 'npm update'
      eachParent(__filename, function (dir) {
        var pckg = path.join(dir, 'package.json')
        var yarnLock = path.join(dir, 'yarn.lock')
        if (isFile(pckg) && isFile(yarnLock)) {
          command = 'yarn upgrade'
        }
      })
      console.warn(
        'Browserslist: caniuse-lite is outdated. ' +
        'Please run next command `' + command + ' caniuse-lite browserslist`')
    }
  },

  currentNode: function currentNode () {
    return 'node ' + process.versions.node
  }
}
<|endoftext|>


<commit_before>define(
	[
		'./mutations/mutationrecord',
		'./util',
		'lodash'
	],
	function(
		MutationRecord,
		util,
		_,
		undefined) {
		// DOM Node
		function Node(type) {
			this.nodeType = type;

			// Parent
			this.parentNode = null;

			// Siblings
			this.nextSibling = null;
			this.previousSibling = null;

			// Child nodes
			this.childNodes = [];
			this.firstChild = this.lastChild = null;

			// User data, use get/setUserData to access
			this.userData = {};

			// Registered mutation observers, use MutationObserver interface to manipulate
			this.registeredObservers = [];
		}

		// Node type constants - not all DOM standard node types are supported
		Node.prototype.ELEMENT_NODE                = Node.ELEMENT_NODE                = 1;
		Node.prototype.TEXT_NODE                   = Node.TEXT_NODE                   = 3;
		Node.prototype.PROCESSING_INSTRUCTION_NODE = Node.PROCESSING_INSTRUCTION_NODE = 7;
		Node.prototype.DOCUMENT_NODE               = Node.DOCUMENT_NODE               = 9;

		// Internal helper used to update the firstChild and lastChild references.
		function updateFirstLast() {
			this.firstChild = _.first(this.childNodes) || null;
			this.lastChild = _.last(this.childNodes) || null;
		}

		// Internal helper used to update the nextSibling and previousSibling references.
		function updateSiblings(index) {
			if (!this.parentNode) {
				// Node has been removed
				if (this.nextSibling) this.nextSibling.previousSibling = this.previousSibling;
				if (this.previousSibling) this.previousSibling.nextSibling = this.nextSibling;
				this.nextSibling = this.previousSibling = null;
				return;
			}

			this.nextSibling = this.parentNode.childNodes[index + 1] || null;
			this.previousSibling = this.parentNode.childNodes[index - 1] || null;

			if (this.nextSibling) this.nextSibling.previousSibling = this;
			if (this.previousSibling) this.previousSibling.nextSibling = this;
		}

		// Adds a node to the end of the list of children of a specified parent node.
		// If the node already exists it is removed from current parent node, then added to new parent node.
		Node.prototype.appendChild = function(childNode) {
			return this.insertBefore(childNode, null);
		};

		// Indicates whether a node is a descendent of a given node.
		Node.prototype.contains = function(childNode) {
			while (childNode && childNode != this) {
				childNode = childNode.parentNode;
			}
			return childNode == this;
		};

		// Inserts the specified node before a reference element as a child of the current node.
		// If referenceNode is null, the new node is appended after the current child nodes.
		Node.prototype.insertBefore = function(newNode, referenceNode, suppressObservers) {
			// Check if referenceNode is a child
			if (referenceNode && referenceNode.parentNode !== this)
				return null;

			// Fix using the new node as a reference
			if (referenceNode === newNode)
				referenceNode = newNode.nextSibling;

			// Detach from old parent
			if (newNode.parentNode) {
				newNode.parentNode.removeChild(newNode, suppressObservers);
			}

			// Check index of reference node
			var index = referenceNode ?
				_.indexOf(this.childNodes, referenceNode) :
				this.childNodes.length;
			if (index < 0) return null;

			// Update ranges
			var document = this.ownerDocument || this;
			for (var iRange = 0, nRanges = document.ranges.length; iRange < nRanges; ++iRange) {
				var range = document.ranges[iRange];
				if (range.startContainer === this && range.startOffset > index)
					range.startOffset += 1;
				if (range.endContainer === this && range.endOffset > index)
					range.endOffset += 1;
			}

			// Queue mutation record
			if (!suppressObservers) {
				var record = new MutationRecord('childList', this);
				record.addedNodes.push(newNode);
				record.nextSibling = referenceNode;
				record.previousSibling = (referenceNode && referenceNode.previousSibling) || null;
				util.queueMutationRecord(record);
			}

			// Insert the node
			newNode.parentNode = this;
			this.childNodes.splice(index, 0, newNode);
			updateFirstLast.call(this);
			updateSiblings.call(newNode, index);

			return newNode;
		};

		// Puts the specified node and all of its subtree into a "normalized" form.
		// In a normalized subtree, no text nodes in the subtree are empty and there are no adjacent text nodes.
		Node.prototype.normalize = function(recurse) {
			if (recurse === undefined)
				recurse = true;
			var childNode = this.firstChild,
				index = 0,
				document = this.ownerDocument || this;
			while (childNode) {
				var nextNode = childNode.nextSibling;
				if (childNode.nodeType == Node.TEXT_NODE) {
					// Delete empty text nodes
					var length = childNode.length();
					if (!length) {
						childNode.parentNode.removeChild(childNode);
						--index;
					} else {
						// Concatenate and collect childNode's contiguous text nodes (excluding current)
						var data = '',
							siblingsToRemove = [],
							siblingIndex, sibling;
						for (sibling = childNode.nextSibling, siblingIndex = index;
							sibling && sibling.nodeType == Node.TEXT_NODE;
							sibling = sibling.nextSibling, ++siblingIndex) {

							data += sibling.nodeValue;
							siblingsToRemove.push(sibling);
						}
						// Append concatenated data, if any
						if (data) {
							childNode.appendData(data);
						}
						// Fix ranges
						for (sibling = childNode.nextSibling, siblingIndex = index + 1;
							sibling && sibling.nodeType == Node.TEXT_NODE;
							sibling = sibling.nextSibling, ++siblingIndex) {

							for (var iRange = 0, nRanges = document.ranges.length; iRange < nRanges; ++iRange) {
								var range = document.ranges[iRange];
								if (range.startContainer === sibling)
									range.setStart(childNode, length + range.startOffset);
								if (range.startContainer === this && range.startOffset == siblingIndex)
									range.setStart(childNode, length);
								if (range.endContainer === sibling)
									range.setEnd(childNode, length + range.endOffset);
								if (range.endContainer === this && range.endOffset == siblingIndex)
									range.setEnd(childNode, length);
							}

							length += sibling.length();
						}
						// Remove contiguous text nodes (excluding current) in tree order
						while (siblingsToRemove.length) {
							this.removeChild(siblingsToRemove.shift());
						}
						// Update next node to process
						nextNode = childNode.nextSibling;
					}
				} else if (recurse) {
					// Recurse
					childNode.normalize();
				}
				// Move to next node
				childNode = nextNode;
				++index;
			}
		};

		function isRegisteredObserverForSubtree(registeredObserver) {
			return !!registeredObserver.options.subtree;
		}

		// Removes a child node from the DOM. Returns removed node.
		Node.prototype.removeChild = function(childNode, suppressObservers) {
			// Check index of node
			var index = _.indexOf(this.childNodes, childNode);
			if (index < 0) return null;

			// Update ranges
			var document = this.ownerDocument || this;
			for (var iRange = 0, nRanges = document.ranges.length; iRange < nRanges; ++iRange) {
				var range = document.ranges[iRange];
				if (childNode.contains(range.startContainer)) {
					range.setStart(this, index);
				}
				if (childNode.contains(range.endContainer)) {
					range.setEnd(this, index);
				}
				if (range.startContainer === this && range.startOffset > index)
					range.startOffset -= 1;
				if (range.endContainer === this && range.endOffset > index)
					range.endOffset -= 1;
			}

			// Queue mutation record
			if (!suppressObservers) {
				var record = new MutationRecord('childList', this);
				record.removedNodes.push(childNode);
				record.nextSibling = childNode.nextSibling;
				record.previousSibling = childNode.previousSibling;
				util.queueMutationRecord(record);
			}

			// Add transient registered observers to detect changes in the removed subtree
			var parent = this;
			while (parent) {
				var subtreeObservers = _.filter(parent.registeredObservers, isRegisteredObserverForSubtree);
				for (var i = 0, l = subtreeObservers.length; i < l; ++i) {
					var registeredObserver = subtreeObservers[i];
					// Append an identical but transient registered observer to childNode's list
					registeredObserver.observer.observe(childNode, registeredObserver.options, true);
				}
				parent = parent.parentNode;
			}

			// Remove the node
			childNode.parentNode = null;
			this.childNodes.splice(index, 1);
			updateFirstLast.call(this);
			updateSiblings.call(childNode, index);

			return childNode;
		};

		// Replaces one child node of the specified node with another. Returns the replaced node.
		Node.prototype.replaceChild = function(newChild, oldChild) {
			// Check if oldChild is a child
			if (oldChild.parentNode !== this)
				return null;

			// Get reference node for insert
			var referenceNode = oldChild.nextSibling;
			if (referenceNode === newChild) referenceNode = newChild.nextSibling;

			// Create mutation record
			var record = new MutationRecord('childList', this);
			record.addedNodes.push(newChild);
			record.removedNodes.push(oldChild);
			record.nextSibling = referenceNode;
			record.previousSibling = oldChild.previousSibling;

			// Remove old child
			this.removeChild(oldChild, true);

			// Insert new child
			this.insertBefore(newChild, referenceNode, true);

			// Queue mutation record
			util.queueMutationRecord(record);

			return oldChild;
		};

		// Retrieves the object associated to a key on a this node.
		Node.prototype.getUserData = function(key) {
			return key in this.userData ? this.userData[key] : null;
		};

		// Associate an object to a key on this node.
		Node.prototype.setUserData = function(key, data) {
			var oldData = this.getUserData(key);

			// No need to trigger observers if the value doesn't actually change
			if (oldData === data)
				return oldData;

			this.userData[key] = data;

			// Queue a mutation record (non-standard, but useful)
			var record = new MutationRecord('userData', this);
			record.attributeName = key;
			record.oldValue = oldData;
			util.queueMutationRecord(record);

			return oldData;
		};

		return Node;
	}
);
<commit_msg>Just use indices.<commit_after>define(
	[
		'./mutations/mutationrecord',
		'./util',
		'lodash'
	],
	function(
		MutationRecord,
		util,
		_,
		undefined) {
		// DOM Node
		function Node(type) {
			this.nodeType = type;

			// Parent
			this.parentNode = null;

			// Siblings
			this.nextSibling = null;
			this.previousSibling = null;

			// Child nodes
			this.childNodes = [];
			this.firstChild = this.lastChild = null;

			// User data, use get/setUserData to access
			this.userData = {};

			// Registered mutation observers, use MutationObserver interface to manipulate
			this.registeredObservers = [];
		}

		// Node type constants - not all DOM standard node types are supported
		Node.prototype.ELEMENT_NODE                = Node.ELEMENT_NODE                = 1;
		Node.prototype.TEXT_NODE                   = Node.TEXT_NODE                   = 3;
		Node.prototype.PROCESSING_INSTRUCTION_NODE = Node.PROCESSING_INSTRUCTION_NODE = 7;
		Node.prototype.DOCUMENT_NODE               = Node.DOCUMENT_NODE               = 9;

		// Internal helper used to update the firstChild and lastChild references.
		function updateFirstLast() {
			this.firstChild = this.childNodes[0] || null;
			this.lastChild = this.childNodes[this.childNodes.length - 1] || null;
		}

		// Internal helper used to update the nextSibling and previousSibling references.
		function updateSiblings(index) {
			if (!this.parentNode) {
				// Node has been removed
				if (this.nextSibling) this.nextSibling.previousSibling = this.previousSibling;
				if (this.previousSibling) this.previousSibling.nextSibling = this.nextSibling;
				this.nextSibling = this.previousSibling = null;
				return;
			}

			this.nextSibling = this.parentNode.childNodes[index + 1] || null;
			this.previousSibling = this.parentNode.childNodes[index - 1] || null;

			if (this.nextSibling) this.nextSibling.previousSibling = this;
			if (this.previousSibling) this.previousSibling.nextSibling = this;
		}

		// Adds a node to the end of the list of children of a specified parent node.
		// If the node already exists it is removed from current parent node, then added to new parent node.
		Node.prototype.appendChild = function(childNode) {
			return this.insertBefore(childNode, null);
		};

		// Indicates whether a node is a descendent of a given node.
		Node.prototype.contains = function(childNode) {
			while (childNode && childNode != this) {
				childNode = childNode.parentNode;
			}
			return childNode == this;
		};

		// Inserts the specified node before a reference element as a child of the current node.
		// If referenceNode is null, the new node is appended after the current child nodes.
		Node.prototype.insertBefore = function(newNode, referenceNode, suppressObservers) {
			// Check if referenceNode is a child
			if (referenceNode && referenceNode.parentNode !== this)
				return null;

			// Fix using the new node as a reference
			if (referenceNode === newNode)
				referenceNode = newNode.nextSibling;

			// Detach from old parent
			if (newNode.parentNode) {
				newNode.parentNode.removeChild(newNode, suppressObservers);
			}

			// Check index of reference node
			var index = referenceNode ?
				_.indexOf(this.childNodes, referenceNode) :
				this.childNodes.length;
			if (index < 0) return null;

			// Update ranges
			var document = this.ownerDocument || this;
			for (var iRange = 0, nRanges = document.ranges.length; iRange < nRanges; ++iRange) {
				var range = document.ranges[iRange];
				if (range.startContainer === this && range.startOffset > index)
					range.startOffset += 1;
				if (range.endContainer === this && range.endOffset > index)
					range.endOffset += 1;
			}

			// Queue mutation record
			if (!suppressObservers) {
				var record = new MutationRecord('childList', this);
				record.addedNodes.push(newNode);
				record.nextSibling = referenceNode;
				record.previousSibling = (referenceNode && referenceNode.previousSibling) || null;
				util.queueMutationRecord(record);
			}

			// Insert the node
			newNode.parentNode = this;
			this.childNodes.splice(index, 0, newNode);
			updateFirstLast.call(this);
			updateSiblings.call(newNode, index);

			return newNode;
		};

		// Puts the specified node and all of its subtree into a "normalized" form.
		// In a normalized subtree, no text nodes in the subtree are empty and there are no adjacent text nodes.
		Node.prototype.normalize = function(recurse) {
			if (recurse === undefined)
				recurse = true;
			var childNode = this.firstChild,
				index = 0,
				document = this.ownerDocument || this;
			while (childNode) {
				var nextNode = childNode.nextSibling;
				if (childNode.nodeType == Node.TEXT_NODE) {
					// Delete empty text nodes
					var length = childNode.length();
					if (!length) {
						childNode.parentNode.removeChild(childNode);
						--index;
					} else {
						// Concatenate and collect childNode's contiguous text nodes (excluding current)
						var data = '',
							siblingsToRemove = [],
							siblingIndex, sibling;
						for (sibling = childNode.nextSibling, siblingIndex = index;
							sibling && sibling.nodeType == Node.TEXT_NODE;
							sibling = sibling.nextSibling, ++siblingIndex) {

							data += sibling.nodeValue;
							siblingsToRemove.push(sibling);
						}
						// Append concatenated data, if any
						if (data) {
							childNode.appendData(data);
						}
						// Fix ranges
						for (sibling = childNode.nextSibling, siblingIndex = index + 1;
							sibling && sibling.nodeType == Node.TEXT_NODE;
							sibling = sibling.nextSibling, ++siblingIndex) {

							for (var iRange = 0, nRanges = document.ranges.length; iRange < nRanges; ++iRange) {
								var range = document.ranges[iRange];
								if (range.startContainer === sibling)
									range.setStart(childNode, length + range.startOffset);
								if (range.startContainer === this && range.startOffset == siblingIndex)
									range.setStart(childNode, length);
								if (range.endContainer === sibling)
									range.setEnd(childNode, length + range.endOffset);
								if (range.endContainer === this && range.endOffset == siblingIndex)
									range.setEnd(childNode, length);
							}

							length += sibling.length();
						}
						// Remove contiguous text nodes (excluding current) in tree order
						while (siblingsToRemove.length) {
							this.removeChild(siblingsToRemove.shift());
						}
						// Update next node to process
						nextNode = childNode.nextSibling;
					}
				} else if (recurse) {
					// Recurse
					childNode.normalize();
				}
				// Move to next node
				childNode = nextNode;
				++index;
			}
		};

		function isRegisteredObserverForSubtree(registeredObserver) {
			return !!registeredObserver.options.subtree;
		}

		// Removes a child node from the DOM. Returns removed node.
		Node.prototype.removeChild = function(childNode, suppressObservers) {
			// Check index of node
			var index = _.indexOf(this.childNodes, childNode);
			if (index < 0) return null;

			// Update ranges
			var document = this.ownerDocument || this;
			for (var iRange = 0, nRanges = document.ranges.length; iRange < nRanges; ++iRange) {
				var range = document.ranges[iRange];
				if (childNode.contains(range.startContainer)) {
					range.setStart(this, index);
				}
				if (childNode.contains(range.endContainer)) {
					range.setEnd(this, index);
				}
				if (range.startContainer === this && range.startOffset > index)
					range.startOffset -= 1;
				if (range.endContainer === this && range.endOffset > index)
					range.endOffset -= 1;
			}

			// Queue mutation record
			if (!suppressObservers) {
				var record = new MutationRecord('childList', this);
				record.removedNodes.push(childNode);
				record.nextSibling = childNode.nextSibling;
				record.previousSibling = childNode.previousSibling;
				util.queueMutationRecord(record);
			}

			// Add transient registered observers to detect changes in the removed subtree
			var parent = this;
			while (parent) {
				var subtreeObservers = _.filter(parent.registeredObservers, isRegisteredObserverForSubtree);
				for (var i = 0, l = subtreeObservers.length; i < l; ++i) {
					var registeredObserver = subtreeObservers[i];
					// Append an identical but transient registered observer to childNode's list
					registeredObserver.observer.observe(childNode, registeredObserver.options, true);
				}
				parent = parent.parentNode;
			}

			// Remove the node
			childNode.parentNode = null;
			this.childNodes.splice(index, 1);
			updateFirstLast.call(this);
			updateSiblings.call(childNode, index);

			return childNode;
		};

		// Replaces one child node of the specified node with another. Returns the replaced node.
		Node.prototype.replaceChild = function(newChild, oldChild) {
			// Check if oldChild is a child
			if (oldChild.parentNode !== this)
				return null;

			// Get reference node for insert
			var referenceNode = oldChild.nextSibling;
			if (referenceNode === newChild) referenceNode = newChild.nextSibling;

			// Create mutation record
			var record = new MutationRecord('childList', this);
			record.addedNodes.push(newChild);
			record.removedNodes.push(oldChild);
			record.nextSibling = referenceNode;
			record.previousSibling = oldChild.previousSibling;

			// Remove old child
			this.removeChild(oldChild, true);

			// Insert new child
			this.insertBefore(newChild, referenceNode, true);

			// Queue mutation record
			util.queueMutationRecord(record);

			return oldChild;
		};

		// Retrieves the object associated to a key on a this node.
		Node.prototype.getUserData = function(key) {
			return key in this.userData ? this.userData[key] : null;
		};

		// Associate an object to a key on this node.
		Node.prototype.setUserData = function(key, data) {
			var oldData = this.getUserData(key);

			// No need to trigger observers if the value doesn't actually change
			if (oldData === data)
				return oldData;

			this.userData[key] = data;

			// Queue a mutation record (non-standard, but useful)
			var record = new MutationRecord('userData', this);
			record.attributeName = key;
			record.oldValue = oldData;
			util.queueMutationRecord(record);

			return oldData;
		};

		return Node;
	}
);
<|endoftext|>


<commit_before>/* Provided under the MIT license. See LICENSE for details */

var dom = {
  $: function(elemId) {
    return document.getElementById(elemId);
  },
  addDiv: function(name, parent) {
    // prevent fastback cache from re-adding the element on load
    var existing = this.$(name);
    if (existing === null) {
      var el = document.createElement('div');
      el.setAttribute('id', name);
      parent.appendChild(el);
    }

    return this.$(name);
  },
  addText: function(text, parent) {
    var el = document.createTextNode(text);
    parent.appendChild(el);
  },
  getCSSValue: function(element, property) {
    var cs = document.defaultView.getComputedStyle(element, null);
    return cs.getPropertyValue(property);
  }
}

function debug(message) {
 debug = dom.$('debug');
 debug.innerHTML += message + '<br>';
}

var pagering = {
 // create paging nav
 // XXX: should move the current onload code in here
 init: function(elem) {
  var content = dom.$(elem);

  var pageNav = dom.addDiv('pagenav', content);
  var pageLeft = dom.addDiv('pageleft', pageNav);
  dom.addText('←', pageLeft);
  var pageRight = dom.addDiv('pageright', pageNav);
  dom.addText('→', pageRight);
 },
 changePage: function(direction, totalPages, pageWidth) {
  var content = dom.$('content');
  var text = dom.$('text');
  var totalWidth = pageWidth * totalPages;
  /* returns e.g. '-30px', so we have to convert it from a String to an Integer */
  var leftMargin = text.style.marginLeft;
  var currentOffset = leftMargin.length == 0 ? 0 : parseInt(leftMargin.split('px')[0]);

  var currentPageNumber = parseInt(dom.$('currentpage').innerHTML);

  if (direction === 'l') {
   if (Math.abs(currentOffset) >= pageWidth) {
    text.style.marginLeft = (currentOffset + pageWidth) + 'px';

    this.setCurrent(currentPageNumber - 1);
   }

  } else {
   if (Math.abs(currentOffset) < totalWidth) {
    text.style.marginLeft = (currentOffset - pageWidth) + 'px';

    this.setCurrent(currentPageNumber + 1);
   }
  }
 },
 CSSDimensionToInt: function(dimension, defaultValue) {
  var dimension = dimension.split('px')[0];
  // if the dimension has not been set (e.g., it's 'auto', 'normal', ...), hand
  // back defaultValue
  return parseInt(dimension) === NaN ? defaultValue : parseInt(dimension);
 },
 getColumnGap: function(element) {
  var columnGap = '';

  /* surely there's a way to compress this */
  if (dom.getCSSValue(element, 'column-gap') !== null) {
    columnGap = dom.getCSSValue(element, 'column-gap');
  } else if (dom.getCSSValue(element, '-webkit-column-gap') !== null) {
    columnGap = dom.getCSSValue(element, '-webkit-column-gap');
  } else if (dom.getCSSValue(element, '-moz-column-gap') !== null) {
    columnGap = dom.getCSSValue(element, '-moz-column-gap');
  }

  // CSS3 spec suggests 1em as the default column gap; use 13px as an average
  return this.CSSDimensionToInt(columnGap, 13);
 },
 setPageCount: function(totalPages) {
  var pageCount = dom.$('totalpages');
  pageCount.innerHTML = Math.round(totalPages);
 },
 setCurrent: function(pageNumber) {
  var currentPage = dom.$('currentpage');
  currentPage.innerHTML = pageNumber;
 }
}

window.onload = function () {
 var text = dom.$('text');

 /* go into page mode and set the page count */
 var fullHeight = text.clientHeight;

 var content = dom.$('content');
 content.setAttribute('class', 'pageringd');

 var pagedHeight = text.clientHeight;
 var totalPages = fullHeight / pagedHeight;
 pagering.setPageCount(totalPages);

 // page width has two parts:
 // 1) the width of the paged element
 // 2) CSS3 column-gap of the paged element
 var pageWidth = text.clientWidth;
 pageWidth += pagering.getColumnGap(text);

 if (totalPages > 1) {
  pagering.init('content');

  var leftArrow = dom.$('pageleft');
  leftArrow.addEventListener('click',
       function() { pagering.changePage('l', totalPages, pageWidth); }, false );

  var rightArrow = dom.$('pageright');
  rightArrow.addEventListener('click',
       function() { pagering.changePage('r', totalPages, pageWidth); }, false );
 }
}
<commit_msg>Drop debug function<commit_after>/* Provided under the MIT license. See LICENSE for details */

var dom = {
  $: function(elemId) {
    return document.getElementById(elemId);
  },
  addDiv: function(name, parent) {
    // prevent fastback cache from re-adding the element on load
    var existing = this.$(name);
    if (existing === null) {
      var el = document.createElement('div');
      el.setAttribute('id', name);
      parent.appendChild(el);
    }

    return this.$(name);
  },
  addText: function(text, parent) {
    var el = document.createTextNode(text);
    parent.appendChild(el);
  },
  getCSSValue: function(element, property) {
    var cs = document.defaultView.getComputedStyle(element, null);
    return cs.getPropertyValue(property);
  }
}

var pagering = {
 // create paging nav
 // XXX: should move the current onload code in here
 init: function(elem) {
  var content = dom.$(elem);

  var pageNav = dom.addDiv('pagenav', content);
  var pageLeft = dom.addDiv('pageleft', pageNav);
  dom.addText('←', pageLeft);
  var pageRight = dom.addDiv('pageright', pageNav);
  dom.addText('→', pageRight);
 },
 changePage: function(direction, totalPages, pageWidth) {
  var content = dom.$('content');
  var text = dom.$('text');
  var totalWidth = pageWidth * totalPages;
  /* returns e.g. '-30px', so we have to convert it from a String to an Integer */
  var leftMargin = text.style.marginLeft;
  var currentOffset = leftMargin.length == 0 ? 0 : parseInt(leftMargin.split('px')[0]);

  var currentPageNumber = parseInt(dom.$('currentpage').innerHTML);

  if (direction === 'l') {
   if (Math.abs(currentOffset) >= pageWidth) {
    text.style.marginLeft = (currentOffset + pageWidth) + 'px';

    this.setCurrent(currentPageNumber - 1);
   }

  } else {
   if (Math.abs(currentOffset) < totalWidth) {
    text.style.marginLeft = (currentOffset - pageWidth) + 'px';

    this.setCurrent(currentPageNumber + 1);
   }
  }
 },
 CSSDimensionToInt: function(dimension, defaultValue) {
  var dimension = dimension.split('px')[0];
  // if the dimension has not been set (e.g., it's 'auto', 'normal', ...), hand
  // back defaultValue
  return parseInt(dimension) === NaN ? defaultValue : parseInt(dimension);
 },
 getColumnGap: function(element) {
  var columnGap = '';

  /* surely there's a way to compress this */
  if (dom.getCSSValue(element, 'column-gap') !== null) {
    columnGap = dom.getCSSValue(element, 'column-gap');
  } else if (dom.getCSSValue(element, '-webkit-column-gap') !== null) {
    columnGap = dom.getCSSValue(element, '-webkit-column-gap');
  } else if (dom.getCSSValue(element, '-moz-column-gap') !== null) {
    columnGap = dom.getCSSValue(element, '-moz-column-gap');
  }

  // CSS3 spec suggests 1em as the default column gap; use 13px as an average
  return this.CSSDimensionToInt(columnGap, 13);
 },
 setPageCount: function(totalPages) {
  var pageCount = dom.$('totalpages');
  pageCount.innerHTML = Math.round(totalPages);
 },
 setCurrent: function(pageNumber) {
  var currentPage = dom.$('currentpage');
  currentPage.innerHTML = pageNumber;
 }
}

window.onload = function () {
 var text = dom.$('text');

 /* go into page mode and set the page count */
 var fullHeight = text.clientHeight;

 var content = dom.$('content');
 content.setAttribute('class', 'pageringd');

 var pagedHeight = text.clientHeight;
 var totalPages = fullHeight / pagedHeight;
 pagering.setPageCount(totalPages);

 // page width has two parts:
 // 1) the width of the paged element
 // 2) CSS3 column-gap of the paged element
 var pageWidth = text.clientWidth;
 pageWidth += pagering.getColumnGap(text);

 if (totalPages > 1) {
  pagering.init('content');

  var leftArrow = dom.$('pageleft');
  leftArrow.addEventListener('click',
       function() { pagering.changePage('l', totalPages, pageWidth); }, false );

  var rightArrow = dom.$('pageright');
  rightArrow.addEventListener('click',
       function() { pagering.changePage('r', totalPages, pageWidth); }, false );
 }
}
<|endoftext|>


<commit_before>
var Path = (function ($, Data, Log, Network) {
    var exports = {};

    // Data objects here
    var waypoints = [];

    // Interactive map objects here
    var map;
    var popup = L.popup();

    // Handle button clicks
    $(document).ready(function () {

        $('#lockOn').on('click', function () {
            // TODO Decouple this from plane marker & figure out somewhere to store last "sensible GPS coordinates"
            // (to prevent bug with erroneous GPS coordinates crashing Leaflet)
            if (planeMarker) {
                map.panTo(planeMarker.getLatLng());
            }
        });

        $('#sendWaypoints').on('click', function () {
            for (i = 0; i < waypoints.length; i++) {
                var latLng = waypoints[i];
                command = "new_Waypoint:" + latLng.lat + "," + latLng.lng + "\r\n";
                Network.write(command);
                Log.write(command);
            }
        });

        $('#clearWaypoints').on('click', function () {
            waypoints = [];
            redrawMap();
        });

        map.on('click', function (e) {
            popup
                .setLatLng(e.latlng)
                .setContent('
Add Waypoint
')
                .openOn(map);

            $('#addWaypoint').on('click', function () {
                map.closePopup();
                waypoints.push(e.latlng);
                redrawMap();
            });
        });
    });

    var planeMarker;
    var waypointMarkerGroup;
    var waypointPolyline;
    var historyPolyline;

    Network.on('data', redrawMap);

    function redrawMap() {

        lat = Data.state.lat;
        lon = Data.state.lon;
        heading = Data.state.heading;

        // Check for GPS fix, assuming we'll never fly off the coast of West Africa
        // (No GPS fix if coordinates close to (0; 0) or impossibly big)
        if (Math.abs(lat) < 1 || Math.abs(lon) < 1 || Math.abs(lat) > 360 || Math.abs(lon) > 360) {
            return;
        }

        // Init map if necessary
        if (!map) {
            map = L.map('map').setView([43.53086, -80.5772], 17);
            L.tileLayer('sat_tiles/{z}/{x}/{y}.png', {
                maxZoom: 19
            }).addTo(map);
        }

        // Init planeMarker if necessary
        if (!planeMarker) {
            planeMarker = new L.RotatedMarker([lat, lon], {
                icon: L.icon({
                    iconUrl: 'plane.png',
                    iconSize: [30, 30], // size of the icon
                }),
            }).addTo(map);
        }

        // Init waypoint marker layer-group if necessary
        if (!waypointMarkerGroup) {
            waypointMarkerGroup = L.layerGroup().addTo(map);
        }

        // Init waypointPolyline if necessary
        if (!waypointPolyline) {
            waypointPolyline = new L.Polyline(waypoints, {
                color: 'red',
                weight: 3,
                opacity: 0.5,
                clickable: false,
            }).addTo(map);
        }

        // Init historyPolyline if necessary
        if (!historyPolyline) {
            historyPolyline = new L.Polyline([], {
                color: '#0000ff',
                weight: 5,
                clickable: false,
            }).addTo(map);
        }

        // Update plane marker
        planeMarker.setLatLng(new L.LatLng(lat, lon));
        planeMarker.options.angle = heading;
        planeMarker.options.title = lat + "°, " + lon + "°, " + heading + "°";
        planeMarker.update();

        // Redraw waypoint markers
        waypointMarkerGroup.clearLayers();
        for (var i = 0; i < waypoints.length; ++i) {
            waypointMarkerGroup.addLayer(new L.marker(waypoints[i]));
        }

        // Redraw waypoint polyline
        waypointPolyline.setLatLngs(waypoints).spliceLatLngs(0, 0, new L.LatLng(lat, lon));

        // Draw points on historyPolyline
        historyPolyline.addLatLng(L.latLng(lat, lon));
    }

    // Export what needs to be
    return exports;

})($, Data, Log, Network);<commit_msg>Fix map click + Init on plane position<commit_after>var Path = (function ($, Data, Log, Network) {
    var exports = {};

    // Data objects here
    var waypoints = [];

    // Interactive map objects here
    var map;
    var popup = L.popup();

    // Handle button clicks
    $(document).ready(function () {

        $('#lockOn').on('click', function () {
            // TODO Decouple this from plane marker & figure out somewhere to store last "sensible GPS coordinates"
            // (to prevent bug with erroneous GPS coordinates crashing Leaflet)
            if (planeMarker) {
                map.panTo(planeMarker.getLatLng());
            }
        });

        $('#sendWaypoints').on('click', function () {
            for (i = 0; i < waypoints.length; i++) {
                var latLng = waypoints[i];
                command = "new_Waypoint:" + latLng.lat + "," + latLng.lng + "\r\n";
                Network.write(command);
                Log.write(command);
            }
        });

        $('#clearWaypoints').on('click', function () {
            waypoints = [];
            redrawMap();
        });
    });

    function mapClick(e) {
        popup
            .setLatLng(e.latlng)
            .setContent('
Add Waypoint
')
            .openOn(map);

        $('#addWaypoint').on('click', function () {
            map.closePopup();
            waypoints.push(e.latlng);
            redrawMap();
        });
    }

    var planeMarker;
    var waypointMarkerGroup;
    var waypointPolyline;
    var historyPolyline;

    Network.on('data', redrawMap);

    function redrawMap() {

        // Check for GPS fix, assuming we'll never fly off the coast of West Africa
        // (No GPS fix if coordinates close to (0; 0) or impossibly big)
        if (Math.abs(lat) < 1 || Math.abs(lon) < 1 || Math.abs(lat) > 360 || Math.abs(lon) > 360) {
            return;
        }

        lat = Data.state.lat;
        lon = Data.state.lon;
        heading = Data.state.heading;

        // Init map if necessary
        if (!map) {
            map = L.map('map').setView([lat, lon], 17);
            L.tileLayer('sat_tiles/{z}/{x}/{y}.png', {
                maxZoom: 19
            }).addTo(map);
            map.on('click', mapClick);
        }

        // Init planeMarker if necessary
        if (!planeMarker) {
            planeMarker = new L.RotatedMarker([lat, lon], {
                icon: L.icon({
                    iconUrl: 'plane.png',
                    iconSize: [30, 30], // size of the icon
                }),
            }).addTo(map);
        }

        // Init waypoint marker layer-group if necessary
        if (!waypointMarkerGroup) {
            waypointMarkerGroup = L.layerGroup().addTo(map);
        }

        // Init waypointPolyline if necessary
        if (!waypointPolyline) {
            waypointPolyline = new L.Polyline(waypoints, {
                color: 'red',
                weight: 3,
                opacity: 0.5,
                clickable: false,
            }).addTo(map);
        }

        // Init historyPolyline if necessary
        if (!historyPolyline) {
            historyPolyline = new L.Polyline([], {
                color: '#0000ff',
                weight: 5,
                clickable: false,
            }).addTo(map);
        }

        // Update plane marker
        planeMarker.setLatLng(new L.LatLng(lat, lon));
        planeMarker.options.angle = heading;
        planeMarker.options.title = lat + "°, " + lon + "°, " + heading + "°";
        planeMarker.update();

        // Redraw waypoint markers
        waypointMarkerGroup.clearLayers();
        for (var i = 0; i < waypoints.length; ++i) {
            waypointMarkerGroup.addLayer(new L.marker(waypoints[i]));
        }

        // Redraw waypoint polyline
        waypointPolyline.setLatLngs(waypoints).spliceLatLngs(0, 0, new L.LatLng(lat, lon));

        // Draw points on historyPolyline
        historyPolyline.addLatLng(L.latLng(lat, lon));
    }

    // Export what needs to be
    return exports;

})($, Data, Log, Network);<|endoftext|>


<commit_before>javascript:
(function(){

var myPrefix = wpTextbox1.value.substring(0, wpTextbox1.selectionStart);
var mySuffix = wpTextbox1.value.substring(wpTextbox1.selectionEnd);
var list = myPrefix.match(/\[\[(User|User talk|User_talk|用戶|用户|用戶討論|用户讨论):[^|\]#]+[^\]]*\]\]/gi);
var username = "";
for (var i = list.length - 1; i >= 0; i--) {
	var temp = list[i].match(/\[\[(?:User|User talk|User_talk|用戶|用户|用戶討論|用户讨论):([^|\]#]+)[^\]]*\]\]/i);
	if (temp !== null && temp[1] != "A2093064") {
		username = temp[1];
		break;
	}
}
var indent = myPrefix.match(/^([\:*]+)/mg);
if (indent === null) {
	indent = ":";
} else {
	indent = indent[indent.length-1]+indent[indent.length-1][0];
}
wpTextbox1.value = myPrefix + indent+ "{{ping|"+username+"}}" + mySuffix;

})();
<commit_msg>ping add no sign<commit_after>javascript:
(function(){

var myPrefix = wpTextbox1.value.substring(0, wpTextbox1.selectionStart);
var mySuffix = wpTextbox1.value.substring(wpTextbox1.selectionEnd);
var list = myPrefix.match(/\[\[(User|User talk|User_talk|用戶|用户|用戶討論|用户讨论):[^|\]#]+[^\]]*\]\]/gi);
if (list === null) {
	wpTextbox1.value = myPrefix + "{{ping|}}" + mySuffix;
	return;
}
var username = "";
for (var i = list.length - 1; i >= 0; i--) {
	var temp = list[i].match(/\[\[(?:User|User talk|User_talk|用戶|用户|用戶討論|用户讨论):([^|\]#]+)[^\]]*\]\]/i);
	if (temp !== null && temp[1] != "A2093064") {
		username = temp[1];
		break;
	}
}
var indent = myPrefix.match(/^([\:*]+)/mg);
if (indent === null) {
	indent = ":";
} else {
	indent = indent[indent.length-1]+indent[indent.length-1][0];
}
wpTextbox1.value = myPrefix + indent+ "{{ping|"+username+"}}" + mySuffix;

})();
<|endoftext|>