<commit_before>// Copyright 2002-2014, University of Colorado Boulder

//TODO Reimplemented this button using sun.button package, which currently doesn't support the "look" or functionality required.
/**
 * A round red button that changes it's on/off state when pressed.
 * Can optionally be configured as a 'momentary' button, which is on while pressed, off when released.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( function( require ) {
  'use strict';

  // modules
  var ButtonListener = require( 'SCENERY/input/ButtonListener' );
  var DownUpListener = require( 'SCENERY/input/DownUpListener' );
  var Image = require( 'SCENERY/nodes/Image' );
  var inherit = require( 'PHET_CORE/inherit' );
  var Node = require( 'SCENERY/nodes/Node' );

  // images
  var pressedImage = require( 'image!SCENERY_PHET/round_red_button_pressed.png' );
  var unpressedImage = require( 'image!SCENERY_PHET/round_red_button_unpressed.png' );
  var disabledImage = require( 'image!SCENERY_PHET/round_red_button_disabled.png' );

  /**
   * @param {Property.<boolean>} onProperty
   * @param {Property.<boolean>} enabledProperty
   * @param {Object} [options]
   * @constructor
   */
  function RoundRedButton( onProperty, enabledProperty, options ) {

    options = _.extend( {
      onWhilePressed: false // true makes this a momentary button, which stays on while pressed
    }, options );

    var thisButton = this;
    Image.call( this, unpressedImage );

    onProperty.link( function( on ) {
      if ( enabledProperty.get() ) {
        thisButton.setImage( on ? pressedImage : unpressedImage );
      }
    } );

    enabledProperty.link( function( enabled ) {
      if ( enabled ) {
        thisButton.setImage( onProperty.get() ? pressedImage : unpressedImage );
        thisButton.cursor = 'pointer';
      }
      else {
        thisButton.setImage( disabledImage );
        thisButton.cursor = 'default';
        onProperty.set( false );
      }
    } );

    if ( options.onWhilePressed ) {
      // momentary button, on while pressed, off when released
      thisButton.addInputListener( new DownUpListener( {
        down: function() {
          onProperty.set( enabledProperty.get() );
        },
        up: function() {
          onProperty.set( false );
        }
      } ) );
    }
    else {
      // toggle button, changes its state when fired
      thisButton.addInputListener( new ButtonListener( {
        fire: function() {
          onProperty.set( !onProperty.get() && enabledProperty.get() );
        }
      } ) );
    }
  }

  return inherit( Image, RoundRedButton );
} );
<commit_msg>Lint fix<commit_after>// Copyright 2002-2014, University of Colorado Boulder

//TODO Reimplemented this button using sun.button package, which currently doesn't support the "look" or functionality required.
/**
 * A round red button that changes it's on/off state when pressed.
 * Can optionally be configured as a 'momentary' button, which is on while pressed, off when released.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( function( require ) {
  'use strict';

  // modules
  var ButtonListener = require( 'SCENERY/input/ButtonListener' );
  var DownUpListener = require( 'SCENERY/input/DownUpListener' );
  var Image = require( 'SCENERY/nodes/Image' );
  var inherit = require( 'PHET_CORE/inherit' );

  // images
  var pressedImage = require( 'image!SCENERY_PHET/round_red_button_pressed.png' );
  var unpressedImage = require( 'image!SCENERY_PHET/round_red_button_unpressed.png' );
  var disabledImage = require( 'image!SCENERY_PHET/round_red_button_disabled.png' );

  /**
   * @param {Property.<boolean>} onProperty
   * @param {Property.<boolean>} enabledProperty
   * @param {Object} [options]
   * @constructor
   */
  function RoundRedButton( onProperty, enabledProperty, options ) {

    options = _.extend( {
      onWhilePressed: false // true makes this a momentary button, which stays on while pressed
    }, options );

    var thisButton = this;
    Image.call( this, unpressedImage );

    onProperty.link( function( on ) {
      if ( enabledProperty.get() ) {
        thisButton.setImage( on ? pressedImage : unpressedImage );
      }
    } );

    enabledProperty.link( function( enabled ) {
      if ( enabled ) {
        thisButton.setImage( onProperty.get() ? pressedImage : unpressedImage );
        thisButton.cursor = 'pointer';
      }
      else {
        thisButton.setImage( disabledImage );
        thisButton.cursor = 'default';
        onProperty.set( false );
      }
    } );

    if ( options.onWhilePressed ) {
      // momentary button, on while pressed, off when released
      thisButton.addInputListener( new DownUpListener( {
        down: function() {
          onProperty.set( enabledProperty.get() );
        },
        up: function() {
          onProperty.set( false );
        }
      } ) );
    }
    else {
      // toggle button, changes its state when fired
      thisButton.addInputListener( new ButtonListener( {
        fire: function() {
          onProperty.set( !onProperty.get() && enabledProperty.get() );
        }
      } ) );
    }
  }

  return inherit( Image, RoundRedButton );
} );
<|endoftext|>


<commit_before>TouchBox = function(){

    var newThis = this;

    this.ringObj = { rings: [],
        drawRing: function(that,ring){

            var x = ring.x;
            var y = ring.y;
            var a = ring.alpha;
            var r = ring.r;
            var w = ring.width;

            that.mainCtx.globalAlpha = a;
            that.mainCtx.strokeStyle = ring.color;
            that.mainCtx.lineWidth = w;
            that.mainCtx.beginPath();
            that.mainCtx.arc(x,y,r,0,2*Math.PI);
            that.mainCtx.stroke();

        },
        changeRing: function(type,col,id,x,y){
            var newx = newThis.screenToCanvas(x,y)[0];
            var newy = newThis.screenToCanvas(x,y)[1];
            if(type=='start'){
                var r = 0;
                var w = 0;
                var a = 0;
            }
            else if(type=='move'){
                var r = 20;
                var w = 5;
                var a = 1;
            }
            else if(type=='end'){
                var r = 20;
                var w = 5;
                var a = 1;
            }
            this.rings.push({id: id, type: type, color: col, x: newx, y: newy, r: r, width: w, alpha: a});
            newThis.intervalOn(id);
        }
    };

    this.init = function(){

        this.interval = [];
        this.ringObj.rings = [];

        this.mainCtnr = document.getElementById('mainDiv');
        this.mainCanvas = this.mainCtnr.getElementsByTagName('canvas')[0];
        this.mainCanvas.width = this.mainCanvas.offsetWidth;
        this.mainCanvas.height = this.mainCanvas.offsetHeight;
        this.mainCtx = this.mainCanvas.getContext('2d');
        this.mainCtx.clearRect(0,0,this.mainCanvas.width,this.mainCanvas.height);
        this.mainTouchBox = document.getElementById('touchBox');
    };

    this.intervalOn = function(i){
        var that = this;
        this.interval[i] = setInterval(function(){that.drawAllRings();},1);
    };
    this.intervalOff = function(i){
        clearInterval(this.interval[i]);
    };

    this.drawAllRings = function(){

        this.mainCtx.clearRect(0,0,this.mainCanvas.width,this.mainCanvas.height);

        var that = this;
        var stepsStart = 20;
        var stepsMove = 30;
        var stepsEnd = 50;

        for (var rId in this.ringObj.rings)
        {
            this.ringObj.drawRing(this,this.ringObj.rings[rId]);
            if(this.ringObj.rings[rId].type=='start'){
                this.ringObj.rings[rId].alpha = this.ringObj.rings[rId].alpha + 1/stepsStart;
                this.ringObj.rings[rId].width = this.ringObj.rings[rId].width + 5/stepsStart;
                this.ringObj.rings[rId].r = this.ringObj.rings[rId].r + 20/stepsStart;
                if(this.ringObj.rings[rId].r > 20){
                    this.intervalOff(this.ringObj.rings[rId].id);
                    this.ringObj.rings.splice(rId,1);
                }
            }
            else if(this.ringObj.rings[rId].type=='move'){
                this.ringObj.rings[rId].alpha = this.ringObj.rings[rId].alpha - 1/stepsMove;
                if(this.ringObj.rings[rId].alpha < 1/stepsMove){
                    this.intervalOff(this.ringObj.rings[rId].id);
                    this.ringObj.rings.splice(rId,1);
                }
            }
            else if(this.ringObj.rings[rId].type=='end'){
                this.ringObj.rings[rId].alpha = this.ringObj.rings[rId].alpha - 1/stepsEnd;
                this.ringObj.rings[rId].width = this.ringObj.rings[rId].width - 5/stepsEnd;
                this.ringObj.rings[rId].r = this.ringObj.rings[rId].r - 20/stepsEnd;
                if(this.ringObj.rings[rId].r < 1){
                    this.intervalOff(this.ringObj.rings[rId].id);
                    this.ringObj.rings.splice(rId,1);
                }
            }
        }

    };

    this.screenToCanvas = function(x,y){
        var newx = x - 12;
        var newy = y - 12;
        return [newx,newy];
    };

    this.init();

};
<commit_msg>wydzielenie parametrow animacji<commit_after>TouchBox = function(){

    var newThis = this;

    this.ringObj = { rings: [],
        animParam: { startRadius: 0, startWidth: 0, startAlpha: 0, startSteps: 20, moveRadius: 20, moveWidth: 5, moveAlpha: 1, moveSteps: 30, endRadius: 20, endWidth: 5, endAlpha: 1, endSteps: 50 },
        drawRing: function(ring){

            var x = ring.x;
            var y = ring.y;
            var a = ring.alpha;
            var r = ring.r;
            var w = ring.width;

            newThis.mainCtx.globalAlpha = a;
            newThis.mainCtx.strokeStyle = ring.color;
            newThis.mainCtx.lineWidth = w;
            newThis.mainCtx.beginPath();
            newThis.mainCtx.arc(x,y,r,0,2*Math.PI);
            newThis.mainCtx.stroke();

        },
        changeRing: function(type,col,id,x,y){
            var newx = newThis.screenToCanvas(x,y)[0];
            var newy = newThis.screenToCanvas(x,y)[1];
            if(type=='start'){
                var r = this.animParam.startRadius;
                var w = this.animParam.startWidth;
                var a = this.animParam.startAlpha;
            }
            else if(type=='move'){
                var r = this.animParam.moveRadius;
                var w = this.animParam.moveWidth;
                var a = this.animParam.moveAlpha;
            }
            else if(type=='end'){
                var r = this.animParam.endRadius;
                var w = this.animParam.endWidth;
                var a = this.animParam.endAlpha;
            }
            this.rings.push({id: id, type: type, color: col, x: newx, y: newy, r: r, width: w, alpha: a});
            newThis.intervalOn(id);
        },
        drawAllRings: function(){
            newThis.mainCtx.clearRect(0,0,newThis.mainCanvas.width,newThis.mainCanvas.height);

            var stepsStart = this.animParam.startSteps;
            var stepsMove = this.animParam.moveSteps;
            var stepsEnd = this.animParam.endSteps;
            var maxRadius = this.animParam.moveRadius;
            var maxWidth = this.animParam.moveWidth;
            var maxAlpha = this.animParam.moveAlpha;

            for (var rId in this.rings)
            {
                this.drawRing(this.rings[rId]);
                if(this.rings[rId].type=='start'){
                    this.rings[rId].alpha = this.rings[rId].alpha + maxAlpha/stepsStart;
                    this.rings[rId].width = this.rings[rId].width + maxWidth/stepsStart;
                    this.rings[rId].r = this.rings[rId].r + maxRadius/stepsStart;
                    if(this.rings[rId].r > maxRadius){
                        newThis.intervalOff(this.rings[rId].id);
                        this.rings.splice(rId,1);
                    }
                }
                else if(this.rings[rId].type=='move'){
                    this.rings[rId].alpha = this.rings[rId].alpha - maxAlpha/stepsMove;
                    if(this.rings[rId].alpha < maxAlpha/stepsMove){
                        newThis.intervalOff(this.rings[rId].id);
                        this.rings.splice(rId,1);
                    }
                }
                else if(this.rings[rId].type=='end'){
                    this.rings[rId].alpha = this.rings[rId].alpha - maxAlpha/stepsEnd;
                    this.rings[rId].width = this.rings[rId].width - maxWidth/stepsEnd;
                    this.rings[rId].r = this.rings[rId].r - maxRadius/stepsEnd;
                    if(this.rings[rId].r < 1){
                        newThis.intervalOff(this.rings[rId].id);
                        this.rings.splice(rId,1);
                    }
                }
            }
        }
    };

    this.init = function(){

        this.interval = [];
        this.ringObj.rings = [];

        this.mainCtnr = document.getElementById('mainDiv');
        this.mainCanvas = this.mainCtnr.getElementsByTagName('canvas')[0];
        this.mainCanvas.width = this.mainCanvas.offsetWidth;
        this.mainCanvas.height = this.mainCanvas.offsetHeight;
        this.mainCtx = this.mainCanvas.getContext('2d');
        this.mainCtx.clearRect(0,0,this.mainCanvas.width,this.mainCanvas.height);
        this.mainTouchBox = document.getElementById('touchBox');
    };

    this.intervalOn = function(i){
        this.interval[i] = setInterval(function(){newThis.ringObj.drawAllRings();},1);
    };
    this.intervalOff = function(i){
        clearInterval(this.interval[i]);
    };

    this.screenToCanvas = function(x,y){
        var newx = x - 12;
        var newy = y - 12;
        return [newx,newy];
    };

    this.init();

};
<|endoftext|>


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

/*global Spinner:true*/

!function ($) {

  'use strict'; // jshint ;_;

  var Ajax = function () {}

  Ajax.prototype.click = function (e) {
    var $this = $(this)
      , url = $this.attr('href')
      , method = $this.attr('data-method')

    if (!method) {
      method = 'get'
    }

    spin($this)

    e.preventDefault()

    $.ajax({
      url: url,
      type: method,
      statusCode: {
        200: function(data) {
          processData(data, $this)
        },
        500: function() {
          processError($this)
        },
        404: function() {
          processError($this)
        }
      }
    })
  }

  Ajax.prototype.submit = function (e) {
    var $this = $(this)
      , url = $this.attr('action')
      , method = $this.attr('method')
      , data = $this.serialize()
      , button = $this.find('input[type=submit],button[type=submit]')

    button.attr('disabled', 'disabled')

    spin($this)

    e.preventDefault()

    $.ajax({
      url: url,
      type: method,
      data: data,
      statusCode: {
        200: function(data) {
            $this.find('input[type=text],textarea').val('')
            processData(data, $this)
        },
        500: function() {
            processError($this)
        },
        404: function() {
            processError($this)
        }
      },
      complete: function() {
        button.removeAttr('disabled')
      }
    })
  }

  Ajax.prototype.cancel = function(e) {
    var $this = $(this)
      , selector = $this.attr('data-cancel-closest')

    e.preventDefault()

    $this.closest(selector).remove()
  }

  if (typeof Spinner !== 'undefined') { // http://fgnass.github.com/spin.js/
    $.fn.spin = function(opts) {
      this.each(function() {
        var $this = $(this)
          , data = $this.data()

        if (data.spinner) {
          data.spinner.stop();
          delete data.spinner
        }
        if (opts !== false) {
          data.spinner = new Spinner($.extend({color: $this.css('color')}, opts)).spin(this)
        }
      })
      return this
    }
  }

  function spin($el) { // http://fgnass.github.com/spin.js/
    if ($.fn.spin !== undefined) {
      var spinner_selector = $el.attr('data-spinner')
        , spinner_selector_replace = $el.attr('data-spinner-replace')
        , spinner_selector_replace_closest = $el.attr('data-spinner-replace-closest')
        , opts = {lines: 11, length:0, width:6, radius:9, rotate:0, trail:89, speed:1.4}

        if (spinner_selector) {
          $(spinner_selector).spin(opts)
        } else if (spinner_selector_replace) {
          $(spinner_selector_replace).html("").spin(opts)
        } else if (spinner_selector_replace_closest) {
          $el.closest(spinner_selector_replace_closest).html("").spin(opts)
        } else {
          $el.html("").spin(opts)
        }
    }
  }

  function stop_spin($el) {
    if ($el.stop !== undefined) {
      $el.stop()
    }
  }

  function processData(data, $el) {
    if (data.location) {
      window.location.href = data.location
    } else {
      var replace_selector = $el.attr('data-replace')
        , replace_closest_selector = $el.attr('data-replace-closest')
        , append_selector = $el.attr('data-append')
        , prepend_selector = $el.attr('data-prepend')
        , refresh_selector = $el.attr('data-refresh')
        , refresh_closest_selector = $el.attr('data-refresh-closest')

      if (replace_selector) {
        $(replace_selector).replaceWith(data.html)
      }
      if (replace_closest_selector) {
        $el.closest(replace_closest_selector).replaceWith(data.html)
      }
      if (append_selector) {
        $(append_selector).append(data.html)
      }
      if (prepend_selector) {
        $(prepend_selector).prepend(data.html)
      }
      if (refresh_selector) {
        $.each($(refresh_selector), function(index, value) {
          $.getJSON($(value).data('refresh-url'), function(data) {
            $(value).replaceWith(data.html)
          })
        })
      }
      if (refresh_closest_selector) {
        $.each($(refresh_closest_selector), function(index, value) {
          $.getJSON($(value).data('refresh-url'), function(data) {
            $el.closest($(value)).replaceWith(data.html)
          })
        })
      }
    }

    if (data.fragments) {
      for (var s in data.fragments) {
        $(s).replaceWith(data.fragments[s])
      }
    }
    if (data['inner-fragments']) {
      for (var i in data['inner-fragments']) {
        $(i).html(data['inner-fragments'][i])
      }
    }
  }

  function processError($el) {
    var msg = '
There was a server error.
'
      , replace_selector = $el.attr('data-replace')
      , replace_closest_selector = $el.attr('data-replace-closest')
      , append_selector = $el.attr('data-append')
      , prepend_selector = $el.attr('data-prepend')

    if (replace_selector) {
      $(replace_selector).replaceWith(msg)
    }
    if (replace_closest_selector) {
      $el.closest(replace_closest_selector).replaceWith(msg)
    }
    if (append_selector) {
      $(append_selector).append(msg)
    }
    if (prepend_selector) {
      $(prepend_selector).prepend(msg)
    }
  }

  $(function () {
    $('body').on('click', 'a.ajax', Ajax.prototype.click)
    $('body').on('submit', 'form.ajax', Ajax.prototype.submit)
    $('body').on('click', 'a[data-cancel-closest]', Ajax.prototype.cancel)
  })
}(window.jQuery);
<commit_msg>v0.4.0<commit_after>/* ====================================================================
 * bootstrap-ajax.js v0.4.0
 * ====================================================================
 * Copyright (c) 2012, Eldarion, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *
 *     * Redistributions in binary form must reproduce the above copyright notice,
 *       this list of conditions and the following disclaimer in the documentation
 *       and/or other materials provided with the distribution.
 *
 *     * Neither the name of Eldarion, Inc. nor the names of its contributors may
 *       be used to endorse or promote products derived from this software without
 *       specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ==================================================================== */

/*global Spinner:true*/

!function ($) {

  'use strict'; // jshint ;_;

  var Ajax = function () {}

  Ajax.prototype.click = function (e) {
    var $this = $(this)
      , url = $this.attr('href')
      , method = $this.attr('data-method')

    if (!method) {
      method = 'get'
    }

    spin($this)

    e.preventDefault()

    $.ajax({
      url: url,
      type: method,
      statusCode: {
        200: function(data) {
          processData(data, $this)
        },
        500: function() {
          processError($this)
        },
        404: function() {
          processError($this)
        }
      }
    })
  }

  Ajax.prototype.submit = function (e) {
    var $this = $(this)
      , url = $this.attr('action')
      , method = $this.attr('method')
      , data = $this.serialize()
      , button = $this.find('input[type=submit],button[type=submit]')

    button.attr('disabled', 'disabled')

    spin($this)

    e.preventDefault()

    $.ajax({
      url: url,
      type: method,
      data: data,
      statusCode: {
        200: function(data) {
            $this.find('input[type=text],textarea').val('')
            processData(data, $this)
        },
        500: function() {
            processError($this)
        },
        404: function() {
            processError($this)
        }
      },
      complete: function() {
        button.removeAttr('disabled')
      }
    })
  }

  Ajax.prototype.cancel = function(e) {
    var $this = $(this)
      , selector = $this.attr('data-cancel-closest')

    e.preventDefault()

    $this.closest(selector).remove()
  }

  if (typeof Spinner !== 'undefined') { // http://fgnass.github.com/spin.js/
    $.fn.spin = function(opts) {
      this.each(function() {
        var $this = $(this)
          , data = $this.data()

        if (data.spinner) {
          data.spinner.stop();
          delete data.spinner
        }
        if (opts !== false) {
          data.spinner = new Spinner($.extend({color: $this.css('color')}, opts)).spin(this)
        }
      })
      return this
    }
  }

  function spin($el) { // http://fgnass.github.com/spin.js/
    if ($.fn.spin !== undefined) {
      var spinner_selector = $el.attr('data-spinner')
        , spinner_selector_replace = $el.attr('data-spinner-replace')
        , spinner_selector_replace_closest = $el.attr('data-spinner-replace-closest')
        , opts = {lines: 11, length:0, width:6, radius:9, rotate:0, trail:89, speed:1.4}

        if (spinner_selector) {
          $(spinner_selector).spin(opts)
        } else if (spinner_selector_replace) {
          $(spinner_selector_replace).html("").spin(opts)
        } else if (spinner_selector_replace_closest) {
          $el.closest(spinner_selector_replace_closest).html("").spin(opts)
        } else {
          $el.html("").spin(opts)
        }
    }
  }

  function stop_spin($el) {
    if ($el.stop !== undefined) {
      $el.stop()
    }
  }

  function processData(data, $el) {
    if (data.location) {
      window.location.href = data.location
    } else {
      var replace_selector = $el.attr('data-replace')
        , replace_closest_selector = $el.attr('data-replace-closest')
        , append_selector = $el.attr('data-append')
        , prepend_selector = $el.attr('data-prepend')
        , refresh_selector = $el.attr('data-refresh')
        , refresh_closest_selector = $el.attr('data-refresh-closest')

      if (replace_selector) {
        $(replace_selector).replaceWith(data.html)
      }
      if (replace_closest_selector) {
        $el.closest(replace_closest_selector).replaceWith(data.html)
      }
      if (append_selector) {
        $(append_selector).append(data.html)
      }
      if (prepend_selector) {
        $(prepend_selector).prepend(data.html)
      }
      if (refresh_selector) {
        $.each($(refresh_selector), function(index, value) {
          $.getJSON($(value).data('refresh-url'), function(data) {
            $(value).replaceWith(data.html)
          })
        })
      }
      if (refresh_closest_selector) {
        $.each($(refresh_closest_selector), function(index, value) {
          $.getJSON($(value).data('refresh-url'), function(data) {
            $el.closest($(value)).replaceWith(data.html)
          })
        })
      }
    }

    if (data.fragments) {
      for (var s in data.fragments) {
        $(s).replaceWith(data.fragments[s])
      }
    }
    if (data['inner-fragments']) {
      for (var i in data['inner-fragments']) {
        $(i).html(data['inner-fragments'][i])
      }
    }
  }

  function processError($el) {
    var msg = '
There was a server error.
'
      , replace_selector = $el.attr('data-replace')
      , replace_closest_selector = $el.attr('data-replace-closest')
      , append_selector = $el.attr('data-append')
      , prepend_selector = $el.attr('data-prepend')

    if (replace_selector) {
      $(replace_selector).replaceWith(msg)
    }
    if (replace_closest_selector) {
      $el.closest(replace_closest_selector).replaceWith(msg)
    }
    if (append_selector) {
      $(append_selector).append(msg)
    }
    if (prepend_selector) {
      $(prepend_selector).prepend(msg)
    }
  }

  $(function () {
    $('body').on('click', 'a.ajax', Ajax.prototype.click)
    $('body').on('submit', 'form.ajax', Ajax.prototype.submit)
    $('body').on('click', 'a[data-cancel-closest]', Ajax.prototype.cancel)
  })
}(window.jQuery);
<|endoftext|>


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

/*global Spinner:true*/

!function ($) {

  'use strict'; // jshint ;_;

  var Ajax = function () {}

  Ajax.prototype.click = function (e) {
    var $this = $(this)
      , url = $this.attr('href')
      , method = $this.attr('data-method')

    if (!method) {
      method = 'get'
    }

    spin($this)

    e.preventDefault()

    $.ajax({
      url: url,
      type: method,
      statusCode: {
        200: function(data) {
          processData(data, $this)
        },
        500: function() {
          processError($this)
        },
        404: function() {
          processError($this)
        }
      }
    })
  }

  Ajax.prototype.submit = function (e) {
    var $this = $(this)
      , url = $this.attr('action')
      , method = $this.attr('method')
      , data = $this.serialize()

    $this.find("input[type=submit],button[type=submit]").attr("disabled", "disabled")

    $('input').val('');

    spin($this)

    e.preventDefault()

    $.ajax({
      url: url,
      type: method,
      data: data,
      statusCode: {
        200: function(data) {
            processData(data, $this)
        },
        500: function() {
            processError($this)
        },
        404: function() {
            processError($this)
        }
      }
    })
  }

  Ajax.prototype.cancel = function(e) {
    var $this = $(this)
      , selector = $this.attr('data-cancel-closest')

    e.preventDefault()

    $this.closest(selector).remove()
  }

  if (typeof Spinner !== 'undefined') { // http://fgnass.github.com/spin.js/
    $.fn.spin = function(opts) {
      this.each(function() {
        var $this = $(this)
          , data = $this.data()

        if (data.spinner) {
          data.spinner.stop();
          delete data.spinner
        }
        if (opts !== false) {
          data.spinner = new Spinner($.extend({color: $this.css('color')}, opts)).spin(this)
        }
      })
      return this
    }
  }

  function spin($el) { // http://fgnass.github.com/spin.js/
    if ($.fn.spin !== undefined) {
      var spinner_selector = $el.attr('data-spinner')
        , spinner_selector_replace = $el.attr('data-spinner-replace')
        , spinner_selector_replace_closest = $el.attr('data-spinner-replace-closest')
        , opts = {lines: 11, length:0, width:6, radius:9, rotate:0, trail:89, speed:1.4}

        if (spinner_selector) {
          $(spinner_selector).spin(opts)
        } else if (spinner_selector_replace) {
          $(spinner_selector_replace).html("").spin(opts)
        } else if (spinner_selector_replace_closest) {
          $el.closest(spinner_selector_replace_closest).html("").spin(opts)
        } else {
          $el.html("").spin(opts)
        }
    }
  }

  function stop_spin($el) {
    if ($el.stop !== undefined) {
      $el.stop()
    }
  }

  function processData(data, $el) {
    if (data.location) {
      window.location.href = data.location
    } else {
      var replace_selector = $el.attr('data-replace')
        , replace_closest_selector = $el.attr('data-replace-closest')
        , append_selector = $el.attr('data-append')
        , refresh_selector = $el.attr('data-refresh')
        , refresh_closest_selector = $el.attr('data-refresh-closest')

      if (replace_selector) {
        $(replace_selector).replaceWith(data.html)
      }
      if (replace_closest_selector) {
        $el.closest(replace_closest_selector).replaceWith(data.html)
      }
      if (append_selector) {
        $(append_selector).append(data.html)
      }
      if (refresh_selector) {
        $.each($(refresh_selector), function(index, value) {
          $.getJSON($(value).data('refresh-url'), function(data) {
            $(value).replaceWith(data.html)
          })
        })
      }
      if (refresh_closest_selector) {
        $.each($(refresh_closest_selector), function(index, value) {
          $.getJSON($(value).data('refresh-url'), function(data) {
            $el.closest($(value)).replaceWith(data.html)
          })
        })
      }
    }

    if (data.fragments) {
      for (var s in data.fragments) {
        $(s).replaceWith(data.fragments[s])
      }
    }
    if (data['inner-fragments']) {
      for (var i in data['inner-fragments']) {
        $(i).html(data['inner-fragments'][i])
      }
    }
  }

  function processError($el) {
    var msg = '
There was a server error.
'
      , replace_selector = $el.attr('data-replace')
      , replace_closest_selector = $el.attr('data-replace-closest')
      , append_selector = $el.attr('data-append')

    if (replace_selector) {
      $(replace_selector).replaceWith(msg)
    }
    if (replace_closest_selector) {
      $el.closest(replace_closest_selector).replaceWith(msg)
    }
    if (append_selector) {
      $(append_selector).append(msg)
    }
  }

  $(function () {
    $('body').on('click', 'a.ajax', Ajax.prototype.click)
    $('body').on('submit', 'form.ajax', Ajax.prototype.submit)
    $('body').on('click', 'a[data-cancel-closest]', Ajax.prototype.cancel)
  })
}(window.jQuery);
<commit_msg>Add prepend selector<commit_after>/* ====================================================================
 * bootstrap-ajax.js v0.3.0
 * ====================================================================
 * Copyright (c) 2012, Eldarion, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *
 *     * Redistributions in binary form must reproduce the above copyright notice,
 *       this list of conditions and the following disclaimer in the documentation
 *       and/or other materials provided with the distribution.
 *
 *     * Neither the name of Eldarion, Inc. nor the names of its contributors may
 *       be used to endorse or promote products derived from this software without
 *       specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ==================================================================== */

/*global Spinner:true*/

!function ($) {

  'use strict'; // jshint ;_;

  var Ajax = function () {}

  Ajax.prototype.click = function (e) {
    var $this = $(this)
      , url = $this.attr('href')
      , method = $this.attr('data-method')

    if (!method) {
      method = 'get'
    }

    spin($this)

    e.preventDefault()

    $.ajax({
      url: url,
      type: method,
      statusCode: {
        200: function(data) {
          processData(data, $this)
        },
        500: function() {
          processError($this)
        },
        404: function() {
          processError($this)
        }
      }
    })
  }

  Ajax.prototype.submit = function (e) {
    var $this = $(this)
      , url = $this.attr('action')
      , method = $this.attr('method')
      , data = $this.serialize()

    $this.find("input[type=submit],button[type=submit]").attr("disabled", "disabled")

    $('input').val('');

    spin($this)

    e.preventDefault()

    $.ajax({
      url: url,
      type: method,
      data: data,
      statusCode: {
        200: function(data) {
            processData(data, $this)
        },
        500: function() {
            processError($this)
        },
        404: function() {
            processError($this)
        }
      }
    })
  }

  Ajax.prototype.cancel = function(e) {
    var $this = $(this)
      , selector = $this.attr('data-cancel-closest')

    e.preventDefault()

    $this.closest(selector).remove()
  }

  if (typeof Spinner !== 'undefined') { // http://fgnass.github.com/spin.js/
    $.fn.spin = function(opts) {
      this.each(function() {
        var $this = $(this)
          , data = $this.data()

        if (data.spinner) {
          data.spinner.stop();
          delete data.spinner
        }
        if (opts !== false) {
          data.spinner = new Spinner($.extend({color: $this.css('color')}, opts)).spin(this)
        }
      })
      return this
    }
  }

  function spin($el) { // http://fgnass.github.com/spin.js/
    if ($.fn.spin !== undefined) {
      var spinner_selector = $el.attr('data-spinner')
        , spinner_selector_replace = $el.attr('data-spinner-replace')
        , spinner_selector_replace_closest = $el.attr('data-spinner-replace-closest')
        , opts = {lines: 11, length:0, width:6, radius:9, rotate:0, trail:89, speed:1.4}

        if (spinner_selector) {
          $(spinner_selector).spin(opts)
        } else if (spinner_selector_replace) {
          $(spinner_selector_replace).html("").spin(opts)
        } else if (spinner_selector_replace_closest) {
          $el.closest(spinner_selector_replace_closest).html("").spin(opts)
        } else {
          $el.html("").spin(opts)
        }
    }
  }

  function stop_spin($el) {
    if ($el.stop !== undefined) {
      $el.stop()
    }
  }

  function processData(data, $el) {
    if (data.location) {
      window.location.href = data.location
    } else {
      var replace_selector = $el.attr('data-replace')
        , replace_closest_selector = $el.attr('data-replace-closest')
        , append_selector = $el.attr('data-append')
        , prepend_selector = $el.attr('data-prepend')
        , refresh_selector = $el.attr('data-refresh')
        , refresh_closest_selector = $el.attr('data-refresh-closest')

      if (replace_selector) {
        $(replace_selector).replaceWith(data.html)
      }
      if (replace_closest_selector) {
        $el.closest(replace_closest_selector).replaceWith(data.html)
      }
      if (append_selector) {
        $(append_selector).append(data.html)
      }
      if (prepend_selector) {
        $(prepend_selector).prepend(data.html)
      }
      if (refresh_selector) {
        $.each($(refresh_selector), function(index, value) {
          $.getJSON($(value).data('refresh-url'), function(data) {
            $(value).replaceWith(data.html)
          })
        })
      }
      if (refresh_closest_selector) {
        $.each($(refresh_closest_selector), function(index, value) {
          $.getJSON($(value).data('refresh-url'), function(data) {
            $el.closest($(value)).replaceWith(data.html)
          })
        })
      }
    }

    if (data.fragments) {
      for (var s in data.fragments) {
        $(s).replaceWith(data.fragments[s])
      }
    }
    if (data['inner-fragments']) {
      for (var i in data['inner-fragments']) {
        $(i).html(data['inner-fragments'][i])
      }
    }
  }

  function processError($el) {
    var msg = '
There was a server error.
'
      , replace_selector = $el.attr('data-replace')
      , replace_closest_selector = $el.attr('data-replace-closest')
      , append_selector = $el.attr('data-append')
      , prepend_selector = $el.attr('data-prepend')

    if (replace_selector) {
      $(replace_selector).replaceWith(msg)
    }
    if (replace_closest_selector) {
      $el.closest(replace_closest_selector).replaceWith(msg)
    }
    if (append_selector) {
      $(append_selector).append(msg)
    }
    if (prepend_selector) {
      $(prepend_selector).prepend(msg)
    }
  }

  $(function () {
    $('body').on('click', 'a.ajax', Ajax.prototype.click)
    $('body').on('submit', 'form.ajax', Ajax.prototype.submit)
    $('body').on('click', 'a[data-cancel-closest]', Ajax.prototype.cancel)
  })
}(window.jQuery);
<|endoftext|>


<commit_before>module('lively.morphic.tests.HTMLText').requires('lively.morphic.tests.Helper').toRun(function() {

lively.morphic.tests.TestCase.subclass('lively.morphic.tests.HTMLText.TestCase',
'running', {
    setUp: function($super) {
        $super();
        this.createWorld();
        this.text = new lively.morphic.Text(new Rectangle(0,0, 400, 200));
        this.world.addMorph(this.text);
    }
});

lively.morphic.tests.HTMLText.TestCase.subclass('lively.morphic.tests.HTMLText.TextAttributes',
'testing', {
    test01RenderingTextShadow: function() {
        this.text.setTextString('eintest');
        this.text.emphasizeAll({textShadow: {offset: pt(1,1), blur: 2, color: Color.red}});
        this.checkChunks([{textString: 'eintest'}]);
        this.checkDOM([{
            tagName: 'span',
            textContent: 'eintest',
            style: {textShadow: ['rgb(204,0,0)', '1px', '1px', '2px'].join('')}
        }]);
    },

    test02ReplaceTextStringKeepsStyling: function() {
        this.text.replaceTextString('eintest');
        this.text.emphasizeAll({fontWeight: 'bold'});
        this.text.replaceTextString('foo');
        this.checkChunks([{textString: 'foo'}]);
        this.checkDOM([{
            tagName: 'span',
            textContent: 'foo',
            style: {fontWeight: 'bold'}
        }]);
    },

    test03SetInputAllowedSetsContenteditable: function() {
        var textNode = this.text.renderContext().textNode;
        this.assert(textNode.contenteditable, 'contenteditable not enabled by default');
        this.text.setInputAllowed(false);
        this.assert(!textNode.contenteditable, 'contenteditable not disabled');
    },

    test04InsertRichTextAndCopy: function() {
        this.text.textString = "Heoe!";
        this.assertEquals(this.text.copy().textString, "Heoe!");
        this.text.insertRichTextAt("y J", {color:Color.red}, 2);
        this.assertEquals(this.text.textString, "Hey Joe!", "text after insert");
        this.assertEquals(this.text.copy().textString, "Hey Joe!", "text after copy");
        this.checkDOM([{tagName: 'span', textContent: 'He', style: {}},
                       {tagName: 'span', textContent: 'y J', style: {color: 'rgb(204,0,0)'}},
                       {tagName: 'span', textContent: 'oe!', style: {}}]);
    },

    test05MergingTextChunksEnsuresLastBr: function() {
        this.text.textString = "Test";
        var chunks = this.text.getTextChunks();
        chunks.last().ensureEndsWithBr();
        var lastNode = Array.from(chunks.last().getChunkNode().childNodes).last();
        this.assertEquals('br', lastNode.tagName.toLowerCase());
        this.text.sliceTextChunks(0,2); this.text.coalesceChunks(); // slice'n fix
        lastNode = Array.from(chunks.last().getChunkNode().childNodes).last();
        this.assertEquals('br', lastNode.tagName.toLowerCase());
    },

    test06SetDoit: function() {
        this.text.setTextString('eintest');
        this.text.emphasize({doit: {code: 'Global.textDoitInvoked=true'}}, 0, 3);
        this.checkChunks(
            [{textString: 'ein', style: {doit: {
                code: "Global.textDoitInvoked=true", context: null}}},
             {textString: 'test'}]);
        var events = $._data(this.text.firstTextChunk().getChunkNode(), "events");

        this.assertEquals(1, events.mouseup.length, 'no doit event handler?');

        this.text.emphasize({doit: {code: 'Global.textDoitInvoked=true'}}, 0, 3);
        events = $._data(this.text.firstTextChunk().getChunkNode(), "events");
        this.assertEquals(1, events.mouseup.length, 'multiple doit event handler?');
    },

    test07OnlyOneHoverEventHandler: function() {
        this.world.addMorph(this.text);
        this.text.setTextString('xyz');
        var hoverSpec1 = {
            inAction: function() { return 1 },
            outAction: function() { return 2 }
        };
        this.text.emphasize({hover: hoverSpec1}, 0, 3);
        this.checkChunks([{
            textString: "xyz",
            style: {hover: hoverSpec1}
        }]);

        var events1 = $._data(this.text.firstTextChunk().getChunkNode(), "events");
        // jQuery decides whether it implements mouseenter/leave with
        // mouseover/out or directly with menter/leave
        this.assertEquals(1, (events1.mouseover || events1.mouseenter).length);
        this.assertEquals(1, (events1.mouseout || events1.mouseleave).length);

        var hoverSpec2 = {
            inAction: function() { return 3 },
            outAction: function() { return 4 }
        };
        this.text.emphasize({hover: hoverSpec2}, 0, 3);
        this.checkChunks([{
            textString: "xyz",
            style: {hover: hoverSpec2}
        }]);
        var events2 = $._data(this.text.firstTextChunk().getChunkNode(), "events");
        this.assertEquals(1, (events2.mouseover || events2.mouseenter).length);
        this.assertEquals(1, (events2.mouseout || events2.mouseleave).length);
    }

});

AsyncTestCase.subclass('lively.morphic.tests.HTMLText.Extent', lively.morphic.tests.HTMLText.TestCase.prototype,
// lively.morphic.tests.HTMLText.Extent.remove()
'testing', {
    testExtentOfClippedAndFixedText: function() {
        var text = new lively.morphic.Text(lively.rect(0,0, 200, 300), 'foo');
        text.applyStyle({fontFamily: 'Courier', fontSize: 12, clipMode: 'auto',
                         fixedWidth: true, fixedHeight: true});
        this.world.addMorph(text);
        var p = text.getPadding(), borderWidth = text.getBorderWidth();
        this.assertEquals(
            pt(200,300).addXY(-p.left() - p.right() - 2*borderWidth, -p.top() - p.bottom() - 2*borderWidth),
            text.getTextExtent());
        this.done();
    },
    testComputeRealExtent: function() {
        var text = new lively.morphic.Text(lively.rect(0,0, 200, 300), 'foo');
        text.applyStyle({fontFamily: 'Courier', fontSize: 12, clipMode: 'auto',
                         fixedWidth: true, fixedHeight: true});
        text.emphasize({fontSize: 24}, 1,2);
        this.world.addMorph(text);
        var bounds = text.computeRealTextBounds();
        this.assertEquals(lively.rect(5,3,39,37), bounds);
        this.done();
    }
});

lively.morphic.tests.MorphTests.subclass('lively.morphic.tests.HTMLText.HtmlParserTests',
'running', {
    setUp: function($super) {
        $super();
        this.sut = lively.morphic.HTMLParser
    }
},
'testing', {
    testSanitizeHtml: function() {
        var s1 = "a
b"
        var r1 = this.sut.sanitizeHtml(s1)
        this.assertEquals(r1, "a
b")
    },
    testSanitizeHtmlReplaceAmp: function() {
        var s1 = "a&b"
        var r1 = this.sut.sanitizeHtml(s1)
        this.assertEquals(r1, "a&b")
    },
    testSanitizeHtmlUnbalancedTags: function() {
        var s1 = "abc",
            r1 = this.sut.sanitizeHtml(s1);
        this.assertEquals(r1, "abc");
    },

    testSourceCodeToNodeStrippedBRs: function() {
      var node = lively.morphic.HTMLParser.sourceToNode('a
b')
      lively.morphic.HTMLParser.sanitizeNode(node);
      this.assertEquals(node.textContent, "ab", "wrong node")

      richText = new lively.morphic.RichText(node.textContent);
      this.assertEquals(richText.textString, "ab", "wrong text string")
    },

    testSanitizeNode: function() {
        var s = "\n\n\n"
              + "a\nb\n"
              + "\n\n",
            node = lively.morphic.HTMLParser.sourceToNode(s);
        lively.morphic.HTMLParser.sanitizeNode(node);
        this.assertEquals(node.textContent, "a\nb", "too many newlines");
    },
    testSanitizeNodeWithNewlineInSpan: function() {
        var s = 'a\nb';
        var node = lively.morphic.HTMLParser.sourceToNode(s);
        lively.morphic.HTMLParser.sanitizeNode(node);
        this.assertEquals(node.textContent, "a\nb", "wrong newlines");
    },
    testSanitizeNodeWindowsChromeWithNewLine: function() {
        var s = '\n\n\nhello\n
\n\n\n';
        var node = lively.morphic.HTMLParser.sourceToNode(s);
        lively.morphic.HTMLParser.sanitizeNode(node);
        this.assertEquals(node.textContent, "hello\n", "wrong newlines");
    },
    testSanitizeNodeLinuxWithMetaTag: function() {
        var s = '<meta >bombs';
        var node = lively.morphic.HTMLParser.sourceToNode(s);
        lively.morphic.HTMLParser.sanitizeNode(node);
        this.assertEquals(node.textContent, "bombs", "linux meta tag brakes it");
    },

    testSourceToNodeWithInvalidTag: function(data) {
        var node = lively.morphic.HTMLParser.sourceToNode('hello<invalidtag>bla');
        this.assert(node.innerHTML, 'hello<invalidtag>bla</invalidtag>');
    },

    testSanitizeNodeWithAmp: function() {
        var s = 'bla';
        var node = lively.morphic.HTMLParser.sourceToNode(s);
        lively.morphic.HTMLParser.sanitizeNode(node);
        this.assertEquals(node.textContent, "bla", "pasting with & is broken");
    },
    testSanitizeNodeWithAmp2: function() {
        var s = 'H&M';
        var node = lively.morphic.HTMLParser.sourceToNode(s);
        lively.morphic.HTMLParser.sanitizeNode(node);
        this.assertEquals(node.textContent, "H&M", "pasting with & is broken");
    },
    testSanitizeNodeWithLt: function() {
        var s = '1<2';
        var node = lively.morphic.HTMLParser.sourceToNode(s);
        lively.morphic.HTMLParser.sanitizeNode(node);
        this.assertEquals(node.textContent, "1<2", "pasting with & is broken");
    },

    testSanitizeNodeWithLt2: function() {
        var s = '<';
        var node = lively.morphic.HTMLParser.sourceToNode(s);
        lively.morphic.HTMLParser.sanitizeNode(node);
        this.assertEquals(node.textContent, "<", "pasting with < is broken");
    }

});

lively.morphic.tests.HTMLText.TestCase.subclass('lively.morphic.tests.HTMLText.ObjectEmbedding',
'testing', {
    xtest01EmbedSimpleMorph: function() {
        var m = lively.morphic.Morph.makeRectangle(0,0,100,100),
            t = this.text;
        t.setTextString('ein test');
        t.emphasizeRanges([[3,4, {embeddedMorph: m}]]);
        // this.checkChunks([{textString: 'ein test'}]);
        this.checkDOM([
            {tagName: 'span',textContent: 'ein'},
            {tagName: 'span',childNodes: {tagName: 'div'}},
            {tagName: 'span',textContent: 'test'}]);
    }
});

});
<commit_msg>text: making real extent test less brittle<commit_after>module('lively.morphic.tests.HTMLText').requires('lively.morphic.tests.Helper').toRun(function() {

lively.morphic.tests.TestCase.subclass('lively.morphic.tests.HTMLText.TestCase',
'running', {
    setUp: function($super) {
        $super();
        this.createWorld();
        this.text = new lively.morphic.Text(new Rectangle(0,0, 400, 200));
        this.world.addMorph(this.text);
    }
});

lively.morphic.tests.HTMLText.TestCase.subclass('lively.morphic.tests.HTMLText.TextAttributes',
'testing', {
    test01RenderingTextShadow: function() {
        this.text.setTextString('eintest');
        this.text.emphasizeAll({textShadow: {offset: pt(1,1), blur: 2, color: Color.red}});
        this.checkChunks([{textString: 'eintest'}]);
        this.checkDOM([{
            tagName: 'span',
            textContent: 'eintest',
            style: {textShadow: ['rgb(204,0,0)', '1px', '1px', '2px'].join('')}
        }]);
    },

    test02ReplaceTextStringKeepsStyling: function() {
        this.text.replaceTextString('eintest');
        this.text.emphasizeAll({fontWeight: 'bold'});
        this.text.replaceTextString('foo');
        this.checkChunks([{textString: 'foo'}]);
        this.checkDOM([{
            tagName: 'span',
            textContent: 'foo',
            style: {fontWeight: 'bold'}
        }]);
    },

    test03SetInputAllowedSetsContenteditable: function() {
        var textNode = this.text.renderContext().textNode;
        this.assert(textNode.contenteditable, 'contenteditable not enabled by default');
        this.text.setInputAllowed(false);
        this.assert(!textNode.contenteditable, 'contenteditable not disabled');
    },

    test04InsertRichTextAndCopy: function() {
        this.text.textString = "Heoe!";
        this.assertEquals(this.text.copy().textString, "Heoe!");
        this.text.insertRichTextAt("y J", {color:Color.red}, 2);
        this.assertEquals(this.text.textString, "Hey Joe!", "text after insert");
        this.assertEquals(this.text.copy().textString, "Hey Joe!", "text after copy");
        this.checkDOM([{tagName: 'span', textContent: 'He', style: {}},
                       {tagName: 'span', textContent: 'y J', style: {color: 'rgb(204,0,0)'}},
                       {tagName: 'span', textContent: 'oe!', style: {}}]);
    },

    test05MergingTextChunksEnsuresLastBr: function() {
        this.text.textString = "Test";
        var chunks = this.text.getTextChunks();
        chunks.last().ensureEndsWithBr();
        var lastNode = Array.from(chunks.last().getChunkNode().childNodes).last();
        this.assertEquals('br', lastNode.tagName.toLowerCase());
        this.text.sliceTextChunks(0,2); this.text.coalesceChunks(); // slice'n fix
        lastNode = Array.from(chunks.last().getChunkNode().childNodes).last();
        this.assertEquals('br', lastNode.tagName.toLowerCase());
    },

    test06SetDoit: function() {
        this.text.setTextString('eintest');
        this.text.emphasize({doit: {code: 'Global.textDoitInvoked=true'}}, 0, 3);
        this.checkChunks(
            [{textString: 'ein', style: {doit: {
                code: "Global.textDoitInvoked=true", context: null}}},
             {textString: 'test'}]);
        var events = $._data(this.text.firstTextChunk().getChunkNode(), "events");

        this.assertEquals(1, events.mouseup.length, 'no doit event handler?');

        this.text.emphasize({doit: {code: 'Global.textDoitInvoked=true'}}, 0, 3);
        events = $._data(this.text.firstTextChunk().getChunkNode(), "events");
        this.assertEquals(1, events.mouseup.length, 'multiple doit event handler?');
    },

    test07OnlyOneHoverEventHandler: function() {
        this.world.addMorph(this.text);
        this.text.setTextString('xyz');
        var hoverSpec1 = {
            inAction: function() { return 1 },
            outAction: function() { return 2 }
        };
        this.text.emphasize({hover: hoverSpec1}, 0, 3);
        this.checkChunks([{
            textString: "xyz",
            style: {hover: hoverSpec1}
        }]);

        var events1 = $._data(this.text.firstTextChunk().getChunkNode(), "events");
        // jQuery decides whether it implements mouseenter/leave with
        // mouseover/out or directly with menter/leave
        this.assertEquals(1, (events1.mouseover || events1.mouseenter).length);
        this.assertEquals(1, (events1.mouseout || events1.mouseleave).length);

        var hoverSpec2 = {
            inAction: function() { return 3 },
            outAction: function() { return 4 }
        };
        this.text.emphasize({hover: hoverSpec2}, 0, 3);
        this.checkChunks([{
            textString: "xyz",
            style: {hover: hoverSpec2}
        }]);
        var events2 = $._data(this.text.firstTextChunk().getChunkNode(), "events");
        this.assertEquals(1, (events2.mouseover || events2.mouseenter).length);
        this.assertEquals(1, (events2.mouseout || events2.mouseleave).length);
    }

});

AsyncTestCase.subclass('lively.morphic.tests.HTMLText.Extent', lively.morphic.tests.HTMLText.TestCase.prototype,
// lively.morphic.tests.HTMLText.Extent.remove()
'testing', {
    testExtentOfClippedAndFixedText: function() {
        var text = new lively.morphic.Text(lively.rect(0,0, 200, 300), 'foo');
        text.applyStyle({fontFamily: 'Courier', fontSize: 12, clipMode: 'auto',
                         fixedWidth: true, fixedHeight: true});
        this.world.addMorph(text);
        var p = text.getPadding(), borderWidth = text.getBorderWidth();
        this.assertEquals(
            pt(200,300).addXY(-p.left() - p.right() - 2*borderWidth, -p.top() - p.bottom() - 2*borderWidth),
            text.getTextExtent());
        this.done();
    },
    testComputeRealExtent: function() {
        var text = new lively.morphic.Text(lively.rect(0,0, 200, 300), 'foo');
        text.applyStyle({fontFamily: 'Courier', fontSize: 12, clipMode: 'auto',
                         fixedWidth: true, fixedHeight: true});
        text.emphasize({fontSize: 24}, 1,2);
        this.world.addMorph(text);
        var bounds = text.computeRealTextBounds();
        this.epsilon = 3;
        this.assertEqualsEpsilon(lively.rect(5,3,39,37), bounds);
        this.done();
    }
});

lively.morphic.tests.MorphTests.subclass('lively.morphic.tests.HTMLText.HtmlParserTests',
'running', {
    setUp: function($super) {
        $super();
        this.sut = lively.morphic.HTMLParser
    }
},
'testing', {
    testSanitizeHtml: function() {
        var s1 = "a
b"
        var r1 = this.sut.sanitizeHtml(s1)
        this.assertEquals(r1, "a
b")
    },
    testSanitizeHtmlReplaceAmp: function() {
        var s1 = "a&b"
        var r1 = this.sut.sanitizeHtml(s1)
        this.assertEquals(r1, "a&b")
    },
    testSanitizeHtmlUnbalancedTags: function() {
        var s1 = "abc",
            r1 = this.sut.sanitizeHtml(s1);
        this.assertEquals(r1, "abc");
    },

    testSourceCodeToNodeStrippedBRs: function() {
      var node = lively.morphic.HTMLParser.sourceToNode('a
b')
      lively.morphic.HTMLParser.sanitizeNode(node);
      this.assertEquals(node.textContent, "ab", "wrong node")

      richText = new lively.morphic.RichText(node.textContent);
      this.assertEquals(richText.textString, "ab", "wrong text string")
    },

    testSanitizeNode: function() {
        var s = "\n\n\n"
              + "a\nb\n"
              + "\n\n",
            node = lively.morphic.HTMLParser.sourceToNode(s);
        lively.morphic.HTMLParser.sanitizeNode(node);
        this.assertEquals(node.textContent, "a\nb", "too many newlines");
    },
    testSanitizeNodeWithNewlineInSpan: function() {
        var s = 'a\nb';
        var node = lively.morphic.HTMLParser.sourceToNode(s);
        lively.morphic.HTMLParser.sanitizeNode(node);
        this.assertEquals(node.textContent, "a\nb", "wrong newlines");
    },
    testSanitizeNodeWindowsChromeWithNewLine: function() {
        var s = '\n\n\nhello\n
\n\n\n';
        var node = lively.morphic.HTMLParser.sourceToNode(s);
        lively.morphic.HTMLParser.sanitizeNode(node);
        this.assertEquals(node.textContent, "hello\n", "wrong newlines");
    },
    testSanitizeNodeLinuxWithMetaTag: function() {
        var s = '<meta >bombs';
        var node = lively.morphic.HTMLParser.sourceToNode(s);
        lively.morphic.HTMLParser.sanitizeNode(node);
        this.assertEquals(node.textContent, "bombs", "linux meta tag brakes it");
    },

    testSourceToNodeWithInvalidTag: function(data) {
        var node = lively.morphic.HTMLParser.sourceToNode('hello<invalidtag>bla');
        this.assert(node.innerHTML, 'hello<invalidtag>bla</invalidtag>');
    },

    testSanitizeNodeWithAmp: function() {
        var s = 'bla';
        var node = lively.morphic.HTMLParser.sourceToNode(s);
        lively.morphic.HTMLParser.sanitizeNode(node);
        this.assertEquals(node.textContent, "bla", "pasting with & is broken");
    },
    testSanitizeNodeWithAmp2: function() {
        var s = 'H&M';
        var node = lively.morphic.HTMLParser.sourceToNode(s);
        lively.morphic.HTMLParser.sanitizeNode(node);
        this.assertEquals(node.textContent, "H&M", "pasting with & is broken");
    },
    testSanitizeNodeWithLt: function() {
        var s = '1<2';
        var node = lively.morphic.HTMLParser.sourceToNode(s);
        lively.morphic.HTMLParser.sanitizeNode(node);
        this.assertEquals(node.textContent, "1<2", "pasting with & is broken");
    },

    testSanitizeNodeWithLt2: function() {
        var s = '<';
        var node = lively.morphic.HTMLParser.sourceToNode(s);
        lively.morphic.HTMLParser.sanitizeNode(node);
        this.assertEquals(node.textContent, "<", "pasting with < is broken");
    }

});

lively.morphic.tests.HTMLText.TestCase.subclass('lively.morphic.tests.HTMLText.ObjectEmbedding',
'testing', {
    xtest01EmbedSimpleMorph: function() {
        var m = lively.morphic.Morph.makeRectangle(0,0,100,100),
            t = this.text;
        t.setTextString('ein test');
        t.emphasizeRanges([[3,4, {embeddedMorph: m}]]);
        // this.checkChunks([{textString: 'ein test'}]);
        this.checkDOM([
            {tagName: 'span',textContent: 'ein'},
            {tagName: 'span',childNodes: {tagName: 'div'}},
            {tagName: 'span',textContent: 'test'}]);
    }
});

});
<|endoftext|>


<commit_before>module('users.timfelgentreff.babelsberg.cassowary_ext').requires('users.timfelgentreff.cassowary.DwarfCassowary').toRun(function() {

Function.addMethods({
    shouldBeTrue: function (priority, ctx) {
        if (!ctx) {
            ctx = priority;
            priority = undefined;
        }
        return ClSimplexSolver.getInstance().always({priority: priority, ctx: ctx}, this);
    }
})

ClSimplexSolver.addMethods({
    isConstraintObject: function() {
        return true;
    },
    constraintVariableFor: function(value, ivarname) {
        if ((typeof(value) == "number") || (value === null) || (value instanceof Number)) {
            var v = new ClVariable(value + 0 /* coerce back into primitive */);
            v.stay();
            v.solver = this;
            return v;
        } else {
            return null;
        }
    },
    get strength() {
        return ClStrength;
    },
    weight: 1000,
    always: function (opts, func) {
        var ctx = opts.ctx,
            priority = opts.priority;
        func.varMapping = ctx;
        var constraint = new Constraint(func, this);
        constraint.priority = priority;
        constraint.enable();
        return constraint;
    }
});

Object.extend(ClSimplexSolver, {
    getInstance: function() {
        if (!this["$$instance"]) {
            this["$$instance"] = new ClSimplexSolver();
            this["$$instance"].setAutosolve(false);
        }
        return this["$$instance"];
    },

    resetInstance: function() {
        this["$$instance"] = undefined;
    }
});

ClAbstractVariable.addMethods({
    isConstraintObject: function() {
        return true;
    },

    stay: function(strength) {
        var cn = new ClStayConstraint(this, strength || ClStrength.weak, 1.0);
        ClSimplexSolver.getInstance().addConstraint(cn);
        this.stayConstraint = cn;
        return cn;
    },
    removeStay: function() {
        if (this.stayConstraint) {
            try {
                ClSimplexSolver.getInstance().removeConstraint(this.stayConstraint);
            } catch(_) {
                this.stayConstraint = null;
            }
        }
    },

    suggestValue: function(value) {
        var c = this.cnEquals(value),
            s = ClSimplexSolver.getInstance();
        s.addConstraint(c);
        s.solve();
        s.removeConstraint(c);
    },
    setReadonly: function(bool) {
        if (bool && !this.readonlyConstraint) {
            var cn = new ClStayConstraint(this, ClStrength.required, 1.0);
            ClSimplexSolver.getInstance().addConstraint(cn);
            this.readonlyConstraint = cn;
            return cn;
        } else if (!bool && this.readonlyConstraint) {
            ClSimplexSolver.getInstance().removeConstraint(this.readonlyConstraint);
            this.readonlyConstraint = undefined;
        }
    },
    isReadonly: function() {
        return !!this.readonlyConstraint;
    },

    plus: function(value) {
        return new ClLinearExpression(this).plus(value);
    },

    minus: function(value) {
        return (new ClLinearExpression(this)).minus(value);
    },

    times: function(value) {
        return new ClLinearExpression(this).times(value);
    },

    divide: function(value) {
        return new ClLinearExpression(this).divide(value);
    },

    cnGeq: function(value) {
        return new ClLinearExpression(this).cnGeq(value);
    },

    cnLeq: function(value) {
        return new ClLinearExpression(this).cnLeq(value);
    },

    cnEquals: function(value) {
        return new ClLinearExpression(this).cnEquals(value);
    },
});

ClLinearExpression.addMethods({
    isConstraintObject: function() {
        return true;
    },

    cnGeq: function(value) {
        if (typeof(value) == 'string') {
            // XXX: Basically, we make numbers in strings readonly here
            value = parseFloat(value);
        }
        return new ClLinearInequality(this.minus(value));
    },

    cnLeq: function(value) {
        if (typeof(value) == 'string') {
            // XXX: Basically, we make numbers in strings readonly here
            value = parseFloat(value);
        }
        if (!(value instanceof ClLinearExpression)) {
            value = new ClLinearExpression(value);
        }
        if (!value.minus) debugger;
        return new ClLinearInequality(value.minus(this));
    },

    cnEquals: function(value) {
        if (typeof(value) == 'string') {
            // XXX: Basically, we make numbers in strings readonly here
            value = parseFloat(value);
        }
        return new ClLinearEquation(this, value);
    },

  plus: function(expr /*ClLinearExpression*/) {
    if (typeof(expr) == 'string') {
        // XXX: Basically, we make numbers in strings readonly here
        expr = parseFloat(expr);
    }

    if (expr instanceof ClLinearExpression) {
      return this.clone().addExpression(expr, 1.0);
    } else if (expr instanceof ClVariable) {
      return this.clone().addVariable(expr, 1.0);
    } else if (typeof(expr) == "number") {
      return this.clone().addExpression(new ClLinearExpression(expr), 1.0);
    } else {
        throw "Not supported: plus with " + expr;
    }
  },
  times: function(x) {
    if (typeof(x) == 'string') {
        // XXX: Basically, we make numbers in strings readonly here
        x = parseFloat(x);
    }

    if (typeof(x) == 'number') {
      return (this.clone()).multiplyMe(x);
    } else {
      if (this.isConstant()) {
        return x.times(this._constant);
      } else if (x.isConstant()) {
        return this.times(x._constant);
      } else {
        throw new ExCLNonlinearExpression();
      }
    }
  },

  minus: function(expr /*ClLinearExpression*/) {
    if (typeof(expr) == 'string') {
        // XXX: Basically, we make numbers in strings readonly here
        expr = parseFloat(expr);
    }

    if (expr instanceof ClLinearExpression) {
      return this.clone().addExpression(expr, -1.0);
    } else if (expr instanceof ClVariable) {
      return this.clone().addVariable(expr, -1.0);
    } else if (typeof(expr) == "number") {
      return this.clone().addExpression(new ClLinearExpression(expr), -1.0);
    } else {
        throw "Not supported: minus with " + expr;
    }
  },

  divide: function(x) {
    if (typeof(x) == 'string') {
        // XXX: Basically, we make numbers in strings readonly here
        x = parseFloat(x);
    }

    if (typeof(x) == 'number') {
      if (CL.approx(x, 0.0)) {
        throw new ExCLNonlinearExpression();
      }
      return this.times(1.0 / x);
    } else if (x instanceof ClLinearExpression) {
      if (!x.isConstant) {
        throw new ExCLNonlinearExpression();
      }
      return this.times(1.0 / x._constant);
    } else {
        throw "Not supported: divide with " + expr;
    }
  },
});

ClConstraint.addMethods({
    isConstraintObject: function() {
        return true;
    },

    enable: function(strength) {
        if (strength) {
            this.setStrength(strength);
        }
        this.solver.addConstraint(this);
    },
    disable: function() {
        this.solver.removeConstraint(this);
    },

    get solver() {
        return this._solver || ClSimplexSolver.getInstance()
    },

    set solver(value) {
        this._solver = value;
    }
});

}) // end of module<commit_msg>remove references to singleton solver instance in ClAbstractVariable<commit_after>module('users.timfelgentreff.babelsberg.cassowary_ext').requires('users.timfelgentreff.cassowary.DwarfCassowary').toRun(function() {

Function.addMethods({
    shouldBeTrue: function (priority, ctx) {
        if (!ctx) {
            ctx = priority;
            priority = undefined;
        }
        return ClSimplexSolver.getInstance().always({priority: priority, ctx: ctx}, this);
    }
})

ClSimplexSolver.addMethods({
    isConstraintObject: function() {
        return true;
    },
    constraintVariableFor: function(value, ivarname) {
        if ((typeof(value) == "number") || (value === null) || (value instanceof Number)) {
            var v = new ClVariable(value + 0 /* coerce back into primitive */);
            v.solver = this;
            v.stay();
            return v;
        } else {
            return null;
        }
    },
    get strength() {
        return ClStrength;
    },
    weight: 1000,
    always: function (opts, func) {
        var ctx = opts.ctx,
            priority = opts.priority;
        func.varMapping = ctx;
        var constraint = new Constraint(func, this);
        constraint.priority = priority;
        constraint.enable();
        return constraint;
    }
});

Object.extend(ClSimplexSolver, {
    getInstance: function() {
        if (!this["$$instance"]) {
            this["$$instance"] = new ClSimplexSolver();
            this["$$instance"].setAutosolve(false);
        }
        return this["$$instance"];
    },

    resetInstance: function() {
        this["$$instance"] = undefined;
    }
});

ClAbstractVariable.addMethods({
    isConstraintObject: function() {
        return true;
    },

    stay: function(strength) {
        var cn = new ClStayConstraint(this, strength || ClStrength.weak, 1.0);
        this.solver.addConstraint(cn);
        this.stayConstraint = cn;
        return cn;
    },
    removeStay: function() {
        if (this.stayConstraint) {
            try {
                this.solver.removeConstraint(this.stayConstraint);
            } catch(_) {
                this.stayConstraint = null;
            }
        }
    },

    suggestValue: function(value) {
        var c = this.cnEquals(value),
            s = this.solver;
        s.addConstraint(c);
        s.solve();
        s.removeConstraint(c);
    },
    setReadonly: function(bool) {
        if (bool && !this.readonlyConstraint) {
            var cn = new ClStayConstraint(this, ClStrength.required, 1.0);
            this.solver.addConstraint(cn);
            this.readonlyConstraint = cn;
            return cn;
        } else if (!bool && this.readonlyConstraint) {
            this.solver.removeConstraint(this.readonlyConstraint);
            this.readonlyConstraint = undefined;
        }
    },
    isReadonly: function() {
        return !!this.readonlyConstraint;
    },

    plus: function(value) {
        return new ClLinearExpression(this).plus(value);
    },

    minus: function(value) {
        return (new ClLinearExpression(this)).minus(value);
    },

    times: function(value) {
        return new ClLinearExpression(this).times(value);
    },

    divide: function(value) {
        return new ClLinearExpression(this).divide(value);
    },

    cnGeq: function(value) {
        return new ClLinearExpression(this).cnGeq(value);
    },

    cnLeq: function(value) {
        return new ClLinearExpression(this).cnLeq(value);
    },

    cnEquals: function(value) {
        return new ClLinearExpression(this).cnEquals(value);
    },
});

ClLinearExpression.addMethods({
    isConstraintObject: function() {
        return true;
    },

    cnGeq: function(value) {
        if (typeof(value) == 'string') {
            // XXX: Basically, we make numbers in strings readonly here
            value = parseFloat(value);
        }
        return new ClLinearInequality(this.minus(value));
    },

    cnLeq: function(value) {
        if (typeof(value) == 'string') {
            // XXX: Basically, we make numbers in strings readonly here
            value = parseFloat(value);
        }
        if (!(value instanceof ClLinearExpression)) {
            value = new ClLinearExpression(value);
        }
        if (!value.minus) debugger;
        return new ClLinearInequality(value.minus(this));
    },

    cnEquals: function(value) {
        if (typeof(value) == 'string') {
            // XXX: Basically, we make numbers in strings readonly here
            value = parseFloat(value);
        }
        return new ClLinearEquation(this, value);
    },

  plus: function(expr /*ClLinearExpression*/) {
    if (typeof(expr) == 'string') {
        // XXX: Basically, we make numbers in strings readonly here
        expr = parseFloat(expr);
    }

    if (expr instanceof ClLinearExpression) {
      return this.clone().addExpression(expr, 1.0);
    } else if (expr instanceof ClVariable) {
      return this.clone().addVariable(expr, 1.0);
    } else if (typeof(expr) == "number") {
      return this.clone().addExpression(new ClLinearExpression(expr), 1.0);
    } else {
        throw "Not supported: plus with " + expr;
    }
  },
  times: function(x) {
    if (typeof(x) == 'string') {
        // XXX: Basically, we make numbers in strings readonly here
        x = parseFloat(x);
    }

    if (typeof(x) == 'number') {
      return (this.clone()).multiplyMe(x);
    } else {
      if (this.isConstant()) {
        return x.times(this._constant);
      } else if (x.isConstant()) {
        return this.times(x._constant);
      } else {
        throw new ExCLNonlinearExpression();
      }
    }
  },

  minus: function(expr /*ClLinearExpression*/) {
    if (typeof(expr) == 'string') {
        // XXX: Basically, we make numbers in strings readonly here
        expr = parseFloat(expr);
    }

    if (expr instanceof ClLinearExpression) {
      return this.clone().addExpression(expr, -1.0);
    } else if (expr instanceof ClVariable) {
      return this.clone().addVariable(expr, -1.0);
    } else if (typeof(expr) == "number") {
      return this.clone().addExpression(new ClLinearExpression(expr), -1.0);
    } else {
        throw "Not supported: minus with " + expr;
    }
  },

  divide: function(x) {
    if (typeof(x) == 'string') {
        // XXX: Basically, we make numbers in strings readonly here
        x = parseFloat(x);
    }

    if (typeof(x) == 'number') {
      if (CL.approx(x, 0.0)) {
        throw new ExCLNonlinearExpression();
      }
      return this.times(1.0 / x);
    } else if (x instanceof ClLinearExpression) {
      if (!x.isConstant) {
        throw new ExCLNonlinearExpression();
      }
      return this.times(1.0 / x._constant);
    } else {
        throw "Not supported: divide with " + expr;
    }
  },
});

ClConstraint.addMethods({
    isConstraintObject: function() {
        return true;
    },

    enable: function(strength) {
        if (strength) {
            this.setStrength(strength);
        }
        this.solver.addConstraint(this);
    },
    disable: function() {
        this.solver.removeConstraint(this);
    },

    get solver() {
        return this._solver || ClSimplexSolver.getInstance()
    },

    set solver(value) {
        this._solver = value;
    }
});

}) // end of module<|endoftext|>


<commit_before>// Source: https://en.wikipedia.org/wiki/List_of_sovereign_states

'use strict';

module.exports = [
	['AF', { label: 'Afghanistan' }],
	['AL', { label: 'Albania' }],
	['DZ', { label: 'Algeria' }],
	['AD', { label: 'Andorra' }],
	['AO', { label: 'Angola' }],
	['AI', { label: 'Anguilla' }],
	['AG', { label: 'Antigua and Barbuda' }],
	['AR', { label: 'Argentina' }],
	['AM', { label: 'Armenia' }],
	['AU', { label: 'Australia' }],
	['AT', { label: 'Austria' }],
	['AZ', { label: 'Azerbaijan' }],
	['BS', { label: 'Bahamas' }],
	['BH', { label: 'Bahrain' }],
	['BD', { label: 'Bangladesh' }],
	['BB', { label: 'Barbados' }],
	['BY', { label: 'Belarus' }],
	['BE', { label: 'Belgium' }],
	['BZ', { label: 'Belize' }],
	['BJ', { label: 'Benin' }],
	['BT', { label: 'Bhutan' }],
	['BO', { label: 'Bolivia' }],
	['BA', { label: 'Bosnia and Herzegovina' }],
	['BW', { label: 'Botswana' }],
	['BR', { label: 'Brazil' }],
	['BN', { label: 'Brunei' }],
	['BG', { label: 'Bulgaria' }],
	['BF', { label: 'Burkina Faso' }],
	['MM', { label: 'Burma' }],
	['BI', { label: 'Burundi' }],
	['KH', { label: 'Cambodia' }],
	['CM', { label: 'Cameroon' }],
	['CA', { label: 'Canada' }],
	['CV', { label: 'Cape Verde' }],
	['CF', { label: 'Central African Republic' }],
	['TD', { label: 'Chad' }],
	['CL', { label: 'Chile' }],
	['CN', { label: 'China' }],
	['CO', { label: 'Colombia' }],
	['KM', { label: 'Comoros' }],
	['CD', { label: 'Congo, Democratic Republic' }],
	['CG', { label: 'Congo, Republic' }],
	['CR', { label: 'Costa Rica' }],
	['HR', { label: 'Croatia' }],
	['CU', { label: 'Cuba' }],
	['CY', { label: 'Cyprus' }],
	['CZ', { label: 'Czech Republic' }],
	['DK', { label: 'Denmark' }],
	['DJ', { label: 'Djibouti' }],
	['DM', { label: 'Dominica' }],
	['DO', { label: 'Dominican Republic' }],
	['TL', { label: 'East Timor' }],
	['EC', { label: 'Ecuador' }],
	['EG', { label: 'Egypt' }],
	['SV', { label: 'El Salvador' }],
	['GQ', { label: 'Equatorial Guinea' }],
	['ER', { label: 'Eritrea' }],
	['EE', { label: 'Estonia' }],
	['ET', { label: 'Ethiopia' }],
	['FJ', { label: 'Fiji' }],
	['FI', { label: 'Finland' }],
	['FR', { label: 'France' }],
	['GA', { label: 'Gabon' }],
	['GM', { label: 'Gambia' }],
	['GE', { label: 'Georgia' }],
	['DE', { label: 'Germany' }],
	['GH', { label: 'Ghana' }],
	['GR', { label: 'Greece' }],
	['GD', { label: 'Grenada' }],
	['GT', { label: 'Guatemala' }],
	['GN', { label: 'Guinea' }],
	['GW', { label: 'Guinea-Bissau' }],
	['GY', { label: 'Guyana' }],
	['HT', { label: 'Haiti' }],
	['HN', { label: 'Honduras' }],
	['HU', { label: 'Hungary' }],
	['IS', { label: 'Iceland' }],
	['IN', { label: 'India' }],
	['ID', { label: 'Indonesia' }],
	['IR', { label: 'Iran' }],
	['IQ', { label: 'Iraq' }],
	['IE', { label: 'Ireland' }],
	['IL', { label: 'Israel' }],
	['IT', { label: 'Italy' }],
	['CI', { label: 'Ivory Coast' }],
	['JM', { label: 'Jamaica' }],
	['JP', { label: 'Japan' }],
	['JO', { label: 'Jordan' }],
	['KZ', { label: 'Kazakhstan' }],
	['KE', { label: 'Kenya' }],
	['KI', { label: 'Kiribati' }],
	['KP', { label: 'Korea, North' }],
	['KR', { label: 'Korea, South' }],
	['KW', { label: 'Kuwait' }],
	['KG', { label: 'Kyrgyzstan' }],
	['LA', { label: 'Laos' }],
	['LV', { label: 'Latvia' }],
	['LB', { label: 'Lebanon' }],
	['LS', { label: 'Lesotho' }],
	['LR', { label: 'Liberia' }],
	['LY', { label: 'Libya' }],
	['LI', { label: 'Liechtenstein' }],
	['LT', { label: 'Lithuania' }],
	['LU', { label: 'Luxembourg' }],
	['MK', { label: 'Macedonia' }],
	['MG', { label: 'Madagascar' }],
	['MW', { label: 'Malawi' }],
	['MY', { label: 'Malaysia' }],
	['MV', { label: 'Maldives' }],
	['ML', { label: 'Mali' }],
	['MT', { label: 'Malta' }],
	['MH', { label: 'Marshall Islands' }],
	['MR', { label: 'Mauritania' }],
	['MU', { label: 'Mauritius' }],
	['MX', { label: 'Mexico' }],
	['FM', { label: 'Micronesia' }],
	['MD', { label: 'Moldova' }],
	['MC', { label: 'Monaco' }],
	['MN', { label: 'Mongolia' }],
	['ME', { label: 'Montenegro' }],
	['MA', { label: 'Morocco' }],
	['MZ', { label: 'Mozambique' }],
	['NA', { label: 'Namibia' }],
	['NR', { label: 'Nauru' }],
	['NP', { label: 'Nepal' }],
	['NL', { label: 'Netherlands' }],
	['NZ', { label: 'New Zealand' }],
	['NI', { label: 'Nicaragua' }],
	['NE', { label: 'Niger' }],
	['NG', { label: 'Nigeria' }],
	['NO', { label: 'Norway' }],
	['OM', { label: 'Oman' }],
	['PK', { label: 'Pakistan' }],
	['PW', { label: 'Palau' }],
	['PS', { label: 'Palestine' }],
	['PA', { label: 'Panama' }],
	['PG', { label: 'Papua New Guinea' }],
	['PY', { label: 'Paraguay' }],
	['YD', { label: 'People\'s Democratic Republic of Yemen' }],
	['PE', { label: 'Peru' }],
	['PH', { label: 'Philippines' }],
	['PL', { label: 'Poland' }],
	['PT', { label: 'Portugal' }],
	['QA', { label: 'Qatar' }],
	['RO', { label: 'Romania' }],
	['RU', { label: 'Russia' }],
	['RW', { label: 'Rwanda' }],
	['KN', { label: 'Saint Kitts and Nevis' }],
	['LC', { label: 'Saint Lucia' }],
	['VC', { label: 'Saint Vincent and the Grenadines' }],
	['WS', { label: 'Samoa' }],
	['SM', { label: 'San Marino' }],
	['ST', { label: 'São Tomé and Príncipe' }],
	['SA', { label: 'Saudi Arabia' }],
	['SN', { label: 'Senegal' }],
	['RS', { label: 'Serbia' }],
	['SC', { label: 'Seychelles' }],
	['SL', { label: 'Sierra Leone' }],
	['SG', { label: 'Singapore' }],
	['SK', { label: 'Slovakia' }],
	['SI', { label: 'Slovenia' }],
	['SB', { label: 'Solomon Islands' }],
	['SO', { label: 'Somalia' }],
	['ZA', { label: 'South Africa' }],
	['SS', { label: 'South Sudan' }],
	['ES', { label: 'Spain' }],
	['LK', { label: 'Sri Lanka' }],
	['SD', { label: 'Sudan' }],
	['SR', { label: 'Suriname' }],
	['SZ', { label: 'Swaziland' }],
	['SE', { label: 'Sweden' }],
	['CH', { label: 'Switzerland' }],
	['SY', { label: 'Syria' }],
	['TJ', { label: 'Tajikistan' }],
	['TZ', { label: 'Tanzania' }],
	['TH', { label: 'Thailand' }],
	['TG', { label: 'Togo' }],
	['TO', { label: 'Tonga' }],
	['TT', { label: 'Trinidad and Tobago' }],
	['TN', { label: 'Tunisia' }],
	['TR', { label: 'Turkey' }],
	['TM', { label: 'Turkmenistan' }],
	['TV', { label: 'Tuvalu' }],
	['UG', { label: 'Uganda' }],
	['UA', { label: 'Ukraine' }],
	['AE', { label: 'United Arab Emirates' }],
	['GB', { label: 'United Kingdom' }],
	['US', { label: 'United States' }],
	['UY', { label: 'Uruguay' }],
	['UZ', { label: 'Uzbekistan' }],
	['VU', { label: 'Vanuatu' }],
	['VA', { label: 'Vatican City' }],
	['VE', { label: 'Venezuela' }],
	['VN', { label: 'Vietnam' }],
	['YE', { label: 'Yemen' }],
	['ZM', { label: 'Zambia' }],
	['ZW', { label: 'Zimbabwe' }]
];
<commit_msg>Remove non existing country<commit_after>// Source: https://en.wikipedia.org/wiki/List_of_sovereign_states

'use strict';

module.exports = [
	['AF', { label: 'Afghanistan' }],
	['AL', { label: 'Albania' }],
	['DZ', { label: 'Algeria' }],
	['AD', { label: 'Andorra' }],
	['AO', { label: 'Angola' }],
	['AI', { label: 'Anguilla' }],
	['AG', { label: 'Antigua and Barbuda' }],
	['AR', { label: 'Argentina' }],
	['AM', { label: 'Armenia' }],
	['AU', { label: 'Australia' }],
	['AT', { label: 'Austria' }],
	['AZ', { label: 'Azerbaijan' }],
	['BS', { label: 'Bahamas' }],
	['BH', { label: 'Bahrain' }],
	['BD', { label: 'Bangladesh' }],
	['BB', { label: 'Barbados' }],
	['BY', { label: 'Belarus' }],
	['BE', { label: 'Belgium' }],
	['BZ', { label: 'Belize' }],
	['BJ', { label: 'Benin' }],
	['BT', { label: 'Bhutan' }],
	['BO', { label: 'Bolivia' }],
	['BA', { label: 'Bosnia and Herzegovina' }],
	['BW', { label: 'Botswana' }],
	['BR', { label: 'Brazil' }],
	['BN', { label: 'Brunei' }],
	['BG', { label: 'Bulgaria' }],
	['BF', { label: 'Burkina Faso' }],
	['MM', { label: 'Burma' }],
	['BI', { label: 'Burundi' }],
	['KH', { label: 'Cambodia' }],
	['CM', { label: 'Cameroon' }],
	['CA', { label: 'Canada' }],
	['CV', { label: 'Cape Verde' }],
	['CF', { label: 'Central African Republic' }],
	['TD', { label: 'Chad' }],
	['CL', { label: 'Chile' }],
	['CN', { label: 'China' }],
	['CO', { label: 'Colombia' }],
	['KM', { label: 'Comoros' }],
	['CD', { label: 'Congo, Democratic Republic' }],
	['CG', { label: 'Congo, Republic' }],
	['CR', { label: 'Costa Rica' }],
	['HR', { label: 'Croatia' }],
	['CU', { label: 'Cuba' }],
	['CY', { label: 'Cyprus' }],
	['CZ', { label: 'Czech Republic' }],
	['DK', { label: 'Denmark' }],
	['DJ', { label: 'Djibouti' }],
	['DM', { label: 'Dominica' }],
	['DO', { label: 'Dominican Republic' }],
	['TL', { label: 'East Timor' }],
	['EC', { label: 'Ecuador' }],
	['EG', { label: 'Egypt' }],
	['SV', { label: 'El Salvador' }],
	['GQ', { label: 'Equatorial Guinea' }],
	['ER', { label: 'Eritrea' }],
	['EE', { label: 'Estonia' }],
	['ET', { label: 'Ethiopia' }],
	['FJ', { label: 'Fiji' }],
	['FI', { label: 'Finland' }],
	['FR', { label: 'France' }],
	['GA', { label: 'Gabon' }],
	['GM', { label: 'Gambia' }],
	['GE', { label: 'Georgia' }],
	['DE', { label: 'Germany' }],
	['GH', { label: 'Ghana' }],
	['GR', { label: 'Greece' }],
	['GD', { label: 'Grenada' }],
	['GT', { label: 'Guatemala' }],
	['GN', { label: 'Guinea' }],
	['GW', { label: 'Guinea-Bissau' }],
	['GY', { label: 'Guyana' }],
	['HT', { label: 'Haiti' }],
	['HN', { label: 'Honduras' }],
	['HU', { label: 'Hungary' }],
	['IS', { label: 'Iceland' }],
	['IN', { label: 'India' }],
	['ID', { label: 'Indonesia' }],
	['IR', { label: 'Iran' }],
	['IQ', { label: 'Iraq' }],
	['IE', { label: 'Ireland' }],
	['IL', { label: 'Israel' }],
	['IT', { label: 'Italy' }],
	['CI', { label: 'Ivory Coast' }],
	['JM', { label: 'Jamaica' }],
	['JP', { label: 'Japan' }],
	['JO', { label: 'Jordan' }],
	['KZ', { label: 'Kazakhstan' }],
	['KE', { label: 'Kenya' }],
	['KI', { label: 'Kiribati' }],
	['KP', { label: 'Korea, North' }],
	['KR', { label: 'Korea, South' }],
	['KW', { label: 'Kuwait' }],
	['KG', { label: 'Kyrgyzstan' }],
	['LA', { label: 'Laos' }],
	['LV', { label: 'Latvia' }],
	['LB', { label: 'Lebanon' }],
	['LS', { label: 'Lesotho' }],
	['LR', { label: 'Liberia' }],
	['LY', { label: 'Libya' }],
	['LI', { label: 'Liechtenstein' }],
	['LT', { label: 'Lithuania' }],
	['LU', { label: 'Luxembourg' }],
	['MK', { label: 'Macedonia' }],
	['MG', { label: 'Madagascar' }],
	['MW', { label: 'Malawi' }],
	['MY', { label: 'Malaysia' }],
	['MV', { label: 'Maldives' }],
	['ML', { label: 'Mali' }],
	['MT', { label: 'Malta' }],
	['MH', { label: 'Marshall Islands' }],
	['MR', { label: 'Mauritania' }],
	['MU', { label: 'Mauritius' }],
	['MX', { label: 'Mexico' }],
	['FM', { label: 'Micronesia' }],
	['MD', { label: 'Moldova' }],
	['MC', { label: 'Monaco' }],
	['MN', { label: 'Mongolia' }],
	['ME', { label: 'Montenegro' }],
	['MA', { label: 'Morocco' }],
	['MZ', { label: 'Mozambique' }],
	['NA', { label: 'Namibia' }],
	['NR', { label: 'Nauru' }],
	['NP', { label: 'Nepal' }],
	['NL', { label: 'Netherlands' }],
	['NZ', { label: 'New Zealand' }],
	['NI', { label: 'Nicaragua' }],
	['NE', { label: 'Niger' }],
	['NG', { label: 'Nigeria' }],
	['NO', { label: 'Norway' }],
	['OM', { label: 'Oman' }],
	['PK', { label: 'Pakistan' }],
	['PW', { label: 'Palau' }],
	['PS', { label: 'Palestine' }],
	['PA', { label: 'Panama' }],
	['PG', { label: 'Papua New Guinea' }],
	['PY', { label: 'Paraguay' }],
	['PE', { label: 'Peru' }],
	['PH', { label: 'Philippines' }],
	['PL', { label: 'Poland' }],
	['PT', { label: 'Portugal' }],
	['QA', { label: 'Qatar' }],
	['RO', { label: 'Romania' }],
	['RU', { label: 'Russia' }],
	['RW', { label: 'Rwanda' }],
	['KN', { label: 'Saint Kitts and Nevis' }],
	['LC', { label: 'Saint Lucia' }],
	['VC', { label: 'Saint Vincent and the Grenadines' }],
	['WS', { label: 'Samoa' }],
	['SM', { label: 'San Marino' }],
	['ST', { label: 'São Tomé and Príncipe' }],
	['SA', { label: 'Saudi Arabia' }],
	['SN', { label: 'Senegal' }],
	['RS', { label: 'Serbia' }],
	['SC', { label: 'Seychelles' }],
	['SL', { label: 'Sierra Leone' }],
	['SG', { label: 'Singapore' }],
	['SK', { label: 'Slovakia' }],
	['SI', { label: 'Slovenia' }],
	['SB', { label: 'Solomon Islands' }],
	['SO', { label: 'Somalia' }],
	['ZA', { label: 'South Africa' }],
	['SS', { label: 'South Sudan' }],
	['ES', { label: 'Spain' }],
	['LK', { label: 'Sri Lanka' }],
	['SD', { label: 'Sudan' }],
	['SR', { label: 'Suriname' }],
	['SZ', { label: 'Swaziland' }],
	['SE', { label: 'Sweden' }],
	['CH', { label: 'Switzerland' }],
	['SY', { label: 'Syria' }],
	['TJ', { label: 'Tajikistan' }],
	['TZ', { label: 'Tanzania' }],
	['TH', { label: 'Thailand' }],
	['TG', { label: 'Togo' }],
	['TO', { label: 'Tonga' }],
	['TT', { label: 'Trinidad and Tobago' }],
	['TN', { label: 'Tunisia' }],
	['TR', { label: 'Turkey' }],
	['TM', { label: 'Turkmenistan' }],
	['TV', { label: 'Tuvalu' }],
	['UG', { label: 'Uganda' }],
	['UA', { label: 'Ukraine' }],
	['AE', { label: 'United Arab Emirates' }],
	['GB', { label: 'United Kingdom' }],
	['US', { label: 'United States' }],
	['UY', { label: 'Uruguay' }],
	['UZ', { label: 'Uzbekistan' }],
	['VU', { label: 'Vanuatu' }],
	['VA', { label: 'Vatican City' }],
	['VE', { label: 'Venezuela' }],
	['VN', { label: 'Vietnam' }],
	['YE', { label: 'Yemen' }],
	['ZM', { label: 'Zambia' }],
	['ZW', { label: 'Zimbabwe' }]
];
<|endoftext|>