<commit_before>import Vue from 'vue'
import Router from 'vue-router'
import App from './App'

import Wechat from './Wechat'
import Home from './Home'
import Yi from './yi'
import Icon from './demos/Icon'
import Switch from './demos/Switch'
import Radio from './demos/Radio'
import Input from './demos/Input'
import Number from './demos/Number'
import Checklist from './demos/Checklist'
import Selector from './demos/Selector'
import Tip from './demos/Tip'
import Button from './demos/Button'
import Textarea from './demos/Textarea'
import Flexbox from './demos/Flexbox'
import Tab from './demos/Tab'
import Swiper from './demos/Swiper'
import Sticky from './demos/Sticky'
import Picker from './demos/Picker'
import Datetime from './demos/Datetime'
import Popup from './demos/Popup'
import Range from './demos/Range'
import Actionsheet from './demos/Actionsheet'
import Clocker from './demos/Clocker'
import Rater from './demos/Rater'
import PopupPicker from './demos/Popup-picker'
import Address from './demos/Address'
import Toast from './demos/Toast'
import Loading from './demos/Loading'
import Alert from './demos/Alert'
import Confirm from './demos/Confirm'
import Progress from './demos/Progress'
import XImg from './demos/XImg'
import Onepx from './demos/1px'
import Orientation from './demos/Orientation'
import Shake from './demos/Shake'
import Cell from './demos/Cell'
import Demo from './demos/Demo'
import Emotion from './demos/Wechat-emotion'
import Search from './demos/Search'
import Donate from './demos/Donate'
import Thanks from './demos/Thanks'
import Spinner from './demos/Spinner'
import Calendar from './demos/Calendar'
import Milestone from './demos/Milestone'
import Circle from './demos/Circle'
import Countup from './demos/Countup'
import ColorPicker from './demos/Color-picker'
import Blur from './demos/Blur'
import Scroller from './demos/Scroller'
import Comment from './demos/Comment'
import Pulldown from './demos/Pulldown'
import Pullup from './demos/Pullup'
import Masker from './demos/Masker'
import InlineCalendar from './demos/Inline-calendar'

const FastClick = require('fastclick')
FastClick.attach(document.body)

Vue.use(Router)

const router = new Router({
  history: /vux.li/.test(location.href), // use history=false when testing
  saveScrollPosition: true
})

router.map({
  '/': {
    component: Home
  },
  '/demo/wechat': {
    component: Wechat
  },
  '/demo/yi': {
    component: Yi
  },
  '/component/icon': {
    component: Icon
  },
  '/component/switch': {
    component: Switch
  },
  '/component/radio': {
    component: Radio
  },
  '/component/input': {
    component: Input
  },
  '/component/number': {
    component: Number
  },
  '/component/checklist': {
    component: Checklist
  },
  '/component/selector': {
    component: Selector
  },
  '/component/tip': {
    component: Tip
  },
  '/component/button': {
    component: Button
  },
  '/component/textarea': {
    component: Textarea
  },
  '/component/flexbox': {
    component: Flexbox
  },
  '/component/tab': {
    component: Tab
  },
  '/component/swiper': {
    component: Swiper
  },
  '/component/sticky': {
    component: Sticky
  },
  '/component/picker': {
    component: Picker
  },
  '/component/datetime': {
    component: Datetime
  },
  '/component/popup': {
    component: Popup
  },
  '/component/range': {
    component: Range
  },
  '/component/actionsheet': {
    component: Actionsheet
  },
  '/component/clocker': {
    component: Clocker
  },
  '/component/rater': {
    component: Rater
  },
  '/component/popup-picker': {
    component: PopupPicker
  },
  '/component/address': {
    component: Address
  },
  '/component/toast': {
    component: Toast
  },
  '/component/loading': {
    component: Loading
  },
  '/component/alert': {
    component: Alert
  },
  '/component/confirm': {
    component: Confirm
  },
  '/component/progress': {
    component: Progress
  },
  '/component/x-img': {
    component: XImg
  },
  '/component/1px': {
    component: Onepx
  },
  '/component/orientation': {
    component: Orientation
  },
  '/component/shake': {
    component: Shake
  },
  '/component/cell': {
    component: Cell
  },
  '/demo': {
    component: Demo
  },
  '/component/emotion': {
    component: Emotion
  },
  '/component/search': {
    component: Search
  },
  '/project/donate': {
    component: Donate
  },
  '/project/thanks': {
    component: Thanks
  },
  '/project/milestone': {
    component: Milestone
  },
  '/component/spinner': {
    component: Spinner
  },
  '/component/calendar': {
    component: Calendar
  },
  '/component/circle': {
    component: Circle
  },
  '/component/countup': {
    component: Countup
  },
  '/component/color-picker': {
    component: ColorPicker
  },
  '/component/blur': {
    component: Blur
  },
  '/component/scroller': {
    component: Scroller
  },
  '/component/comment': {
    component: Comment
  },
  '/component/pulldown': {
    component: Pulldown
  },
  '/component/pullup': {
    component: Pullup
  },
  '/component/masker': {
    component: Masker
  },
  '/component/inline-calendar': {
    component: InlineCalendar
  }
})

router.beforeEach(function (transition) {
  if (/\/http/.test(transition.to.path)) {
    let url = transition.to.path.split('http')[1]
    window.location.href = `http${url}`
  } else {
    transition.next()
  }
})

router.afterEach(function (transition) {
  if (transition.to.fullPath !== '/demo') {
    window.scrollTo(0, 0)
  }
})

router.start(App, '#app')
<commit_msg>Remove in-developing component<commit_after>import Vue from 'vue'
import Router from 'vue-router'
import App from './App'

import Wechat from './Wechat'
import Home from './Home'
import Yi from './yi'
import Icon from './demos/Icon'
import Switch from './demos/Switch'
import Radio from './demos/Radio'
import Input from './demos/Input'
import Number from './demos/Number'
import Checklist from './demos/Checklist'
import Selector from './demos/Selector'
import Tip from './demos/Tip'
import Button from './demos/Button'
import Textarea from './demos/Textarea'
import Flexbox from './demos/Flexbox'
import Tab from './demos/Tab'
import Swiper from './demos/Swiper'
import Sticky from './demos/Sticky'
import Picker from './demos/Picker'
import Datetime from './demos/Datetime'
import Popup from './demos/Popup'
import Range from './demos/Range'
import Actionsheet from './demos/Actionsheet'
import Clocker from './demos/Clocker'
import Rater from './demos/Rater'
import PopupPicker from './demos/Popup-picker'
import Address from './demos/Address'
import Toast from './demos/Toast'
import Loading from './demos/Loading'
import Alert from './demos/Alert'
import Confirm from './demos/Confirm'
import Progress from './demos/Progress'
import XImg from './demos/XImg'
import Onepx from './demos/1px'
import Orientation from './demos/Orientation'
import Shake from './demos/Shake'
import Cell from './demos/Cell'
import Demo from './demos/Demo'
import Emotion from './demos/Wechat-emotion'
import Search from './demos/Search'
import Donate from './demos/Donate'
import Thanks from './demos/Thanks'
import Spinner from './demos/Spinner'
import Calendar from './demos/Calendar'
import Milestone from './demos/Milestone'
import Circle from './demos/Circle'
import Countup from './demos/Countup'
import ColorPicker from './demos/Color-picker'
import Blur from './demos/Blur'
import Scroller from './demos/Scroller'
import Comment from './demos/Comment'
import Pulldown from './demos/Pulldown'
import Pullup from './demos/Pullup'
import Masker from './demos/Masker'

const FastClick = require('fastclick')
FastClick.attach(document.body)

Vue.use(Router)

const router = new Router({
  history: /vux.li/.test(location.href), // use history=false when testing
  saveScrollPosition: true
})

router.map({
  '/': {
    component: Home
  },
  '/demo/wechat': {
    component: Wechat
  },
  '/demo/yi': {
    component: Yi
  },
  '/component/icon': {
    component: Icon
  },
  '/component/switch': {
    component: Switch
  },
  '/component/radio': {
    component: Radio
  },
  '/component/input': {
    component: Input
  },
  '/component/number': {
    component: Number
  },
  '/component/checklist': {
    component: Checklist
  },
  '/component/selector': {
    component: Selector
  },
  '/component/tip': {
    component: Tip
  },
  '/component/button': {
    component: Button
  },
  '/component/textarea': {
    component: Textarea
  },
  '/component/flexbox': {
    component: Flexbox
  },
  '/component/tab': {
    component: Tab
  },
  '/component/swiper': {
    component: Swiper
  },
  '/component/sticky': {
    component: Sticky
  },
  '/component/picker': {
    component: Picker
  },
  '/component/datetime': {
    component: Datetime
  },
  '/component/popup': {
    component: Popup
  },
  '/component/range': {
    component: Range
  },
  '/component/actionsheet': {
    component: Actionsheet
  },
  '/component/clocker': {
    component: Clocker
  },
  '/component/rater': {
    component: Rater
  },
  '/component/popup-picker': {
    component: PopupPicker
  },
  '/component/address': {
    component: Address
  },
  '/component/toast': {
    component: Toast
  },
  '/component/loading': {
    component: Loading
  },
  '/component/alert': {
    component: Alert
  },
  '/component/confirm': {
    component: Confirm
  },
  '/component/progress': {
    component: Progress
  },
  '/component/x-img': {
    component: XImg
  },
  '/component/1px': {
    component: Onepx
  },
  '/component/orientation': {
    component: Orientation
  },
  '/component/shake': {
    component: Shake
  },
  '/component/cell': {
    component: Cell
  },
  '/demo': {
    component: Demo
  },
  '/component/emotion': {
    component: Emotion
  },
  '/component/search': {
    component: Search
  },
  '/project/donate': {
    component: Donate
  },
  '/project/thanks': {
    component: Thanks
  },
  '/project/milestone': {
    component: Milestone
  },
  '/component/spinner': {
    component: Spinner
  },
  '/component/calendar': {
    component: Calendar
  },
  '/component/circle': {
    component: Circle
  },
  '/component/countup': {
    component: Countup
  },
  '/component/color-picker': {
    component: ColorPicker
  },
  '/component/blur': {
    component: Blur
  },
  '/component/scroller': {
    component: Scroller
  },
  '/component/comment': {
    component: Comment
  },
  '/component/pulldown': {
    component: Pulldown
  },
  '/component/pullup': {
    component: Pullup
  },
  '/component/masker': {
    component: Masker
  }
})

router.beforeEach(function (transition) {
  if (/\/http/.test(transition.to.path)) {
    let url = transition.to.path.split('http')[1]
    window.location.href = `http${url}`
  } else {
    transition.next()
  }
})

router.afterEach(function (transition) {
  if (transition.to.fullPath !== '/demo') {
    window.scrollTo(0, 0)
  }
})

router.start(App, '#app')
<|endoftext|>


<commit_before>
define(['ResultHeadersView', 'ResultRowsView', 'SystemDeserializer'],
function(ResultHeadersView, ResultRowsView, SystemDeserializer) {

  var ResultsView = Backbone.Marionette.LayoutView.extend({
    initialize: function(options) {
      this.options = options
      this.resultsCollection = this.options.results
      this.lazyResultsBlock = 50
      this.resultHeaders = new Backbone.Collection()
      // this.resultRows = new Backbone.Collection()
      this.model = this.options.model
      this.resultHeadersView = new ResultHeadersView({
        collection: this.resultHeaders
      })
      this.resultRowsView = new ResultRowsView({
        collection: this.resultsCollection
      })

      this.listenTo(this.resultsCollection, 'reset add', this.fillInResultRowBlank)
      this.listenTo(this.resultsCollection, 'sendCurrentWidth', this.setGreatestWidthForHeader)
      this.listenTo(this.resultRowsView, 'collection:rendered', this.dynamicResize)
      this.listenTo(this.model, 'change:resultsArray', this.lazyRenderCollection)
    },

    template: Handlebars.templates['query/results_layout'],

    className: 'results-table',

    regions: {
      'headers': '.result-headers',
      'rows': '.result-rows'
    },

    events: {
      'scroll': 'triggerLazyRender'
    },

    bindings: {
      '.fa-spinner': {
        attributes: [{
          observe: 'loading',
          name: 'class',
          onGet: function(loading) {
            return loading ? "" : "hide"
          }
        }]
      },
      'table': {
        attributes: [{
          observe: 'loading',
          name: 'class',
          onGet: function(loading) {
            return loading ? "hide" : ""
          }
        }]
      }
    },

    lazyRenderCollection: function() {

      var currentIndex = this.model.get("currentIndex"),
          resultsToAdd = this.model.get("resultsArray").slice(currentIndex, currentIndex + this.lazyResultsBlock),
          collectionToAdd = SystemDeserializer.deserializeQueryResponse(resultsToAdd)

      if (this.model.get("lazyIteration") == 0) this.setHeadersCollection(collectionToAdd)

      this.model.set("lazyLoading", true)
      this.resultsCollection.add(collectionToAdd.models)
      this.model.set("currentIndex", this.resultsCollection.length)
      this.model.set("lazyIteration", this.model.get("lazyIteration") + 1)
      this.model.set("lazyLoading", false)
    },

    triggerLazyRender: function(e) {
      e.stopPropagation()
      var topOfResults = this.$el.scrollTop(),
          rowHeight = 25,
          resultsBlockHeight = rowHeight * this.lazyResultsBlock,
          currentResultsHeight = (this.model.get("lazyIteration") * resultsBlockHeight) - this.$el.height(),
          view = this

      // this.$('.headers-container').css({top: topOfResults})
      if (currentResultsHeight < topOfResults && !this.model.get("lazyLoading")) {
        this.model.set("lazyLoading", true)
        this.lazyRenderCollection()
      }

      // view.$('.headers-container').hide()
      // setTimeout(function() {
      //   view.$('.headers-container').css({top: topOfResults})
      //   view.$('.headers-container').show()
      // }, 25)
    },

    setGreatestWidthForHeader: function(width, index) {
      var currentHeader = this.resultHeaders.at(index)

      if (currentHeader.get("width") < width) currentHeader.set("width", width)
    },

    assignHeaderModelsInitialWidths: function() {
      this.resultHeaders.each(function(header, index) {
        var currentHeaderWidth = $(this.resultHeadersView.el.childNodes[index]).outerWidth()
        header.set("width", currentHeaderWidth)
      }, this)
    },

    dynamicResize: function() {
      this.resultsCollection.each(function(result) {
        this.resultHeaders.each(function(header, index) {
          result.get("tableDataCollection").at(index).set("width", header.get("width"))
        })
      }, this)
    },

    setHeadersCollection: function(collection) {
      var headersCollection = new Backbone.Collection()
      collection.each(function(result) {
        result.get("tableDataCollection").each(function(data) {
          var dataHeader = data.get("header")
          if (!headersCollection.findWhere({header: dataHeader}))
            headersCollection.add(new Backbone.Model({header: dataHeader}))
        })
      })
      this.resultHeaders.reset(headersCollection.models)
      this.assignHeaderModelsInitialWidths()
    },

    fillInResultRowBlanks: function() {
      this.resultsCollection.each(function(row) {
        this.resultHeaders.each(function(header, index) {
          var currentHeaderDataModel = row.get("tableDataCollection").findWhere({header: header.get("header")})
          if (!(currentHeaderDataModel && row.get("tableDataCollection").indexOf(currentHeaderDataModel) == index)) {
            row.get("tableDataCollection").add(new Backbone.Model({
              header: header.get("header"),
              value: "Undefined"
            }), { at: index })
          }
        })
      })
    },

    onDestroy: function() {
      this.options = null
      this.resultsCollection = null
    },

    render: function() {
      this.unstickit()
      Backbone.Marionette.LayoutView.prototype.render.call(this)
      this.headers.show(this.resultHeadersView)
      this.rows.show(this.resultRowsView)
      this.stickit()
    }
  })

  return ResultsView
})<commit_msg>Since cassandra doesn't allow joins, removed fillInResultRowBlanks function calls<commit_after>
define(['ResultHeadersView', 'ResultRowsView', 'SystemDeserializer'],
function(ResultHeadersView, ResultRowsView, SystemDeserializer) {

  var ResultsView = Backbone.Marionette.LayoutView.extend({
    initialize: function(options) {
      this.options = options
      this.resultsCollection = this.options.results
      this.lazyResultsBlock = 50
      this.resultHeaders = new Backbone.Collection()
      // this.resultRows = new Backbone.Collection()
      this.model = this.options.model
      this.resultHeadersView = new ResultHeadersView({
        collection: this.resultHeaders
      })
      this.resultRowsView = new ResultRowsView({
        collection: this.resultsCollection
      })

      // this.listenTo(this.resultsCollection, 'reset add', this.fillInResultRowBlank)
      this.listenTo(this.resultsCollection, 'sendCurrentWidth', this.setGreatestWidthForHeader)
      this.listenTo(this.resultRowsView, 'collection:rendered', this.dynamicResize)
      this.listenTo(this.model, 'change:resultsArray', this.lazyRenderCollection)
    },

    template: Handlebars.templates['query/results_layout'],

    className: 'results-table',

    regions: {
      'headers': '.result-headers',
      'rows': '.result-rows'
    },

    events: {
      'scroll': 'triggerLazyRender'
    },

    bindings: {
      '.fa-spinner': {
        attributes: [{
          observe: 'loading',
          name: 'class',
          onGet: function(loading) {
            return loading ? "" : "hide"
          }
        }]
      },
      'table': {
        attributes: [{
          observe: 'loading',
          name: 'class',
          onGet: function(loading) {
            return loading ? "hide" : ""
          }
        }]
      }
    },

    lazyRenderCollection: function() {

      var currentIndex = this.model.get("currentIndex"),
          resultsToAdd = this.model.get("resultsArray").slice(currentIndex, currentIndex + this.lazyResultsBlock),
          collectionToAdd = SystemDeserializer.deserializeQueryResponse(resultsToAdd)

      if (this.model.get("lazyIteration") == 0) this.setHeadersCollection(collectionToAdd)

      this.model.set("lazyLoading", true)
      this.resultsCollection.add(collectionToAdd.models)
      this.model.set("currentIndex", this.resultsCollection.length)
      this.model.set("lazyIteration", this.model.get("lazyIteration") + 1)
      this.model.set("lazyLoading", false)
    },

    triggerLazyRender: function(e) {
      e.stopPropagation()
      var topOfResults = this.$el.scrollTop(),
          rowHeight = 25,
          resultsBlockHeight = rowHeight * this.lazyResultsBlock,
          currentResultsHeight = (this.model.get("lazyIteration") * resultsBlockHeight) - this.$el.height(),
          view = this

      // this.$('.headers-container').css({top: topOfResults})
      if (currentResultsHeight < topOfResults && !this.model.get("lazyLoading")) {
        this.model.set("lazyLoading", true)
        this.lazyRenderCollection()
      }

      // view.$('.headers-container').hide()
      // setTimeout(function() {
      //   view.$('.headers-container').css({top: topOfResults})
      //   view.$('.headers-container').show()
      // }, 25)
    },

    setGreatestWidthForHeader: function(width, index) {
      var currentHeader = this.resultHeaders.at(index)

      if (currentHeader.get("width") < width) currentHeader.set("width", width)
    },

    assignHeaderModelsInitialWidths: function() {
      this.resultHeaders.each(function(header, index) {
        var currentHeaderWidth = $(this.resultHeadersView.el.childNodes[index]).outerWidth()
        header.set("width", currentHeaderWidth)
      }, this)
    },

    dynamicResize: function() {
      this.resultsCollection.each(function(result) {
        this.resultHeaders.each(function(header, index) {
          result.get("tableDataCollection").at(index).set("width", header.get("width"))
        })
      }, this)
    },

    setHeadersCollection: function(collection) {
      var headersCollection = new Backbone.Collection()
      collection.each(function(result) {
        result.get("tableDataCollection").each(function(data) {
          var dataHeader = data.get("header")
          if (!headersCollection.findWhere({header: dataHeader}))
            headersCollection.add(new Backbone.Model({header: dataHeader}))
        })
      })
      this.resultHeaders.reset(headersCollection.models)
      this.assignHeaderModelsInitialWidths()
    },

    fillInResultRowBlanks: function() {
      this.resultsCollection.each(function(row) {
        this.resultHeaders.each(function(header, index) {
          var currentHeaderDataModel = row.get("tableDataCollection").findWhere({header: header.get("header")})
          if (!(currentHeaderDataModel && row.get("tableDataCollection").indexOf(currentHeaderDataModel) == index)) {
            row.get("tableDataCollection").add(new Backbone.Model({
              header: header.get("header"),
              value: "Undefined"
            }), { at: index })
          }
        })
      })
    },

    onDestroy: function() {
      this.options = null
      this.resultsCollection = null
    },

    render: function() {
      this.unstickit()
      Backbone.Marionette.LayoutView.prototype.render.call(this)
      this.headers.show(this.resultHeadersView)
      this.rows.show(this.resultRowsView)
      this.stickit()
    }
  })

  return ResultsView
})<|endoftext|>


<commit_before>enyo.kind({
  /*
   *  name:
   *  name of this "kind" (optionally namespaced with a .)
   */
  name: 'Slides.Main',
  /*
   *  components:
   *  Array of "kind" objects that compose the layout of your app
   */
  components: [
    {name: 'mainLayout', kind: 'FittableRows', classes: 'enyo-fit', components: [
      {
        kind: 'newness.InfiniteSlidingPane',
        name: 'slidesPanes',
        fit:  true
      },
      {
        kind: 'onyx.Toolbar',
        layoutKind: 'FittableColumnsLayout',
        components: [
          {kind:      'onyx.Button',
           allowHtml: true,
           content:   '← Back',
           onclick:   'previousSlide'},
          {kind: 'onyx.ProgressBar', name: 'slidesProgress', position: '50', style: 'height: 12px; margin: 10px !important;', fit: true},
          {kind:      'onyx.Button',
           allowHtml: true,
           content:   'Next →',
           onclick:   'nextSlide'}
        ]
      }
    ]}
  ],

  create: function() {
    this.inherited(arguments);

    var component = { kind: "Slides.Slide", name: "slide1", content: "Hello world 1!" };
    this.$.slidesPanes.viewTypes.push( component );
    component = { kind: "Slides.Slide", name: "slide2", content: "Hello world 2!" };
    this.$.slidesPanes.viewTypes.push( component );
    component = { kind: "Slides.Slide", name: "slide3", content: "Hello world 3!" };
    this.$.slidesPanes.viewTypes.push( component );

    this.nextSlide(); // start at slide 1
  },

  nextSlide: function() {
    if( this.$.slidesPanes.getViewCount() < this.$.slidesPanes.viewTypes.length )
    {
      component = this.$.slidesPanes.viewTypes[this.$.slidesPanes.getViewCount()];
      this.$.slidesPanes.push(component.name);
      this.updateProgress();
    }
  },

  previousSlide: function() {
    if( this.$.slidesPanes.getViewCount() > 1 )
    {
        this.$.slidesPanes.getView().pop();
        setTimeout(enyo.bind(this,this.updateProgress), 500); // Fuck this.
    }
  },

  updateProgress: function() {
    var full = this.$.slidesPanes.viewTypes.length;
    var current = this.$.slidesPanes.getViewCount();

    this.$.slidesProgress.max = full;
    this.$.slidesProgress.animateProgressTo( current );
  }
});

<commit_msg>Make it possible to drag to next and previous slides<commit_after>enyo.kind({
  /*
   *  name:
   *  name of this "kind" (optionally namespaced with a .)
   */
  name: 'Slides.Main',
  /*
   *  components:
   *  Array of "kind" objects that compose the layout of your app
   */
  components: [
    {name: 'mainLayout', kind: 'FittableRows', classes: 'enyo-fit', components: [
      {
        kind: 'newness.InfiniteSlidingPane',
        name: 'slidesPanes',
        fit:  true,
        ondragfinish: "dragfinish"
      },
      {
        kind: 'onyx.Toolbar',
        layoutKind: 'FittableColumnsLayout',
        components: [
          {kind:      'onyx.Button',
           allowHtml: true,
           content:   '← Back',
           onclick:   'previousSlide'},
          {kind: 'onyx.ProgressBar', name: 'slidesProgress', position: '50', style: 'height: 12px; margin: 10px !important;', fit: true},
          {kind:      'onyx.Button',
           allowHtml: true,
           content:   'Next →',
           onclick:   'nextSlide'}
        ]
      }
    ]}
  ],

  create: function() {
    this.inherited(arguments);

    var component = { kind: "Slides.Slide", name: "slide1", content: "Hello world 1!" };
    this.$.slidesPanes.viewTypes.push( component );
    component = { kind: "Slides.Slide", name: "slide2", content: "Hello world 2!" };
    this.$.slidesPanes.viewTypes.push( component );
    component = { kind: "Slides.Slide", name: "slide3", content: "Hello world 3!" };
    this.$.slidesPanes.viewTypes.push( component );

    this.nextSlide(); // start at slide 1
  },

  nextSlide: function() {
    if( this.$.slidesPanes.getViewCount() < this.$.slidesPanes.viewTypes.length )
    {
      component = this.$.slidesPanes.viewTypes[this.$.slidesPanes.getViewCount()];
      this.$.slidesPanes.push(component.name);
      this.updateProgress();
    }
  },

  previousSlide: function() {
    if( this.$.slidesPanes.getViewCount() > 1 )
    {
        this.$.slidesPanes.getView().pop();
        setTimeout(enyo.bind(this,this.updateProgress), 500); // Fuck this.
    }
  },

  updateProgress: function() {
    var full = this.$.slidesPanes.viewTypes.length;
    var current = this.$.slidesPanes.getViewCount();

    this.$.slidesProgress.max = full;
    this.$.slidesProgress.animateProgressTo( current );
  },

  dragfinish: function(inSender,inEvent) {
    var poop;
    if( inEvent.dx < -window.innerWidth/3 )
    {
      this.nextSlide();
    }
    else  if( inEvent.dx > window.innerWidth/3 )
    {
      this.previousSlide();
    }
    inEvent.preventDefault();
  }
});

<|endoftext|>


<commit_before>// TODO: Complete implementation / Document
// QML MouseArea
// http://qt-project.org/doc/qt-5.0/qtquick/qml-qtquick2-mousearea.html
QObjects.MouseArea = {
  init: function() {
    this._.kNode = new Kinetic.Rect();

    var self = this;

    this._.accepted = false; // Is this event handled already?
    this._.lastDown = 0; // For doubleClick

    this._.kNode.on('mousedown.signal', function(kEvent) {
      self._.lastEvent = self.getMouseEvent(kEvent);
      self._.accepted = false;
      if(self.enabled) {
        // Without hoverEnabled 'entered' is fired on mousedown
        if(!self.hoverEnabled) {
          self.entered();
        }
        // Start waiting for pressAndHold, can be canceled by mouseup or mouseleave
        self._.holdTimer = setTimeout(function() {
          if(true /* TODO: self.pressAndHold._.slots.length */) { // Prevent acceptance if no handler present
            self.pressAndHold(self._.lastEvent);
            self._.accepted = self._.lastEvent.accepted;
          }
        }, 800);
      }
    });

    this._.kNode.on('mouseup.signal', function(kEvent) {
      clearTimeout(self._.holdTimer);
    });

    this._.kNode.on('click.signal', function(kEvent) {
      var mouse = self.getMouseEvent(kEvent);
      if(!self._.accepted && self.enabled && (self.acceptedButtons & mouse.button)) {
        self.clicked(mouse);
      }
      // Without hoverEnabled 'exited' is fired after 'clicked'
      if(self.enabled && !self.hoverEnabled) {
        self.exited();
      }
    });

    // QML doubleClicked fires on the second mousedown based on time since last mousedown
    this._.kNode.on('mousedown.doubleClick', function(kEvent) {
      var mouse = self.getMouseEvent(kEvent);
      var now = Date.now();
      if(/* TODO: self.doubleClicked._.slots.length && */ now - self._.lastDown < 500) {
        if(!self._.accepted && self.enabled && (self.acceptedButtons & mouse.button)) {
          self.doubleClicked(mouse);
        }
        self._.lastDown = 0;
        self._.accepted = mouse.accepted;
      }
      else {
        self._.lastDown = now;
      }
    });

    this._.kNode.on('mouseenter.signal', function(kEvent) {
      if(self.enabled && self.hoverEnabled) {
        self.entered();
      }
    });

    this._.kNode.on('mouseleave.signal', function(kEvent) {
      clearTimeout(self._.holdTimer);
      if(self.enabled && self.hoverEnabled) {
        self.exited();
      }
    });

    this._.kNode.on('mousemove.signal', function(kEvent) {
      var mouse = self._.lastEvent = self.getMouseEvent(kEvent);
      // TODO: Support for coordinates outside MouseArea on click and drag
      if(self.enabled && (self.hoverEnabled || mouse.buttons)) {
        self.positionChanged(mouse);
      }
    });

    try {
      this.parent._.kNode.add(this._.kNode);
    }
    catch (e) {
      // Throw 'MouseArea cannot be child of parent.type'
    }
    this.update();
  },
  update: function() {
    this.layout(this._.kNode);
  },
  getMouseEvent: function(kEvent) {
    var Qt = HQML.environment.Qt;
    // Even though getPointerPosition returns of object of just {x,y} it can't
    // be used and modified directly as Kinetic caches the reference and reuses it
    // for subsequent events
    var pointer = HQML.stage.getPointerPosition();
    var mouse = {};
    var offset = this.offset();
    mouse.x = pointer.x - offset.x;
    mouse.y = pointer.y - offset.y;
    mouse.accepted = true;
    switch(kEvent.button) {
      case 0:
        mouse.button = Qt.LeftButton;
        break;
      case 1:
        mouse.button = Qt.MiddleButton;
        break;
      case 2:
        mouse.button = Qt.RightButton;
        break;
    }
    mouse.buttons = kEvent.buttons;
    mouse.modifiers =
      (kEvent.shiftKey && Qt.ShiftModifier) |
      (kEvent.ctrlKey && Qt.ControlModifier) |
      (kEvent.altKey && Qt.AltModifier) |
      (kEvent.metaKey && Qt.MetaModifier);

    // The spec suggests this should be true on 'clicked' and 'released' events
    // where mouseup occurs > 800ms after mousedown. In practice it is only (and
    // always) true for the onPressAndHold signal (Qt 5.2)
    mouse.wasHeld = false;

    return mouse;
  }
};

Object.defineProperties(QObjects.MouseArea, {
  inherits: {
    value: 'Item'
  },
  defaultProperties: {
    value: {
      acceptedButtons: HQML.environment.Qt.LeftButton,
      cursorShape: HQML.environment.Qt.ArrowCursor,
      drag: {
        active: false,
        axis: null,
        filterChildren: false,
        maximumX: 0,
        maximumY: 0,
        minimumX: 0,
        minimumY: 0,
        target: null
      },
      enabled: true,
      hoverEnabled: false,
      preventStealing: false,
      propagateComposedEvents: false
    }
  },
  readOnly: {
    value: {
      containsMouse: function() { return false; }, // TODO: Implement
      mouseX: function() { return 0; }, // TODO: Implement
      mouseY: function() { return 0; }, // TODO: Implement
      pressed: function() { return false; }, // TODO: Implement
      pressedButtons: function() { return null; } // TODO: Implement
    }
  },
  signals: {
    value : {
      canceled: [], // TODO: Implement
      clicked: ['mouse'],
      doubleClicked: ['mouse'],
      entered: [],
      exited: [],
      positionChanged: ['mouse'],
      pressAndHold: ['mouse']
    }
  }
});
<commit_msg>Implement press signal on MouseArea<commit_after>// TODO: Complete implementation / Document
// QML MouseArea
// http://qt-project.org/doc/qt-5.0/qtquick/qml-qtquick2-mousearea.html
QObjects.MouseArea = {
  init: function() {
    this._.kNode = new Kinetic.Rect();

    var self = this;

    this._.accepted = false; // Is this event handled already?
    this._.lastDown = 0; // For doubleClick

    this._.kNode.on('mousedown.signal', function(kEvent) {
      var mouse = self._.lastEvent = self.getMouseEvent(kEvent);
      self._.accepted = false;
      if(self.enabled) {
        // Without hoverEnabled 'entered' is fired on mousedown
        if(!self.hoverEnabled) {
          self.entered();
        }
        if(true /* TODO: self.pressed._.slots.length */) {
          self.pressed(mouse);
          self._.accepted = !mouse.accepted; // Inverted accepted behaviour for pressed
          if(self._.accepted) {
            // TODO: Send events to any MouseArea directly below this one
          }
        }
        // Start waiting for pressAndHold, can be canceled by mouseup or mouseleave
        self._.holdTimer = setTimeout(function() {
          if(true /* TODO: self.pressAndHold._.slots.length */) { // Prevent acceptance if no handler present
            self.pressAndHold(self._.lastEvent);
            self._.accepted = self._.lastEvent.accepted;
          }
        }, 800);
      }
    });

    this._.kNode.on('mouseup.signal', function(kEvent) {
      clearTimeout(self._.holdTimer);
    });

    this._.kNode.on('click.signal', function(kEvent) {
      var mouse = self.getMouseEvent(kEvent);
      if(!self._.accepted && self.enabled && (self.acceptedButtons & mouse.button)) {
        self.clicked(mouse);
      }
      // Without hoverEnabled 'exited' is fired after 'clicked'
      if(self.enabled && !self.hoverEnabled) {
        self.exited();
      }
    });

    // QML doubleClicked fires on the second mousedown based on time since last mousedown
    this._.kNode.on('mousedown.doubleClick', function(kEvent) {
      var mouse = self.getMouseEvent(kEvent);
      var now = Date.now();
      if(/* TODO: self.doubleClicked._.slots.length && */ now - self._.lastDown < 500) {
        if(!self._.accepted && self.enabled && (self.acceptedButtons & mouse.button)) {
          self.doubleClicked(mouse);
        }
        self._.lastDown = 0;
        self._.accepted = mouse.accepted;
      }
      else {
        self._.lastDown = now;
      }
    });

    this._.kNode.on('mouseenter.signal', function(kEvent) {
      if(self.enabled && self.hoverEnabled) {
        self.entered();
      }
    });

    this._.kNode.on('mouseleave.signal', function(kEvent) {
      clearTimeout(self._.holdTimer);
      if(self.enabled && self.hoverEnabled) {
        self.exited();
      }
    });

    this._.kNode.on('mousemove.signal', function(kEvent) {
      var mouse = self._.lastEvent = self.getMouseEvent(kEvent);
      // TODO: Support for coordinates outside MouseArea on click and drag
      if(self.enabled && (self.hoverEnabled || mouse.buttons)) {
        self.positionChanged(mouse);
      }
    });

    try {
      this.parent._.kNode.add(this._.kNode);
    }
    catch (e) {
      // Throw 'MouseArea cannot be child of parent.type'
    }
    this.update();
  },
  update: function() {
    this.layout(this._.kNode);
  },
  getMouseEvent: function(kEvent) {
    var Qt = HQML.environment.Qt;
    // Even though getPointerPosition returns of object of just {x,y} it can't
    // be used and modified directly as Kinetic caches the reference and reuses it
    // for subsequent events
    var pointer = HQML.stage.getPointerPosition();
    var mouse = {};
    var offset = this.offset();
    mouse.x = pointer.x - offset.x;
    mouse.y = pointer.y - offset.y;
    mouse.accepted = true;
    switch(kEvent.button) {
      case 0:
        mouse.button = Qt.LeftButton;
        break;
      case 1:
        mouse.button = Qt.MiddleButton;
        break;
      case 2:
        mouse.button = Qt.RightButton;
        break;
    }
    mouse.buttons = kEvent.buttons;
    mouse.modifiers =
      (kEvent.shiftKey && Qt.ShiftModifier) |
      (kEvent.ctrlKey && Qt.ControlModifier) |
      (kEvent.altKey && Qt.AltModifier) |
      (kEvent.metaKey && Qt.MetaModifier);

    // The spec suggests this should be true on 'clicked' and 'released' events
    // where mouseup occurs > 800ms after mousedown. In practice it is only (and
    // always) true for the onPressAndHold signal (Qt 5.2)
    mouse.wasHeld = false;

    return mouse;
  }
};

Object.defineProperties(QObjects.MouseArea, {
  inherits: {
    value: 'Item'
  },
  defaultProperties: {
    value: {
      acceptedButtons: HQML.environment.Qt.LeftButton,
      cursorShape: HQML.environment.Qt.ArrowCursor,
      drag: {
        active: false,
        axis: null,
        filterChildren: false,
        maximumX: 0,
        maximumY: 0,
        minimumX: 0,
        minimumY: 0,
        target: null
      },
      enabled: true,
      hoverEnabled: false,
      preventStealing: false,
      propagateComposedEvents: false
    }
  },
  readOnly: {
    value: {
      containsMouse: function() { return false; }, // TODO: Implement
      mouseX: function() { return 0; }, // TODO: Implement
      mouseY: function() { return 0; }, // TODO: Implement
      // TODO: Figure out what to do with name collision between pressed property and signal
      //       http://qt-project.org/forums/viewthread/36764/
      //pressed: function() { return false; }, // TODO: Implement
      pressedButtons: function() { return null; } // TODO: Implement
    }
  },
  signals: {
    value : {
      canceled: [], // TODO: Implement
      clicked: ['mouse'],
      doubleClicked: ['mouse'],
      entered: [],
      exited: [],
      positionChanged: ['mouse'],
      pressAndHold: ['mouse'],
      pressed: ['mouse']
    }
  }
});
<|endoftext|>


<commit_before>var MSXML = (typeof DOMParser === 'undefined' || typeof XSLTProcessor === 'undefined');
var xslt = {
	/**
	* @param {!string} xsl
	*/
	init: function(xsl)
	{
		var stylesheet = xslt.loadXML(xsl);
		if (MSXML)
		{
			var generator = new ActiveXObject('MSXML2.XSLTemplate.6.0');
			generator['stylesheet'] = stylesheet;
			xslt.proc = generator['createProcessor']();
		}
		else
		{
			xslt.proc = new XSLTProcessor;
			xslt.proc['importStylesheet'](stylesheet);
		}
	},

	/**
	* @param {string} xml
	*/
	loadXML: function(xml)
	{
		if (MSXML)
		{
			var dom = new ActiveXObject('MSXML2.FreeThreadedDOMDocument.6.0');
			dom['async'] = false;
			dom['validateOnParse'] = false;
			dom['loadXML'](xml);

			return dom;
		}

		return (new DOMParser).parseFromString(xml, 'text/xml');
	},

	/**
	* @param {!string} paramName  Parameter name
	* @param {!string} paramValue Parameter's value
	*/
	setParameter: function(paramName, paramValue)
	{
		if (MSXML)
		{
			xslt.proc['addParameter'](paramName, paramValue, '');
		}
		else
		{
			xslt.proc['setParameter'](null, paramName, paramValue);
		}
	},

	/**
	* @param {!string} xml
	* @param {!HTMLDocument} targetDoc
	*/
	transformToFragment: function(xml, targetDoc)
	{
		if (MSXML)
		{
			var div = targetDoc.createElement('div'),
				fragment = targetDoc.createDocumentFragment();

			xslt.proc['input'] = xslt.loadXML(xml);
			xslt.proc['transform']();
			div.innerHTML = xslt.proc['output'];
			while (div.firstChild)
			{
				fragment.appendChild(div.firstChild);
			}

			return fragment;
		}

		// NOTE: importNode() is used because of https://code.google.com/p/chromium/issues/detail?id=266305
		return targetDoc.importNode(xslt.proc['transformToFragment'](xslt.loadXML(xml), targetDoc), true);
	}
}
xslt.init(xsl);

var postProcessFunctions = {};

/**
* Parse a given text and render it into given HTML element
*
* @param  {!string} text
* @param  {!HTMLElement} target
* @return {!Node}
*/
function preview(text, target)
{
	var targetDoc      = target.ownerDocument,
		resultFragment = xslt.transformToFragment(parse(text).replace(/<[eis]>.*?<\/[eis]>/g, ''), targetDoc),
		lastUpdated    = target;

	// Apply post-processing
	if (HINT.postProcessing)
	{
		var nodes = resultFragment.querySelectorAll('[data-s9e-livepreview-postprocess]'),
			i     = nodes.length;
		while (--i >= 0)
		{
			/** @type {!string} */
			var code = nodes[i]['getAttribute']('data-s9e-livepreview-postprocess');
			if (!postProcessFunctions[code])
			{
				postProcessFunctions[code] = new Function(code);
			}

			postProcessFunctions[code]['call'](nodes[i]);
		}
	}

	/**
	* Update the content of given element oldEl to match element newEl
	*
	* @param {!HTMLElement} oldEl
	* @param {!HTMLElement} newEl
	*/
	function refreshElementContent(oldEl, newEl)
	{
		var oldNodes = oldEl.childNodes,
			newNodes = newEl.childNodes,
			oldCnt   = oldNodes.length,
			newCnt   = newNodes.length,
			oldNode,
			newNode,
			left     = 0,
			right    = 0;

		// Skip the leftmost matching nodes
		while (left < oldCnt && left < newCnt)
		{
			oldNode = oldNodes[left];
			newNode = newNodes[left];
			if (!refreshNode(oldNode, newNode))
			{
				break;
			}

			++left;
		}

		// Skip the rightmost matching nodes
		var maxRight = Math.min(oldCnt - left, newCnt - left);
		while (right < maxRight)
		{
			oldNode = oldNodes[oldCnt - (right + 1)];
			newNode = newNodes[newCnt - (right + 1)];
			if (!refreshNode(oldNode, newNode))
			{
				break;
			}

			++right;
		}

		// Remove the old dirty nodes in the middle of the tree
		var i = oldCnt - right;
		while (--i >= left)
		{
			oldEl.removeChild(oldNodes[i]);
			lastUpdated = oldEl;
		}

		// Test whether there are any nodes in the new tree between the matching nodes at the left
		// and the matching nodes at the right
		var rightBoundary = newCnt - right;
		if (left >= rightBoundary)
		{
			return;
		}

		// Clone the new nodes
		var newNodesFragment = targetDoc.createDocumentFragment();
		i = left;
		do
		{
			lastUpdated = newNodesFragment.appendChild(newNodes[i]);
		}
		while (i < --rightBoundary);

		// If we haven't skipped any nodes to the right, we can just append the fragment
		if (!right)
		{
			oldEl.appendChild(newNodesFragment);
		}
		else
		{
			oldEl.insertBefore(newNodesFragment, oldEl.childNodes[left]);
		}
	}

	/**
	* Update given node oldNode to make it match newNode
	*
	* @param {!HTMLElement} oldNode
	* @param {!HTMLElement} newNode
	* @return boolean Whether the node can be skipped
	*/
	function refreshNode(oldNode, newNode)
	{
		if (oldNode.nodeName !== newNode.nodeName
		 || oldNode.nodeType !== newNode.nodeType)
		{
			return false;
		}

		// Node.TEXT_NODE || Node.COMMENT_NODE
		if (oldNode.nodeType === 3 || oldNode.nodeType === 8)
		{
			if (oldNode.nodeValue !== newNode.nodeValue)
			{
				oldNode.nodeValue = newNode.nodeValue;
				lastUpdated = oldNode;
			}

			return true;
		}

		if (!oldNode.isEqualNode || !oldNode.isEqualNode(newNode))
		{
			syncElementAttributes(oldNode, newNode);
			refreshElementContent(oldNode, newNode);
		}

		return true;
	}

	/**
	* Make the set of attributes of given element oldEl match newEl's
	*
	* @param {!HTMLElement} oldEl
	* @param {!HTMLElement} newEl
	*/
	function syncElementAttributes(oldEl, newEl)
	{
		var oldAttributes = oldEl['attributes'],
			newAttributes = newEl['attributes'],
			oldCnt        = oldAttributes.length,
			newCnt        = newAttributes.length,
			i             = oldCnt,
			ignoreAttrs   = ' ' + oldEl['getAttribute']('data-s9e-livepreview-ignore-attrs') + ' ';

		while (--i >= 0)
		{
			var oldAttr      = oldAttributes[i],
				namespaceURI = oldAttr['namespaceURI'],
				attrName     = oldAttr['name'];

			if (HINT.ignoreAttrs && ignoreAttrs.indexOf(' ' + attrName + ' ') > -1)
			{
				continue;
			}
			if (!newEl.hasAttributeNS(namespaceURI, attrName))
			{
				oldEl.removeAttributeNS(namespaceURI, attrName);
				lastUpdated = oldEl;
			}
		}

		i = newCnt;
		while (--i >= 0)
		{
			var newAttr      = newAttributes[i],
				namespaceURI = newAttr['namespaceURI'],
				attrName     = newAttr['name'],
				attrValue    = newAttr['value'];

			if (HINT.ignoreAttrs && ignoreAttrs.indexOf(' ' + attrName + ' ') > -1)
			{
				continue;
			}
			if (attrValue !== oldEl.getAttributeNS(namespaceURI, attrName))
			{
				oldEl.setAttributeNS(namespaceURI, attrName, attrValue);
				lastUpdated = oldEl;
			}
		}
	}

	refreshElementContent(target, resultFragment);

	return lastUpdated;
}

/**
* Set the value of a stylesheet parameter
*
* @param {!string} paramName  Parameter name
* @param {!string} paramValue Parameter's value
*/
function setParameter(paramName, paramValue)
{
	xslt.setParameter(paramName, paramValue);
}<commit_msg>Reorganized DOM diffing in live preview<commit_after>var MSXML = (typeof DOMParser === 'undefined' || typeof XSLTProcessor === 'undefined');
var xslt = {
	/**
	* @param {!string} xsl
	*/
	init: function(xsl)
	{
		var stylesheet = xslt.loadXML(xsl);
		if (MSXML)
		{
			var generator = new ActiveXObject('MSXML2.XSLTemplate.6.0');
			generator['stylesheet'] = stylesheet;
			xslt.proc = generator['createProcessor']();
		}
		else
		{
			xslt.proc = new XSLTProcessor;
			xslt.proc['importStylesheet'](stylesheet);
		}
	},

	/**
	* @param {string} xml
	*/
	loadXML: function(xml)
	{
		if (MSXML)
		{
			var dom = new ActiveXObject('MSXML2.FreeThreadedDOMDocument.6.0');
			dom['async'] = false;
			dom['validateOnParse'] = false;
			dom['loadXML'](xml);

			return dom;
		}

		return (new DOMParser).parseFromString(xml, 'text/xml');
	},

	/**
	* @param {!string} paramName  Parameter name
	* @param {!string} paramValue Parameter's value
	*/
	setParameter: function(paramName, paramValue)
	{
		if (MSXML)
		{
			xslt.proc['addParameter'](paramName, paramValue, '');
		}
		else
		{
			xslt.proc['setParameter'](null, paramName, paramValue);
		}
	},

	/**
	* @param {!string} xml
	* @param {!HTMLDocument} targetDoc
	*/
	transformToFragment: function(xml, targetDoc)
	{
		if (MSXML)
		{
			var div = targetDoc.createElement('div'),
				fragment = targetDoc.createDocumentFragment();

			xslt.proc['input'] = xslt.loadXML(xml);
			xslt.proc['transform']();
			div.innerHTML = xslt.proc['output'];
			while (div.firstChild)
			{
				fragment.appendChild(div.firstChild);
			}

			return fragment;
		}

		// NOTE: importNode() is used because of https://code.google.com/p/chromium/issues/detail?id=266305
		return targetDoc.importNode(xslt.proc['transformToFragment'](xslt.loadXML(xml), targetDoc), true);
	}
}
xslt.init(xsl);

var postProcessFunctions = {};

/**
* Parse a given text and render it into given HTML element
*
* @param  {!string} text
* @param  {!HTMLElement} target
* @return {!Node}
*/
function preview(text, target)
{
	var targetDoc      = target.ownerDocument,
		resultFragment = xslt.transformToFragment(parse(text).replace(/<[eis]>.*?<\/[eis]>/g, ''), targetDoc),
		lastUpdated    = target;

	// Apply post-processing
	if (HINT.postProcessing)
	{
		var nodes = resultFragment.querySelectorAll('[data-s9e-livepreview-postprocess]'),
			i     = nodes.length;
		while (--i >= 0)
		{
			/** @type {!string} */
			var code = nodes[i]['getAttribute']('data-s9e-livepreview-postprocess');
			if (!postProcessFunctions[code])
			{
				postProcessFunctions[code] = new Function(code);
			}

			postProcessFunctions[code]['call'](nodes[i]);
		}
	}

	/**
	* Update the content of given element oldEl to match element newEl
	*
	* @param {!HTMLElement} oldEl
	* @param {!HTMLElement} newEl
	*/
	function refreshElementContent(oldEl, newEl)
	{
		var oldNodes = oldEl.childNodes,
			newNodes = newEl.childNodes,
			oldCnt   = oldNodes.length,
			newCnt   = newNodes.length,
			oldNode,
			newNode,
			left     = 0,
			right    = 0;

		// Skip the leftmost matching nodes
		while (left < oldCnt && left < newCnt)
		{
			oldNode = oldNodes[left];
			newNode = newNodes[left];
			if (!refreshNode(oldNode, newNode))
			{
				break;
			}

			++left;
		}

		// Skip the rightmost matching nodes
		var maxRight = Math.min(oldCnt - left, newCnt - left);
		while (right < maxRight)
		{
			oldNode = oldNodes[oldCnt - (right + 1)];
			newNode = newNodes[newCnt - (right + 1)];
			if (!refreshNode(oldNode, newNode))
			{
				break;
			}

			++right;
		}

		// Remove the old dirty nodes in the middle of the tree
		var i = oldCnt - right;
		while (--i >= left)
		{
			oldEl.removeChild(oldNodes[i]);
			lastUpdated = oldEl;
		}

		// Test whether there are any nodes in the new tree between the matching nodes at the left
		// and the matching nodes at the right
		var rightBoundary = newCnt - right;
		if (left >= rightBoundary)
		{
			return;
		}

		// Clone the new nodes
		var newNodesFragment = targetDoc.createDocumentFragment();
		i = left;
		do
		{
			lastUpdated = newNodesFragment.appendChild(newNodes[i]);
		}
		while (i < --rightBoundary);

		// If we haven't skipped any nodes to the right, we can just append the fragment
		if (!right)
		{
			oldEl.appendChild(newNodesFragment);
		}
		else
		{
			oldEl.insertBefore(newNodesFragment, oldEl.childNodes[left]);
		}
	}

	/**
	* Update given node oldNode to make it match newNode
	*
	* @param {!Node} oldNode
	* @param {!Node} newNode
	* @return {boolean} Whether the node can be skipped
	*/
	function refreshNode(oldNode, newNode)
	{
		if (oldNode.nodeName !== newNode.nodeName || oldNode.nodeType !== newNode.nodeType)
		{
			return false;
		}

		if (oldNode instanceof HTMLElement && newNode instanceof HTMLElement)
		{
			if (!oldNode.isEqualNode(newNode))
			{
				syncElementAttributes(oldNode, newNode);
				refreshElementContent(oldNode, newNode);
			}
		}
		// Node.TEXT_NODE || Node.COMMENT_NODE
		else if (oldNode.nodeType === 3 || oldNode.nodeType === 8)
		{
			if (oldNode.nodeValue !== newNode.nodeValue)
			{
				oldNode.nodeValue = newNode.nodeValue;
				lastUpdated = oldNode;
			}
		}

		return true;
	}

	/**
	* Make the set of attributes of given element oldEl match newEl's
	*
	* @param {!HTMLElement} oldEl
	* @param {!HTMLElement} newEl
	*/
	function syncElementAttributes(oldEl, newEl)
	{
		var oldAttributes = oldEl['attributes'],
			newAttributes = newEl['attributes'],
			oldCnt        = oldAttributes.length,
			newCnt        = newAttributes.length,
			i             = oldCnt,
			ignoreAttrs   = ' ' + oldEl['getAttribute']('data-s9e-livepreview-ignore-attrs') + ' ';

		while (--i >= 0)
		{
			var oldAttr      = oldAttributes[i],
				namespaceURI = oldAttr['namespaceURI'],
				attrName     = oldAttr['name'];

			if (HINT.ignoreAttrs && ignoreAttrs.indexOf(' ' + attrName + ' ') > -1)
			{
				continue;
			}
			if (!newEl.hasAttributeNS(namespaceURI, attrName))
			{
				oldEl.removeAttributeNS(namespaceURI, attrName);
				lastUpdated = oldEl;
			}
		}

		i = newCnt;
		while (--i >= 0)
		{
			var newAttr      = newAttributes[i],
				namespaceURI = newAttr['namespaceURI'],
				attrName     = newAttr['name'],
				attrValue    = newAttr['value'];

			if (HINT.ignoreAttrs && ignoreAttrs.indexOf(' ' + attrName + ' ') > -1)
			{
				continue;
			}
			if (attrValue !== oldEl.getAttributeNS(namespaceURI, attrName))
			{
				oldEl.setAttributeNS(namespaceURI, attrName, attrValue);
				lastUpdated = oldEl;
			}
		}
	}

	refreshElementContent(target, resultFragment);

	return lastUpdated;
}

/**
* Set the value of a stylesheet parameter
*
* @param {!string} paramName  Parameter name
* @param {!string} paramValue Parameter's value
*/
function setParameter(paramName, paramValue)
{
	xslt.setParameter(paramName, paramValue);
}<|endoftext|>


<commit_before>/* =========================================================
 * bootstrap-pincode-input.js
 *
 * =========================================================
 * Created by Ferry Kranenburg
 *
 * 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.
 * ========================================================= */

;(function ($, window, document, undefined) {

	"use strict";

	// Create the defaults once
	var pluginName = "pincodeInput";
	var defaults = {
		placeholders: undefined,						// seperate with a " "(space) to set an placeholder for each input box
		inputs: 4,									    // 4 input boxes = code of 4 digits long
		hidedigits: true,								// hide digits
		pattern: '[0-9]*',
		inputtype: 'number',
		inputmode: 'numeric',
		inputclass: '',									// could be changed to form-control-lg or any other class
		letterspacingfix: 2.8,							// this value could be changed when the digits are not completely visible in touch device mode
		keydown: function (e) {
		},
		change: function (input, value, inputnumber) {		// callback on every input on change (keyup event)
			//input = the input textbox DOM element
			//value = the value entered by user (or removed)
			//inputnumber = the position of the input box (in touch mode we only have 1 big input box, so always 1 is returned here)
		},
		complete: function (value, e, errorElement) {	// callback when all inputs are filled in (keyup event)
			//value = the entered code
			//e = last keyup event
			//errorElement = error span next to to this, fill with html e.g. : $(errorElement).html("Code not correct");
		}

	};

	// The actual plugin constructor
	function Plugin(element, options) {
		this.element = element;
		this.settings = $.extend({}, defaults, options);
		this._defaults = defaults;
		this._name = pluginName;
		this.init();
	}

	// Avoid Plugin.prototype conflicts
	$.extend(Plugin.prototype, {
		init: function () {
			this.buildInputBoxes();

		},
		updateOriginalInput: function () {
			var newValue = "";
			$('.pincode-input-text', this._container).each(function (index, value) {
				newValue += $(value).val().toString();
			});
			$(this.element).val(newValue);
		},
		check: function () {
			var isComplete = true;
			var code = "";
			$('.pincode-input-text', this._container).each(function (index, value) {
				code += $(value).val().toString();
				if (!$(value).val()) {
					isComplete = false;
				}
			});

			if (this._isTouchDevice()) {
				// check if single input has it all
				if (code.length == this.settings.inputs) {
					return true;
				}
			} else {
				return isComplete;
			}

		},
		buildInputBoxes: function () {
			this._container = $('<div />').addClass('pincode-input-container');

			var currentValue = [];
			var placeholders = [];
			var touchplaceholders = "";  // in touch mode we have just 1 big input box, and there is only 1 placeholder in this case

			if (this.settings.placeholders) {
				placeholders = this.settings.placeholders.split(" ");
				touchplaceholders = this.settings.placeholders.replace(/ /g, "");
			}

			// If we do not hide digits, we need to include the current value of the input box
			// This will only work if the current value is not longer than the number of input boxes.
			if (this.settings.hidedigits == false && $(this.element).val() != "") {
				currentValue = $(this.element).val().split("");
			}

			// make sure this is the first password field here
			if (this.settings.hidedigits) {
				this._pwcontainer = $('<div />').css("display", "none").appendTo(this._container);
				this._pwfield = $('<input>').attr({
                    'type': this.settings.inputtype,
					'pattern': this.settings.pattern,
					'inputmode': this.settings.inputmode,
					'id': 'preventautofill',
					'autocomplete': 'off'
				}).addClass('pincode-input-text-masked').appendTo(this._pwcontainer);
			}

			if (this._isTouchDevice()) {
				// set main class
				$(this._container).addClass("touch");

				// For touch devices we build a html table directly under the pincode textbox. The textbox will become transparent
				// This table is used for styling only, it will display how many 'digits' the user should fill in.
				// With CSS letter-spacing we try to put every digit visually insize each table cell.

				var wrapper = $('<div />').addClass('touchwrapper touch' + this.settings.inputs).appendTo(this._container);
				var input = $('<input>').attr({
					'type': this.settings.inputtype,
					'pattern': this.settings.pattern,
					'inputmode': this.settings.inputmode,
					'placeholder': touchplaceholders,
					'maxlength': this.settings.inputs,
					'autocomplete': 'off'
				}).addClass(this.settings.inputclass + ' form-control pincode-input-text').appendTo(wrapper);

				// calculate letter-spacing in Javascript since this isn't possible in CSS
				var inputs = this.settings.inputs;
				var letterspacingfix = this.settings.letterspacingfix;
				setTimeout(function(){
					var width = $(input).innerWidth() - ((inputs + letterspacingfix) * inputs);
					var spacing = (width / inputs) ;
					$(input).css({"letter-spacing":spacing + "px"});
				},0);

				var touchtable = $('<div>').addClass('touch-flex').appendTo(wrapper);
				// create touch background elements (for showing user how many digits must be entered)
				for (var i = 0; i < this.settings.inputs; i++) {
					if (i == (this.settings.inputs - 1)) {
						$('<div/>').addClass('touch-flex-cell').addClass('last').appendTo(touchtable);
					} else {
						$('<div/>').addClass('touch-flex-cell').appendTo(touchtable);
					}
				}
				if (this.settings.hidedigits) {
					// hide digits
					input.addClass('pincode-input-text-masked');
				} else {
					// show digits, also include default value
					input.val($(this.element).val());
                }

				// add events
				this._addEventsToInput(input, 1);

			} else {
				// for desktop mode we build one input for each digit
				for (var i = 0; i < this.settings.inputs; i++) {

					var input = $('<input>').attr({
						'type': 'text',
						'maxlength': "1",
						'autocomplete': 'off',
						'placeholder': (placeholders[i] ? placeholders[i] : undefined)
					}).addClass(this.settings.inputclass + ' form-control pincode-input-text').appendTo(this._container);
					if (this.settings.hidedigits) {
						// hide digits
						input.addClass('pincode-input-text-masked');
					} else {
						// show digits, also include default value
						input.val(currentValue[i]);
					}

					if (i == 0) {
						input.addClass('first');
					} else if (i == (this.settings.inputs - 1)) {
						input.addClass('last');
					} else {
						input.addClass('mid');
					}

					// add events
					this._addEventsToInput(input, (i + 1));
				}
			}

			// hide original element and place this before it
			$(this.element).css("display", "none");
			this._container.insertBefore(this.element);

			// error box
			this._error = $('<div />').addClass('text-danger pincode-input-error').insertBefore(this.element);

		},
		enable: function () {
			$('.pincode-input-text', this._container).each(function (index, value) {
				$(value).prop('disabled', false);
			});
		},
		disable: function () {
			$('.pincode-input-text', this._container).each(function (index, value) {
				$(value).prop('disabled', true);
			});
		},
		focus: function () {
			$('.pincode-input-text', this._container).first().select().focus();
		},
		clear: function () {
			$('.pincode-input-text', this._container).each(function (index, value) {
				$(value).val("");
			});
			this.updateOriginalInput();
		},
		_setValue:function(newValue, e){

			// slice value
			var value = newValue.substring(0,this.settings.inputs);

			if (this._isTouchDevice()) {

				// update value
				$('.pincode-input-text', this._container).each(function (index, input) {
					$(input).val(value);
				});

				// a hack to prevent visual issues on mobile devices
				$(this.element).addClass("noletterspacing");
				$(this.element).select();
				$(this.element).blur();
				$(this.element).removeClass("noletterspacing");

				// update original input box
				this.updateOriginalInput();

				// oncomplete check
				if (this.check()) {
					this.settings.complete($(this.element).val(), e, this._error);
				}

			}else{

				var values = value.split('');

				$('.pincode-input-text', this._container).each(function (index, input) {
					$(input).val(values[index]);
				});

				// update original input box
				this.updateOriginalInput();

				// oncomplete check
				if (this.check()) {
					this.settings.complete($(this.element).val(), e, this._error);
				}

			}

		},
		_isTouchDevice: function () {
			// I know, sniffing is a really bad idea, but it works 99% of the times
			if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
				return true;
			}
		},
		_addEventsToInput: function (input, inputnumber) {

			input.on('focus', function (e) {
				this.select();  // automatically select current value
			});

			// paste event should call onchange and oncomplete callbacks
			input.on('paste', $.proxy(function (e) {
				e.preventDefault();

				var clipboardData =  (e.originalEvent || e).clipboardData || window.clipboardData;
    			var pastedData = clipboardData.getData('text/plain');

				this._setValue(pastedData,e);

			},this));

			input.on('keydown', $.proxy(function (e) {
				if (this._pwfield) {
					// Because we need to prevent password saving by browser
					// remove the value here and change the type!
					// we do this every time the user types
					$(this._pwfield).attr({'type': 'text'});
					$(this._pwfield).val("");
				}

				// prevent more input for touch device (we can't limit it)
				if (this._isTouchDevice()) {
					if (e.keyCode == 8 || e.keyCode == 46) {
						// do nothing on backspace and delete
					} else if ($(this.element).val().length == this.settings.inputs) {
						e.preventDefault();
						e.stopPropagation();
					}

				} else {
					// in desktop mode, check if an number was entered

					if (!(e.keyCode == 8                            // backspace key
						|| e.keyCode == 9							// tab key
						|| e.keyCode == 46                          // delete key
						|| (e.keyCode >= 48 && e.keyCode <= 57)     // numbers on keyboard
						|| (e.keyCode >= 96 && e.keyCode <= 105)    // number on keypad
						|| ((this.settings.inputtype != 'number' && this.settings.inputtype != 'tel') && e.keyCode >= 65 && e.keyCode <= 90))   // alphabet
					) {
						e.preventDefault();     // Prevent character input
						e.stopPropagation();
					}

				}

				this.settings.keydown(e);
			}, this));

			input.on('keyup', $.proxy(function (e) {
				// after every keystroke we check if all inputs have a value, if yes we call complete callback
				if (!this._isTouchDevice()) {
					// on backspace or delete go to previous input box
					if (e.keyCode == 8 || e.keyCode == 46) {
						// goto previous
						$(e.currentTarget).prev().select();
						$(e.currentTarget).prev().focus();
					} else if ($(e.currentTarget).val() != "") {
						$(e.currentTarget).next().select();
						$(e.currentTarget).next().focus();
					}
				}

				// update original input box
				this.updateOriginalInput();

				// oncomplete check
				if (this.check()) {
					this.settings.complete($(this.element).val(), e, this._error);
				}

				// onchange event for each input
				if (this.settings.change) {
					this.settings.change(e.currentTarget, $(e.currentTarget).val(), inputnumber);
				}

				// prevent more input for touch device (we can't limit it)
				if (this._isTouchDevice()) {
					if (e.keyCode == 8 || e.keyCode == 46) {
						// do nothing on backspace and delete
					} else if ($(this.element).val().length == this.settings.inputs) {
						$(e.currentTarget).addClass("noletterspacing");

						$(e.currentTarget).select();
						$(e.currentTarget).blur();

						$(e.currentTarget).removeClass("noletterspacing");

					}
				}

			}, this));

		}

	});

	// A really lightweight plugin wrapper around the constructor,
	// preventing against multiple instantiations
	$.fn[pluginName] = function (options) {
		return this.each(function () {
			if (!$.data(this, "plugin_" + pluginName)) {
				$.data(this, "plugin_" + pluginName, new Plugin(this, options));
			}
		});
	};

})(jQuery, window, document);
<commit_msg>Detect iPad Pro as a touchscreen device<commit_after>/* =========================================================
 * bootstrap-pincode-input.js
 *
 * =========================================================
 * Created by Ferry Kranenburg
 *
 * 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.
 * ========================================================= */

;(function ($, window, document, undefined) {

	"use strict";

	// Create the defaults once
	var pluginName = "pincodeInput";
	var defaults = {
		placeholders: undefined,						// seperate with a " "(space) to set an placeholder for each input box
		inputs: 4,									    // 4 input boxes = code of 4 digits long
		hidedigits: true,								// hide digits
		pattern: '[0-9]*',
		inputtype: 'number',
		inputmode: 'numeric',
		inputclass: '',									// could be changed to form-control-lg or any other class
		letterspacingfix: 2.8,							// this value could be changed when the digits are not completely visible in touch device mode
		keydown: function (e) {
		},
		change: function (input, value, inputnumber) {		// callback on every input on change (keyup event)
			//input = the input textbox DOM element
			//value = the value entered by user (or removed)
			//inputnumber = the position of the input box (in touch mode we only have 1 big input box, so always 1 is returned here)
		},
		complete: function (value, e, errorElement) {	// callback when all inputs are filled in (keyup event)
			//value = the entered code
			//e = last keyup event
			//errorElement = error span next to to this, fill with html e.g. : $(errorElement).html("Code not correct");
		}

	};

	// The actual plugin constructor
	function Plugin(element, options) {
		this.element = element;
		this.settings = $.extend({}, defaults, options);
		this._defaults = defaults;
		this._name = pluginName;
		this.init();
	}

	// Avoid Plugin.prototype conflicts
	$.extend(Plugin.prototype, {
		init: function () {
			this.buildInputBoxes();

		},
		updateOriginalInput: function () {
			var newValue = "";
			$('.pincode-input-text', this._container).each(function (index, value) {
				newValue += $(value).val().toString();
			});
			$(this.element).val(newValue);
		},
		check: function () {
			var isComplete = true;
			var code = "";
			$('.pincode-input-text', this._container).each(function (index, value) {
				code += $(value).val().toString();
				if (!$(value).val()) {
					isComplete = false;
				}
			});

			if (this._isTouchDevice()) {
				// check if single input has it all
				if (code.length == this.settings.inputs) {
					return true;
				}
			} else {
				return isComplete;
			}

		},
		buildInputBoxes: function () {
			this._container = $('<div />').addClass('pincode-input-container');

			var currentValue = [];
			var placeholders = [];
			var touchplaceholders = "";  // in touch mode we have just 1 big input box, and there is only 1 placeholder in this case

			if (this.settings.placeholders) {
				placeholders = this.settings.placeholders.split(" ");
				touchplaceholders = this.settings.placeholders.replace(/ /g, "");
			}

			// If we do not hide digits, we need to include the current value of the input box
			// This will only work if the current value is not longer than the number of input boxes.
			if (this.settings.hidedigits == false && $(this.element).val() != "") {
				currentValue = $(this.element).val().split("");
			}

			// make sure this is the first password field here
			if (this.settings.hidedigits) {
				this._pwcontainer = $('<div />').css("display", "none").appendTo(this._container);
				this._pwfield = $('<input>').attr({
                    'type': this.settings.inputtype,
					'pattern': this.settings.pattern,
					'inputmode': this.settings.inputmode,
					'id': 'preventautofill',
					'autocomplete': 'off'
				}).addClass('pincode-input-text-masked').appendTo(this._pwcontainer);
			}

			if (this._isTouchDevice()) {
				// set main class
				$(this._container).addClass("touch");

				// For touch devices we build a html table directly under the pincode textbox. The textbox will become transparent
				// This table is used for styling only, it will display how many 'digits' the user should fill in.
				// With CSS letter-spacing we try to put every digit visually insize each table cell.

				var wrapper = $('<div />').addClass('touchwrapper touch' + this.settings.inputs).appendTo(this._container);
				var input = $('<input>').attr({
					'type': this.settings.inputtype,
					'pattern': this.settings.pattern,
					'inputmode': this.settings.inputmode,
					'placeholder': touchplaceholders,
					'maxlength': this.settings.inputs,
					'autocomplete': 'off'
				}).addClass(this.settings.inputclass + ' form-control pincode-input-text').appendTo(wrapper);

				// calculate letter-spacing in Javascript since this isn't possible in CSS
				var inputs = this.settings.inputs;
				var letterspacingfix = this.settings.letterspacingfix;
				setTimeout(function(){
					var width = $(input).innerWidth() - ((inputs + letterspacingfix) * inputs);
					var spacing = (width / inputs) ;
					$(input).css({"letter-spacing":spacing + "px"});
				},0);

				var touchtable = $('<div>').addClass('touch-flex').appendTo(wrapper);
				// create touch background elements (for showing user how many digits must be entered)
				for (var i = 0; i < this.settings.inputs; i++) {
					if (i == (this.settings.inputs - 1)) {
						$('<div/>').addClass('touch-flex-cell').addClass('last').appendTo(touchtable);
					} else {
						$('<div/>').addClass('touch-flex-cell').appendTo(touchtable);
					}
				}
				if (this.settings.hidedigits) {
					// hide digits
					input.addClass('pincode-input-text-masked');
				} else {
					// show digits, also include default value
					input.val($(this.element).val());
                }

				// add events
				this._addEventsToInput(input, 1);

			} else {
				// for desktop mode we build one input for each digit
				for (var i = 0; i < this.settings.inputs; i++) {

					var input = $('<input>').attr({
						'type': 'text',
						'maxlength': "1",
						'autocomplete': 'off',
						'placeholder': (placeholders[i] ? placeholders[i] : undefined)
					}).addClass(this.settings.inputclass + ' form-control pincode-input-text').appendTo(this._container);
					if (this.settings.hidedigits) {
						// hide digits
						input.addClass('pincode-input-text-masked');
					} else {
						// show digits, also include default value
						input.val(currentValue[i]);
					}

					if (i == 0) {
						input.addClass('first');
					} else if (i == (this.settings.inputs - 1)) {
						input.addClass('last');
					} else {
						input.addClass('mid');
					}

					// add events
					this._addEventsToInput(input, (i + 1));
				}
			}

			// hide original element and place this before it
			$(this.element).css("display", "none");
			this._container.insertBefore(this.element);

			// error box
			this._error = $('<div />').addClass('text-danger pincode-input-error').insertBefore(this.element);

		},
		enable: function () {
			$('.pincode-input-text', this._container).each(function (index, value) {
				$(value).prop('disabled', false);
			});
		},
		disable: function () {
			$('.pincode-input-text', this._container).each(function (index, value) {
				$(value).prop('disabled', true);
			});
		},
		focus: function () {
			$('.pincode-input-text', this._container).first().select().focus();
		},
		clear: function () {
			$('.pincode-input-text', this._container).each(function (index, value) {
				$(value).val("");
			});
			this.updateOriginalInput();
		},
		_setValue:function(newValue, e){

			// slice value
			var value = newValue.substring(0,this.settings.inputs);

			if (this._isTouchDevice()) {

				// update value
				$('.pincode-input-text', this._container).each(function (index, input) {
					$(input).val(value);
				});

				// a hack to prevent visual issues on mobile devices
				$(this.element).addClass("noletterspacing");
				$(this.element).select();
				$(this.element).blur();
				$(this.element).removeClass("noletterspacing");

				// update original input box
				this.updateOriginalInput();

				// oncomplete check
				if (this.check()) {
					this.settings.complete($(this.element).val(), e, this._error);
				}

			}else{

				var values = value.split('');

				$('.pincode-input-text', this._container).each(function (index, input) {
					$(input).val(values[index]);
				});

				// update original input box
				this.updateOriginalInput();

				// oncomplete check
				if (this.check()) {
					this.settings.complete($(this.element).val(), e, this._error);
				}

			}

		},
		_isTouchDevice: function () {
			// I know, sniffing is a really bad idea, but it works 99% of the times
			if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
				return true;
			}
			// iPad Pro pretends to be a Mac, but Macs don't have touch controls
			if (navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1) {
				return true;
			}
		},
		_addEventsToInput: function (input, inputnumber) {

			input.on('focus', function (e) {
				this.select();  // automatically select current value
			});

			// paste event should call onchange and oncomplete callbacks
			input.on('paste', $.proxy(function (e) {
				e.preventDefault();

				var clipboardData =  (e.originalEvent || e).clipboardData || window.clipboardData;
    			var pastedData = clipboardData.getData('text/plain');

				this._setValue(pastedData,e);

			},this));

			input.on('keydown', $.proxy(function (e) {
				if (this._pwfield) {
					// Because we need to prevent password saving by browser
					// remove the value here and change the type!
					// we do this every time the user types
					$(this._pwfield).attr({'type': 'text'});
					$(this._pwfield).val("");
				}

				// prevent more input for touch device (we can't limit it)
				if (this._isTouchDevice()) {
					if (e.keyCode == 8 || e.keyCode == 46) {
						// do nothing on backspace and delete
					} else if ($(this.element).val().length == this.settings.inputs) {
						e.preventDefault();
						e.stopPropagation();
					}

				} else {
					// in desktop mode, check if an number was entered

					if (!(e.keyCode == 8                            // backspace key
						|| e.keyCode == 9							// tab key
						|| e.keyCode == 46                          // delete key
						|| (e.keyCode >= 48 && e.keyCode <= 57)     // numbers on keyboard
						|| (e.keyCode >= 96 && e.keyCode <= 105)    // number on keypad
						|| ((this.settings.inputtype != 'number' && this.settings.inputtype != 'tel') && e.keyCode >= 65 && e.keyCode <= 90))   // alphabet
					) {
						e.preventDefault();     // Prevent character input
						e.stopPropagation();
					}

				}

				this.settings.keydown(e);
			}, this));

			input.on('keyup', $.proxy(function (e) {
				// after every keystroke we check if all inputs have a value, if yes we call complete callback
				if (!this._isTouchDevice()) {
					// on backspace or delete go to previous input box
					if (e.keyCode == 8 || e.keyCode == 46) {
						// goto previous
						$(e.currentTarget).prev().select();
						$(e.currentTarget).prev().focus();
					} else if ($(e.currentTarget).val() != "") {
						$(e.currentTarget).next().select();
						$(e.currentTarget).next().focus();
					}
				}

				// update original input box
				this.updateOriginalInput();

				// oncomplete check
				if (this.check()) {
					this.settings.complete($(this.element).val(), e, this._error);
				}

				// onchange event for each input
				if (this.settings.change) {
					this.settings.change(e.currentTarget, $(e.currentTarget).val(), inputnumber);
				}

				// prevent more input for touch device (we can't limit it)
				if (this._isTouchDevice()) {
					if (e.keyCode == 8 || e.keyCode == 46) {
						// do nothing on backspace and delete
					} else if ($(this.element).val().length == this.settings.inputs) {
						$(e.currentTarget).addClass("noletterspacing");

						$(e.currentTarget).select();
						$(e.currentTarget).blur();

						$(e.currentTarget).removeClass("noletterspacing");

					}
				}

			}, this));

		}

	});

	// A really lightweight plugin wrapper around the constructor,
	// preventing against multiple instantiations
	$.fn[pluginName] = function (options) {
		return this.each(function () {
			if (!$.data(this, "plugin_" + pluginName)) {
				$.data(this, "plugin_" + pluginName, new Plugin(this, options));
			}
		});
	};

})(jQuery, window, document);
<|endoftext|>


<commit_before>class VectorAim extends Phaser.Graphics {
	constructor(game, x, y) {
		super(game, x, y);

        //this._points = [];
        this.p0 = new Phaser.Point(0, 0);
        //this._points.push(p0);

        this.fixedToCamera = false;
        this.render();

		this.game.world.add(this);
	}

    update() {
        var pointer = this.game.input.mousePointer; //activePointer;
        this.p0.x = pointer.worldX;
        this.p0.y = pointer.worldY;
        this.render()
    }

    render() {
        this.clear();

        var object_x = this.x;
        var object_y = this.y;

        this.lineStyle(1, 0xffff00);

        this.beginFill(0xff0000);
        this.drawCircle(0, 0, 100);
        this.endFill();

        this.lineStyle(1, 0xffff00);
        this.moveTo(0,0);
        this.lineTo(this.p0.x-object_x, this.p0.y-object_y);

        this.beginFill(0xffff00);
        this.drawRect(0-2, 0-2, 4, 4);
        this.endFill();

        this.beginFill(0xfff000);
        this.drawRect(this.p0.x-object_x-2, this.p0.y-object_y-2, 4, 4);
        this.endFill();
    }
}

export default VectorAim;
<commit_msg>Less long line.<commit_after>class VectorAim extends Phaser.Graphics {
	constructor(game, x, y) {
		super(game, x, y);

        //this._points = [];
        this.world_mouse_coords = new Phaser.Point(0, 0);
        //this._points.push(p0);

        this.fixedToCamera = false;
        this.render();

		this.game.world.add(this);
	}

    update() {
        var pointer = this.game.input.mousePointer; //activePointer;
        this.world_mouse_coords.x = pointer.worldX;
        this.world_mouse_coords.y = pointer.worldY;
        this.render();
    }

    render() {
        this.clear();

        var world_object_coords = new Phaser.Point(this.x, this.y);
        var world_line_end = new Phaser.Point(0,0);

        this.lineStyle(1, 0xffff00);

        this.beginFill(0xff0000);
        this.drawCircle(0, 0, 100);
        this.endFill();

        this.lineStyle(1, 0xffff00);
        this.moveTo(0,0);
        this.lineTo(this.world_mouse_coords.x-object_x, this.world_mouse_coords.y-object_y);

        this.beginFill(0xffff00);
        this.drawRect(0-2, 0-2, 4, 4);
        this.endFill();

        this.beginFill(0xfff000);
        this.drawRect(this.world_mouse_coords.x-object_x-2, this.world_mouse_coords.y-object_y-2, 4, 4);
        this.endFill();
    }
}

export default VectorAim;
<|endoftext|>


<commit_before>function resizeView() {
  var minX = -0.01;
  var minY = -0.01;
  var maxX = 0.01;
  var maxY = 0.01;
  var allItems = paper.project.getItems();
  for (var k = 0; k < allItems.length; k++) {
    var bounds = allItems[k].getBounds();
    minX = Math.min(minX, bounds.x);
    minY = Math.min(minY, bounds.y);
    maxX = Math.max(maxX, bounds.x + bounds.width);
    maxY = Math.max(maxY, bounds.y + bounds.height);
  }
  paper.view.setCenter(new paper.Point(
    minX + (maxX - minX) / 2, minY + (maxY - minY) / 2));

  var scaleX = (paper.view.getBounds().width / ((maxX - minX) * 1.1)) * paper.view.getZoom();
  var scaleY = (paper.view.getBounds().height / ((maxY - minY) * 1.1)) * paper.view.getZoom();
  paper.view.setZoom(Math.min(scaleX, scaleY));
}

function renderYaml(txt) {
  console.time("render YAML");
  paper.project.clear();

  // parse the YAML.
  var obj = function(t) {
    // Sadly, the YAML parser doesn't deal with comments nicely.
    var contentLines = [];
    var lines = txt.split("\n");
    for (var i = 0; i < lines.length; i++) {
      if (lines[i].split("#", 2)[0].trim().length > 0) {
        contentLines.push(lines[i]);
      }
    }
    return window.YAML.parse(contentLines.join("\n"));
  }(txt);

  // Render the shapes which the cuts will be centered around.
  var cutShapes = new paper.Group();
  for (var i = 0; i < obj.cuts.length; i++) {
    var cut = obj.cuts[i];
    if (cut.points && cut.points.length > 0) {
      if (cut.type == "drill") {
        console.log("TODO: implement drill cuts");
      } else {
        var path = new paper.Path();
        path.moveTo(new paper.Point(cut.points[0]));
        for (var j = 1; j < cut.points.length; j++) {
          path.lineTo(new paper.Point(cut.points[j]));
        }
        cutShapes.addChild(path);
      }
    }

    if (cut.shape) {
      if (cut.shape.type == "circle") {
        cutShapes.addChild(new paper.Shape.Circle(
          new paper.Point(cut.shape.center), cut.shape.radius));
      } else if (cut.shape.type == "rectangle") {
        cutShapes.addChild(new paper.Shape.Rectangle(
          new paper.Point(cut.shape.origin), new paper.Point(cut.shape.size)));
      } else {
        console.log("unknown shape: " + cut.shape.type);
      }
    }

    if (cutShapes.lastChild) {
      cutShapes.lastChild.strokeColor = (cut.color !== undefined) ? cut.color : "black";
    }
  }

  // Invert everything (to move the origin to the bottom left).
  cutShapes.scale(1, -1);

  resizeView();

  // The view must be resized before setting the stroke width
  // so we know how wide to stroke.
  cutShapes.style.strokeWidth = 1 / paper.view.getZoom();

  paper.view.draw();
  console.timeEnd("render YAML");
}

function renderGcode(txt) {
  console.log("TODO: implement support for gcode");
}

function handleFile(file) {
  console.log("processing file: " + file.name);
  console.time("read file");
  var reader = new FileReader();
  reader.onloadend = function(evt) {
    if (evt.target.readyState == FileReader.DONE) {
      console.timeEnd("read file");

      // TODO: this should be endsWith, but that is not yet supported...
      if (file.name.indexOf(".yaml") != -1) {
        renderYaml(evt.target.result);
      } else if (file.name.indexOf(".gcode") != -1 || file.name.indexOf(".nc") != -1) {
        renderGcode(evt.target.result);
      } else {
        console.log("unknown file type");
      }
    }
  };
  reader.readAsText(file);
}

function setupDragDrop() {
  var dropZone = $("body")[0];
  dropZone.addEventListener('dragover', function(evt) {
    evt.stopPropagation();
    evt.preventDefault();
  }, false);
  dropZone.addEventListener('drop', function(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    console.log("file drop detected.");

    var files = [];
    if (evt.target.files) {
      files = evt.target.files; // FileList object
    } else if (evt.dataTransfer) {
      files = evt.dataTransfer.files; // FileList object.
    } else {
      console.log("unknown file input");
    }
    if (files.length > 0) {
      handleFile(files[0]);
    }
  }, false);
}

$(document).ready(function() {
  setupDragDrop();

	paper.setup(document.getElementById('myCanvas'));

  // Listen for updates from our main page.
  window.addEventListener("message", function(event) {
    console.log("got a message from the heavens:\n" + event.data);
    renderYaml(event.data);
  }, false);

  // Update the viewport on resize.
  $(window).resize(function() {
    resizeView();
  });
});
<commit_msg>rendering drill points<commit_after>function resizeView() {
  var minX = -0.01;
  var minY = -0.01;
  var maxX = 0.01;
  var maxY = 0.01;
  var allItems = paper.project.getItems();
  for (var k = 0; k < allItems.length; k++) {
    var bounds = allItems[k].getBounds();
    minX = Math.min(minX, bounds.x);
    minY = Math.min(minY, bounds.y);
    maxX = Math.max(maxX, bounds.x + bounds.width);
    maxY = Math.max(maxY, bounds.y + bounds.height);
  }
  paper.view.setCenter(new paper.Point(
    minX + (maxX - minX) / 2, minY + (maxY - minY) / 2));

  var scaleX = (paper.view.getBounds().width / ((maxX - minX) * 1.1)) * paper.view.getZoom();
  var scaleY = (paper.view.getBounds().height / ((maxY - minY) * 1.1)) * paper.view.getZoom();
  paper.view.setZoom(Math.min(scaleX, scaleY));
}

function renderYaml(txt) {
  console.time("render YAML");
  paper.project.clear();

  // parse the YAML.
  var job = function(t) {
    // Sadly, the YAML parser doesn't deal with comments nicely.
    var contentLines = [];
    var lines = txt.split("\n");
    for (var i = 0; i < lines.length; i++) {
      if (lines[i].split("#", 2)[0].trim().length > 0) {
        contentLines.push(lines[i]);
      }
    }
    return window.YAML.parse(contentLines.join("\n"));
  }(txt);

  // Render the shapes which the cuts will be centered around.
  var cutShapes = new paper.Group();
  for (var i = 0; i < job.cuts.length; i++) {
    var cut = job.cuts[i];
    if (cut.points && cut.points.length > 0) {
      if (cut.type == "drill") {
        for (var k = 0; k < cut.points.length; k++) {
          var drillSpot = new paper.Shape.Circle(
            new paper.Point(cut.points[k]), job.bit_diameter / 2);
          drillSpot.strokeColor = "black";
          drillSpot.fillColor = "grey";
          cutShapes.addChild(drillSpot);
        }
      } else {
        var path = new paper.Path();
        path.moveTo(new paper.Point(cut.points[0]));
        for (var j = 1; j < cut.points.length; j++) {
          path.lineTo(new paper.Point(cut.points[j]));
        }
        cutShapes.addChild(path);
      }
    }

    if (cut.shape) {
      if (cut.shape.type == "circle") {
        cutShapes.addChild(new paper.Shape.Circle(
          new paper.Point(cut.shape.center), cut.shape.radius));
      } else if (cut.shape.type == "rectangle") {
        cutShapes.addChild(new paper.Shape.Rectangle(
          new paper.Point(cut.shape.origin), new paper.Point(cut.shape.size)));
      } else {
        console.log("unknown shape: " + cut.shape.type);
      }
    }

    if (cutShapes.lastChild) {
      cutShapes.lastChild.strokeColor = (cut.color !== undefined) ? cut.color : "black";
    }
  }

  // Invert everything (to move the origin to the bottom left).
  cutShapes.scale(1, -1);

  resizeView();

  // The view must be resized before setting the stroke width
  // so we know how wide to stroke.
  cutShapes.style.strokeWidth = 1 / paper.view.getZoom();

  paper.view.draw();
  console.timeEnd("render YAML");
}

function renderGcode(txt) {
  console.log("TODO: implement support for gcode");
}

function handleFile(file) {
  console.log("processing file: " + file.name);
  console.time("read file");
  var reader = new FileReader();
  reader.onloadend = function(evt) {
    if (evt.target.readyState == FileReader.DONE) {
      console.timeEnd("read file");

      // TODO: this should be endsWith, but that is not yet supported...
      if (file.name.indexOf(".yaml") != -1) {
        renderYaml(evt.target.result);
      } else if (file.name.indexOf(".gcode") != -1 || file.name.indexOf(".nc") != -1) {
        renderGcode(evt.target.result);
      } else {
        console.log("unknown file type");
      }
    }
  };
  reader.readAsText(file);
}

function setupDragDrop() {
  var dropZone = $("body")[0];
  dropZone.addEventListener('dragover', function(evt) {
    evt.stopPropagation();
    evt.preventDefault();
  }, false);
  dropZone.addEventListener('drop', function(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    console.log("file drop detected.");

    var files = [];
    if (evt.target.files) {
      files = evt.target.files; // FileList object
    } else if (evt.dataTransfer) {
      files = evt.dataTransfer.files; // FileList object.
    } else {
      console.log("unknown file input");
    }
    if (files.length > 0) {
      handleFile(files[0]);
    }
  }, false);
}

$(document).ready(function() {
  setupDragDrop();

	paper.setup(document.getElementById('myCanvas'));

  // Listen for updates from our main page.
  window.addEventListener("message", function(event) {
    console.log("got a message from the heavens:\n" + event.data);
    renderYaml(event.data);
  }, false);

  // Update the viewport on resize.
  $(window).resize(function() {
    resizeView();
  });
});
<|endoftext|>


<commit_before>var compliments = {
	complimentLocation: '.compliment',
	currentCompliment: '',
	complimentList: {
		'morning': config.compliments.morning,
		'afternoon': config.compliments.afternoon,
		'evening': config.compliments.evening
	},
	updateInterval: config.compliments.interval || 30000,
	fadeInterval: config.compliments.fadeInterval || 4000,
	intervalId: null
};

/**
 * Changes the compliment visible on the screen
 */
compliments.updateCompliment = function () {

	var _list = [];

	var hour = moment().hour();

	// In the followign if statement we use .slice() on the
	// compliments array to make a copy by value.
	// This way the original array of compliments stays in tact.

	if (hour >= 3 && hour < 12) {
		// Morning compliments
		_list = compliments.complimentList['morning'].slice();
	} else if (hour >= 12 && hour < 17) {
		// Afternoon compliments
		_list = compliments.complimentList['afternoon'].slice();
	} else if (hour >= 17 || hour < 3) {
		// Evening compliments
		_list = compliments.complimentList['evening'].slice();
	} else {
		// Edge case in case something weird happens
		// This will select a compliment from all times of day
		Object.keys(compliments.complimentList).forEach(function (_curr) {
			_list = _list.concat(compliments.complimentList[_curr]).slice();
		});
	}

	// Search for the location of the current compliment in the list
	var _spliceIndex = _list.indexOf(compliments.currentCompliment);

	// If it exists, remove it so we don't see it again
	if (_spliceIndex !== -1) {
		_list.splice(_spliceIndex, 1);
	}

	// Randomly select a location
	var _randomIndex = Math.floor(Math.random() * _list.length);
	compliments.currentCompliment = _list[_randomIndex];

	$('.compliment').updateWithText(compliments.currentCompliment, compliments.fadeInterval);

}

compliments.init = function () {

	this.updateCompliment();

	this.intervalId = setInterval(function () {
		this.updateCompliment();
	}.bind(this), this.updateInterval)

}<commit_msg>Update compliments.js<commit_after>var compliments = {
	complimentLocation: '.compliment',
	currentCompliment: '',
	complimentList: {
		'morning': config.compliments.morning,
		'afternoon': config.compliments.afternoon,
		'evening': config.compliments.evening
	},
	updateInterval: config.compliments.interval || 30000,
	fadeInterval: config.compliments.fadeInterval || 4000,
	intervalId: null
};

/**
 * Changes the compliment visible on the screen
 */
compliments.updateCompliment = function () {

	var _list = [];

	var hour = moment().hour();

	// In the following if statement we use .slice() on the
	// compliments array to make a copy by value.
	// This way the original array of compliments stays intact.

	if (hour >= 3 && hour < 12) {
		// Morning compliments
		_list = compliments.complimentList['morning'].slice();
	} else if (hour >= 12 && hour < 17) {
		// Afternoon compliments
		_list = compliments.complimentList['afternoon'].slice();
	} else if (hour >= 17 || hour < 3) {
		// Evening compliments
		_list = compliments.complimentList['evening'].slice();
	} else {
		// Edge case in case something weird happens
		// This will select a compliment from all times of day
		Object.keys(compliments.complimentList).forEach(function (_curr) {
			_list = _list.concat(compliments.complimentList[_curr]).slice();
		});
	}

	// Search for the location of the current compliment in the list
	var _spliceIndex = _list.indexOf(compliments.currentCompliment);

	// If it exists, remove it so we don't see it again
	if (_spliceIndex !== -1) {
		_list.splice(_spliceIndex, 1);
	}

	// Randomly select a location
	var _randomIndex = Math.floor(Math.random() * _list.length);
	compliments.currentCompliment = _list[_randomIndex];

	$('.compliment').updateWithText(compliments.currentCompliment, compliments.fadeInterval);

}

compliments.init = function () {

	this.updateCompliment();

	this.intervalId = setInterval(function () {
		this.updateCompliment();
	}.bind(this), this.updateInterval)

}
<|endoftext|>


<commit_before>var memoryManager = require('memoryManager')
var roleTower = require('roleTower')
var roleWorker = require('roleWorker')
var roleHarvester = require('roleHarvester')
var roleSpawner = require('roleSpawner')
var roleGeneralist = require('roleGeneralist')
var oldGc = require('garbageCollector')
var _ = require('lodash')

module.exports.loop = function () {

    // temp fix
    var ca = Game.creeps['London'];
    delete(ca.memory.assignedResource);
    delete(ca.memory.assignedStorage);
    var cb = Game.creeps['Keira'];
    delete(cb.memory.assignedResource);
    delete(cb.memory.assignedStorage);
    delete(Memory.assignments);

    Memory.home = 'W8N68';

    memoryManager.collect();
    memoryManager.updateStructureStore(Memory.home);
    memoryManager.updateResourceStore(Memory.home);

    oldGc.collect();

    roleSpawner.run();
    roleTower.run(Memory.home);

    for(var name in Game.creeps) {
	    var creep = Game.creeps[name];
	    switch (creep.memory.role) {
	        case 'worker':
	            roleWorker.run(creep);
	            break;
	        case 'harvester':
	            roleHarvester.run(creep);
	            break;
	        case 'generalist':
	            roleGeneralist.run(creep);
	            break;
	    }
    }
}
<commit_msg>end fix<commit_after>var memoryManager = require('memoryManager')
var roleTower = require('roleTower')
var roleWorker = require('roleWorker')
var roleHarvester = require('roleHarvester')
var roleSpawner = require('roleSpawner')
var roleGeneralist = require('roleGeneralist')
var oldGc = require('garbageCollector')
var _ = require('lodash')

module.exports.loop = function () {

    // temp fix
//    var ca = Game.creeps['London'];
//    delete(ca.memory.assignedResource);
//    delete(ca.memory.assignedStorage);
//    var cb = Game.creeps['Keira'];
//    delete(cb.memory.assignedResource);
//    delete(cb.memory.assignedStorage);
//    delete(Memory.assignments);

    Memory.home = 'W8N68';

    memoryManager.collect();
    memoryManager.updateStructureStore(Memory.home);
    memoryManager.updateResourceStore(Memory.home);

    oldGc.collect();

    roleSpawner.run();
    roleTower.run(Memory.home);

    for(var name in Game.creeps) {
	    var creep = Game.creeps[name];
	    switch (creep.memory.role) {
	        case 'worker':
	            roleWorker.run(creep);
	            break;
	        case 'harvester':
	            roleHarvester.run(creep);
	            break;
	        case 'generalist':
	            roleGeneralist.run(creep);
	            break;
	    }
    }
}
<|endoftext|>