<commit_before>(function() {

	var _support = {
		normalizesNewlines: (function () {
			var textarea = document.createElement('textarea');
			var text = 'abc\r\ndef';
			textarea.value = text;
			return textarea.value.length === text.length - 1;
		}())
	};

	/**
	 * Normalizes line endings by removing all \r (carriage return) characters.
	 * In IE, newlines in textareas are stored as \r\n instead of just \n, which screws up length calculations.
	 * All other browsers automatically remove \r characters when you set the value of the textarea.
	 * @returns {string}
	 */
	String.prototype.norm = function() {
		return this.replace(/\r/g, '');
	};

	pavlov.specify.extendAssertions({
		isOneOf: function(actual, expected, message) {
			ok(expected.indexOf(actual) !== -1, message);
		}
	});

	pavlov.specify('jQuery Caret Plugin', function() {

		var $fixture = $('#qunit-fixture');

		var _single = 'abcdefghijklmnop',
			_multi = 'abcdefg\r\nhijklmnop',
			_short = 'abc',
			_long = 'abcdefghijklmnopqrstuvwxyz',
			_empty = '';

		describe('All Plugins', function() {
			var $input, $textarea;

			// befores and afters:

			before(function() {
				$input = $('<input/>').appendTo($fixture);
				$textarea = $('<textarea/>').appendTo($fixture);
			});

			// plugins:

			describe('Caret', function() {
				describe('Get', function() {
					// Note: Every browser handles caret placement a little differently.
					// Chrome always places the caret at the END of an <input>, but at the BEGINNING of a <textarea>;
					//
					// which means our tests need to accommodate both placement strategies.

					describe('<input>', function() {
						it("Returns zero (0) when no value has been set", function() {
							assert($input.caret()).equals(0);
						});
					});

					describe('<textarea>', function() {
						it("Returns zero (0) when no value has been set", function() {
							assert($textarea.caret()).equals(0);
						});
					});

					describe('<input>', function() {
						it("Returns zero (0) or value.length when a value has been set", function() {
							// In IE and FF, the caret remains at index 0 the first time a value is set;
							// the second time a value is set, the caret moves to the end of the input/textarea.
							assert($input.val(_single).caret()).isOneOf([ 0, _single.length ]);
							assert($input.val(_single).caret()).isOneOf([ 0, _single.length ]);
						});
					});

					describe('<textarea>', function() {
						it("Returns zero (0) or value.length when a value has been set", function() {
							// In IE and FF, the caret remains at index 0 the first time a value is set;
							// the second time a value is set, the caret moves to the end of the input/textarea.
							assert($textarea.val(_multi).caret()).isOneOf([ 0, _multi.norm().length ]);
							assert($textarea.val(_multi).caret()).isOneOf([ 0, _multi.norm().length ]);
						});
					});

					describe('<input>', function() {
						it("Returns zero (0) or value.length when the input's value changes", function() {
							assert($input.val(_short).caret()).isOneOf([ 0, _short.length ]);
							assert($input.val(_long).caret()).isOneOf([ 0, _long.length ]);
							assert($input.val(_short).caret()).isOneOf([ 0, _short.length ]);
							assert($input.val(_empty).caret()).isOneOf([ 0, _empty.length ]);
						});
					});

					describe('<textarea>', function() {
						it("Returns zero (0) or value.length when the textarea's value changes", function() {
							assert($textarea.val(_short).caret()).isOneOf([ 0, _short.length ]);
							assert($textarea.val(_long).caret()).isOneOf([ 0, _long.length ]);
							assert($textarea.val(_short).caret()).isOneOf([ 0, _short.length ]);
							assert($textarea.val(_empty).caret()).isOneOf([ 0, _empty.length ]);
						});
					});
				});

				describe('Set', function() {
					describe('<input>', function() {
						var text = _single,
							len = text.length,
							mid = Math.floor(len / 2);

						it("Gets the same position that was set", function() {
							assert($input.val(text).caret(0).caret()).equals(0);
							assert($input.val(text).caret(1).caret()).equals(1);
							assert($input.val(text).caret(mid - 2).caret()).equals(mid - 2);
							assert($input.val(text).caret(mid - 1).caret()).equals(mid - 1);
							assert($input.val(text).caret(mid).caret()).equals(mid);
							assert($input.val(text).caret(mid + 1).caret()).equals(mid + 1);
							assert($input.val(text).caret(mid + 2).caret()).equals(mid + 2);
							assert($input.val(text).caret(len - 1).caret()).equals(len - 1);
							assert($input.val(text).caret(len).caret()).equals(len);
						});

						it("Enforces start/end boundaries", function() {
							assert($input.val(text).caret(-1).caret()).equals(0);
							assert($input.val(text).caret(len + 1).caret()).equals(len);
						});

						it("Converts floating point values to integers", function() {
							assert($input.val(text).caret(1.5).caret()).equals(1.0);
							assert($input.val(text).caret(2.5).caret()).equals(2.0);
						});
					});

					describe('<textarea>', function() {
						var text = _multi,
							len = text.norm().length,
							mid = text.indexOf('\n');

						it("Gets the same position that was set", function() {
							assert($textarea.val(text).caret(0).caret()).equals(0);
							assert($textarea.val(text).caret(1).caret()).equals(1);
							assert($textarea.val(text).caret(mid - 2).caret()).equals(mid - 2);
							assert($textarea.val(text).caret(mid - 1).caret()).equals(mid - 1);
							assert($textarea.val(text).caret(mid).caret()).equals(mid);
							assert($textarea.val(text).caret(mid + 1).caret()).equals(mid + 1);
							assert($textarea.val(text).caret(mid + 2).caret()).equals(mid + 2);
							assert($textarea.val(text).caret(len - 1).caret()).equals(len - 1);
							assert($textarea.val(text).caret(len).caret()).equals(len);
						});

						it("Enforces start/end boundaries", function() {
							assert($textarea.val(text).caret(-1).caret()).equals(0);
							assert($textarea.val(text).caret(len + 1).caret()).equals(len);
							assert($textarea.val(text).caret(len + 2).caret()).equals(len);
						});

						it("Converts floating point values to integers", function() {
							assert($textarea.val(text).caret(1.5).caret()).equals(1.0);
							assert($textarea.val(text).caret(2.5).caret()).equals(2.0);
						});
					});
				});
			});
		});

	});

}());<commit_msg>Minor/ignore - Moved variable into inner scope<commit_after>(function() {

	/**
	 * Normalizes line endings by removing all \r (carriage return) characters.
	 * In IE, newlines in textareas are stored as \r\n instead of just \n, which screws up length calculations.
	 * All other browsers automatically remove \r characters when you set the value of the textarea.
	 * @returns {string}
	 */
	String.prototype.norm = function() {
		return this.replace(/\r/g, '');
	};

	pavlov.specify.extendAssertions({
		isOneOf: function(actual, expected, message) {
			ok(expected.indexOf(actual) !== -1, message);
		}
	});

	pavlov.specify('jQuery Caret Plugin', function() {

		var _support = {
			normalizesNewlines: (function () {
				var textarea = _e('textarea');
				var text = 'abc\r\ndef';
				textarea.value = text;
				return textarea.value.length === text.length - 1;
			}())
		};

		var $fixture = $('#qunit-fixture');

		var _single = 'abcdefghijklmnop',
			_multi = 'abcdefg\r\nhijklmnop',
			_short = 'abc',
			_long = 'abcdefghijklmnopqrstuvwxyz',
			_empty = '';

		describe('All Plugins', function() {
			var $input, $textarea;

			// befores and afters:

			before(function() {
				$input = $('<input/>').appendTo($fixture);
				$textarea = $('<textarea/>').appendTo($fixture);
			});

			// plugins:

			describe('Caret', function() {
				describe('Get', function() {
					// Note: Every browser handles caret placement a little differently.
					// Chrome always places the caret at the END of an <input>, but at the BEGINNING of a <textarea>;
					//
					// which means our tests need to accommodate both placement strategies.

					describe('<input>', function() {
						it("Returns zero (0) when no value has been set", function() {
							assert($input.caret()).equals(0);
						});
					});

					describe('<textarea>', function() {
						it("Returns zero (0) when no value has been set", function() {
							assert($textarea.caret()).equals(0);
						});
					});

					describe('<input>', function() {
						it("Returns zero (0) or value.length when a value has been set", function() {
							// In IE and FF, the caret remains at index 0 the first time a value is set;
							// the second time a value is set, the caret moves to the end of the input/textarea.
							assert($input.val(_single).caret()).isOneOf([ 0, _single.length ]);
							assert($input.val(_single).caret()).isOneOf([ 0, _single.length ]);
						});
					});

					describe('<textarea>', function() {
						it("Returns zero (0) or value.length when a value has been set", function() {
							// In IE and FF, the caret remains at index 0 the first time a value is set;
							// the second time a value is set, the caret moves to the end of the input/textarea.
							assert($textarea.val(_multi).caret()).isOneOf([ 0, _multi.norm().length ]);
							assert($textarea.val(_multi).caret()).isOneOf([ 0, _multi.norm().length ]);
						});
					});

					describe('<input>', function() {
						it("Returns zero (0) or value.length when the input's value changes", function() {
							assert($input.val(_short).caret()).isOneOf([ 0, _short.length ]);
							assert($input.val(_long).caret()).isOneOf([ 0, _long.length ]);
							assert($input.val(_short).caret()).isOneOf([ 0, _short.length ]);
							assert($input.val(_empty).caret()).isOneOf([ 0, _empty.length ]);
						});
					});

					describe('<textarea>', function() {
						it("Returns zero (0) or value.length when the textarea's value changes", function() {
							assert($textarea.val(_short).caret()).isOneOf([ 0, _short.length ]);
							assert($textarea.val(_long).caret()).isOneOf([ 0, _long.length ]);
							assert($textarea.val(_short).caret()).isOneOf([ 0, _short.length ]);
							assert($textarea.val(_empty).caret()).isOneOf([ 0, _empty.length ]);
						});
					});
				});

				describe('Set', function() {
					describe('<input>', function() {
						var text = _single,
							len = text.length,
							mid = Math.floor(len / 2);

						it("Gets the same position that was set", function() {
							assert($input.val(text).caret(0).caret()).equals(0);
							assert($input.val(text).caret(1).caret()).equals(1);
							assert($input.val(text).caret(mid - 2).caret()).equals(mid - 2);
							assert($input.val(text).caret(mid - 1).caret()).equals(mid - 1);
							assert($input.val(text).caret(mid).caret()).equals(mid);
							assert($input.val(text).caret(mid + 1).caret()).equals(mid + 1);
							assert($input.val(text).caret(mid + 2).caret()).equals(mid + 2);
							assert($input.val(text).caret(len - 1).caret()).equals(len - 1);
							assert($input.val(text).caret(len).caret()).equals(len);
						});

						it("Enforces start/end boundaries", function() {
							assert($input.val(text).caret(-1).caret()).equals(0);
							assert($input.val(text).caret(len + 1).caret()).equals(len);
						});

						it("Converts floating point values to integers", function() {
							assert($input.val(text).caret(1.5).caret()).equals(1.0);
							assert($input.val(text).caret(2.5).caret()).equals(2.0);
						});
					});

					describe('<textarea>', function() {
						var text = _multi,
							len = text.norm().length,
							mid = text.indexOf('\n');

						it("Gets the same position that was set", function() {
							assert($textarea.val(text).caret(0).caret()).equals(0);
							assert($textarea.val(text).caret(1).caret()).equals(1);
							assert($textarea.val(text).caret(mid - 2).caret()).equals(mid - 2);
							assert($textarea.val(text).caret(mid - 1).caret()).equals(mid - 1);
							assert($textarea.val(text).caret(mid).caret()).equals(mid);
							assert($textarea.val(text).caret(mid + 1).caret()).equals(mid + 1);
							assert($textarea.val(text).caret(mid + 2).caret()).equals(mid + 2);
							assert($textarea.val(text).caret(len - 1).caret()).equals(len - 1);
							assert($textarea.val(text).caret(len).caret()).equals(len);
						});

						it("Enforces start/end boundaries", function() {
							assert($textarea.val(text).caret(-1).caret()).equals(0);
							assert($textarea.val(text).caret(len + 1).caret()).equals(len);
							assert($textarea.val(text).caret(len + 2).caret()).equals(len);
						});

						it("Converts floating point values to integers", function() {
							assert($textarea.val(text).caret(1.5).caret()).equals(1.0);
							assert($textarea.val(text).caret(2.5).caret()).equals(2.0);
						});
					});
				});
			});
		});

	});

}());<|endoftext|>


<commit_before>import Node from '../Node.js';
import spread, { isArguments } from '../../utils/spread.js';

export default class NewExpression extends Node {
	initialise ( transforms ) {
		if ( transforms.spreadRest && this.arguments.length ) {
			const lexicalBoundary = this.findLexicalBoundary();

			let i = this.arguments.length;
			while ( i-- ) {
				const arg = this.arguments[i];
				if ( arg.type === 'SpreadElement' && isArguments( arg.argument ) ) {
					this.argumentsArrayAlias = lexicalBoundary.getArgumentsArrayAlias();
				}
			}
		}

		super.initialise( transforms );
	}

	transpile ( code, transforms ) {
		if ( transforms.spreadRest && this.arguments.length ) {
			const firstArgument = this.arguments[0];
			const isNew = true;
			let hasSpreadElements = spread( code, this.arguments, firstArgument.start, this.argumentsArrayAlias, isNew );

			if ( hasSpreadElements ) {
				code.insertLeft( this.start + 'new'.length, ' (Function.prototype.bind.apply(' );
				code.overwrite( this.callee.end, firstArgument.start, ', ' );
				code.insertLeft( firstArgument.start, "[ null ].concat( " );
				code.insertRight( this.end, ' ))' );
			}
		}

		super.transpile( code, transforms );
	}
}
<commit_msg>break from loop once this.argumentsArrayAlias set<commit_after>import Node from '../Node.js';
import spread, { isArguments } from '../../utils/spread.js';

export default class NewExpression extends Node {
	initialise ( transforms ) {
		if ( transforms.spreadRest && this.arguments.length ) {
			const lexicalBoundary = this.findLexicalBoundary();

			let i = this.arguments.length;
			while ( i-- ) {
				const arg = this.arguments[i];
				if ( arg.type === 'SpreadElement' && isArguments( arg.argument ) ) {
					this.argumentsArrayAlias = lexicalBoundary.getArgumentsArrayAlias();
					break;
				}
			}
		}

		super.initialise( transforms );
	}

	transpile ( code, transforms ) {
		if ( transforms.spreadRest && this.arguments.length ) {
			const firstArgument = this.arguments[0];
			const isNew = true;
			let hasSpreadElements = spread( code, this.arguments, firstArgument.start, this.argumentsArrayAlias, isNew );

			if ( hasSpreadElements ) {
				code.insertLeft( this.start + 'new'.length, ' (Function.prototype.bind.apply(' );
				code.overwrite( this.callee.end, firstArgument.start, ', ' );
				code.insertLeft( firstArgument.start, "[ null ].concat( " );
				code.insertRight( this.end, ' ))' );
			}
		}

		super.transpile( code, transforms );
	}
}
<|endoftext|>


<commit_before>var Format = new _Format()
var Storage = new _Storage()

function _Directory () {
  var self = this
  this.body = $('.list table tbody')
  this.table = $('.list table')
  this.size = $('.top-menu .folder-size')
  this.table = $('.list')
  this.actions = {
    download: $('.top-menu .action #download'),
    rename: $('.top-menu .action #rename'),
    remove: $('.top-menu .action #remove'),
    info: $('.top-menu .action #info')
  }

  this.timer = null
  this.refresh = 30000

  $(window).bind('hashchange', function () {
    self.body.html('')
    self.getList()
    self.setActions('', {
      download: null,
      rename: null,
      remove: null,
      info: null
    })
  }).trigger('hashchange')
}

_Directory.prototype.appendSize = function (size) {
  this.size.text(Format.size(size))
}

_Directory.prototype.getList = function () {
  var hash = document.location.hash.substring(1) ? document.location.hash.substring(1) : '/'
  var self = this
  $.post('/list-d', {
    dir: hash
  }, function (directory) {
    directory = JSON.parse(directory)
    if (directory.err) {
      var notif = new Pnotif()
      notif.init('top-right', "
Action impossible: " + directory.err + '
', 10000)
      notif.draw()
    } else {
      self.appendSize(directory.totalSize)

      var current_scroll = $('body').scrollTop()

      self.list(directory.files, directory.downloading)

      $('body').scrollTop(current_scroll)

    }
  })
  clearTimeout(this.timer)
  this.timer = setTimeout(function () {
    self.getList()
  }, this.refresh)
}

_Directory.prototype.list = function (directory, locked) {
  var kownFiles = Storage.readData('directory') ? Storage.readData('directory') : [] // array

  // ...
  var href = document.location.hash.substring(1).split('\/')
  href.splice(href.length - 2 || 0, 1)
  href = href.join('\/')
  this.append({new: false, name: '..', href: href, isfile: false, isdir: true, })

  for (var key in directory) {
    var file = directory[key]
    file.name = key
    file.href = document.location.hash.substring(1) + file.name + '/'
    if (kownFiles.indexOf(file.name) == -1) {
      file.new = true
      kownFiles.push(file.name)
    } else {
      file.new = false
    }

    file.locked = locked[file.href.slice(0, -1)] ? true : false

    this.append(file)
  }
  Storage.storeData('directory', kownFiles)
}

_Directory.prototype.append = function (file) {
  var self = this

  if ($('.list  .file[data-file="' + file.name + '"]').length > 0) {
    return 0
  } else {
    var $raw = $('
').addClass(file.new ? 'file button new' : 'file button').attr('data-file', file.name).click(function (event) {
      event.stopPropagation()
      $('.list .selected').children('#name').draggable('disable')
      $('.list .file').removeClass('selected')
      $(this).addClass('selected')

      self.setActions(file, {
        download: file.isfile ? true : false,
        rename: file.locked ? false : true,
        remove: file.locked ? false : true,
        info: file.isfile ? true : false
      })

      $(this).children('#name').draggable('enable')
    })

    var $name = $('').attr('id', 'name').attr('extension', Format.extention(file)).attr('data-file', file.name).html(
      file.isdir ?
        $('').addClass('button').attr('href', '#' + file.href).text(file.name) :
        file.name).appendTo($raw).draggable({
      revert: true
    }).draggable('disable')
    if (file.isdir)
      $name.droppable({
        greedy: true,
        drop: function (data, element) {
          var folder = $(this).attr('data-file')
          var file = element.draggable.attr('data-file')
          var path = document.location.hash.substring(1) ? document.location.hash.substring(1) : '/'

          $.post('/mv-d', {
            'file': file,
            'path': path,
            'folder': folder
          }, function (file) {
            file = JSON.parse(file)
            if (file.err) {
              var notif = new Pnotif()
              notif.init('top-right', "
Action impossible: " + file.err + '
', 10000)
              notif.draw()
            } else {
              $('tr[data-file="' + file.file + '"]').remove()
            }
          })
        }
      })
    if (file.locked) {
      $('').addClass('fa fa-lock locked').appendTo($name)
    }

    // drag and drop

    var $size = $('').attr('id', 'size').text(Format.size(file.size)).appendTo($raw)
    var $date = $('').attr('id', 'date').text(Format.date(file.ctime)).appendTo($raw)

    this.body.append($raw)
    $('.list table').trigger('update')
  }
}

_Directory.prototype.setActions = function (file, actions) {
  for (var key in this.actions) {
    this.actions[key].addClass('hide').unbind()
    this.actions[key].removeClass('unactive')
  }

  // DOWNLOAD
  if (actions.download) {
    this.actions.download.removeClass('hide')
    this.actions.download.parent().attr('href', 'files/?f=' + document.location.hash.substring(1) + file.name)
  } else if (actions.download == false) {
    this.actions.download.removeClass('hide')
    this.actions.download.addClass('unactive')
  }

  // RENAME
  if (actions.rename) {
    this.actions.rename.removeClass('hide').click(function () {
      var oldname = file.name.split('.')
      if (oldname.length > 1 && file.isfile) {
        var extension = oldname.pop()
        extension = extension.length > 0 ? '.' + extension : ''
      } else {
        var extension = ''
      }
      var name = prompt('New name for: ' + oldname.join(' '), oldname.join(' '))
      if (name) {
        name = name.split('\/').pop() + extension
        name = name.trim()
        $.post('/rename-d', {
          'path': document.location.hash.substring(1) ? document.location.hash.substring(1) : '/',
          'oldname': file.name,
          'newname': name
        }, function (data) {
          data = JSON.parse(data)
          if (data.err) {
            var notif = new Pnotif()
            notif.init('top-right', "
Action impossible: " + data.err + '
', 10000)
            notif.draw()
          } else {
            file.name = data.newname
            $('tr[data-file="' + data.oldname + '"] td#name').attr('data-file', data.newname).html(
              file.isdir ?
                $('').attr('href', '#' + document.location.hash.substring(1) + data.newname + '/').text(data.newname) :
                data.newname
            )
            $('tr[data-file="' + data.oldname + '"]').attr('data-file', data.newname)
          }
        })
      }
    })

  } else if (actions.rename == false) {
    this.actions.rename.removeClass('hide')
    this.actions.rename.addClass('unactive')
  }

  // REMOVE
  if (actions.remove) {
    this.actions.remove.removeClass('hide').click(function () {
      if (confirm('Confirmer la suppression de ' + file.name + ' ?'))
        $.post('/remove-d', {
          file: document.location.hash.substring(1) + file.name
        }, function (file) {
          file = JSON.parse(file)
          if (file.err) {
            var notif = new Pnotif()
            notif.init('top-right', "
Action impossible: " + file.err + '
', 10000)
            notif.draw()
          } else {
            $('tr[data-file="' + file.file + '"]').remove()
          }
        })
    })
  } else if (actions.remove == false) {
    this.actions.remove.removeClass('hide')
    this.actions.remove.addClass('unactive')
  }

  // INFOS
  if (actions.info) {
    this.actions.info.removeClass('hide').click(function () {
      var info = new _MediaInfo()
      info.get(file.name)
    })
  } else if (actions.info == false) {
    this.actions.info.removeClass('hide')
    this.actions.info.addClass('unactive')
  }
}
<commit_msg>fix remove file from tab when they doesn't exist anymore<commit_after>var Format = new _Format()
var Storage = new _Storage()

function _Directory () {
  var self = this
  this.body = $('.list table tbody')
  this.table = $('.list table')
  this.size = $('.top-menu .folder-size')
  this.table = $('.list')
  this.actions = {
    download: $('.top-menu .action #download'),
    rename: $('.top-menu .action #rename'),
    remove: $('.top-menu .action #remove'),
    info: $('.top-menu .action #info')
  }

  this.timer = null
  this.refresh = 30000

  $(window).bind('hashchange', function () {
    self.body.html('')
    self.getList()
    self.setActions('', {
      download: null,
      rename: null,
      remove: null,
      info: null
    })
  }).trigger('hashchange')
}

_Directory.prototype.appendSize = function (size) {
  this.size.text(Format.size(size))
}

_Directory.prototype.getList = function () {
  var hash = document.location.hash.substring(1) ? document.location.hash.substring(1) : '/'
  var self = this
  $.post('/list-d', {
    dir: hash
  }, function (directory) {
    directory = JSON.parse(directory)
    if (directory.err) {
      var notif = new Pnotif()
      notif.init('top-right', "
Action impossible: " + directory.err + '
', 10000)
      notif.draw()
    } else {
      self.appendSize(directory.totalSize)

      var current_scroll = $('body').scrollTop()

      self.list(directory.files, directory.downloading)

      $('body').scrollTop(current_scroll)

    }
  })
  clearTimeout(this.timer)
  this.timer = setTimeout(function () {
    self.getList()
  }, this.refresh)
}

_Directory.prototype.list = function (directory, locked) {
  var kownFiles = Storage.readData('directory') ? Storage.readData('directory') : [] // array

  // ...
  var href = document.location.hash.substring(1).split('\/')
  href.splice(href.length - 2 || 0, 1)
  href = href.join('\/')
  this.append({new: false, name: '..', href: href, isfile: false, isdir: true, })

  $('.file.button').addClass('toremove')

  for (var key in directory) {
    var file = directory[key]
    file.name = key
    file.href = document.location.hash.substring(1) + file.name + '/'
    if (kownFiles.indexOf(file.name) == -1) {
      file.new = true
      kownFiles.push(file.name)
    } else {
      file.new = false
    }

    file.locked = locked[file.href.slice(0, -1)] ? true : false

    this.append(file)
  }

  $('.file.toremove').remove()
  Storage.storeData('directory', kownFiles)
}

_Directory.prototype.append = function (file) {
  var self = this

  if ($('.list  .file[data-file="' + file.name + '"]').length > 0) {
    var $raw = $('.list  .file[data-file="' + file.name + '"]')
    $raw.removeClass('toremove')
    return 0
  } else {
    var $raw = $('
').addClass(file.new ? 'file button new' : 'file button').attr('data-file', file.name).click(function (event) {
      event.stopPropagation()
      $('.list .selected').children('#name').draggable('disable')
      $('.list .file').removeClass('selected')
      $(this).addClass('selected')

      self.setActions(file, {
        download: file.isfile ? true : false,
        rename: file.locked ? false : true,
        remove: file.locked ? false : true,
        info: file.isfile ? true : false
      })

      $(this).children('#name').draggable('enable')
    })

    var $name = $('').attr('id', 'name').attr('extension', Format.extention(file)).attr('data-file', file.name).html(
      file.isdir ?
        $('').addClass('button').attr('href', '#' + file.href).text(file.name) :
        file.name).appendTo($raw).draggable({
      revert: true
    }).draggable('disable')
    if (file.isdir)
      $name.droppable({
        greedy: true,
        drop: function (data, element) {
          var folder = $(this).attr('data-file')
          var file = element.draggable.attr('data-file')
          var path = document.location.hash.substring(1) ? document.location.hash.substring(1) : '/'

          $.post('/mv-d', {
            'file': file,
            'path': path,
            'folder': folder
          }, function (file) {
            file = JSON.parse(file)
            if (file.err) {
              var notif = new Pnotif()
              notif.init('top-right', "
Action impossible: " + file.err + '
', 10000)
              notif.draw()
            } else {
              $('tr[data-file="' + file.file + '"]').remove()
            }
          })
        }
      })
    if (file.locked) {
      $('').addClass('fa fa-lock locked').appendTo($name)
    }

    // drag and drop

    var $size = $('').attr('id', 'size').text(Format.size(file.size)).appendTo($raw)
    var $date = $('').attr('id', 'date').text(Format.date(file.ctime)).appendTo($raw)

    this.body.append($raw)
    $('.list table').trigger('update')
  }
}

_Directory.prototype.setActions = function (file, actions) {
  for (var key in this.actions) {
    this.actions[key].addClass('hide').unbind()
    this.actions[key].removeClass('unactive')
  }

  // DOWNLOAD
  if (actions.download) {
    this.actions.download.removeClass('hide')
    this.actions.download.parent().attr('href', 'files/?f=' + document.location.hash.substring(1) + file.name)
  } else if (actions.download == false) {
    this.actions.download.removeClass('hide')
    this.actions.download.addClass('unactive')
  }

  // RENAME
  if (actions.rename) {
    this.actions.rename.removeClass('hide').click(function () {
      var oldname = file.name.split('.')
      if (oldname.length > 1 && file.isfile) {
        var extension = oldname.pop()
        extension = extension.length > 0 ? '.' + extension : ''
      } else {
        var extension = ''
      }
      var name = prompt('New name for: ' + oldname.join(' '), oldname.join(' '))
      if (name) {
        name = name.split('\/').pop() + extension
        name = name.trim()
        $.post('/rename-d', {
          'path': document.location.hash.substring(1) ? document.location.hash.substring(1) : '/',
          'oldname': file.name,
          'newname': name
        }, function (data) {
          data = JSON.parse(data)
          if (data.err) {
            var notif = new Pnotif()
            notif.init('top-right', "
Action impossible: " + data.err + '
', 10000)
            notif.draw()
          } else {
            file.name = data.newname
            $('tr[data-file="' + data.oldname + '"] td#name').attr('data-file', data.newname).html(
              file.isdir ?
                $('').attr('href', '#' + document.location.hash.substring(1) + data.newname + '/').text(data.newname) :
                data.newname
            )
            $('tr[data-file="' + data.oldname + '"]').attr('data-file', data.newname)
          }
        })
      }
    })

  } else if (actions.rename == false) {
    this.actions.rename.removeClass('hide')
    this.actions.rename.addClass('unactive')
  }

  // REMOVE
  if (actions.remove) {
    this.actions.remove.removeClass('hide').click(function () {
      if (confirm('Confirmer la suppression de ' + file.name + ' ?'))
        $.post('/remove-d', {
          file: document.location.hash.substring(1) + file.name
        }, function (file) {
          file = JSON.parse(file)
          if (file.err) {
            var notif = new Pnotif()
            notif.init('top-right', "
Action impossible: " + file.err + '
', 10000)
            notif.draw()
          } else {
            $('tr[data-file="' + file.file + '"]').remove()
          }
        })
    })
  } else if (actions.remove == false) {
    this.actions.remove.removeClass('hide')
    this.actions.remove.addClass('unactive')
  }

  // INFOS
  if (actions.info) {
    this.actions.info.removeClass('hide').click(function () {
      var info = new _MediaInfo()
      info.get(file.name)
    })
  } else if (actions.info == false) {
    this.actions.info.removeClass('hide')
    this.actions.info.addClass('unactive')
  }
}
<|endoftext|>


<commit_before>var Pnotif = function () {
  this.init = function (pos, html, timeOut) {
    this.pos = getXYFromPos(pos)
    this.html = html
    this.timeOut = timeOut
  }

  this.draw = function () {
    $container = $('<div>').addClass('pnotif-container')
    for (var key in this.pos) {
      $container.css(key, this.pos[key])
    }

    $container.append(this.html)
    $('body').append($container)

    $container.fadeIn().delay(this.timeOut).fadeOut('slow')
    setTimeout(function () {
      $container.remove()
    }, this.timeOut + 1000)
  }
}

function pnotifClose () {
  $('.pnotif-container').remove()
}

function getXYFromPos (pos) {
  var xy = {}
  switch (pos) {
    case 'top-right':
      xy.top = '5%'
      xy.right = '3%'
      break

    case 'top-left':
      xy.top = '5%'
      xy.left = '3%'
      break

    case 'bottom-right':
      xy.bottom = '15%'
      xy.right = '3%'
      break

    case 'bottom-left':
      xy.bottom = '15%'
      xy.left = '3%'
      break

    default:
      xy.bottom = '15%'
      xy.left = '5%'
      break
  }

  return xy
}

$('head').append('<link rel="stylesheet" href="src/js/pnotif/pnotif.css">')
<commit_msg>add remove method for pnotif<commit_after>var Pnotif = function () {
  this.init = function (pos, html, timeOut) {
    this.pos = getXYFromPos(pos)
    this.html = html
    this.timeOut = timeOut
  }

  this.container = null

  this.draw = function () {
    $container = $('<div>').addClass('pnotif-container')
    this.container = $container
    for (var key in this.pos) {
      $container.css(key, this.pos[key])
    }

    $container.append(this.html)
    $('body').append($container)

    $container.fadeIn().delay(this.timeOut).fadeOut('slow')
    setTimeout(function () {
      $container.remove()
    }, this.timeOut + 1000)
  }

  this.remove = function(){
    if(this.container){
      this.container.remove()
    }
  }
}

function pnotifClose () {
  $('.pnotif-container').remove()
}

function getXYFromPos (pos) {
  var xy = {}
  switch (pos) {
    case 'top-right':
      xy.top = '5%'
      xy.right = '3%'
      break

    case 'top-left':
      xy.top = '5%'
      xy.left = '3%'
      break

    case 'bottom-right':
      xy.bottom = '15%'
      xy.right = '3%'
      break

    case 'bottom-left':
      xy.bottom = '15%'
      xy.left = '3%'
      break

    default:
      xy.bottom = '15%'
      xy.left = '5%'
      break
  }

  return xy
}

$('head').append('<link rel="stylesheet" href="src/js/pnotif/pnotif.css">')
<|endoftext|>


<commit_before>
"use strict";

var takashyx = takashyx || {};

takashyx.toast = (function () {

	/**
	 * The main Toast object
	 * @param {Object} options See Toast.prototype.DEFAULT_SETTINGS for more info
	 */
	function Toast(title, content, options) {
		if (getToastStage() != null) {
			// If there is already a Toast being shown, hide it
			Toast.prototype.destroy();
		}
		var _options = options || {};
		_options = Toast.prototype.mergeOptions(Toast.prototype.DEFAULT_SETTINGS, _options);

		Toast.prototype.show(title, content, _options);

		_options = null;
	};

	/**
	 * The toastStage. This is the HTML element in which the toast resides
	 * Getter and setter methods are available privately
	 * @type {Element}
	 */
	var _toastStage = null;
	function getToastStage() {
		return _toastStage;
	};
	function setToastStage(toastStage) {
		_toastStage = toastStage;
	};

	/**
	 * The Toast animation speed; how long the Toast takes to move to and from the screen
	 * @type {Number}
	 */
	Toast.prototype.TOAST_ANIMATION_SPEED = 400;

	// Toast classes
	Toast.prototype.CLASS_TOAST_GONE = "takashyx_toast_gone";
	Toast.prototype.CLASS_TOAST_VISIBLE = "takashyx_toast_visible";
	Toast.prototype.CLASS_TOAST_ANIMATED = "takashyx_toast_animated";

	/**
	 * The default Toast settings
	 * @type {Object}
	 */
	Toast.prototype.DEFAULT_SETTINGS = {
		style: {
			main: {
				"background": "rgba(0, 0, 0, .85)",
				"box-shadow": "0 0 10px rgba(0, 0, 0, .9)",

				"border-radius": "5px",

				"z-index": "99999",

				"color": "rgba(255, 255, 255, .9)",

				"max-width": "60%",
				"word-break": "keep-all",
				"text-align": "center",

				"position": "fixed",
				"left": "0",
				"right": "0",

				"margin": "0px auto",
				"padding": "10px"
			},
			title: {
				"font-weight": "bold",
				"font-size": "1.5rem",
				"margin": "0px, 6px, 6px, 6px",
				"padding": "4px",
			},
			content: {
				"margin": "6px",
				"padding": "4px",
				"border": "1px solid white",
				"border-radius": "5px",
			}
		},
		settings: {
			duration: 2500
		}
	};

	/**
	 * Specifies whether or not the inline style in the <head> exists. It only needs to be added once to a page
	 * @type {Boolean}
	 */
	Toast.prototype.styleExists = false;

	/**
	 * The Timeout object for animations.
	 * This should be shared among the Toasts, because timeouts may be cancelled e.g. on explicit call of hide()
	 * @type {Object}
	 */
	Toast.prototype.timeout = null;

	/**
	 * Merge the DEFAULT_SETTINGS with the user defined options if specified
	 * @param  {Object} options The user defined options
	 */
	Toast.prototype.mergeOptions = function (initialOptions, customOptions) {
		var merged = customOptions;
		for (var prop in initialOptions) {
			if (merged.hasOwnProperty(prop)) {
				if (initialOptions[prop] != null && initialOptions[prop].constructor == Object) {
					merged[prop] = Toast.prototype.mergeOptions(initialOptions[prop], merged[prop]);
				}
			} else {
				merged[prop] = initialOptions[prop];
			}
		}
		return merged;
	};

	/**
	 * Add the inline stylesheet to the <head>
	 * These inline styles are needed for animation purposes.
	 */
	Toast.prototype.initializeStyles = function () {
		if (Toast.prototype.styleExists) return;

		var style = document.createElement("style");

		style.insertAdjacentHTML("beforeend",
			Toast.prototype.generateInlineStylesheetRules(this.CLASS_TOAST_GONE, {
				"opacity": "0",
				"top": "10%"
			}) +
			Toast.prototype.generateInlineStylesheetRules(this.CLASS_TOAST_VISIBLE, {
				"opacity": "0.9",
				"top": "10%"
			}) +
			Toast.prototype.generateInlineStylesheetRules(this.CLASS_TOAST_ANIMATED, {
				"transition": "opacity " + this.TOAST_ANIMATION_SPEED + "ms, bottom " + this.TOAST_ANIMATION_SPEED + "ms"
			})
		);

		document.head.appendChild(style);
		style = null;

		// Notify that the stylesheet exists to avoid creating more
		Toast.prototype.styleExists = true;
	};

	/**
	 * Generate the Toast with the specified content.
	 * @param  {String} title The content to show inside the Toast, can be an HTML element or plain content
	 * @param  {String|Object} content The content to show inside the Toast, can be an HTML element or plain content
	 * @param  {Object} style style to set for the Toast
	 */
	Toast.prototype.generate = function (title, content, style) {

		var toastStage = document.createElement("div");
		var titleDiv = document.createElement("div");
		titleDiv.appendChild(document.createTextNode(title));

		toastStage.appendChild(titleDiv);

		var contentDiv = document.createElement("div");
		/**
		 * If the content is a String, create a textNode for appending
		 */
		if (typeof content === "string") {

			var lines = content.split('[[[br]]]');

			for (var i in lines) {
				var l = document.createTextNode(lines[i]);
				contentDiv.appendChild(l);
			}
		}
		else {
			contentDiv.appendChild(content);
		}

		toastStage.appendChild(contentDiv);
		setToastStage(toastStage);
		toastStage = null;

		Toast.prototype.stylize(getToastStage(), style.main);
		Toast.prototype.stylize(titleDiv, style.title);
		Toast.prototype.stylize(contentDiv, style.content);
	};

	/**
	 * Stylize the Toast.
	 * @param  {Element} element The HTML element to stylize
	 * @param  {Object}  styles  An object containing the style to apply
	 * @return                   Returns nothing
	 */
	Toast.prototype.stylize = function (element, styles) {
		Object.keys(styles).forEach(function (style) {
			element.style[style] = styles[style];
		});
	};

	/**
	 * Generates styles to be used in an inline stylesheet. The output will be something like:
	 * .class {background: blue;}
	 * @param  {String} elementClass The class of the element to style
	 * @param  {Object} styles       The style to insert into the inline stylsheet
	 * @return {String}              The inline style as a string
	 */
	Toast.prototype.generateInlineStylesheetRules = function (elementClass, styles) {
		var out = "." + elementClass + "{";

		Object.keys(styles).forEach(function (style) {
			out += style + ":" + styles[style] + ";";
		});
		out += "}";

		return out;
	};

	/**
	 * Show the Toast
	 * @param  {String} title content to show inside the Toast
	 * @param  {Object} content The content to show inside the Toast
	 * @param  {Object} options The object containing the options for the Toast
	 */
	Toast.prototype.show = function (title, content, options) {
		this.initializeStyles();
		this.generate(title, content, options.style);

		var toastStage = getToastStage();
		toastStage.classList.add(this.CLASS_TOAST_ANIMATED);
		toastStage.classList.add(this.CLASS_TOAST_GONE);
		document.body.insertBefore(toastStage, document.body.firstChild);

		// This is a hack to get animations started. Apparently without explicitly redrawing, it'll just attach the class and no animations would be done
		toastStage.offsetHeight;

		toastStage.classList.remove(this.CLASS_TOAST_GONE);
		toastStage.classList.add(this.CLASS_TOAST_VISIBLE);

		var toastStage = null;

		clearTimeout(Toast.prototype.timeout);
		Toast.prototype.timeout = setTimeout(Toast.prototype.hide, options.settings.duration);
	};

	/**
	 * Hide the Toast that's currently shown
	 */
	Toast.prototype.hide = function () {
		var toastStage = getToastStage();
		toastStage.classList.remove(Toast.prototype.CLASS_TOAST_VISIBLE);
		toastStage.classList.add(Toast.prototype.CLASS_TOAST_GONE);
		toastStage = null;

		// Destroy the Toast element after animations end
		clearTimeout(Toast.prototype.timeout);
		Toast.prototype.timeout = setTimeout(Toast.prototype.destroy, Toast.prototype.TOAST_ANIMATION_SPEED);
	};

	/**
	 * Clean up after the Toast slides away. Namely, removing the Toast from the DOM.
	 */
	Toast.prototype.destroy = function () {
		var toastStage = getToastStage();
		document.body.removeChild(toastStage);

		toastStage = null;
		setToastStage(null);
	};

	return {
		Toast: Toast
	};
})();<commit_msg>Cosme toast<commit_after>
"use strict";

var takashyx = takashyx || {};

takashyx.toast = (function () {

	/**
	 * The main Toast object
	 * @param {Object} options See Toast.prototype.DEFAULT_SETTINGS for more info
	 */
	function Toast(title, content, options) {
		if (getToastStage() != null) {
			// If there is already a Toast being shown, hide it
			Toast.prototype.destroy();
		}
		var _options = options || {};
		_options = Toast.prototype.mergeOptions(Toast.prototype.DEFAULT_SETTINGS, _options);

		Toast.prototype.show(title, content, _options);

		_options = null;
	};

	/**
	 * The toastStage. This is the HTML element in which the toast resides
	 * Getter and setter methods are available privately
	 * @type {Element}
	 */
	var _toastStage = null;
	function getToastStage() {
		return _toastStage;
	};
	function setToastStage(toastStage) {
		_toastStage = toastStage;
	};

	/**
	 * The Toast animation speed; how long the Toast takes to move to and from the screen
	 * @type {Number}
	 */
	Toast.prototype.TOAST_ANIMATION_SPEED = 400;

	// Toast classes
	Toast.prototype.CLASS_TOAST_GONE = "takashyx_toast_gone";
	Toast.prototype.CLASS_TOAST_VISIBLE = "takashyx_toast_visible";
	Toast.prototype.CLASS_TOAST_ANIMATED = "takashyx_toast_animated";

	/**
	 * The default Toast settings
	 * @type {Object}
	 */
	Toast.prototype.DEFAULT_SETTINGS = {
		style: {
			main: {
				"background": "rgba(0, 0, 0, .85)",
				"box-shadow": "0 0 10px rgba(0, 0, 0, .9)",

				"border-radius": "5px",

				"z-index": "99999",

				"color": "rgba(255, 255, 255, .9)",

				"max-width": "60%",
				"word-break": "keep-all",
				"text-align": "center",

				"position": "fixed",
				"left": "0",
				"right": "0",

				"margin": "0px auto",
				"padding": "10px"
			},
			title: {
				"font-weight": "bold",
				"font-size": "1.5rem",
				"margin": "0px, 6px, 6px, 6px",
				"padding": "4px",
			},
			content: {
				"margin": "6px",
				"padding": "4px",
				"border": "1px solid white",
				"border-radius": "5px",
			}
		},
		settings: {
			duration: 2500
		}
	};

	/**
	 * Specifies whether or not the inline style in the <head> exists. It only needs to be added once to a page
	 * @type {Boolean}
	 */
	Toast.prototype.styleExists = false;

	/**
	 * The Timeout object for animations.
	 * This should be shared among the Toasts, because timeouts may be cancelled e.g. on explicit call of hide()
	 * @type {Object}
	 */
	Toast.prototype.timeout = null;

	/**
	 * Merge the DEFAULT_SETTINGS with the user defined options if specified
	 * @param  {Object} options The user defined options
	 */
	Toast.prototype.mergeOptions = function (initialOptions, customOptions) {
		var merged = customOptions;
		for (var prop in initialOptions) {
			if (merged.hasOwnProperty(prop)) {
				if (initialOptions[prop] != null && initialOptions[prop].constructor == Object) {
					merged[prop] = Toast.prototype.mergeOptions(initialOptions[prop], merged[prop]);
				}
			} else {
				merged[prop] = initialOptions[prop];
			}
		}
		return merged;
	};

	/**
	 * Add the inline stylesheet to the <head>
	 * These inline styles are needed for animation purposes.
	 */
	Toast.prototype.initializeStyles = function () {
		if (Toast.prototype.styleExists) return;

		var style = document.createElement("style");

		style.insertAdjacentHTML("beforeend",
			Toast.prototype.generateInlineStylesheetRules(this.CLASS_TOAST_GONE, {
				"opacity": "0",
				"top": "10%"
			}) +
			Toast.prototype.generateInlineStylesheetRules(this.CLASS_TOAST_VISIBLE, {
				"opacity": "0.9",
				"top": "10%"
			}) +
			Toast.prototype.generateInlineStylesheetRules(this.CLASS_TOAST_ANIMATED, {
				"transition": "opacity " + this.TOAST_ANIMATION_SPEED + "ms, bottom " + this.TOAST_ANIMATION_SPEED + "ms"
			})
		);

		document.head.appendChild(style);
		style = null;

		// Notify that the stylesheet exists to avoid creating more
		Toast.prototype.styleExists = true;
	};

	/**
	 * Generate the Toast with the specified content.
	 * @param  {String} title The content to show inside the Toast, can be an HTML element or plain content
	 * @param  {String|Object} content The content to show inside the Toast, can be an HTML element or plain content
	 * @param  {Object} style style to set for the Toast
	 */
	Toast.prototype.generate = function (title, content, style) {

		var toastStage = document.createElement("div");
		var titleDiv = document.createElement("div");
		titleDiv.appendChild(document.createTextNode(title));

		toastStage.appendChild(titleDiv);

		var contentDiv = document.createElement("div");
		/**
		 * If the content is a String, create a textNode for appending
		 */
		if (typeof content === "string") {

			var lines = content.split('[[[br]]]');

			var s = document.createElement('br');
			contentDiv.appendChild(s);
			for (var i in lines) {
				var l = document.createTextNode(lines[i]);
				contentDiv.appendChild(l);
				var r = document.createElement('br');
				contentDiv.appendChild(r);
			}
		}
		else {
			contentDiv.appendChild(content);
		}

		toastStage.appendChild(contentDiv);
		setToastStage(toastStage);
		toastStage = null;

		Toast.prototype.stylize(getToastStage(), style.main);
		Toast.prototype.stylize(titleDiv, style.title);
		Toast.prototype.stylize(contentDiv, style.content);
	};

	/**
	 * Stylize the Toast.
	 * @param  {Element} element The HTML element to stylize
	 * @param  {Object}  styles  An object containing the style to apply
	 * @return                   Returns nothing
	 */
	Toast.prototype.stylize = function (element, styles) {
		Object.keys(styles).forEach(function (style) {
			element.style[style] = styles[style];
		});
	};

	/**
	 * Generates styles to be used in an inline stylesheet. The output will be something like:
	 * .class {background: blue;}
	 * @param  {String} elementClass The class of the element to style
	 * @param  {Object} styles       The style to insert into the inline stylsheet
	 * @return {String}              The inline style as a string
	 */
	Toast.prototype.generateInlineStylesheetRules = function (elementClass, styles) {
		var out = "." + elementClass + "{";

		Object.keys(styles).forEach(function (style) {
			out += style + ":" + styles[style] + ";";
		});
		out += "}";

		return out;
	};

	/**
	 * Show the Toast
	 * @param  {String} title content to show inside the Toast
	 * @param  {Object} content The content to show inside the Toast
	 * @param  {Object} options The object containing the options for the Toast
	 */
	Toast.prototype.show = function (title, content, options) {
		this.initializeStyles();
		this.generate(title, content, options.style);

		var toastStage = getToastStage();
		toastStage.classList.add(this.CLASS_TOAST_ANIMATED);
		toastStage.classList.add(this.CLASS_TOAST_GONE);
		document.body.insertBefore(toastStage, document.body.firstChild);

		// This is a hack to get animations started. Apparently without explicitly redrawing, it'll just attach the class and no animations would be done
		toastStage.offsetHeight;

		toastStage.classList.remove(this.CLASS_TOAST_GONE);
		toastStage.classList.add(this.CLASS_TOAST_VISIBLE);

		var toastStage = null;

		clearTimeout(Toast.prototype.timeout);
		Toast.prototype.timeout = setTimeout(Toast.prototype.hide, options.settings.duration);
	};

	/**
	 * Hide the Toast that's currently shown
	 */
	Toast.prototype.hide = function () {
		var toastStage = getToastStage();
		toastStage.classList.remove(Toast.prototype.CLASS_TOAST_VISIBLE);
		toastStage.classList.add(Toast.prototype.CLASS_TOAST_GONE);
		toastStage = null;

		// Destroy the Toast element after animations end
		clearTimeout(Toast.prototype.timeout);
		Toast.prototype.timeout = setTimeout(Toast.prototype.destroy, Toast.prototype.TOAST_ANIMATION_SPEED);
	};

	/**
	 * Clean up after the Toast slides away. Namely, removing the Toast from the DOM.
	 */
	Toast.prototype.destroy = function () {
		var toastStage = getToastStage();
		document.body.removeChild(toastStage);

		toastStage = null;
		setToastStage(null);
	};

	return {
		Toast: Toast
	};
})();<|endoftext|>


<commit_before>(function(oCanvas, window, document, undefined){

	// Define the class
	var tools = function () {

		// Return an object when instantiated
		return {
			// Method used by oCanvas to give this object access to the current instance of the core object
			setCore: function (thecore) {
				this.core = thecore;
			},

			// Method for checking if the pointer's current position is inside the specified object
			isPointerInside: function (obj) {

				// Line
				// Does not work correctly at the moment
				if (obj.type === "line") {
					var mouse = this.core.mouse;
					return ((mouse.x > obj.start.x) && (mouse.x < obj.end.x) && (mouse.y > obj.start.y - obj.strokeWeight / 2) && (mouse.y < obj.end.y + obj.strokeWeight / 2) );
				} else

				// Point
				if (obj.type === "point") {
					var mouse = this.core.mouse;

					return (mouse.x === obj.abs_x && mouse.y === obj.abs_y);
				} else

				// Rectangle
				if (obj.shapeType === "rectangular") {
					var mouse = this.core.mouse;

					return ((mouse.x > obj.abs_x) && (mouse.x < obj.abs_x + obj.width) && (mouse.y > obj.abs_y) && (mouse.y < obj.abs_y + obj.height));
				} else

				// Circle
				if (obj.type === "ellipse" && obj.radius_x === obj.radius_y) {
					var mouse = this.core.mouse;
					var D = Math.sqrt(Math.pow(mouse.x - obj.abs_x, 2) + Math.pow(mouse.y - obj.abs_y, 2));
					return (D < obj.radius_x);
				} else

				// Ellipse
				if (obj.type === "ellipse") {
					var mouse = {x: this.core.mouse.x, y: this.core.mouse.y };
					mouse.x -= obj.abs_x;
					mouse.y -= obj.abs_y;
					var a = obj.radius_x,
						b = obj.radius_y;

					return ((mouse.x*mouse.x)/(a*a) + (mouse.y*mouse.y)/(b*b) < 1);
				} else

				// Polygon
				if (obj.type === "polygon") {
					var mouse = this.core.mouse,
						points = obj._.points,
						length = points.length,
						j = length-1,
						odd = false,
						i;

					for (i = 0; i < length; i++) {
						if ( ((points[i].y < mouse.y) && (points[j].y >= mouse.y)) || ((points[j].y < mouse.y) && (points[i].y >= mouse.y)) ) {
							if(points[i].x+(mouse.y-points[i].y)/(points[j].y-points[i].y)*(points[j].x-points[i].x) < mouse.x) {
								odd = !odd;
							}
						}
						j = i;
					}

					return odd;
				} else

				// Arc
				// Does not work correctly at the moment
				if (obj.type === "arc") {
					var mouse = this.core.mouse,
						D = Math.sqrt(Math.pow(mouse.x - obj.abs_x, 2) + Math.pow(mouse.y - obj.abs_y, 2)),
						radius = obj.radius,
						eP = {},
						p1 = {},
						angleRange, a, y_, z, angle;

					if (obj.strokeWeight === obj.radius * 2) {
						radius = obj.strokeWeight;
					}

					if (D > radius) {
						return false;
					}

					angleRange = obj.end - obj.start;

					// If the arc is made like a pie chart piece
					// (desired radius is set as stroke weight and actual radius is set to half that size)
					if (radius === obj.strokeWeight) {

					}

					// If it's a normal arc
					else {

						if (angleRange > 180) {
							a = (360 - angleRange) / 2;
							y_ = Math.cos(a * Math.PI / 180) * radius;

							eP.x = obj.abs_x + Math.cos(a * Math.PI / 180) * y_;
							eP.y = obj.abs_y - Math.sin(a * Math.PI / 180) * y_;

							z = 180 - 2 * a;

							p1.x = obj.abs_x - Math.cos(z * Math.PI / 180) * radius;
							p1.y = obj.abs_y - Math.sin(z * Math.PI / 180) * radius;

							var aRight = 90 - (90 - z) - (90 - a);

							if (mouse.y < eP.y && mouse.x < eP.x) {
								angle = a - Math.acos(Math.abs(mouse.y - eP.y) / Math.sqrt(Math.pow(mouse.x - eP.x, 2) + Math.pow(mouse.y - eP.y, 2))) * 180 / Math.PI;
							} else
							if (mouse.y > eP.y && mouse.x >= eP.x) {
								angle = aRight - Math.acos(Math.abs(mouse.x - eP.x) / Math.sqrt(Math.pow(mouse.x - eP.x, 2) + Math.pow(mouse.y - eP.y, 2))) * 180 / Math.PI;
							} else
							if (mouse.y < obj.abs_y && mouse.x >= eP.x) {
								return false;
							} else {
								angle = -1000000;
							}

							if (angle <= 0 && mouse.x >= p1.x && mouse.y > eP.y && mouse.y < obj.abs_y) {
								return true;
							} else if (angle <= 0 && mouse.y <= obj.abs_y && D <= radius) {
								return true;
							} else if (D <= radius && ((mouse.x <= p1.x && mouse.y <= obj.abs_y) || (mouse.y >= obj.abs_y)) ) {
								return true;
							} else {
								return false;
							}
						} else if (angleRange === 180) {
							if (mouse.y >= obj.abs_y && D <= radius) {
								return true;
							} else {
								return false;
							}
						} else if (angleRange < 180) {
							a = angleRange / 2;
							x_ = Math.sin(a * Math.PI / 180) * radius;
							y_ = Math.cos(a * Math.PI / 180) * radius;

							eP.x = obj.abs_x + Math.cos(a * Math.PI / 180) * y_;
							eP.y = obj.abs_y + Math.sin(a * Math.PI / 180) * y_;

							var a_ = Math.acos(Math.abs(mouse.x - eP.x) / Math.sqrt(Math.pow(mouse.x - eP.x, 2) + Math.pow(mouse.y - eP.y, 2))) * 180 / Math.PI,
								angle = 90 - a - a_;

							if (angle <= 0 && mouse.y > eP.y) {
								return true;
							} else if (angle >= 0 && mouse.y < eP.y && mouse.x > eP.x) {
								return true;
							} else {
								return false;
							}
						}
					}
				}
			}
		};
	};

	// Register the module
	oCanvas.registerModule("tools", tools);

})(oCanvas, window, document);<commit_msg>Added method transformPointerPosition() in tools. This transforms the position according to the specified rotation and center. This method will be used later when transformations are added. It is also currently used to correct the angle for line and arc in isPointerInside().<commit_after>(function(oCanvas, window, document, undefined){

	// Define the class
	var tools = function () {

		// Return an object when instantiated
		return {
			// Method used by oCanvas to give this object access to the current instance of the core object
			setCore: function (thecore) {
				this.core = thecore;
			},

			// Method for transforming the pointer position to the current object's transformation
			transformPointerPosition : function (rotation, cX, cY, extraAngle) {
				extraAngle = extraAngle || 0;

				var mouse = this.core.mouse,
					topright = (mouse.x >= cX && mouse.y <= cY),
					bottomright = (mouse.x >= cX && mouse.y >= cY),
					bottomleft = (mouse.x <= cX && mouse.y >= cY),
					topleft = (mouse.x <= cX && mouse.y <= cY),
					D = Math.sqrt(Math.pow(mouse.x - cX, 2) + Math.pow(mouse.y - cY, 2)),
					rotation = ((rotation / 360) - Math.floor(rotation / 360)) * 360 - extraAngle,
					c, x, y;

				// When pointer is in top right or bottom left corner
				if ( topright || bottomleft ) {
					c = (180 - rotation - Math.asin(Math.abs(mouse.y - cY) / D) * 180 / Math.PI) * Math.PI / 180;

					x = cX + Math.cos(c) * D * (topright ? -1 : 1);
					y = cY + Math.sin(c) * D * (topright ? -1 : 1);
				}

				// When pointer is in top left or bottom right corner
				else if (topleft || bottomright) {
					c = (Math.asin(Math.abs(mouse.y - cY) / D) * 180 / Math.PI - rotation) * Math.PI / 180;

					x = cX + Math.cos(c) * D * (topleft ? -1 : 1);
					y = cY + Math.sin(c) * D * (topleft ? -1 : 1);
				}

				return {
					x: x,
					y: y
				};
			},

			// Method for checking if the pointer's current position is inside the specified object
			isPointerInside: function (obj) {

				// Line
				if (obj.type === "line") {

					// Get angle difference relative to if it had been horizontal
					var dX = Math.abs(obj.end.x - obj.x),
						dY = Math.abs(obj.end.y - obj.y),
						D = Math.sqrt(dX * dX + dY * dY),
						angle = Math.asin(dY / D) * 180 / Math.PI,

						// Transform the pointer position with the angle correction
						pointer = this.transformPointerPosition(obj.rotation, obj.x, obj.y, angle * -1);

					// Check if pointer is inside the line
					// Pointer coordinates are transformed to be compared with a horizontal line
					return (pointer.x > obj.x - D && pointer.x < obj.x + D && pointer.y > obj.y - obj.strokeWeight / 2 && pointer.y < obj.y + obj.strokeWeight / 2);
				} else

				// Point
				if (obj.type === "point") {
					var pointer = this.transformPointerPosition(obj.rotation, obj.x, obj.y);
					return (pointer.x === obj.abs_x && pointer.y === obj.abs_y);
				} else

				// Rectangle
				if (obj.shapeType === "rectangular") {
					var pointer = this.transformPointerPosition(obj.rotation, obj.x + (obj.width / 2), obj.y + (obj.height / 2));
					return ((pointer.x > obj.abs_x) && (pointer.x < obj.abs_x + obj.width) && (pointer.y > obj.abs_y) && (pointer.y < obj.abs_y + obj.height));
				} else

				// Circle
				if (obj.type === "ellipse" && obj.radius_x === obj.radius_y) {
					var pointer = this.transformPointerPosition(obj.rotation, obj.x, obj.y),
						D = Math.sqrt(Math.pow(pointer.x - obj.abs_x, 2) + Math.pow(pointer.y - obj.abs_y, 2));
					return (D < obj.radius_x);
				} else

				// Ellipse
				if (obj.type === "ellipse") {
					var pointer = this.transformPointerPosition(obj.rotation, obj.x, obj.y),
						a = obj.radius_x,
						b = obj.radius_y;
					pointer.x -= obj.abs_x;
					pointer.y -= obj.abs_y;

					return ((pointer.x*pointer.x)/(a*a) + (pointer.y*pointer.y)/(b*b) < 1);
				} else

				// Polygon
				if (obj.type === "polygon") {
					var pointer = this.transformPointerPosition(obj.rotation, obj.x, obj.y),
						points = obj._.points,
						length = points.length,
						j = length-1,
						odd = false,
						i;

					for (i = 0; i < length; i++) {
						if ( ((points[i].y < pointer.y) && (points[j].y >= pointer.y)) || ((points[j].y < pointer.y) && (points[i].y >= pointer.y)) ) {
							if(points[i].x+(pointer.y-points[i].y)/(points[j].y-points[i].y)*(points[j].x-points[i].x) < pointer.x) {
								odd = !odd;
							}
						}
						j = i;
					}

					return odd;
				} else

				// Arc
				// Does not work correctly at the moment
				if (obj.type === "arc") {
					var pointer = this.transformPointerPosition(obj.rotation, obj.x, obj.y, obj.start * -1),
						D = Math.sqrt(Math.pow(pointer.x - obj.abs_x, 2) + Math.pow(pointer.y - obj.abs_y, 2)),
						radius = obj.radius,
						eP = {},
						p1 = {},
						angleRange, a, y_, z, angle;

					if (obj.strokeWeight === obj.radius * 2) {
						radius = obj.strokeWeight;
					}

					if (D > radius) {
						return false;
					}

					angleRange = obj.end - obj.start;

					// If the arc is made like a pie chart piece
					// (desired radius is set as stroke weight and actual radius is set to half that size)
					if (radius === obj.strokeWeight) {

					}

					// If it's a normal arc
					else {

						if (angleRange > 180) {
							a = (360 - angleRange) / 2;
							y_ = Math.cos(a * Math.PI / 180) * radius;

							eP.x = obj.abs_x + Math.cos(a * Math.PI / 180) * y_;
							eP.y = obj.abs_y - Math.sin(a * Math.PI / 180) * y_;

							z = 180 - 2 * a;

							p1.x = obj.abs_x - Math.cos(z * Math.PI / 180) * radius;
							p1.y = obj.abs_y - Math.sin(z * Math.PI / 180) * radius;

							var aRight = 90 - (90 - z) - (90 - a);

							if (pointer.y < eP.y && pointer.x < eP.x) {
								angle = a - Math.acos(Math.abs(pointer.y - eP.y) / Math.sqrt(Math.pow(pointer.x - eP.x, 2) + Math.pow(pointer.y - eP.y, 2))) * 180 / Math.PI;
							} else
							if (pointer.y > eP.y && pointer.x >= eP.x) {
								angle = aRight - Math.acos(Math.abs(pointer.x - eP.x) / Math.sqrt(Math.pow(pointer.x - eP.x, 2) + Math.pow(pointer.y - eP.y, 2))) * 180 / Math.PI;
							} else
							if (pointer.y < obj.abs_y && pointer.x >= eP.x) {
								return false;
							} else {
								angle = -1000000;
							}

							if (angle <= 0 && pointer.x >= p1.x && pointer.y > eP.y && pointer.y < obj.abs_y) {
								return true;
							} else if (angle <= 0 && pointer.y <= obj.abs_y && D <= radius) {
								return true;
							} else if (D <= radius && ((pointer.x <= p1.x && pointer.y <= obj.abs_y) || (pointer.y >= obj.abs_y)) ) {
								return true;
							} else {
								return false;
							}
						} else if (angleRange === 180) {
							if (pointer.y >= obj.abs_y && D <= radius) {
								return true;
							} else {
								return false;
							}
						} else if (angleRange < 180) {
							a = angleRange / 2;
							x_ = Math.sin(a * Math.PI / 180) * radius;
							y_ = Math.cos(a * Math.PI / 180) * radius;

							eP.x = obj.abs_x + Math.cos(a * Math.PI / 180) * y_;
							eP.y = obj.abs_y + Math.sin(a * Math.PI / 180) * y_;

							var a_ = Math.acos(Math.abs(pointer.x - eP.x) / Math.sqrt(Math.pow(pointer.x - eP.x, 2) + Math.pow(pointer.y - eP.y, 2))) * 180 / Math.PI,
								angle = 90 - a - a_;

							if (angle <= 0 && pointer.y > eP.y) {
								return true;
							} else if (angle >= 0 && pointer.y < eP.y && pointer.x > eP.x) {
								return true;
							} else {
								return false;
							}
						}
					}
				}
			}
		};
	};

	// Register the module
	oCanvas.registerModule("tools", tools);

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


<commit_before>import $ from 'jquery';
import {
    nextUID,
    createStyles
}
from 'utils';
import toolyTpl from 'tooly.html!text';
import 'tooly.scss!';
const DEFAULT_OPTIONS = {

};
const TARGET_CLASS_PREFIX = 'tooly-id-';
const CONTAINER_CLASS_PREFIX = 'tooly-container-id-';
const STYLE_PREFIX = 'tooly-style-id-';
const ANCHOR_HEIGHT = 10;
const TOOLY_OPTIONS = 'tooly-options';
let elMap = new WeakMap();
let currWinHeight, currWinWidth;
let $window = $(window),
    $body = $('body');
$window.resize(() => {
    console.log('window resized');
    currWinHeight = $window.height();
    currWinWidth = $window.width();
});

function _getStyles(el, container) {
    let options = el.data(TOOLY_OPTIONS);
    let elWidth = el.width(),
        elHeight = el.height(),
        elPosition = el.position();
    let containerWidth = container.width(),
        containerHeight = container.height() + ANCHOR_HEIGHT,
        containerId = `#${_getToolyContainerId(options.id)}`;
    let containerTop = elPosition.top - containerHeight,
        containerLeft = elPosition.left;
    let containerStyles = createStyles(containerId, {
            top: containerTop + 'px',
            left: containerLeft + 'px'
        }),
        anchorStyles = createStyles(`${containerId}:after`, {
            left: '20px'
        });
    // return {
    //     'margin-left': -width / 2
    // };
    return containerStyles + anchorStyles;
}

function _getToolyContainerId(id) {
    return CONTAINER_CLASS_PREFIX + id;
}

function _getToolyTargetClass(id) {
    return TARGET_CLASS_PREFIX + id;
}

function _getToolyStyleId(id) {
    return STYLE_PREFIX + id;
}
$.fn.tooly = function (options) {
    let _this = this;
    let type = $.type(options);
    if (type === 'object' || type === 'undefined') {
        options = $.extend({}, DEFAULT_OPTIONS, options);
        options.id = nextUID();
        _this.data(TOOLY_OPTIONS, options);
        !elMap.has(_this) && elMap.set(_this, options);
        _this.mouseover(() => {
            let _this = this;
            let toolyContainer = $(toolyTpl).attr('id', _getToolyContainerId(options.id));
            _this.addClass(`tooly ${_getToolyTargetClass(options.id)}`);
            $body.append(toolyContainer);
            $body.append(`<style id="${_getToolyStyleId(options.id)}">${_getStyles(_this,toolyContainer)}</style>`);
        });
        _this.mouseout(() => {
            let _this = this;
            let options = _this.data(TOOLY_OPTIONS);
            $body.find(`#${_getToolyContainerId(options.id)}, #${_getToolyStyleId(options.id)}`).remove();
            elMap.delete(_this);
        });
    }
    return _this;
};
<commit_msg>removed commented code<commit_after>import $ from 'jquery';
import {
    nextUID,
    createStyles
}
from 'utils';
import toolyTpl from 'tooly.html!text';
import 'tooly.scss!';
const DEFAULT_OPTIONS = {

};
const TARGET_CLASS_PREFIX = 'tooly-id-';
const CONTAINER_CLASS_PREFIX = 'tooly-container-id-';
const STYLE_PREFIX = 'tooly-style-id-';
const ANCHOR_HEIGHT = 10;
const TOOLY_OPTIONS = 'tooly-options';
let elMap = new WeakMap();
let currWinHeight, currWinWidth;
let $window = $(window),
    $body = $('body');
$window.resize(() => {
    console.log('window resized');
    currWinHeight = $window.height();
    currWinWidth = $window.width();
});

function _getStyles(el, container) {
    let options = el.data(TOOLY_OPTIONS);
    let elWidth = el.width(),
        elHeight = el.height(),
        elPosition = el.position();
    let containerWidth = container.width(),
        containerHeight = container.height() + ANCHOR_HEIGHT,
        containerId = `#${_getToolyContainerId(options.id)}`;
    let containerTop = elPosition.top - containerHeight,
        containerLeft = elPosition.left;
    let containerStyles = createStyles(containerId, {
            top: containerTop + 'px',
            left: containerLeft + 'px'
        }),
        anchorStyles = createStyles(`${containerId}:after`, {
            left: '20px'
        });
    return containerStyles + anchorStyles;
}

function _getToolyContainerId(id) {
    return CONTAINER_CLASS_PREFIX + id;
}

function _getToolyTargetClass(id) {
    return TARGET_CLASS_PREFIX + id;
}

function _getToolyStyleId(id) {
    return STYLE_PREFIX + id;
}
$.fn.tooly = function (options) {
    let _this = this;
    let type = $.type(options);
    if (type === 'object' || type === 'undefined') {
        options = $.extend({}, DEFAULT_OPTIONS, options);
        options.id = nextUID();
        _this.data(TOOLY_OPTIONS, options);
        !elMap.has(_this) && elMap.set(_this, options);
        _this.mouseover(() => {
            let _this = this;
            let toolyContainer = $(toolyTpl).attr('id', _getToolyContainerId(options.id));
            _this.addClass(`tooly ${_getToolyTargetClass(options.id)}`);
            $body.append(toolyContainer);
            $body.append(`<style id="${_getToolyStyleId(options.id)}">${_getStyles(_this,toolyContainer)}</style>`);
        });
        _this.mouseout(() => {
            let _this = this;
            let options = _this.data(TOOLY_OPTIONS);
            $body.find(`#${_getToolyContainerId(options.id)}, #${_getToolyStyleId(options.id)}`).remove();
            elMap.delete(_this);
        });
    }
    return _this;
};
<|endoftext|>


<commit_before>//     Zepto.js
//     (c) 2010-2016 Thomas Fuchs
//     Zepto.js may be freely distributed under the MIT license.

;(function($){
  var touch = {},
    touchTimeout, tapTimeout, swipeTimeout, longTapTimeout,
    longTapDelay = 750,
    gesture

  function swipeDirection(x1, x2, y1, y2) {
    return Math.abs(x1 - x2) >=
      Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')
  }

  function longTap() {
    longTapTimeout = null
    if (touch.last) {
      touch.el.trigger('longTap')
      touch = {}
    }
  }

  function cancelLongTap() {
    if (longTapTimeout) clearTimeout(longTapTimeout)
    longTapTimeout = null
  }

  function cancelAll() {
    if (touchTimeout) clearTimeout(touchTimeout)
    if (tapTimeout) clearTimeout(tapTimeout)
    if (swipeTimeout) clearTimeout(swipeTimeout)
    if (longTapTimeout) clearTimeout(longTapTimeout)
    touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null
    touch = {}
  }

  function isPrimaryTouch(event){
    return (event.pointerType == 'touch' ||
      event.pointerType == event.MSPOINTER_TYPE_TOUCH)
      && event.isPrimary
  }

  function isPointerEventType(e, type){
    return (e.type == 'pointer'+type ||
      e.type.toLowerCase() == 'mspointer'+type)
  }

  $(document).ready(function(){
    var now, delta, deltaX = 0, deltaY = 0, firstTouch, _isPointerType

    if ('MSGesture' in window) {
      gesture = new MSGesture()
      gesture.target = document.body
    }

    $(document)
      .bind('MSGestureEnd', function(e){
        var swipeDirectionFromVelocity =
          e.velocityX > 1 ? 'Right' : e.velocityX < -1 ? 'Left' : e.velocityY > 1 ? 'Down' : e.velocityY < -1 ? 'Up' : null;
        if (swipeDirectionFromVelocity) {
            touch.el.trigger('swipe')
            touch.el.trigger('swipe'+ swipeDirectionFromVelocity)
        }
      })
      .on('touchstart MSPointerDown pointerdown', function(e){
        if((_isPointerType = isPointerEventType(e, 'down')) &&
          !isPrimaryTouch(e)) return
        firstTouch = _isPointerType ? e : e.touches[0]
        if (e.touches && e.touches.length === 1 && touch.x2) {
          // Clear out touch movement data if we have it sticking around
          // This can occur if touchcancel doesn't fire due to preventDefault, etc.
          touch.x2 = undefined
          touch.y2 = undefined
        }
        now = Date.now()
        delta = now - (touch.last || now)
        touch.el = $('tagName' in firstTouch.target ?
          firstTouch.target : firstTouch.target.parentNode)
        touchTimeout && clearTimeout(touchTimeout)
        touch.x1 = firstTouch.pageX
        touch.y1 = firstTouch.pageY
        if (delta > 0 && delta <= 250) touch.isDoubleTap = true
        touch.last = now
        longTapTimeout = setTimeout(longTap, longTapDelay)
        // adds the current touch contact for IE gesture recognition
        if (gesture && _isPointerType) gesture.addPointer(e.pointerId);
      })
      .on('touchmove MSPointerMove pointermove', function(e){
        if((_isPointerType = isPointerEventType(e, 'move')) &&
          !isPrimaryTouch(e)) return
        firstTouch = _isPointerType ? e : e.touches[0]
        cancelLongTap()
        touch.x2 = firstTouch.pageX
        touch.y2 = firstTouch.pageY

        deltaX += Math.abs(touch.x1 - touch.x2)
        deltaY += Math.abs(touch.y1 - touch.y2)
      })
      .on('touchend MSPointerUp pointerup', function(e){
        if((_isPointerType = isPointerEventType(e, 'up')) &&
          !isPrimaryTouch(e)) return
        cancelLongTap()

        // swipe
        if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) ||
            (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30))

          swipeTimeout = setTimeout(function() {
            if (touch.el){
              touch.el.trigger('swipe')
              touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)))
            }
            touch = {}
          }, 0)

        // normal tap
        else if ('last' in touch)
          // don't fire tap when delta position changed by more than 30 pixels,
          // for instance when moving to a point and back to origin
          if (deltaX < 30 && deltaY < 30) {
            // delay by one tick so we can cancel the 'tap' event if 'scroll' fires
            // ('tap' fires before 'scroll')
            tapTimeout = setTimeout(function() {

              // trigger universal 'tap' with the option to cancelTouch()
              // (cancelTouch cancels processing of single vs double taps for faster 'tap' response)
              var event = $.Event('tap')
              event.cancelTouch = cancelAll
              touch.el.trigger(event)

              // trigger double tap immediately
              if (touch.isDoubleTap) {
                if (touch.el) touch.el.trigger('doubleTap')
                touch = {}
              }

              // trigger single tap after 250ms of inactivity
              else {
                touchTimeout = setTimeout(function(){
                  touchTimeout = null
                  if (touch.el) touch.el.trigger('singleTap')
                  touch = {}
                }, 250)
              }
            }, 0)
          } else {
            touch = {}
          }
          deltaX = deltaY = 0

      })
      // when the browser window loses focus,
      // for example when a modal dialog is shown,
      // cancel all ongoing events
      .on('touchcancel MSPointerCancel pointercancel', cancelAll)

    // scrolling the window indicates intention of the user
    // to scroll, not tap or swipe, so cancel all ongoing events
    $(window).on('scroll', cancelAll)
  })

  ;['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown',
    'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(eventName){
    $.fn[eventName] = function(callback){ return this.on(eventName, callback) }
  })
})(Zepto)
<commit_msg>fix  "TypeError: 'undefined' is not an object (evaluating 'touch.el.trigger'), when double tap<commit_after>//     Zepto.js
//     (c) 2010-2016 Thomas Fuchs
//     Zepto.js may be freely distributed under the MIT license.

;(function($){
  var touch = {},
    touchTimeout, tapTimeout, swipeTimeout, longTapTimeout,
    longTapDelay = 750,
    gesture

  function swipeDirection(x1, x2, y1, y2) {
    return Math.abs(x1 - x2) >=
      Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')
  }

  function longTap() {
    longTapTimeout = null
    if (touch.last) {
      touch.el.trigger('longTap')
      touch = {}
    }
  }

  function cancelLongTap() {
    if (longTapTimeout) clearTimeout(longTapTimeout)
    longTapTimeout = null
  }

  function cancelAll() {
    if (touchTimeout) clearTimeout(touchTimeout)
    if (tapTimeout) clearTimeout(tapTimeout)
    if (swipeTimeout) clearTimeout(swipeTimeout)
    if (longTapTimeout) clearTimeout(longTapTimeout)
    touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null
    touch = {}
  }

  function isPrimaryTouch(event){
    return (event.pointerType == 'touch' ||
      event.pointerType == event.MSPOINTER_TYPE_TOUCH)
      && event.isPrimary
  }

  function isPointerEventType(e, type){
    return (e.type == 'pointer'+type ||
      e.type.toLowerCase() == 'mspointer'+type)
  }

  $(document).ready(function(){
    var now, delta, deltaX = 0, deltaY = 0, firstTouch, _isPointerType

    if ('MSGesture' in window) {
      gesture = new MSGesture()
      gesture.target = document.body
    }

    $(document)
      .bind('MSGestureEnd', function(e){
        var swipeDirectionFromVelocity =
          e.velocityX > 1 ? 'Right' : e.velocityX < -1 ? 'Left' : e.velocityY > 1 ? 'Down' : e.velocityY < -1 ? 'Up' : null;
        if (swipeDirectionFromVelocity) {
            touch.el.trigger('swipe')
            touch.el.trigger('swipe'+ swipeDirectionFromVelocity)
        }
      })
      .on('touchstart MSPointerDown pointerdown', function(e){
        if((_isPointerType = isPointerEventType(e, 'down')) &&
          !isPrimaryTouch(e)) return
        firstTouch = _isPointerType ? e : e.touches[0]
        if (e.touches && e.touches.length === 1 && touch.x2) {
          // Clear out touch movement data if we have it sticking around
          // This can occur if touchcancel doesn't fire due to preventDefault, etc.
          touch.x2 = undefined
          touch.y2 = undefined
        }
        now = Date.now()
        delta = now - (touch.last || now)
        touch.el = $('tagName' in firstTouch.target ?
          firstTouch.target : firstTouch.target.parentNode)
        touchTimeout && clearTimeout(touchTimeout)
        touch.x1 = firstTouch.pageX
        touch.y1 = firstTouch.pageY
        if (delta > 0 && delta <= 250) touch.isDoubleTap = true
        touch.last = now
        longTapTimeout = setTimeout(longTap, longTapDelay)
        // adds the current touch contact for IE gesture recognition
        if (gesture && _isPointerType) gesture.addPointer(e.pointerId);
      })
      .on('touchmove MSPointerMove pointermove', function(e){
        if((_isPointerType = isPointerEventType(e, 'move')) &&
          !isPrimaryTouch(e)) return
        firstTouch = _isPointerType ? e : e.touches[0]
        cancelLongTap()
        touch.x2 = firstTouch.pageX
        touch.y2 = firstTouch.pageY

        deltaX += Math.abs(touch.x1 - touch.x2)
        deltaY += Math.abs(touch.y1 - touch.y2)
      })
      .on('touchend MSPointerUp pointerup', function(e){
        if((_isPointerType = isPointerEventType(e, 'up')) &&
          !isPrimaryTouch(e)) return
        cancelLongTap()

        // swipe
        if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) ||
            (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30))

          swipeTimeout = setTimeout(function() {
            if (touch.el){
              touch.el.trigger('swipe')
              touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)))
            }
            touch = {}
          }, 0)

        // normal tap
        else if ('last' in touch)
          // don't fire tap when delta position changed by more than 30 pixels,
          // for instance when moving to a point and back to origin
          if (deltaX < 30 && deltaY < 30) {
            // delay by one tick so we can cancel the 'tap' event if 'scroll' fires
            // ('tap' fires before 'scroll')
            tapTimeout = setTimeout(function() {

              // trigger universal 'tap' with the option to cancelTouch()
              // (cancelTouch cancels processing of single vs double taps for faster 'tap' response)
              var event = $.Event('tap')
              event.cancelTouch = cancelAll
              // [by paper] fix -> "TypeError: 'undefined' is not an object (evaluating 'touch.el.trigger'), when double tap
              if (touch.el) touch.el.trigger(event)

              // trigger double tap immediately
              if (touch.isDoubleTap) {
                if (touch.el) touch.el.trigger('doubleTap')
                touch = {}
              }

              // trigger single tap after 250ms of inactivity
              else {
                touchTimeout = setTimeout(function(){
                  touchTimeout = null
                  if (touch.el) touch.el.trigger('singleTap')
                  touch = {}
                }, 250)
              }
            }, 0)
          } else {
            touch = {}
          }
          deltaX = deltaY = 0

      })
      // when the browser window loses focus,
      // for example when a modal dialog is shown,
      // cancel all ongoing events
      .on('touchcancel MSPointerCancel pointercancel', cancelAll)

    // scrolling the window indicates intention of the user
    // to scroll, not tap or swipe, so cancel all ongoing events
    $(window).on('scroll', cancelAll)
  })

  ;['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown',
    'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(eventName){
    $.fn[eventName] = function(callback){ return this.on(eventName, callback) }
  })
})(Zepto)
<|endoftext|>


<commit_before>'use strict';

import React from 'react';
import assign from 'object-assign';
import classnames from 'classnames';
import { getPreClones } from './utils/trackUtils';

// given specifications/props for a slide, fetch all the classes that need to be applied to the slide
var getSlideClasses = (spec) => {
  // if spec has currentSlideIndex, we can also apply slickCurrent class according to that (https://github.com/kenwheeler/slick/blob/master/slick/slick.js#L2300-L2302)
  var slickActive, slickCenter, slickCloned;
  var centerOffset, index;

  if (spec.rtl) { // if we're going right to left, index is reversed
    index = spec.slideCount - 1 - spec.index;
  } else { // index of the slide
    index = spec.index;
  }
  slickCloned = (index < 0) || (index >= spec.slideCount);
  if (spec.centerMode) {
    centerOffset = Math.floor(spec.slidesToShow / 2);
    slickCenter = (index - spec.currentSlide) % spec.slideCount === 0; // concern: not sure if this should be correct (https://github.com/kenwheeler/slick/blob/master/slick/slick.js#L2328-L2346)
    if ((index > spec.currentSlide - centerOffset - 1) && (index <= spec.currentSlide + centerOffset)) {
      slickActive = true;
    }
  } else {
    // concern: following can be incorrect in case where currentSlide is lastSlide in frame and rest of the slides to show have index smaller than currentSlideIndex
    slickActive = (spec.currentSlide <= index) && (index < spec.currentSlide + spec.slidesToShow);
  }
  let slickCurrent = index === spec.currentSlide
  return classnames({
    'slick-slide': true,
    'slick-active': slickActive,
    'slick-center': slickCenter,
    'slick-cloned': slickCloned,
    'slick-current': slickCurrent // dubious in case of RTL
  });
};

var getSlideStyle = function (spec) {
  var style = {};

  if (spec.variableWidth === undefined || spec.variableWidth === false) {
    style.width = spec.slideWidth;
  }

  if (spec.fade) {
    style.position = 'relative';
    if (spec.vertical) {
      style.top = -spec.index * spec.slideHeight;
    } else {
      style.left = -spec.index * spec.slideWidth;
    }
    style.opacity = (spec.currentSlide === spec.index) ? 1 : 0;
    style.visibility = (spec.currentSlide === spec.index) ? 'visible' : 'hidden';
    style.transition = 'opacity ' + spec.speed + 'ms ' + spec.cssEase + ', ' + 'visibility ' + spec.speed + 'ms ' + spec.cssEase;
    style.WebkitTransition = 'opacity ' + spec.speed + 'ms ' + spec.cssEase + ', ' + 'visibility ' + spec.speed + 'ms ' + spec.cssEase;
  }

  return style;
};

const getKey = (child, fallbackKey) => child.key || fallbackKey

var renderSlides = function (spec) {
  var key;
  var slides = [];
  var preCloneSlides = [];
  var postCloneSlides = [];
  var childrenCount = React.Children.count(spec.children);

  React.Children.forEach(spec.children, (elem, index) => {
    let child;
    var childOnClickOptions = {
      message: 'children',
      index: index,
      slidesToScroll: spec.slidesToScroll,
      currentSlide: spec.currentSlide
    };

    // in case of lazyLoad, whether or not we want to fetch the slide
    if (!spec.lazyLoad || (spec.lazyLoad && spec.lazyLoadedList.indexOf(index) >= 0)) {
      child = elem;
    } else {
      child = (

);
    }
    var childStyle = getSlideStyle(assign({}, spec, {index: index}));
    const slideClass = child.props.className || ''

    const onClick = function(e) {
      child.props && child.props.onClick && child.props.onClick(e)
      if (spec.focusOnSelect) {
        spec.focusOnSelect(childOnClickOptions)
      }
    }

    // push a cloned element of the desired slide
    slides.push(React.cloneElement(child, {
      key: 'original' + getKey(child, index),
      'data-index': index,
      className: classnames(getSlideClasses(assign({index: index}, spec)), slideClass),
      tabIndex: '-1',
      style: assign({outline: 'none'}, child.props.style || {}, childStyle),
      onClick
    }));

    // variableWidth doesn't wrap properly.
    // if slide needs to be precloned or postcloned
    if (spec.infinite && spec.fade === false) {
      let preCloneNo = childrenCount - index
      if (preCloneNo <= getPreClones(spec)
        && childrenCount !== spec.slidesToShow){
        key = -preCloneNo;
        preCloneSlides.push(React.cloneElement(child, {
          key: 'precloned' + getKey(child, key),
          'data-index': key,
          className: classnames(getSlideClasses(assign({index: key}, spec)), slideClass),
          style: assign({}, child.props.style || {}, childStyle),
          onClick
        }));
      }

      if (childrenCount !== spec.slidesToShow) {
        key = childrenCount + index;
        postCloneSlides.push(React.cloneElement(child, {
          key: 'postcloned' + getKey(child, key),
          'data-index': key,
          className: classnames(getSlideClasses(assign({index: key}, spec)), slideClass),
          style: assign({}, child.props.style || {}, childStyle),
          onClick
        }));
      }
    }
  });

  if (spec.rtl) {
    return preCloneSlides.concat(slides, postCloneSlides).reverse();
  } else {
    return preCloneSlides.concat(slides, postCloneSlides);
  }
};

export class Track extends React.Component {
  render() {
    // var slides = renderSlides.call(this, this.props);
    var slides = renderSlides(this.props)
    return (

        { slides }

    );
  }
}
<commit_msg>made all the slides untabbable<commit_after>'use strict';

import React from 'react';
import assign from 'object-assign';
import classnames from 'classnames';
import { getPreClones } from './utils/trackUtils';

// given specifications/props for a slide, fetch all the classes that need to be applied to the slide
var getSlideClasses = (spec) => {
  // if spec has currentSlideIndex, we can also apply slickCurrent class according to that (https://github.com/kenwheeler/slick/blob/master/slick/slick.js#L2300-L2302)
  var slickActive, slickCenter, slickCloned;
  var centerOffset, index;

  if (spec.rtl) { // if we're going right to left, index is reversed
    index = spec.slideCount - 1 - spec.index;
  } else { // index of the slide
    index = spec.index;
  }
  slickCloned = (index < 0) || (index >= spec.slideCount);
  if (spec.centerMode) {
    centerOffset = Math.floor(spec.slidesToShow / 2);
    slickCenter = (index - spec.currentSlide) % spec.slideCount === 0; // concern: not sure if this should be correct (https://github.com/kenwheeler/slick/blob/master/slick/slick.js#L2328-L2346)
    if ((index > spec.currentSlide - centerOffset - 1) && (index <= spec.currentSlide + centerOffset)) {
      slickActive = true;
    }
  } else {
    // concern: following can be incorrect in case where currentSlide is lastSlide in frame and rest of the slides to show have index smaller than currentSlideIndex
    slickActive = (spec.currentSlide <= index) && (index < spec.currentSlide + spec.slidesToShow);
  }
  let slickCurrent = index === spec.currentSlide
  return classnames({
    'slick-slide': true,
    'slick-active': slickActive,
    'slick-center': slickCenter,
    'slick-cloned': slickCloned,
    'slick-current': slickCurrent // dubious in case of RTL
  });
};

var getSlideStyle = function (spec) {
  var style = {};

  if (spec.variableWidth === undefined || spec.variableWidth === false) {
    style.width = spec.slideWidth;
  }

  if (spec.fade) {
    style.position = 'relative';
    if (spec.vertical) {
      style.top = -spec.index * spec.slideHeight;
    } else {
      style.left = -spec.index * spec.slideWidth;
    }
    style.opacity = (spec.currentSlide === spec.index) ? 1 : 0;
    style.visibility = (spec.currentSlide === spec.index) ? 'visible' : 'hidden';
    style.transition = 'opacity ' + spec.speed + 'ms ' + spec.cssEase + ', ' + 'visibility ' + spec.speed + 'ms ' + spec.cssEase;
    style.WebkitTransition = 'opacity ' + spec.speed + 'ms ' + spec.cssEase + ', ' + 'visibility ' + spec.speed + 'ms ' + spec.cssEase;
  }

  return style;
};

const getKey = (child, fallbackKey) => child.key || fallbackKey

var renderSlides = function (spec) {
  var key;
  var slides = [];
  var preCloneSlides = [];
  var postCloneSlides = [];
  var childrenCount = React.Children.count(spec.children);

  React.Children.forEach(spec.children, (elem, index) => {
    let child;
    var childOnClickOptions = {
      message: 'children',
      index: index,
      slidesToScroll: spec.slidesToScroll,
      currentSlide: spec.currentSlide
    };

    // in case of lazyLoad, whether or not we want to fetch the slide
    if (!spec.lazyLoad || (spec.lazyLoad && spec.lazyLoadedList.indexOf(index) >= 0)) {
      child = elem;
    } else {
      child = (

);
    }
    var childStyle = getSlideStyle(assign({}, spec, {index: index}));
    const slideClass = child.props.className || ''

    const onClick = function(e) {
      child.props && child.props.onClick && child.props.onClick(e)
      if (spec.focusOnSelect) {
        spec.focusOnSelect(childOnClickOptions)
      }
    }

    // push a cloned element of the desired slide
    slides.push(React.cloneElement(child, {
      key: 'original' + getKey(child, index),
      'data-index': index,
      className: classnames(getSlideClasses(assign({index: index}, spec)), slideClass),
      tabIndex: '-1',
      style: assign({outline: 'none'}, child.props.style || {}, childStyle),
      onClick
    }));

    // variableWidth doesn't wrap properly.
    // if slide needs to be precloned or postcloned
    if (spec.infinite && spec.fade === false) {
      let preCloneNo = childrenCount - index
      if (preCloneNo <= getPreClones(spec)
        && childrenCount !== spec.slidesToShow){
        key = -preCloneNo;
        preCloneSlides.push(React.cloneElement(child, {
          key: 'precloned' + getKey(child, key),
          'data-index': key,
          tabIndex: '-1',
          className: classnames(getSlideClasses(assign({index: key}, spec)), slideClass),
          style: assign({}, child.props.style || {}, childStyle),
          onClick
        }));
      }

      if (childrenCount !== spec.slidesToShow) {
        key = childrenCount + index;
        postCloneSlides.push(React.cloneElement(child, {
          key: 'postcloned' + getKey(child, key),
          'data-index': key,
          tabIndex: '-1',
          className: classnames(getSlideClasses(assign({index: key}, spec)), slideClass),
          style: assign({}, child.props.style || {}, childStyle),
          onClick
        }));
      }
    }
  });

  if (spec.rtl) {
    return preCloneSlides.concat(slides, postCloneSlides).reverse();
  } else {
    return preCloneSlides.concat(slides, postCloneSlides);
  }
};

export class Track extends React.Component {
  render() {
    // var slides = renderSlides.call(this, this.props);
    var slides = renderSlides(this.props)
    return (

        { slides }

    );
  }
}
<|endoftext|>