<commit_before>/* ==========================================================
 * Carousel.js v1.1.0
 * ==========================================================
 * Copyright 2012 xsokev
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================== */
define([
    "dojo/_base/declare",
    "dojo/_base/sniff",
    "dojo/query",
    "dojo/_base/lang",
    "dojo/_base/window",
    "dojo/on",
    "dojo/dom-class",
    "dojo/dom-attr",
    "dojo/dom-construct",
    'dojo/mouse',
    "dojo/dom-geometry",
    "dojo/dom-style",
    "dojo/_base/array",
    "./Support",
    "dojo/domReady!"
], function (declare, sniff, query, lang, win, on, domClass, domAttr, domConstruct, mouse, domGeom, domStyle, array, support) {
    "use strict";

    var slideSelector = '[data-slide]';
    var Carousel = declare([], {
        defaultOptions: {
            interval: 3000,
            pause: 'hover'
        },
        constructor: function (element, options) {
            this.options = lang.mixin(lang.clone(this.defaultOptions), (options || {}));
            this.domNode = element;
            if (this.options.slide) { this.slide(this.options.slide); }
            if (this.options.pause === 'hover') {
                on(this.domNode, mouse.enter, lang.hitch(this, 'pause'));
                on(this.domNode, mouse.leave, lang.hitch(this, 'cycle'));
            }
            if (this.options.interval) { this.cycle(); }
        },
        cycle: function (e) {
            if (!e) { this.paused = false; }
            if (this.options.interval && !this.paused) {
                this.interval = setInterval(lang.hitch(this, 'next'), this.options.interval);
            }
            return this;
        },
        to: function (pos) {
            var active = query('.item.active', this.domNode),
                children = active.parent().children(),
                activePos = children.indexOf(active[0]),
                _this = this;
            if (pos > (children.length - 1) || pos < 0) { return; }
            if (this.sliding) {
                return on.once(_this.domNode, 'slid', function () {
                    _this.to(pos);
                });
            }
            if (activePos === pos) {
                return this.pause().cycle();
            }
            return this.slide((pos > activePos ? 'next' : 'prev'), query(children[pos]));
        },
        pause: function (e) {
            if (!e) { this.paused = true; }
            if (query('.next, .prev', this.domNode).length && support.trans.end) {
                on.emit(this.domNode, support.trans.end, { bubbles:true, cancelable:true });
                this.cycle();
            }
            clearInterval(this.interval);
            this.interval = null;
            return this;
        },
        next: function () {
            if (this.sliding) { return; }
            return this.slide('next');
        },
        prev: function () {
            if (this.sliding) { return; }
            return this.slide('prev');
        },
        slide: function (type, next) {
            var active = query('.item.active', this.domNode),
                isCycling = this.interval,
                direction = type === 'next' ? 'left' : 'right',
                fallback = type === 'next' ? 'first' : 'last',
                _this = this;
            next = next || active[type]();

            this.sliding = true;
            if (isCycling) { this.pause(); }

            next = next.length ? next : query('.item', this.domNode)[fallback]();

            if (domClass.contains(next[0], 'active')) { return; }

            if (support.trans && domClass.contains(this.domNode, 'slide')) {
                on.emit(this.domNode, 'slide', { bubbles:false, cancelable:false, relatedTarget: next[0] });
                //if (e && e.defaultPrevented) { return; }
                domClass.add(next[0], type);
                next[0].offsetWidth;

                domClass.add(active[0], direction);
                domClass.add(next[0], direction);
                on.once(this.domNode, support.trans.end, function () {
                    domClass.remove(next[0], [type, direction].join(' '));
                    domClass.add(next[0], 'active');
                    domClass.remove(active[0], ['active', direction].join(' '));
                    _this.sliding = false;
                    setTimeout(function () {
                        on.emit(_this.domNode, 'slid', { bubbles:false, cancelable:false });
                    }, 0);
                });
            } else {
                on.emit(this.domNode, 'slide', { bubbles:false, cancelable:false, relatedTarget: next[0] });
                domClass.remove(active[0], 'active');
                domClass.add(next[0], 'active');
                this.sliding = false;
                on.emit(_this.domNode, 'slid', { bubbles:false, cancelable:false });
            }

            if (isCycling) { this.cycle(); }
            return this;
        }
    });

    lang.extend(query.NodeList, {
        carousel:function (option) {
            var options = (lang.isObject(option)) ? option : {};
            return this.forEach(function (node) {
                var data = support.getData(node, 'carousel');
                var action = typeof option === 'string' ? option : options.slide;
                if (!data) { support.setData(node, 'carousel', (data = new Carousel(node, options))); }
                if (typeof option === 'number') { data.to(option); }
                else if (action) { data[action].call(data); }
            });
        }
    });
    on(document, on.selector(slideSelector, 'click'), function (e) {
        var href, target = domAttr.get(e.target, 'data-target') || (href = domAttr.get(e.target, 'href')) && href.replace(/.*(?=#[^\s]+$)/, ''); //strip for ie7
        var options = {};
        if(!support.getData(target, 'collapse')){
            options = lang.mixin({}, lang.mixin(support.getData(target), support.getData(e.target)));
        }
        query(target).carousel(options);
        e.preventDefault();
    });

    return Carousel;
});<commit_msg>Updated Carousel to include NodeList-traverse<commit_after>/* ==========================================================
 * Carousel.js v1.1.0
 * ==========================================================
 * Copyright 2012 xsokev
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================== */
define([
    "dojo/_base/declare",
    "dojo/_base/sniff",
    "dojo/query",
    "dojo/_base/lang",
    "dojo/_base/window",
    "dojo/on",
    "dojo/dom-class",
    "dojo/dom-attr",
    "dojo/dom-construct",
    'dojo/mouse',
    "dojo/dom-geometry",
    "dojo/dom-style",
    "dojo/_base/array",
    "./Support",
    "dojo/NodeList-traverse",
    "dojo/domReady!"
], function (declare, sniff, query, lang, win, on, domClass, domAttr, domConstruct, mouse, domGeom, domStyle, array, support) {
    "use strict";

    var slideSelector = '[data-slide]';
    var Carousel = declare([], {
        defaultOptions: {
            interval: 3000,
            pause: 'hover'
        },
        constructor: function (element, options) {
            this.options = lang.mixin(lang.clone(this.defaultOptions), (options || {}));
            this.domNode = element;
            if (this.options.slide) { this.slide(this.options.slide); }
            if (this.options.pause === 'hover') {
                on(this.domNode, mouse.enter, lang.hitch(this, 'pause'));
                on(this.domNode, mouse.leave, lang.hitch(this, 'cycle'));
            }
            if (this.options.interval) { this.cycle(); }
        },
        cycle: function (e) {
            if (!e) { this.paused = false; }
            if (this.options.interval && !this.paused) {
                this.interval = setInterval(lang.hitch(this, 'next'), this.options.interval);
            }
            return this;
        },
        to: function (pos) {
            var active = query('.item.active', this.domNode),
                children = active.parent().children(),
                activePos = children.indexOf(active[0]),
                _this = this;
            if (pos > (children.length - 1) || pos < 0) { return; }
            if (this.sliding) {
                return on.once(_this.domNode, 'slid', function () {
                    _this.to(pos);
                });
            }
            if (activePos === pos) {
                return this.pause().cycle();
            }
            return this.slide((pos > activePos ? 'next' : 'prev'), query(children[pos]));
        },
        pause: function (e) {
            if (!e) { this.paused = true; }
            if (query('.next, .prev', this.domNode).length && support.trans.end) {
                on.emit(this.domNode, support.trans.end, { bubbles:true, cancelable:true });
                this.cycle();
            }
            clearInterval(this.interval);
            this.interval = null;
            return this;
        },
        next: function () {
            if (this.sliding) { return; }
            return this.slide('next');
        },
        prev: function () {
            if (this.sliding) { return; }
            return this.slide('prev');
        },
        slide: function (type, next) {
            var active = query('.item.active', this.domNode),
                isCycling = this.interval,
                direction = type === 'next' ? 'left' : 'right',
                fallback = type === 'next' ? 'first' : 'last',
                _this = this;
            next = next || active[type]();

            this.sliding = true;
            if (isCycling) { this.pause(); }

            next = next.length ? next : query('.item', this.domNode)[fallback]();

            if (domClass.contains(next[0], 'active')) { return; }

            if (support.trans && domClass.contains(this.domNode, 'slide')) {
                on.emit(this.domNode, 'slide', { bubbles:false, cancelable:false, relatedTarget: next[0] });
                //if (e && e.defaultPrevented) { return; }
                domClass.add(next[0], type);
                next[0].offsetWidth;

                domClass.add(active[0], direction);
                domClass.add(next[0], direction);
                on.once(this.domNode, support.trans.end, function () {
                    domClass.remove(next[0], [type, direction].join(' '));
                    domClass.add(next[0], 'active');
                    domClass.remove(active[0], ['active', direction].join(' '));
                    _this.sliding = false;
                    setTimeout(function () {
                        on.emit(_this.domNode, 'slid', { bubbles:false, cancelable:false });
                    }, 0);
                });
            } else {
                on.emit(this.domNode, 'slide', { bubbles:false, cancelable:false, relatedTarget: next[0] });
                domClass.remove(active[0], 'active');
                domClass.add(next[0], 'active');
                this.sliding = false;
                on.emit(_this.domNode, 'slid', { bubbles:false, cancelable:false });
            }

            if (isCycling) { this.cycle(); }
            return this;
        }
    });

    lang.extend(query.NodeList, {
        carousel:function (option) {
            var options = (lang.isObject(option)) ? option : {};
            return this.forEach(function (node) {
                var data = support.getData(node, 'carousel');
                var action = typeof option === 'string' ? option : options.slide;
                if (!data) { support.setData(node, 'carousel', (data = new Carousel(node, options))); }
                if (typeof option === 'number') { data.to(option); }
                else if (action) { data[action].call(data); }
            });
        }
    });
    on(document, on.selector(slideSelector, 'click'), function (e) {
        var href, target = domAttr.get(e.target, 'data-target') || (href = domAttr.get(e.target, 'href')) && href.replace(/.*(?=#[^\s]+$)/, ''); //strip for ie7
        var options = {};
        if(!support.getData(target, 'collapse')){
            options = lang.mixin({}, lang.mixin(support.getData(target), support.getData(e.target)));
        }
        query(target).carousel(options);
        e.preventDefault();
    });

    return Carousel;
});<|endoftext|>


<commit_before>import React from "react";
import Item from "./Item"
import AddItemBar from "./AddItemBar";
import SearchSuggestions from "./SearchSuggestions";
import Footer from "./Footer";
import range from 'lodash.range';
import util from "../utilities";
import autobind from 'autobind-decorator';

// Firebase
import Rebase  from "re-base";
var base = Rebase.createClass("https://collaboralist.firebaseio.com/");

var deleteTimeout;
var deleteList = [];
const orderPlaceholder = 999999999999999;
var scrollInterval;
const scrollBuffer = 80;
const scrollSpeed = 0.2;
var touchY;
var scrollPosition;
var windowHeight;

@autobind
class List extends React.Component {
  constructor() {
    super();

    this.state = {
      name: "List",
      firebase: {
        items: {},
        history: {},
        order: {}
      },
      listEmpty: true,
      loaded: false,
      suggestions: [],
      highlightIndex: 0,
      suggestionsHover: false,
      autoDelete: true,
      delta: 0,
      mouse: 0,
      isPressed: false,
      lastPressed: 0
    }
  }

  componentDidMount() {
    var order = this.state.firebase.order;
    base.syncState(this.props.params.listId, {
      context: this,
      state: "firebase",
      then: function() {
        if (Object.keys(this.state.firebase.items).length > 1) {
          order[orderPlaceholder] = null;
          this.setState({
            firebase: {items: {placeholder: null}, order: order}
          });
          this.setState({
            listEmpty: false
          });
        }
        this.setState({
          loaded: true
        });
        if (Object.keys(this.state.firebase.history).length > 1) {
          this.setState({
            firebase: {history: {placeholder: null}}
          });
        }
      }
    });
    order[orderPlaceholder] = orderPlaceholder;
    this.setState({
      firebase: {items: {placeholder: true}, history: {placeholder: true}, order: order}
    });
    window.addEventListener('touchmove', this.handleTouchMove);
    window.addEventListener('touchend', this.handleReorderUp);
    window.addEventListener('mousemove', this.handleReorderMove);
    window.addEventListener('mouseup', this.handleReorderUp);
  }

  updateItem(key, entry, orderIndex) {
    var parsedEntry = util.parseEntry(entry);
    if (!parsedEntry.itemName) {
      return this.deleteItem(key, orderIndex);
    }
    this.state.firebase.items[key].count = parsedEntry.itemCount;
    this.state.firebase.items[key].name = parsedEntry.itemName;
    this.setState({
      firebase: {items: this.state.firebase.items}
    });
  }

  addItem(item) {
    var items = this.state.firebase.items;
    var order = this.state.firebase.order;
    var history = this.state.firebase.history;
    var timestamp = (new Date()).getTime();
    items["item-" + timestamp] = item;
    var itemsCount = Object.keys(items).length - 1;
    if (this.state.listEmpty) {
      items["placeholder"] = null;
      order[orderPlaceholder] = null;
      itemsCount--;
      this.setState({
        listEmpty: false
      });
    }
    order[itemsCount] = itemsCount;
    var itemName = item.name;
    history[itemName] = history.hasOwnProperty(itemName) ? history[itemName] + 1 : 1;
    if (history.hasOwnProperty("placeholder")) {
      history["placeholder"] = null;
    }
    this.setState({
      firebase: {items: items, order: order, history: history}
    });
  }

  renderItem(key, orderIndex) {
    if (key == 0) {
      return;
    }
    return (
      <Item key={key}
            index={key}
            ref={key}
            details={this.state.firebase.items[key]}
            items={this.state.firebase.items}
            checkItem={this.checkItem}
            updateItem={this.updateItem}
            setDelete={this.setDelete}
            autoDelete={this.state.autoDelete}
            mouse={this.state.mouse}
            isPressed={this.state.isPressed}
            order={this.state.firebase.order}
            initialOrder={range(Object.keys(this.state.firebase.items).length)}
            lastPressed={this.state.lastPressed}
            orderIndex={orderIndex}
            handleReorderStart={this.handleReorderStart}
            handleTouchStart={this.handleTouchStart}/>
    )
  }

  checkItem(key) {
    this.state.firebase.items[key].checked = !this.state.firebase.items[key].checked;
    this.setState({
      firebase: {items: this.state.firebase.items}
    });
  }

  setDelete(key, orderIndex) {
    clearTimeout(deleteTimeout);
    deleteList.push({key: key, orderIndex: orderIndex});
    var self = this;
    deleteTimeout = setTimeout(function() {
      deleteList.map(function(obj, index) {
        var currentOrderInd = obj.orderIndex;
        self.deleteItem(obj.key, currentOrderInd);
        for (var i = index; i < deleteList.length; i++) {
          if (deleteList[i].orderIndex > currentOrderInd) {
            deleteList[i].orderIndex--;
          }
        }
      });
      deleteList = [];
    }, 1600);
  }

  deleteItem(key, orderIndex) {
    window.removeEventListener('touchend', this.refs[key].reorderMouseUp);
    window.removeEventListener('mouseup', this.refs[key].reorderMouseUp);
    var items = this.state.firebase.items;
    var order = this.state.firebase.order;
    order.splice(order.indexOf(orderIndex), 1);
    var newOrder = order.map(function(index) {
      return index > orderIndex ? index - 1 : index;
    });
    if (Object.keys(items).length - 1 == 0) {
      this.setState({
        listEmpty: true
      });
      items["placeholder"] = true;
      newOrder[orderPlaceholder] = orderPlaceholder;
    }
    items[key] = null;
    order = newOrder;
    this.setState({
      firebase: {items: items, order: order}
    });
  }

  handleTouchStart(event, key, pressLocation) {
    this.initAutoScroll();
    scrollInterval = setInterval(this.autoScroll, 20);
    this.handleReorderStart(event.touches[0], key, pressLocation);
  }

  handleTouchMove(event) {
    if (this.state.isPressed) {
      event.preventDefault();
      this.handleReorderMove(event.touches[0]);
    }
  }

  handleReorderStart(event, pos, pressY) {
    var mySheet = document.styleSheets[0];
    var firstRule = mySheet.cssRules ? mySheet.cssRules[0] : mySheet.rules[0];
    firstRule.style.setProperty("cursor", "grabbing", "important");
    firstRule.style.setProperty("cursor", "-moz-grabbing", "important");
    firstRule.style.setProperty("cursor", "-webkit-grabbing", "important");
    this.setState({
      delta: event.pageY - pressY,
      mouse: pressY,
      isPressed: true,
      lastPressed: pos
    });
  }

  initAutoScroll() {
    touchY = -1;
    windowHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
  }

  autoScroll() {
    var scrollChange = 0;
    scrollPosition = window.scrollY;
    if (touchY >= 0 && touchY < scrollPosition + scrollBuffer) {
      scrollChange = touchY - (scrollPosition + scrollBuffer);
    } else if (touchY >=0 && touchY > windowHeight - scrollBuffer) {
      scrollChange = touchY - (windowHeight - scrollBuffer);
    }
    if (scrollChange !== 0) {
      var newScroll = scrollPosition + scrollSpeed * scrollChange;
      if (newScroll < 0) {
        newScroll = 0;
      } else if (newScroll > windowHeight) {
        newScroll = windowHeight;
      }
      window.scrollTo(0, newScroll);
    }
  }

  handleReorderMove(event) {
    var isPressed = this.state.isPressed;
    var delta = this.state.delta;
    var items = this.state.firebase.items;
    var order = this.state.firebase.order;
    var lastPressed = this.state.lastPressed;
    touchY = event.pageY;
    if (isPressed) {
      var mouse = event.pageY - delta;
      var row = util.clamp(Math.round(mouse / 50), 0, Object.keys(items).length - 1);
      var newOrder = util.reinsert(order, order.indexOf(lastPressed), row);
      this.setState({
        mouse: mouse
      });
      this.setState({
        firebase: {order: newOrder}
      });
    }
  }

  handleReorderUp() {
    if (this.state.isPressed) {
      window.getSelection().removeAllRanges();
    }
    var mySheet = document.styleSheets[0];
    var firstRule = mySheet.cssRules ? mySheet.cssRules[0] : mySheet.rules[0];
    firstRule.style.cssText = null;
    this.setState({
      isPressed: false,
      delta: 0
    });
    clearInterval(scrollInterval);
  }

  populateSuggestions(suggestions) {
    this.state.suggestions = suggestions;
    this.setState({
      suggestions: this.state.suggestions
    });
  }

  changeHighlightIndex(index) {
    this.setState({
      highlightIndex: index
    });
  }

  suggestionsMouseOver() {
    this.setState({
      suggestionsHover: true
    });
  }

  suggestionsMouseOut() {
    this.setState({
      suggestionsHover: false
    });
  }

  suggestionSubmit(index) {
    this.refs.addItemBar.suggestionSubmit(index);
  }

  render() {
    var items = !(this.state.listEmpty) ? this.state.firebase.items : {};
    return (

{this.state.name}

          {/*

*/}

                {Object.keys(items).map(this.renderItem)}
                <AddItemBar ref="addItemBar"
                            addItem={this.addItem}
                            history={this.state.firebase.history}
                            suggestions={this.state.suggestions}
                            highlightIndex={this.state.highlightIndex}
                            suggestionsHover={this.state.suggestionsHover}
                            changeHighlightIndex={this.changeHighlightIndex}
                            populateSuggestions={this.populateSuggestions} />

              <SearchSuggestions suggestionsMouseOver={this.suggestionsMouseOver}
                                 suggestionsMouseOut={this.suggestionsMouseOut}
                                 suggestions={this.state.suggestions}
                                 highlightIndex={this.state.highlightIndex}
                                 changeHighlightIndex={this.changeHighlightIndex}
                                 suggestionSubmit={this.suggestionSubmit} />

    )
  }
}

export default List;<commit_msg>Fixed mobile reorder scroll bugs.<commit_after>import React from "react";
import Item from "./Item"
import AddItemBar from "./AddItemBar";
import SearchSuggestions from "./SearchSuggestions";
import Footer from "./Footer";
import range from 'lodash.range';
import util from "../utilities";
import autobind from 'autobind-decorator';

// Firebase
import Rebase  from "re-base";
var base = Rebase.createClass("https://collaboralist.firebaseio.com/");

var deleteTimeout;
var deleteList = [];
const orderPlaceholder = 999999999999999;
var scrollInterval;
const scrollBuffer = 80;
const scrollSpeed = 0.2;
var touchY;
var scrollPosition;
var windowHeight;

@autobind
class List extends React.Component {
  constructor() {
    super();

    this.state = {
      name: "List",
      firebase: {
        items: {},
        history: {},
        order: {}
      },
      listEmpty: true,
      loaded: false,
      suggestions: [],
      highlightIndex: 0,
      suggestionsHover: false,
      autoDelete: true,
      delta: 0,
      mouse: 0,
      isPressed: false,
      lastPressed: 0
    }
  }

  componentDidMount() {
    var order = this.state.firebase.order;
    base.syncState(this.props.params.listId, {
      context: this,
      state: "firebase",
      then: function() {
        if (Object.keys(this.state.firebase.items).length > 1) {
          order[orderPlaceholder] = null;
          this.setState({
            firebase: {items: {placeholder: null}, order: order}
          });
          this.setState({
            listEmpty: false
          });
        }
        this.setState({
          loaded: true
        });
        if (Object.keys(this.state.firebase.history).length > 1) {
          this.setState({
            firebase: {history: {placeholder: null}}
          });
        }
      }
    });
    order[orderPlaceholder] = orderPlaceholder;
    this.setState({
      firebase: {items: {placeholder: true}, history: {placeholder: true}, order: order}
    });
    window.addEventListener('touchmove', this.handleTouchMove);
    window.addEventListener('touchend', this.handleReorderUp);
    window.addEventListener('mousemove', this.handleReorderMove);
    window.addEventListener('mouseup', this.handleReorderUp);
  }

  updateItem(key, entry, orderIndex) {
    var parsedEntry = util.parseEntry(entry);
    if (!parsedEntry.itemName) {
      return this.deleteItem(key, orderIndex);
    }
    this.state.firebase.items[key].count = parsedEntry.itemCount;
    this.state.firebase.items[key].name = parsedEntry.itemName;
    this.setState({
      firebase: {items: this.state.firebase.items}
    });
  }

  addItem(item) {
    var items = this.state.firebase.items;
    var order = this.state.firebase.order;
    var history = this.state.firebase.history;
    var timestamp = (new Date()).getTime();
    items["item-" + timestamp] = item;
    var itemsCount = Object.keys(items).length - 1;
    if (this.state.listEmpty) {
      items["placeholder"] = null;
      order[orderPlaceholder] = null;
      itemsCount--;
      this.setState({
        listEmpty: false
      });
    }
    order[itemsCount] = itemsCount;
    var itemName = item.name;
    history[itemName] = history.hasOwnProperty(itemName) ? history[itemName] + 1 : 1;
    if (history.hasOwnProperty("placeholder")) {
      history["placeholder"] = null;
    }
    this.setState({
      firebase: {items: items, order: order, history: history}
    });
  }

  renderItem(key, orderIndex) {
    if (key == 0) {
      return;
    }
    return (
      <Item key={key}
            index={key}
            ref={key}
            details={this.state.firebase.items[key]}
            items={this.state.firebase.items}
            checkItem={this.checkItem}
            updateItem={this.updateItem}
            setDelete={this.setDelete}
            autoDelete={this.state.autoDelete}
            mouse={this.state.mouse}
            isPressed={this.state.isPressed}
            order={this.state.firebase.order}
            initialOrder={range(Object.keys(this.state.firebase.items).length)}
            lastPressed={this.state.lastPressed}
            orderIndex={orderIndex}
            handleReorderStart={this.handleReorderStart}
            handleTouchStart={this.handleTouchStart}/>
    )
  }

  checkItem(key) {
    this.state.firebase.items[key].checked = !this.state.firebase.items[key].checked;
    this.setState({
      firebase: {items: this.state.firebase.items}
    });
  }

  setDelete(key, orderIndex) {
    clearTimeout(deleteTimeout);
    deleteList.push({key: key, orderIndex: orderIndex});
    var self = this;
    deleteTimeout = setTimeout(function() {
      deleteList.map(function(obj, index) {
        var currentOrderInd = obj.orderIndex;
        self.deleteItem(obj.key, currentOrderInd);
        for (var i = index; i < deleteList.length; i++) {
          if (deleteList[i].orderIndex > currentOrderInd) {
            deleteList[i].orderIndex--;
          }
        }
      });
      deleteList = [];
    }, 1600);
  }

  deleteItem(key, orderIndex) {
    window.removeEventListener('touchend', this.refs[key].reorderMouseUp);
    window.removeEventListener('mouseup', this.refs[key].reorderMouseUp);
    var items = this.state.firebase.items;
    var order = this.state.firebase.order;
    order.splice(order.indexOf(orderIndex), 1);
    var newOrder = order.map(function(index) {
      return index > orderIndex ? index - 1 : index;
    });
    if (Object.keys(items).length - 1 == 0) {
      this.setState({
        listEmpty: true
      });
      items["placeholder"] = true;
      newOrder[orderPlaceholder] = orderPlaceholder;
    }
    items[key] = null;
    order = newOrder;
    this.setState({
      firebase: {items: items, order: order}
    });
  }

  handleTouchStart(event, key, pressLocation) {
    this.initAutoScroll();
    scrollInterval = setInterval(this.autoScroll, 20);
    this.handleReorderStart(event.touches[0], key, pressLocation);
  }

  handleTouchMove(event) {
    if (this.state.isPressed) {
      event.preventDefault();
      this.handleReorderMove(event.touches[0]);
    }
  }

  handleReorderStart(event, pos, pressY) {
    var mySheet = document.styleSheets[0];
    var firstRule = mySheet.cssRules ? mySheet.cssRules[0] : mySheet.rules[0];
    firstRule.style.setProperty("cursor", "grabbing", "important");
    firstRule.style.setProperty("cursor", "-moz-grabbing", "important");
    firstRule.style.setProperty("cursor", "-webkit-grabbing", "important");
    this.setState({
      delta: event.pageY - pressY,
      mouse: pressY,
      isPressed: true,
      lastPressed: pos
    });
  }

  initAutoScroll() {
    touchY = -1;
    windowHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
  }

  autoScroll() {
    var scrollChange = 0;
    scrollPosition = window.scrollY;
    if (touchY >= 0 && touchY < scrollPosition + scrollBuffer) {
      scrollChange = touchY - (scrollPosition + scrollBuffer);
    } else if (touchY >=0 && touchY > windowHeight + scrollPosition - scrollBuffer) {
      scrollChange = touchY - (windowHeight + scrollPosition - scrollBuffer);
    }
    if (scrollChange !== 0) {
      var newScroll = scrollPosition + scrollSpeed * scrollChange;
      if (newScroll < 0) {
        newScroll = 0;
      } else if (newScroll > windowHeight) {
        newScroll = windowHeight;
      }
      window.scrollTo(0, newScroll);
    }
  }

  handleReorderMove(event) {
    var isPressed = this.state.isPressed;
    var delta = this.state.delta;
    var items = this.state.firebase.items;
    var order = this.state.firebase.order;
    var lastPressed = this.state.lastPressed;
    touchY = event.pageY;
    if (isPressed) {
      var mouse = event.pageY - delta;
      var row = util.clamp(Math.round(mouse / 50), 0, Object.keys(items).length - 1);
      var newOrder = util.reinsert(order, order.indexOf(lastPressed), row);
      this.setState({
        mouse: mouse
      });
      this.setState({
        firebase: {order: newOrder}
      });
    }
  }

  handleReorderUp() {
    if (this.state.isPressed) {
      window.getSelection().removeAllRanges();
    }
    var mySheet = document.styleSheets[0];
    var firstRule = mySheet.cssRules ? mySheet.cssRules[0] : mySheet.rules[0];
    firstRule.style.cssText = null;
    this.setState({
      isPressed: false,
      delta: 0
    });
    clearInterval(scrollInterval);
  }

  populateSuggestions(suggestions) {
    this.state.suggestions = suggestions;
    this.setState({
      suggestions: this.state.suggestions
    });
  }

  changeHighlightIndex(index) {
    this.setState({
      highlightIndex: index
    });
  }

  suggestionsMouseOver() {
    this.setState({
      suggestionsHover: true
    });
  }

  suggestionsMouseOut() {
    this.setState({
      suggestionsHover: false
    });
  }

  suggestionSubmit(index) {
    this.refs.addItemBar.suggestionSubmit(index);
  }

  render() {
    var items = !(this.state.listEmpty) ? this.state.firebase.items : {};
    return (

{this.state.name}

          {/*

*/}

                {Object.keys(items).map(this.renderItem)}
                <AddItemBar ref="addItemBar"
                            addItem={this.addItem}
                            history={this.state.firebase.history}
                            suggestions={this.state.suggestions}
                            highlightIndex={this.state.highlightIndex}
                            suggestionsHover={this.state.suggestionsHover}
                            changeHighlightIndex={this.changeHighlightIndex}
                            populateSuggestions={this.populateSuggestions} />

              <SearchSuggestions suggestionsMouseOver={this.suggestionsMouseOver}
                                 suggestionsMouseOut={this.suggestionsMouseOut}
                                 suggestions={this.state.suggestions}
                                 highlightIndex={this.state.highlightIndex}
                                 changeHighlightIndex={this.changeHighlightIndex}
                                 suggestionSubmit={this.suggestionSubmit} />

    )
  }
}

export default List;<|endoftext|>


<commit_before>/*global desc, task, jake, fail, complete */
"use strict";

(function () {
    desc("Default build task");
    task("default", ["lint", "test"], function () {
        console.log("\n\nBuild OK");
    });

    desc("Lint everything");
    task("lint", [], function () {
        console.log("Lint is running");

        var lint = require("./build/lint/lint_runner.js");

        var files = new jake.FileList();
        files.include("**/*.js");
        files.exclude("node_modules");
        var pass = lint.validateFileList(files.toArray(), getOptions(), getGlobals());
        if (!pass) fail("Lint failed");
    });

    desc("Test everything");
    task("test", [], function () {
        console.log("Tests go here");
        var reporter = require("nodeunit").reporters.default;
        reporter.run(['test'], null, function (failures) {
                if (failures) fail('tests fail!', failures);
                complete();
            }
        );
    }, {async: true});

    desc("Integrate");
    task("integrate", ["default"], function () {
        console.log("Integrate");
        console.log("1. Make sure git status is clean and can be pulled from integration box");
        console.log("2. Build on integration box");
        console.log("  a. Open integration box");
        console.log("  b. git pull");
        console.log("  c. jake");
        console.log("  d. If jake fails, stop! Start over!");
        console.log("3. git checkout integration");
        console.log("4. git merge master --no-ff --log");
        console.log("5. git checkout master");

    });

    function getOptions() {
        return {
            bitwise: true,
            curly: false,
            eqeqeq: true,
            forin: true,
            immed: true,
            latedef: true,
            newcap: true,
            noarg: true,
            noempty: true,
            nonew: true,
            regexp: true,
            undef: true,
            strict: true,
            trailing: true,
            node: true
        };
    }

    function getGlobals() {
        return {
            describe: false,
            it: false,
            beforeEach: false,
            afterEach: false
        };
    }
})();
<commit_msg>Changed integration workflow<commit_after>/*global desc, task, jake, fail, complete */
"use strict";

(function () {
    desc("Default build task");
    task("default", ["lint", "test"], function () {
        console.log("\n\nBuild OK");
    });

    desc("Lint everything");
    task("lint", [], function () {
        console.log("Lint is running");

        var lint = require("./build/lint/lint_runner.js");

        var files = new jake.FileList();
        files.include("**/*.js");
        files.exclude("node_modules");
        var pass = lint.validateFileList(files.toArray(), getOptions(), getGlobals());
        if (!pass) fail("Lint failed");
    });

    desc("Test everything");
    task("test", [], function () {
        console.log("Tests go here");
        var reporter = require("nodeunit").reporters.default;
        reporter.run(['test'], null, function (failures) {
                if (failures) fail('tests fail!', failures);
                complete();
            }
        );
    }, {async: true});

    desc("Integrate");
    task("integrate", ["default"], function () {
        console.log("Integrate");
        console.log("1. Make sure git status is clean and can be pulled from integration box");
        console.log("2. Build on integration box");
        console.log("  a. Open integration box");
        console.log("  b. git pull from development");
        console.log("  c. jake");
        console.log("  d. If jake fails, stop! Start over!");
        console.log("3. git checkout master");
        console.log("4. git merge development --no-ff --log");
        console.log("5. git checkout development");

    });

    function getOptions() {
        return {
            bitwise: true,
            curly: false,
            eqeqeq: true,
            forin: true,
            immed: true,
            latedef: true,
            newcap: true,
            noarg: true,
            noempty: true,
            nonew: true,
            regexp: true,
            undef: true,
            strict: true,
            trailing: true,
            node: true
        };
    }

    function getGlobals() {
        return {
            describe: false,
            it: false,
            beforeEach: false,
            afterEach: false
        };
    }
})();
<|endoftext|>


<commit_before>/*
 * Jakefile for Rimu Markup (http://github.com/srackham/rimu).
 */
'use strict'

if (parseInt(process.versions.node) < 6) {
  fail('nodejs must be version 6 or greater')
}

let pkg = require('./package.json')
let shelljs = require('shelljs')
let child_process = require('child_process')

/* Inputs and outputs */

let RIMU_LIB = 'lib/rimu.js'
let RIMU_LIB_MIN = 'lib/rimu.min.js'
let RIMU_SRC = shelljs.ls('src/rimu/*.ts')
let RIMU_TSD = 'typings/rimu.d.ts'
let TESTS = shelljs.ls('test/*.js')
let GH_PAGES_DIR = 'gh-pages/'
let RIMUC_JS = 'bin/rimuc.js'
let RIMUC_TS = 'src/rimuc/rimuc.ts'
let RIMUC_EXE = 'node ' + RIMUC_JS

let DOCS = [
  {
    src: 'README.md',
    dst: 'doc/index.html',
    title: 'Rimu Markup',
    rimucOptions: ''
  },
  {
    src: 'doc/changelog.rmu',
    dst: 'doc/changelog.html',
    title: 'Rimu Change Log',
    rimucOptions: ''
  },
  {
    src: 'doc/reference.rmu',
    dst: 'doc/reference.html',
    title: 'Rimu Reference',
    rimucOptions: '--highlightjs --prepend "{generate-examples}=\'yes\'"'
  },
  {
    src: 'doc/tips.rmu',
    dst: 'doc/tips.html',
    title: 'Rimu Tips',
    rimucOptions: '--highlightjs --mathjax --prepend "{generate-examples}=\'yes\'"'
  },
  {
    src: 'doc/rimuplayground.rmu',
    dst: 'doc/rimuplayground.html',
    title: 'Rimu Playground',
    rimucOptions: '--prepend "{generate-examples}=\'yes\'"'
  },
  {
    src: 'doc/gallery.rmu',
    dst: 'doc/gallery.html',
    title: 'Rimu layout and themes gallery',
    rimucOptions: ''
  }
]
let HTML = DOCS.map(doc => doc.dst)

/* Utility functions. */

/*
 Execute shell commands in parallel then run the `callback` when they have all finished.
 Abort immediately an error occurs unless options.executeAll is true (in which case run all commands
 commands and abort if one or more failed).
 Write command output to the inherited stdout (unless the Jake --quiet option is set).
 Print a status message when each command starts and finishes (unless the Jake --quiet option is set).

 NOTE: This function is similar to the built-in jake.exec function but is twice as fast.
 */
function exec(commands, callback, options = {}) {
  if (typeof commands === 'string') {
    commands = [commands]
  }
  let remaining = commands.length
  if (remaining === 0) {
    callback()
  }
  else {
    let error_count = 0
    commands.forEach(command => {
      jake.logger.log('STARTING: ' + command)
      child_process.exec(command, function (error, stdout, stderr) {
        jake.logger.log((error === null ? 'FINISHED: ' : 'FAILED: ') + command)
        if (!jake.program.opts.quiet) {
          jake.logger.log(stdout)
        }
        if (error !== null) {
          if (options.executeAll) {
            error_count++
          }
          else {
            fail(error, error.code)
          }
        }
        remaining--
        if (remaining === 0) {
          if (error_count > 0) {
            fail(error_count + ' errors(s)')
          }
          else {
            callback()
          }
        }
      })
    })
  }
}

/*
 Tasks

 All tasks are synchronous (another task will not run until the current task has completed).
 Consequently all task dependencies are executed asynchronously in declaration order.
 The `exec` function ensures shell commands within each task run in parallel.
 */

desc(`Run tests.`)
task('default', ['test'])

desc(`build, lint and test rimu and tools, build gh-pages, validate HTML. Use vers=x.y.z argument to set a new version number.`)
task('build', ['test', 'lint', 'version', 'build-gh-pages', 'validate-html'])

desc(`Update version number, tag and push to Github and npm. Use vers=x.y.z argument to set a new version number. Finally, rebuild and publish docs website.`)
task('release', ['build', 'tag', 'publish', 'release-gh-pages'])

desc(`Lint TypeScript, Javascript and JSON files.`)
task('lint', {async: true}, function () {
  let commands = []
    .concat(RIMU_SRC.concat([RIMUC_TS, RIMU_TSD]).map(file => 'tslint ' + file))
    .concat(TESTS.map(file => 'jshint ' + file))
// TODO: Disable jsonlint until the nomnom bug is fixed (see https://github.com/zaach/jsonlint/issues/103).
//    .concat(['jsonlint --quiet package.json'])
  exec(commands, complete)
})

desc(`Run tests (rebuild if necessary).`)
task('test', ['build-rimu', 'build-rimuc'], {async: true}, function () {
  let commands = TESTS.map(file => 'tape ' + file + ' | faucet')
  exec(commands, complete)
})

desc(`Compile and bundle rimu.js and rimu.min.js libraries and generate .map files.`)
task('build-rimu', [RIMU_LIB])

file(RIMU_LIB, RIMU_SRC, {async: true}, function () {
  exec('webpack --config ./src/rimu/webpack.config.js', complete)
})

desc(`Compile rimuc to JavaScript executable and generate .map file.`)
task('build-rimuc', {async: true}, function () {
  exec('webpack --config ./src/rimuc/webpack.config.js', function () {
    shelljs.chmod('+x', RIMUC_JS)
    complete()
  })
})

desc(`Generate HTML documentation`)
task('build-docs', ['build-rimu', 'build-gallery'], {async: true}, function () {
  let commands = DOCS.map(doc =>
    RIMUC_EXE +
    ' --no-rimurc --theme legend --custom-toc --header-links' +
    ' --layout sequel' +
    ' --output "' + doc.dst + '"' +
    ' --lang en' +
    ' --title "' + doc.title + '"' +
    ' ' + doc.rimucOptions + ' ' +
    ' ./src/examples/example-rimurc.rmu ./doc/doc-header.rmu ' + doc.src
  )
  exec(commands, complete)
})

function forEachGalleryDocument(documentCallback, layoutCallback, themeCallback) {
  ['sequel', 'classic', 'flex', 'plain'].forEach(function (layout) {
    if (layoutCallback) layoutCallback(layout);
    if (layout === 'plain') {
      documentCallback('--layout plain --no-toc', 'plain-example.html')
      return
    }
    ['legend', 'vintage', 'graystone'].forEach(function (theme) {
      if (themeCallback) themeCallback(layout, theme);
      ['', 'dropdown-toc', 'no-toc'].forEach(function (variant) {
        let option = variant;
        switch (variant) {
          case 'dropdown-toc':
            if (layout !== 'classic') return
            else option = '--prepend "{--dropdown-toc}=\'yes\'"';
            break;
          case 'no-toc':
            option = '--no-toc';
            break;
        }
        let options = '--layout ' + layout + ' --theme ' + theme + ' ' + option
        options = options.trim()
        let outfile = layout + '-' + theme + '-' + variant + '-example.html'
        outfile = outfile.replace('--', '-')
        documentCallback(options, outfile, layout, theme)
      })
    })
  })
}

desc(`Generate gallery documentation examples`)
task('build-gallery', ['build-rimu'], {async: true}, function () {
  let commands = [];
  forEachGalleryDocument(function (options, outfile, layout, theme) {
    let command =
      RIMUC_EXE +
      ' --custom-toc' +
      ' --no-rimurc' +
      ' ' + options +
      ' --output ./doc/' + outfile +
      ' --prepend "{gallery-options}=\'' + options.replace(/(["{])/g, '\\$1') + '\'"' +
      ' ./src/examples/example-rimurc.rmu' +
      ' ./doc/doc-header.rmu' +
      ' ./doc/gallery-example-template.rmu'
    commands.push(command)
  })
  exec(commands, complete)
})

desc(`Generate gallery index Rimu markup for doc/gallery.rmu`)
task('gallery-markup', function () {
  forEachGalleryDocument(function (options, outfile, layout, theme) {
      let link = '[`' + options.replace(/{/g, '\\{') + '`](' + outfile + ')'
      console.log('- ' + link)
    },
    function (layout) {
      console.log('\n\n## ' + layout + ' layout');
    },
    function (layout, theme) {
      console.log('\n### ' + theme + ' theme');
    })
})

desc(`Validate HTML documents.`)
task('validate-html', {async: true}, function () {
  let commands = HTML.map(file => 'html-validator --verbose --format=text --file=' + file)
  exec(commands, complete, {executeAll: true})
})

desc(`Display or update the project version number. Use vers=x.y.z argument to set a new version number.`)
task('version', {async: true}, function () {
  let version = process.env.vers
  if (!version) {
    console.log(`version: ${pkg.version}`)
    complete()
  }
  else {
    if (!version.match(/^\d+\.\d+\.\d+$/)) {
      fail('Invalid version number: ' + version + '\n')
    }
    shelljs.sed('-i', /(\s*"version"\s*:\s*)"\d+\.\d+\.\d+"/, `$1"${version}"`, 'package.json')
    pkg.version = version
    exec('git commit -m "Bump version number." package.json', complete)
  }
})

desc(`Create tag ${pkg.version}`)
task('tag', ['test'], {async: true}, function () {
  exec('git tag -a -m "Tag ' + pkg.version + '" ' + pkg.version, complete)
})

desc(`Commit changes to local Git repo.`)
task('commit', ['test'], {async: true}, function () {
  jake.exec('git commit -a', {interactive: true}, complete)
})

desc(`Push to Github and publish to npm.`)
task('publish', ['push', 'publish-npm'])

desc(`Push local commits to Github.`)
task('push', ['test'], {async: true}, function () {
  exec('git push -u --tags origin master', complete)
})

desc(`Publish to npm.`)
task('publish-npm', {async: true}, ['test', 'build-rimu'], function () {
  exec('npm publish', complete)
})

desc(`Rebuild and validate documentation then commit and publish to GitHub Pages`)
task('release-gh-pages', ['build-gh-pages', 'commit-gh-pages', 'push-gh-pages'])

desc(`Generate documentation and copy to local gh-pages repo`)
task('build-gh-pages', ['build-rimu', 'build-docs'], function () {
  shelljs.cp('-f', HTML.concat(RIMU_LIB_MIN), GH_PAGES_DIR)
  shelljs.cp('-f', 'doc/*-example.html', GH_PAGES_DIR)
})

desc(`Commit changes to local gh-pages repo. Use msg='commit message' to set a custom commit message.`)
task('commit-gh-pages', ['test'], {async: true}, function () {
  let msg = process.env.msg
  if (!msg) {
    msg = 'rebuilt project website'
  }
  shelljs.cd(GH_PAGES_DIR)
  exec('git commit -a -m "' + msg + '"', function () {
    shelljs.cd('..')
    complete()
  })
})

desc(`Push gh-pages commits to Github.`)
task('push-gh-pages', ['test'], {async: true}, function () {
  shelljs.cd(GH_PAGES_DIR)
  exec('git push origin gh-pages', function () {
    shelljs.cd('..')
    complete()
  })
})
<commit_msg>docs: Enable source code highlighting in README.<commit_after>/*
 * Jakefile for Rimu Markup (http://github.com/srackham/rimu).
 */
'use strict'

if (parseInt(process.versions.node) < 6) {
  fail('nodejs must be version 6 or greater')
}

let pkg = require('./package.json')
let shelljs = require('shelljs')
let child_process = require('child_process')

/* Inputs and outputs */

let RIMU_LIB = 'lib/rimu.js'
let RIMU_LIB_MIN = 'lib/rimu.min.js'
let RIMU_SRC = shelljs.ls('src/rimu/*.ts')
let RIMU_TSD = 'typings/rimu.d.ts'
let TESTS = shelljs.ls('test/*.js')
let GH_PAGES_DIR = 'gh-pages/'
let RIMUC_JS = 'bin/rimuc.js'
let RIMUC_TS = 'src/rimuc/rimuc.ts'
let RIMUC_EXE = 'node ' + RIMUC_JS

let DOCS = [
  {
    src: 'README.md',
    dst: 'doc/index.html',
    title: 'Rimu Markup',
    rimucOptions: '--highlightjs'
  },
  {
    src: 'doc/changelog.rmu',
    dst: 'doc/changelog.html',
    title: 'Rimu Change Log',
    rimucOptions: ''
  },
  {
    src: 'doc/reference.rmu',
    dst: 'doc/reference.html',
    title: 'Rimu Reference',
    rimucOptions: '--highlightjs --prepend "{generate-examples}=\'yes\'"'
  },
  {
    src: 'doc/tips.rmu',
    dst: 'doc/tips.html',
    title: 'Rimu Tips',
    rimucOptions: '--highlightjs --mathjax --prepend "{generate-examples}=\'yes\'"'
  },
  {
    src: 'doc/rimuplayground.rmu',
    dst: 'doc/rimuplayground.html',
    title: 'Rimu Playground',
    rimucOptions: '--prepend "{generate-examples}=\'yes\'"'
  },
  {
    src: 'doc/gallery.rmu',
    dst: 'doc/gallery.html',
    title: 'Rimu layout and themes gallery',
    rimucOptions: ''
  }
]
let HTML = DOCS.map(doc => doc.dst)

/* Utility functions. */

/*
 Execute shell commands in parallel then run the `callback` when they have all finished.
 Abort immediately an error occurs unless options.executeAll is true (in which case run all commands
 commands and abort if one or more failed).
 Write command output to the inherited stdout (unless the Jake --quiet option is set).
 Print a status message when each command starts and finishes (unless the Jake --quiet option is set).

 NOTE: This function is similar to the built-in jake.exec function but is twice as fast.
 */
function exec(commands, callback, options = {}) {
  if (typeof commands === 'string') {
    commands = [commands]
  }
  let remaining = commands.length
  if (remaining === 0) {
    callback()
  }
  else {
    let error_count = 0
    commands.forEach(command => {
      jake.logger.log('STARTING: ' + command)
      child_process.exec(command, function (error, stdout, stderr) {
        jake.logger.log((error === null ? 'FINISHED: ' : 'FAILED: ') + command)
        if (!jake.program.opts.quiet) {
          jake.logger.log(stdout)
        }
        if (error !== null) {
          if (options.executeAll) {
            error_count++
          }
          else {
            fail(error, error.code)
          }
        }
        remaining--
        if (remaining === 0) {
          if (error_count > 0) {
            fail(error_count + ' errors(s)')
          }
          else {
            callback()
          }
        }
      })
    })
  }
}

/*
 Tasks

 All tasks are synchronous (another task will not run until the current task has completed).
 Consequently all task dependencies are executed asynchronously in declaration order.
 The `exec` function ensures shell commands within each task run in parallel.
 */

desc(`Run tests.`)
task('default', ['test'])

desc(`build, lint and test rimu and tools, build gh-pages, validate HTML. Use vers=x.y.z argument to set a new version number.`)
task('build', ['test', 'lint', 'version', 'build-gh-pages', 'validate-html'])

desc(`Update version number, tag and push to Github and npm. Use vers=x.y.z argument to set a new version number. Finally, rebuild and publish docs website.`)
task('release', ['build', 'tag', 'publish', 'release-gh-pages'])

desc(`Lint TypeScript, Javascript and JSON files.`)
task('lint', {async: true}, function () {
  let commands = []
    .concat(RIMU_SRC.concat([RIMUC_TS, RIMU_TSD]).map(file => 'tslint ' + file))
    .concat(TESTS.map(file => 'jshint ' + file))
// TODO: Disable jsonlint until the nomnom bug is fixed (see https://github.com/zaach/jsonlint/issues/103).
//    .concat(['jsonlint --quiet package.json'])
  exec(commands, complete)
})

desc(`Run tests (rebuild if necessary).`)
task('test', ['build-rimu', 'build-rimuc'], {async: true}, function () {
  let commands = TESTS.map(file => 'tape ' + file + ' | faucet')
  exec(commands, complete)
})

desc(`Compile and bundle rimu.js and rimu.min.js libraries and generate .map files.`)
task('build-rimu', [RIMU_LIB])

file(RIMU_LIB, RIMU_SRC, {async: true}, function () {
  exec('webpack --config ./src/rimu/webpack.config.js', complete)
})

desc(`Compile rimuc to JavaScript executable and generate .map file.`)
task('build-rimuc', {async: true}, function () {
  exec('webpack --config ./src/rimuc/webpack.config.js', function () {
    shelljs.chmod('+x', RIMUC_JS)
    complete()
  })
})

desc(`Generate HTML documentation`)
task('build-docs', ['build-rimu', 'build-gallery'], {async: true}, function () {
  let commands = DOCS.map(doc =>
    RIMUC_EXE +
    ' --no-rimurc --theme legend --custom-toc --header-links' +
    ' --layout sequel' +
    ' --output "' + doc.dst + '"' +
    ' --lang en' +
    ' --title "' + doc.title + '"' +
    ' ' + doc.rimucOptions + ' ' +
    ' ./src/examples/example-rimurc.rmu ./doc/doc-header.rmu ' + doc.src
  )
  exec(commands, complete)
})

function forEachGalleryDocument(documentCallback, layoutCallback, themeCallback) {
  ['sequel', 'classic', 'flex', 'plain'].forEach(function (layout) {
    if (layoutCallback) layoutCallback(layout);
    if (layout === 'plain') {
      documentCallback('--layout plain --no-toc', 'plain-example.html')
      return
    }
    ['legend', 'vintage', 'graystone'].forEach(function (theme) {
      if (themeCallback) themeCallback(layout, theme);
      ['', 'dropdown-toc', 'no-toc'].forEach(function (variant) {
        let option = variant;
        switch (variant) {
          case 'dropdown-toc':
            if (layout !== 'classic') return
            else option = '--prepend "{--dropdown-toc}=\'yes\'"';
            break;
          case 'no-toc':
            option = '--no-toc';
            break;
        }
        let options = '--layout ' + layout + ' --theme ' + theme + ' ' + option
        options = options.trim()
        let outfile = layout + '-' + theme + '-' + variant + '-example.html'
        outfile = outfile.replace('--', '-')
        documentCallback(options, outfile, layout, theme)
      })
    })
  })
}

desc(`Generate gallery documentation examples`)
task('build-gallery', ['build-rimu'], {async: true}, function () {
  let commands = [];
  forEachGalleryDocument(function (options, outfile, layout, theme) {
    let command =
      RIMUC_EXE +
      ' --custom-toc' +
      ' --no-rimurc' +
      ' ' + options +
      ' --output ./doc/' + outfile +
      ' --prepend "{gallery-options}=\'' + options.replace(/(["{])/g, '\\$1') + '\'"' +
      ' ./src/examples/example-rimurc.rmu' +
      ' ./doc/doc-header.rmu' +
      ' ./doc/gallery-example-template.rmu'
    commands.push(command)
  })
  exec(commands, complete)
})

desc(`Generate gallery index Rimu markup for doc/gallery.rmu`)
task('gallery-markup', function () {
  forEachGalleryDocument(function (options, outfile, layout, theme) {
      let link = '[`' + options.replace(/{/g, '\\{') + '`](' + outfile + ')'
      console.log('- ' + link)
    },
    function (layout) {
      console.log('\n\n## ' + layout + ' layout');
    },
    function (layout, theme) {
      console.log('\n### ' + theme + ' theme');
    })
})

desc(`Validate HTML documents.`)
task('validate-html', {async: true}, function () {
  let commands = HTML.map(file => 'html-validator --verbose --format=text --file=' + file)
  exec(commands, complete, {executeAll: true})
})

desc(`Display or update the project version number. Use vers=x.y.z argument to set a new version number.`)
task('version', {async: true}, function () {
  let version = process.env.vers
  if (!version) {
    console.log(`version: ${pkg.version}`)
    complete()
  }
  else {
    if (!version.match(/^\d+\.\d+\.\d+$/)) {
      fail('Invalid version number: ' + version + '\n')
    }
    shelljs.sed('-i', /(\s*"version"\s*:\s*)"\d+\.\d+\.\d+"/, `$1"${version}"`, 'package.json')
    pkg.version = version
    exec('git commit -m "Bump version number." package.json', complete)
  }
})

desc(`Create tag ${pkg.version}`)
task('tag', ['test'], {async: true}, function () {
  exec('git tag -a -m "Tag ' + pkg.version + '" ' + pkg.version, complete)
})

desc(`Commit changes to local Git repo.`)
task('commit', ['test'], {async: true}, function () {
  jake.exec('git commit -a', {interactive: true}, complete)
})

desc(`Push to Github and publish to npm.`)
task('publish', ['push', 'publish-npm'])

desc(`Push local commits to Github.`)
task('push', ['test'], {async: true}, function () {
  exec('git push -u --tags origin master', complete)
})

desc(`Publish to npm.`)
task('publish-npm', {async: true}, ['test', 'build-rimu'], function () {
  exec('npm publish', complete)
})

desc(`Rebuild and validate documentation then commit and publish to GitHub Pages`)
task('release-gh-pages', ['build-gh-pages', 'commit-gh-pages', 'push-gh-pages'])

desc(`Generate documentation and copy to local gh-pages repo`)
task('build-gh-pages', ['build-rimu', 'build-docs'], function () {
  shelljs.cp('-f', HTML.concat(RIMU_LIB_MIN), GH_PAGES_DIR)
  shelljs.cp('-f', 'doc/*-example.html', GH_PAGES_DIR)
})

desc(`Commit changes to local gh-pages repo. Use msg='commit message' to set a custom commit message.`)
task('commit-gh-pages', ['test'], {async: true}, function () {
  let msg = process.env.msg
  if (!msg) {
    msg = 'rebuilt project website'
  }
  shelljs.cd(GH_PAGES_DIR)
  exec('git commit -a -m "' + msg + '"', function () {
    shelljs.cd('..')
    complete()
  })
})

desc(`Push gh-pages commits to Github.`)
task('push-gh-pages', ['test'], {async: true}, function () {
  shelljs.cd(GH_PAGES_DIR)
  exec('git push origin gh-pages', function () {
    shelljs.cd('..')
    complete()
  })
})
<|endoftext|>


<commit_before>// TODO
/*
  - load plug-ins
  - select transport/driver
*/

var jake = require("jake")
  , gzip = require('gzip')
  , sys = require("sys")
  , path = require("path")
  , fs = require("fs")
  , util = require('util')
  , files = ['MIT-LICENSE', 'snake', 'base', 'web.db', 'vql']
  , i = 0
  , code = []
  , outputFile = "build/snake.js"
  , outputMinFile = "build/snake.min.js"
  , outputDevFile = "build/snake.dev.js"
  , gzippedFile = "build/snake.js.gz"
  , sys = require('sys')
  , exec = require('child_process').exec;

function jshint() {
  // Test code using jshint
  // TODO check to make sure jshint is installed
  console.log("Started Lint testing " + outputFile);
  exec("jshint " + outputFile + " --config jshint.json", function (error, stdout, stderr) {
    if (stdout) {
      console.log("--jshint--");
      console.log(stdout);
    }
    if (error !== null) {
      console.log('exec error: ' + error);
    }
  });
}

function createDirs() {
  // create directory for build
  exec("mkdir build");

  // create directory for Docs
  exec("mkdir docs");
}

task("default", [], function () {

  var finishr = function () {
    fs.readFile(outputFile, "utf8", function (err, text) {
      if (err) {
        throw err;
      }

      // test code with jshint
      jshint();

      // Minimify the code using uglifyJS
      // TODO check that uglify is installed
      console.log("Compressing " + outputFile + " using UglifyJS");
      exec("uglifyjs " + outputFile + " > " + outputMinFile, function (error, stdout, stderr) {
        if (stdout) {
          console.log("--UglifyJS--");
          console.log(stdout);
        }

        if (error !== null) {
          console.log('exec error: ' + error);
        }
      });

    });
  },

  writeFile = function () {
    createDirs();

    // delete the file first
    fs.unlink(outputFile);

    // write all files into a snake build
    fs.writeFile(outputFile, code.join("\n"), 'utf8', function (err) {
      console.log("Wrote to " + outputFile);

      if (err) {
        throw err;
      }

      // run minimifier, jshint and gzip
      finishr();
    });

    // write files into a dev version
    fs.writeFile(outputDevFile, code.join("\n") + "\n(function () { Snake.debug = true; }());", 'utf8', function (err) {
      console.log("Wrote to " + outputDevFile);
    });
  },

  readFile = function () {
    if (code.length === files.length) {
      writeFile();
    } else {
      var inputFile = null;

      switch (files[i]) {
      case "MIT-LICENSE":
        inputFile = files[i];
        break;
      default:
        inputFile = "src/" + files[i] + ".js";
      }
      console.log("Merging " + inputFile);

      fs.readFile(inputFile, 'utf8', function (err, data) {
        if (err) {
          throw err;
        }

        // join all the files
        code.push(data);

        // read the next file...
        readFile();
      });

      i = i + 1;
    }
  };

  readFile();

}, true);

task("docs", [], function () {
  // Build docs
  console.log("Building documentation...");
  exec("java -jar vendor/jsdoc/jsrun.jar vendor/jsdoc/app/run.js -c=jsdoc.conf", function () {
    console.log("Documentation available in docs/");
  });
}, true);

task("jshint", [], function () {
  jshint();
}, true);

task("gzip", [], function () {
  fs.readFile(outputFile, "utf8", function (err, text) {
    // NOTE: requires gzip (npm install gzip)
    // TODO check for gzip installed!
    console.log("Compressing " + outputFile + " using node-gzip");
    gzip(text, function (err, data) {
      // Save gzip output to a file
      fs.writeFile(gzippedFile, data, 'utf8', function (err) {
        console.log("gzipped file: " + gzippedFile);
        fs.stat(gzippedFile, function (err, stats) {
          console.log("gzipped size: " + stats.size);
        });
      });
    });
  });
}, true);

task("mkdir", [], function () {
  createDirs();
}, true);
<commit_msg>refactoring jakefile, adding mysql<commit_after>// TODO
/*
  - load plug-ins
  - select transport/driver
*/

var gzip = require('gzip'),
    sys = require("sys"),
    fs = require("fs"),
    files = ['MIT-LICENSE', 'snake', 'base', 'vql'],
    output = {
      file: "build/snake.js",
      min: "build/snake.min.js",
      dev: "build/snake.dev.js",
      gzip: "build/snake.js.gz"
    },
    exec = require('child_process').exec,
    Jake = null;

Jake = {
  jshint: function () {
    // Test code using jshint
    // TODO check to make sure jshint is installed
    console.log("Started Lint testing " + output.file);
    exec("jshint " + output.file + " --config jshint.json", function (error, stdout, stderr) {
      if (stdout) {
        console.log("--jshint--");
        console.log(stdout);
      }
      if (error !== null) {
        console.log('exec error: ' + error);
      }
    });
  },

  createDirs: function () {
    // create directory for build
    exec("mkdir build");

    // create directory for Docs
    exec("mkdir docs");
  },

  compress: function () {
    // Minimify the code using uglifyJS
    // TODO check that uglify is installed
    console.log("Compressing " + output.file + " using UglifyJS");
    exec("uglifyjs " + output.file + " > " + output.min, function (error, stdout, stderr) {
      if (stdout) {
        console.log("--UglifyJS--");
        console.log(stdout);
      }

      if (error !== null) {
        console.log('exec error: ' + error);
      }
    });
  },

  main: function () {
    var finishr = function () {
      fs.readFile(output.file, "utf8", function (err, text) {
        if (err) {
          throw err;
        }

        // test code with jshint
        Jake.jshint();

        // minimify using uglifyjs
        Jake.compress();
      });
    },

    writeFile = function (code) {
      Jake.createDirs();

      // delete the file first
      fs.unlink(output.file);

      // write all files into a snake build
      fs.writeFile(output.file, code.join("\n"), 'utf8', function (err) {
        console.log("Wrote to " + output.file);

        if (err) {
          throw err;
        }

        // run minimifier and jshint
        finishr();
      });

      // write files into a dev version
      fs.writeFile(output.dev, code.join("\n") + "\n(function () { Snake.debug = true; }());", 'utf8', function (err) {
        console.log("Wrote to " + output.dev);
      });
    },

    readFile = function (code) {
      if (files.length === 0) {
        writeFile(code);
      } else {
        var inputFile = null;

        switch (files[0]) {
        case "MIT-LICENSE":
          inputFile = files[0];
          break;
        default:
          inputFile = "src/" + files[0] + ".js";
        }
        console.log("Merging " + inputFile);

        fs.readFile(inputFile, 'utf8', function (err, data) {
          if (err) {
            throw err;
          }

          // join all the files
          code.push(data);

          // read the next file...
          readFile(code);
        });

        files.shift();
      }
    };

    readFile([]);
  }
}

/**
  Tasks
  */

/** Web SQL Database */
task("default", [], function () {
  files.push('web.db');
  Jake.main();
}, true);

/** MySQL */
task("mysql", [], function () {
  files.push('mysql.db');
  Jake.main();
}, true);

/** Tasks */

task("docs", [], function () {
  // Build docs
  console.log("Building documentation...");
  exec("java -jar vendor/jsdoc/jsrun.jar vendor/jsdoc/app/run.js -c=jsdoc.conf", function () {
    console.log("Documentation available in docs/");
  });
}, true);

task("jshint", [], function () {
  Jake.jshint();
}, true);

task("uglify", [], function () {
  Jake.compress();
}, true);

task("gzip", [], function () {
  fs.readFile(output.file, "utf8", function (err, text) {
    // NOTE: requires gzip (npm install gzip)
    // TODO check for gzip installed!
    console.log("Compressing " + output.file + " using node-gzip");
    gzip(text, function (err, data) {
      // Save gzip output to a file
      fs.writeFile(output.gzip, data, 'utf8', function (err) {
        console.log("gzipped file: " + output.gzip);
        fs.stat(output.gzip, function (err, stats) {
          console.log("gzipped size: " + stats.size);
        });
      });
    });
  });
}, true);

task("mkdir", [], function () {
  Jake.createDirs();
}, true);

/*
task("node", [], function () {
  console.log("Building node file");
  fs.readFile(output.file, "utf8", function (err, text) {
    fs.writeFile("lib/index.js", text + "\nmodule.exports = Snake", 'utf8', function (err) {
      if (!err) {
        console.log("Wrote to lib/index.js");
      }
    });
  });
}, true);
*/
<|endoftext|>


<commit_before>'use strict';

describe('LEM2 Module', function () {
    ("should exist", function () {
        expect(LEM2).to.not.be.undefined;
    });

    // Properties

    const propertyTests = [
        { "name": "dataset", "type": "array", "value": [] },
        { "name": "blocks", "type": "object", "value": {} },
        { "name": "datasetConcepts", "type": "array", "value": [] },
        { "name": "goal", "type": "set", "value": new Set() },
        { "name": "singleLocalCovering", "type": "array", "value": [] },
        { "name": "concept", "type": "object", "value": { "decision": "", "value": "", "cases": new Set() } }
    ];

    propertyTests.forEach(function (property) {
        it("should have a " + property.name + " " + property.type, function () {
            expect(LEM2).to.have.property(property.name)
                .that.is.a(property.type)
                .that.deep.equals(property.value);
        });
    });

    // Functions

    const functionTests = [
        { "name": "invokeProcedure" },
        { "name": "newConcepts" },
        { "name": "newAttributeValueBlocks" },
        { "name": "getCasesCoveredByRule" },
        { "name": "getCasesCoveredByRuleset" },
        { "name": "compressRuleset" },
        { "name": "initialize" },
        { "name": "newRuleset" },
        { "name": "compressRule" },
        { "name": "initializeProcedure" },
        { "name": "newGoalBlockIntersections" },
        { "name": "selectBestBlock" },
        { "name": "newRule" },
        { "name": "findCondition" },
        { "name": "convertToSetValuedDataset" },
    ];

    functionTests.forEach(function (funct) {
        it("should have an " + funct.name + " function", function () {
            expect(LEM2).to.have.property(funct.name)
                .that.is.a('function');
        });
    });
});
<commit_msg>Fix single qutoes in module tests<commit_after>'use strict';

describe('LEM2 Module', function () {
    ("should exist", function () {
        expect(LEM2).to.not.be.undefined;
    });

    // Properties

    const propertyTests = [
        { "name": "dataset", "type": "array", "value": [] },
        { "name": "blocks", "type": "object", "value": {} },
        { "name": "datasetConcepts", "type": "array", "value": [] },
        { "name": "goal", "type": "set", "value": new Set() },
        { "name": "singleLocalCovering", "type": "array", "value": [] },
        { "name": "concept", "type": "object", "value": { "decision": "", "value": "", "cases": new Set() } }
    ];

    propertyTests.forEach(function (property) {
        it("should have a " + property.name + " " + property.type, function () {
            expect(LEM2).to.have.property(property.name)
                .that.is.a(property.type)
                .that.deep.equals(property.value);
        });
    });

    // Functions

    const functionTests = [
        { "name": "invokeProcedure" },
        { "name": "newConcepts" },
        { "name": "newAttributeValueBlocks" },
        { "name": "getCasesCoveredByRule" },
        { "name": "getCasesCoveredByRuleset" },
        { "name": "compressRuleset" },
        { "name": "initialize" },
        { "name": "newRuleset" },
        { "name": "compressRule" },
        { "name": "initializeProcedure" },
        { "name": "newGoalBlockIntersections" },
        { "name": "selectBestBlock" },
        { "name": "newRule" },
        { "name": "findCondition" },
        { "name": "convertToSetValuedDataset" },
    ];

    functionTests.forEach(function (funct) {
        it("should have an " + funct.name + " function", function () {
            expect(LEM2).to.have.property(funct.name)
                .that.is.a("function");
        });
    });
});
<|endoftext|>


<commit_before>describe('provider', function () {

    var easyMask;
    beforeEach(module('wt.easy'));

    describe('mask registry', function () {
        var someMaskName = 'name';
        var someMaskValue = '999.99';

        describe('can retrieve a published mask', function () {
            var easyMaskProvider;
            beforeEach(function () {
                module(function (_easyMaskProvider_) {
                    easyMaskProvider = _easyMaskProvider_;
                    easyMaskProvider.publishMask(someMaskName, someMaskValue);
                });
            });

            it('by name', function () {
                inject(function (easyMask) {
                    var mask = easyMask.getMask(someMaskName);
                    expect(mask).toEqual(someMaskValue);
                });
            });

            it('the comparison is case insensitive', function () {
                inject(function (easyMask) {
                    var mask1 = easyMask.getMask(someMaskName.toLowerCase());
                    expect(mask1).toEqual(someMaskValue);

                    var mask2 = easyMask.getMask(someMaskName.toUpperCase());
                    expect(mask2).toEqual(someMaskValue);
                });
            });
        });
    });
});
<commit_msg>refactor(tests): simplify unit tests<commit_after>/* global inject */
/// <reference path="../typings/jasmine/jasmine.d.ts"/>
describe('provider', function () {

    var easyMaskProvider;
    var easyMask;
    beforeEach(module('wt.easy'));

    describe('mask registry', function () {
        var someMaskName = 'name';
        var someMaskValue = '999.99';

        describe('can retrieve a published mask', function () {
            beforeEach(function () {
                module(function (_easyMaskProvider_) {
                    easyMaskProvider = _easyMaskProvider_;
                    easyMaskProvider.publishMask(someMaskName, someMaskValue);
                });
            });
            beforeEach(function () {
                inject(function (_easyMask_) {
                    easyMask = _easyMask_;
                });
            });

            it('by name', function () {
                var mask = easyMask.getMask(someMaskName);
                expect(mask).toEqual(someMaskValue);
            });

            it('the comparison is case insensitive', function () {
                var mask1 = easyMask.getMask(someMaskName.toLowerCase());
                expect(mask1).toEqual(someMaskValue);

                var mask2 = easyMask.getMask(someMaskName.toUpperCase());
                expect(mask2).toEqual(someMaskValue);
            });
        });
    });
});
<|endoftext|>


<commit_before>/**
 * @requires OpenLayers/Control.js
 * @requires OpenLayers/Util/hideFromOldIE.js
 */
OpenLayers.Control.Print =
    OpenLayers.Class(OpenLayers.Control, {

    // remember that suffixes are added to this class: ItemActive or ItemInactive
    btnClass: 'olControlButtonPrint',
    classElemToHide:  ['.searchDiv', '.logoDiv', '.olControlNoSelect', '.selZoom'],
    elemsToHideSelector: '',
    title: null,
    widget: null,
    cnt: null,

    initialize: function(options) {
        OpenLayers.Control.prototype.initialize.apply(this, [options]);

        this.type = OpenLayers.Control.TYPE_BUTTON;

        this.title = OpenLayers.Lang.translate('Print');
    }, // initialize

    draw: function () {
        var self   = this, cName = 'btn nkButton';
	    var mapped = 'OpenLayers_Control_Print' + self.map.id;
        var btn    = OpenLayers.Util.createButton( mapped, null, null, null, 'static');

        OpenLayers.Event.observe(btn, 'click',
            OpenLayers.Function.bind( self.toggleControls, self )
        );

        OpenLayers.Util.appendToggleToolClick({'self':self});

        btn.title = self.title;
        btn.className = btn.className === "" ? cName : btn.className + " " + cName;
        btn.innerHTML = OpenLayers.Util.hideFromOldIE('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" preserveAspectRatio="xMinYMid meet" class="icon print"><path d="M17.617,2H6.383v3.299h11.234V2z M21.026,6.487H2.974C2.437,6.487,2,6.934,2,7.483v7.327h2.934v-4.448h14.133v4.448H22V7.483C22,6.934,21.564,6.487,21.026,6.487z M19.885,8.929c-0.43,0-0.779-0.356-0.779-0.796s0.35-0.797,0.779-0.797s0.778,0.357,0.778,0.797S20.314,8.929,19.885,8.929z M16.787,20.828h-4.701c-1.703,0-0.883-4.129-0.883-4.129s-3.937,0.979-3.987-0.867v-3.79H6.069v5.339l0.336,0.344L10.586,22h7.347v-9.958h-1.146V20.828z" /></svg>');

        if (self.div == null) {
            self.div = btn;
        } else {
            self.div.appendChild(btn);
        }

    	self.cnt = document.createElement("div");
        OpenLayers.Element.addClass(self.cnt, "cnt");

        self.widget = OpenLayers.Util.createWidget( self.cnt, 1 );
        self.div.appendChild( self.widget );

        return self.div;
    }, // draw

    printPage: function () {
        if (window && window.print) {
            window.print();
        }
    },

    hideControls: function () {
        OpenLayers.Element.removeClass( this.div, 'active' );
        map.events.unregister('moveend', map, this.onMapMoveEnd);
    }, //hideControls

    showControls: function () {
        var self = this, btn = self.div;
        OpenLayers.Util.renderToggleToolClick({'self':self});
        OpenLayers.Element.addClass( self.div, 'active' );
        self.getContent(self.cnt);
        map.events.register('moveend', map, this.onMapMoveEnd);
    }, // showControls

    enable: function () {
    }, // enable

    disable: function () {
    }, // disable

    toggleControls: function () {
        OpenLayers.Element.hasClass(this.div, 'active') ? this.hideControls() : this.showControls();
    },//togglecontrols

    getContent: function (holder) {
        var self = this;

        if (!holder) return;
        if (holder.childNodes.length > 0) return;

        var center = map.getCenter();
        var params = [map.getZoom()];
        params.push(Math.round(center.lon));
        params.push(Math.round(center.lat));
        if (params[0] > 13) params[0] = 13;

        var html = ''
        + '
Velg type utskrift
'
        + '
'
        + '
'
        + '<button class="print-btn" id="print-btn-print">Skriv ut kartutsnitt fra skjerm</button>'
        + '
'
        + '
'
        + 'Lag turkart for utskrift'
        + '
'
        + '
'
        + '';

        holder.innerHTML = html;

        var printBtnPrint = document.getElementById('print-btn-print');
        if (printBtnPrint !== null) {
            OpenLayers.Event.observe(printBtnPrint, 'click',
                OpenLayers.Function.bind(self.printPage, self)
            );
        }
    },//getContent

    onMapMoveEnd: function (e) {
        var printBtnOpen = document.getElementById('print-btn-open');
        if (printBtnOpen !== null) {
            var params = [e.object.zoom, Math.round(e.object.center.lon), Math.round(e.object.center.lat)];
            if (params[0] > 13) params[0] = 13;
            var url = printBtnOpen.getAttribute('href').split('#').shift() + '#' + params.join('/');
            printBtnOpen.setAttribute('href', url);
        }
    },//onMapMoveEnd

    CLASS_NAME: "OpenLayers.Control.Print"
}); // OpenLayers.Control.Print
<commit_msg>Removed 'dev' from print widget<commit_after>/**
 * @requires OpenLayers/Control.js
 * @requires OpenLayers/Util/hideFromOldIE.js
 */
OpenLayers.Control.Print =
    OpenLayers.Class(OpenLayers.Control, {

    // remember that suffixes are added to this class: ItemActive or ItemInactive
    btnClass: 'olControlButtonPrint',
    classElemToHide:  ['.searchDiv', '.logoDiv', '.olControlNoSelect', '.selZoom'],
    elemsToHideSelector: '',
    title: null,
    widget: null,
    cnt: null,

    initialize: function(options) {
        OpenLayers.Control.prototype.initialize.apply(this, [options]);

        this.type = OpenLayers.Control.TYPE_BUTTON;

        this.title = OpenLayers.Lang.translate('Print');
    }, // initialize

    draw: function () {
        var self   = this, cName = 'btn nkButton';
	    var mapped = 'OpenLayers_Control_Print' + self.map.id;
        var btn    = OpenLayers.Util.createButton( mapped, null, null, null, 'static');

        OpenLayers.Event.observe(btn, 'click',
            OpenLayers.Function.bind( self.toggleControls, self )
        );

        OpenLayers.Util.appendToggleToolClick({'self':self});

        btn.title = self.title;
        btn.className = btn.className === "" ? cName : btn.className + " " + cName;
        btn.innerHTML = OpenLayers.Util.hideFromOldIE('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" preserveAspectRatio="xMinYMid meet" class="icon print"><path d="M17.617,2H6.383v3.299h11.234V2z M21.026,6.487H2.974C2.437,6.487,2,6.934,2,7.483v7.327h2.934v-4.448h14.133v4.448H22V7.483C22,6.934,21.564,6.487,21.026,6.487z M19.885,8.929c-0.43,0-0.779-0.356-0.779-0.796s0.35-0.797,0.779-0.797s0.778,0.357,0.778,0.797S20.314,8.929,19.885,8.929z M16.787,20.828h-4.701c-1.703,0-0.883-4.129-0.883-4.129s-3.937,0.979-3.987-0.867v-3.79H6.069v5.339l0.336,0.344L10.586,22h7.347v-9.958h-1.146V20.828z" /></svg>');

        if (self.div == null) {
            self.div = btn;
        } else {
            self.div.appendChild(btn);
        }

    	self.cnt = document.createElement("div");
        OpenLayers.Element.addClass(self.cnt, "cnt");

        self.widget = OpenLayers.Util.createWidget( self.cnt, 1 );
        self.div.appendChild( self.widget );

        return self.div;
    }, // draw

    printPage: function () {
        if (window && window.print) {
            window.print();
        }
    },

    hideControls: function () {
        OpenLayers.Element.removeClass( this.div, 'active' );
        map.events.unregister('moveend', map, this.onMapMoveEnd);
    }, //hideControls

    showControls: function () {
        var self = this, btn = self.div;
        OpenLayers.Util.renderToggleToolClick({'self':self});
        OpenLayers.Element.addClass( self.div, 'active' );
        self.getContent(self.cnt);
        map.events.register('moveend', map, this.onMapMoveEnd);
    }, // showControls

    enable: function () {
    }, // enable

    disable: function () {
    }, // disable

    toggleControls: function () {
        OpenLayers.Element.hasClass(this.div, 'active') ? this.hideControls() : this.showControls();
    },//togglecontrols

    getContent: function (holder) {
        var self = this;

        if (!holder) return;
        if (holder.childNodes.length > 0) return;

        var center = map.getCenter();
        var params = [map.getZoom()];
        params.push(Math.round(center.lon));
        params.push(Math.round(center.lat));
        if (params[0] > 13) params[0] = 13;

        var html = ''
        + '
Velg type utskrift
'
        + '
'
        + '
'
        + '<button class="print-btn" id="print-btn-print">Skriv ut kartutsnitt fra skjerm</button>'
        + '
'
        + '
'
        + 'Lag turkart for utskrift'
        + '
'
        + '
'
        + '';

        holder.innerHTML = html;

        var printBtnPrint = document.getElementById('print-btn-print');
        if (printBtnPrint !== null) {
            OpenLayers.Event.observe(printBtnPrint, 'click',
                OpenLayers.Function.bind(self.printPage, self)
            );
        }
    },//getContent

    onMapMoveEnd: function (e) {
        var printBtnOpen = document.getElementById('print-btn-open');
        if (printBtnOpen !== null) {
            var params = [e.object.zoom, Math.round(e.object.center.lon), Math.round(e.object.center.lat)];
            if (params[0] > 13) params[0] = 13;
            var url = printBtnOpen.getAttribute('href').split('#').shift() + '#' + params.join('/');
            printBtnOpen.setAttribute('href', url);
        }
    },//onMapMoveEnd

    CLASS_NAME: "OpenLayers.Control.Print"
}); // OpenLayers.Control.Print
<|endoftext|>


<commit_before>/* * GNU General Public License Usage
 * This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
 *
 * http://www.gnu.org/licenses/lgpl.html
 *
 * @description: This class provide additional format to numbers by extending Ext.form.field.Number
 *
 * @author: Greivin Britton
 * @email: brittongr@gmail.com
 * @version: 2 compatible with ExtJS 4 (And ExtJS 5 - chamacs)
 */
Ext.define('Ext.ux.form.field.Currency', {
    extend: 'Ext.form.field.Number',//Extending the NumberField
    xtype: [
        'currencyfield',
        'numericfield'
    ],
    alternateClassName: ['Ext.ux.form.field.Numeric', 'Ext.ux.form.NumericField'],
    currencySymbol: '$ ',
    useThousandSeparator: true,
    thousandSeparator: '.',
    alwaysDisplayDecimals: true,
    // MOD - chamacs
    // @private
    isCurrency: false,

    // MOD - pmiguelmartins
    currencySymbolPos: 'left', // left , right

    // MOD - chamacs
    //fieldStyle: 'text-align: right;',

    // MOD - chamacs
    allowExponential: false,

    /**
     * initComponent
     */
    initComponent: function () {
        if (this.useThousandSeparator && this.decimalSeparator == ',' && this.thousandSeparator == ',') {
            this.thousandSeparator = '.';
        }
        else if (this.allowDecimals && this.thousandSeparator == '.' && this.decimalSeparator == '.') {
            this.decimalSeparator = ',';
        }

        // MOD - chamacs
        this.isCurrency = !Ext.isEmpty(this.currencySymbol);

        this.callParent(arguments);
    },

    /**
     * setValue
     */
    setValue: function (value) {
        // MOD - chamacs
        Ext.ux.form.field.Currency.superclass.setValue.apply(this, [value != null ? value.toString().replace('.', this.decimalSeparator) : value]);

        this.setRawValue(this.getFormattedValue(this.getValue()));
    },

    /**
     * getFormattedValue
     */
    getFormattedValue: function (value) {
        if (Ext.isEmpty(value) || !this.hasFormat()) {
            return value;
        }
        else {
            var neg = null;

            value = (neg = value < 0) ? value * -1 : value;
            value = this.allowDecimals && this.alwaysDisplayDecimals ? value.toFixed(this.decimalPrecision) : value;

            if (this.useThousandSeparator) {
                if (this.useThousandSeparator && Ext.isEmpty(this.thousandSeparator)) {
                    throw ('NumberFormatException: invalid thousandSeparator, property must has a valid character.');
                }
                if (this.thousandSeparator == this.decimalSeparator) {
                    throw ('NumberFormatException: invalid thousandSeparator, thousand separator must be different from decimalSeparator.');
                }

                value = value.toString();

                var ps = value.split('.');
                ps[1] = ps[1] ? ps[1] : null;

                var whole = ps[0];

                var r = /(\d+)(\d{3})/;

                var ts = this.thousandSeparator;

                while (r.test(whole)) {
                    whole = whole.replace(r, '$1' + ts + '$2');
                }

                value = whole + (ps[1] ? this.decimalSeparator + ps[1] : '');
            }

            // MOD - pmiguelmartins - updated by chamacs
            var position1 = this.isCurrency ? this.currencySymbol + ' ' : '';
            var position2 = value;
            if (this.currencySymbolPos === 'right') {
                position1 = value;
                position2 = this.isCurrency ? ' ' + this.currencySymbol : '';
            }
            return Ext.String.format('{0}{1}{2}', position1, (neg ? '-' : ''), position2);
        }
    },

    /**
     * overrides parseValue to remove the format applied by this class
     */
    parseValue: function (value) {
        // MOD - chamacs
        //Replace the currency symbol and thousand separator
        return Ext.ux.form.field.Currency.superclass.parseValue.apply(this, [this.removeFormat(value)]);
    },

    /**
     * Remove only the format added by this class to let the superclass validate with it's rules.
     * @param {Object} value
     */
    removeFormat: function (value) {
        // MOD - chamacs
        if (Ext.isEmpty(value)) {
            return '';
        }
        else if (!this.hasFormat()) {
            return value;
        }
        else {
            // MOD - bhaidaya
            value = Ext.String.trim(value.toString().replace(this.currencySymbol, ''));

            value = this.useThousandSeparator ? value.replace(new RegExp('[' + this.thousandSeparator + ']', 'g'), '') : value;
            return value;
        }
    },

    /** * Remove the format before validating the the value.
     * @param {Number} value
     */
    getErrors: function (value) {
        //FIX data binding by antiplaka
        value = arguments.length > 0 ? value : this.processRawValue(this.getRawValue());
        return this.callParent([this.removeFormat(value)]);
    },

    /**
     * hasFormat
     */
    hasFormat: function () {
        return this.decimalSeparator != '.' || (this.useThousandSeparator == true && this.getRawValue() != null) || !Ext.isEmpty(this.currencySymbol) || this.alwaysDisplayDecimals;
    },

    /**
     * Display the numeric value with the fixed decimal precision and without the format using the setRawValue, don't need to do a setValue because we don't want a double
     * formatting and process of the value because beforeBlur perform a getRawValue and then a setValue.
     */
    onFocus: function () {
        this.setRawValue(this.removeFormat(this.getRawValue()));

        this.callParent(arguments);
    },

    /**
     * MOD - Jeff.Evans
     */
    processRawValue: function (value) {
        return this.removeFormat(value);
    }
});
<commit_msg>Update Currency.js<commit_after>/* * GNU General Public License Usage
 * This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
 *
 * http://www.gnu.org/licenses/lgpl.html
 *
 * @description: This class provide additional format to numbers by extending Ext.form.field.Number
 *
 * @author: Greivin Britton
 * @email: brittongr@gmail.com
 * @version: 2 compatible with ExtJS 4 (And ExtJS 5 - chamacs)
 */
Ext.define('Ext.ux.form.field.Currency', {
    extend: 'Ext.form.field.Number',//Extending the NumberField
    xtype: [
        'currencyfield',
        'numericfield'
    ],
    alternateClassName: ['Ext.ux.form.field.Numeric', 'Ext.ux.form.NumericField'],
    currencySymbol: '$ ',
    useThousandSeparator: true,
    thousandSeparator: '.',
    alwaysDisplayDecimals: true,
    // MOD - chamacs
    // @private
    isCurrency: false,

    // MOD - pmiguelmartins
    currencySymbolPos: 'left', // left , right

    // MOD - chamacs
    //fieldStyle: 'text-align: right;',

    // MOD - chamacs
    allowExponential: false,

    /**
     * initComponent
     */
    initComponent: function () {
        if (this.useThousandSeparator && this.decimalSeparator == ',' && this.thousandSeparator == ',') {
            this.thousandSeparator = '.';
        }
        else if (this.allowDecimals && this.thousandSeparator == '.' && this.decimalSeparator == '.') {
            this.decimalSeparator = ',';
        }

        // MOD - chamacs
        this.isCurrency = !Ext.isEmpty(this.currencySymbol);

        this.callParent(arguments);
    },

    /**
     * setValue
     */
    setValue: function (value) {
        var me = this,
            bind, valueBind;

        // This portion of the code is to prevent a binding from stomping over
        // the typed value. Say we have decimalPrecision 4 and the user types
        // 1.23456. The value of the field will be set as 1.2346 and published to
        // the viewmodel, which will trigger the binding to fire and setValue to
        // be called on the field, which would then set the value (and rawValue) to
        // 1.2346. Instead, if we have focus and the value is the same, just leave
        // the rawValue alone
        if (me.hasFocus) {
            bind = me.getBind();
            valueBind = bind && bind.value;
            if (valueBind && valueBind.syncing && value === me.value) {
                return me;
            }
        }

        // MOD - chamacs
        Ext.ux.form.field.Currency.superclass.setValue.apply(this, [value != null ? value.toString().replace('.', this.decimalSeparator) : value]);

        this.setRawValue(this.getFormattedValue(this.getValue()));
    },

    /**
     * getFormattedValue
     */
    getFormattedValue: function (value) {
        if (Ext.isEmpty(value) || !this.hasFormat()) {
            return value;
        }
        else {
            var neg = null;

            value = (neg = value < 0) ? value * -1 : value;
            value = this.allowDecimals && this.alwaysDisplayDecimals ? value.toFixed(this.decimalPrecision) : value;

            if (this.useThousandSeparator) {
                if (this.useThousandSeparator && Ext.isEmpty(this.thousandSeparator)) {
                    throw ('NumberFormatException: invalid thousandSeparator, property must has a valid character.');
                }
                if (this.thousandSeparator == this.decimalSeparator) {
                    throw ('NumberFormatException: invalid thousandSeparator, thousand separator must be different from decimalSeparator.');
                }

                value = value.toString();

                var ps = value.split('.');
                ps[1] = ps[1] ? ps[1] : null;

                var whole = ps[0];

                var r = /(\d+)(\d{3})/;

                var ts = this.thousandSeparator;

                while (r.test(whole)) {
                    whole = whole.replace(r, '$1' + ts + '$2');
                }

                value = whole + (ps[1] ? this.decimalSeparator + ps[1] : '');
            }

            // MOD - pmiguelmartins - updated by chamacs
            var position1 = this.isCurrency ? this.currencySymbol + ' ' : '';
            var position2 = value;
            if (this.currencySymbolPos === 'right') {
                position1 = value;
                position2 = this.isCurrency ? ' ' + this.currencySymbol : '';
            }
            return Ext.String.format('{0}{1}{2}', position1, (neg ? '-' : ''), position2);
        }
    },

    /**
     * overrides parseValue to remove the format applied by this class
     */
    parseValue: function (value) {
        // MOD - chamacs
        //Replace the currency symbol and thousand separator
        return Ext.ux.form.field.Currency.superclass.parseValue.apply(this, [this.removeFormat(value)]);
    },

    /**
     * Remove only the format added by this class to let the superclass validate with it's rules.
     * @param {Object} value
     */
    removeFormat: function (value) {
        // MOD - chamacs
        if (Ext.isEmpty(value)) {
            return '';
        }
        else if (!this.hasFormat()) {
            return value;
        }
        else {
            // MOD - bhaidaya
            value = Ext.String.trim(value.toString().replace(this.currencySymbol, ''));

            value = this.useThousandSeparator ? value.replace(new RegExp('[' + this.thousandSeparator + ']', 'g'), '') : value;
            return value;
        }
    },

    /** * Remove the format before validating the the value.
     * @param {Number} value
     */
    getErrors: function (value) {
        //FIX data binding by antiplaka
        value = arguments.length > 0 ? value : this.processRawValue(this.getRawValue());
        return this.callParent([this.removeFormat(value)]);
    },

    /**
     * hasFormat
     */
    hasFormat: function () {
        return this.decimalSeparator != '.' || (this.useThousandSeparator == true && this.getRawValue() != null) || !Ext.isEmpty(this.currencySymbol) || this.alwaysDisplayDecimals;
    },

    /**
     * Display the numeric value with the fixed decimal precision and without the format using the setRawValue, don't need to do a setValue because we don't want a double
     * formatting and process of the value because beforeBlur perform a getRawValue and then a setValue.
     */
    onFocus: function () {
        this.setRawValue(this.removeFormat(this.getRawValue()));

        this.callParent(arguments);
    },

    /**
     * MOD - Jeff.Evans
     */
    processRawValue: function (value) {
        return this.removeFormat(value);
    }
});
<|endoftext|>