[Pkg-javascript-commits] [libjs-jquery-selectize.js] 02/04: Imported Upstream version 0.12.3+dfsg

Sergio Durigan Junior sergiodj-guest at moszumanska.debian.org
Wed Aug 31 17:25:02 UTC 2016


This is an automated email from the git hooks/post-receive script.

sergiodj-guest pushed a commit to branch master
in repository libjs-jquery-selectize.js.

commit 293ef57c5730d60b442201ac64741505d1cbb516
Author: Sergio Durigan Junior <sergiodj at sergiodj.net>
Date:   Wed Aug 31 13:22:11 2016 -0400

    Imported Upstream version 0.12.3+dfsg
---
 .github/ISSUE_TEMPLATE.md           |  29 ++++--
 CHANGELOG.md                        |  16 ++++
 Gruntfile.js                        |  19 ++++
 Makefile                            |   3 +-
 README.md                           |  49 ++++++++--
 dist/css/selectize.bootstrap2.css   |   2 +-
 dist/css/selectize.bootstrap3.css   |   2 +-
 dist/css/selectize.css              |   2 +-
 dist/css/selectize.default.css      |   2 +-
 dist/css/selectize.legacy.css       |   2 +-
 dist/js/selectize.js                | 109 +++++++++++++++++----
 dist/js/standalone/selectize.js     | 109 +++++++++++++++++----
 dist/less/selectize.bootstrap2.less |   2 +-
 dist/less/selectize.bootstrap3.less |   2 +-
 dist/less/selectize.default.less    |   2 +-
 dist/less/selectize.legacy.less     |   2 +-
 docs/api.md                         |  61 +++++++-----
 docs/events.md                      |   2 +-
 docs/plugins.md                     |   4 +-
 docs/usage.md                       | 184 +++++++++++++++++++++++-------------
 examples/api.html                   |   2 +-
 examples/basic.html                 |   4 +-
 examples/cities.html                |   4 +-
 examples/confirm.html               |   4 +-
 examples/contacts.html              |   4 +-
 examples/create-filter.html         |   2 +-
 examples/customization.html         |  12 +--
 examples/dynamic.html               |   4 +-
 examples/events.html                |   2 +-
 examples/github.html                |   4 +-
 examples/lock.html                  |   2 +-
 examples/movies.html                |   4 +-
 examples/optgroups.html             |   4 +-
 examples/performance.html           |   2 +-
 examples/plugins.html               |   4 +-
 examples/required.html              |   7 +-
 examples/rtl.html                   |   4 +-
 package.json                        |   6 +-
 selectize.jquery.json               |   2 +-
 src/constants.js                    |   2 +-
 src/contrib/highlight.js            |  15 ++-
 src/selectize.js                    |  76 +++++++++++----
 src/utils.js                        |  14 +++
 test/interaction.js                 |  70 ++++++++++++--
 test/setup.js                       |  44 ++++++---
 45 files changed, 663 insertions(+), 238 deletions(-)

diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index fee9e9b..7e8f7dd 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -7,21 +7,34 @@ them.
 
 If you've never done so, please read the
 [guide to reporting issues](https://github.com/selectize/selectize.js/wiki/Reporting-issues-guide)
-in the Wiki to help us better understand your issue. Here's the gist:
+in the Wiki to help us better understand your issue.
 
-* Search for if your issue has already been submitted
-* Make sure you're reporting something precise that needs to be fixed
-* Give your issue a descriptive and concise title
-* Create a *minimal* working example
-* Indicate the steps to reproduce and result
-* Use proper formatting, especially for code
-* Help it be solved by finding the cause and proposing fixes
+Place an `x` in the checklist steps (`[ ]` becomes `[x]`) to demonstrate
+you have done/verified all the steps you needed to do.
 
 Thank you for reading this! You can now erase everything up to the
 following dashes, and then complete what's after.
 
+ISSUES THAT EITHER:
+
+* IGNORE THE ISSUE GUIDELINES
+* ERASE THE FOLLOWING TEMPLATE
+* DON'T FOLLOW THE PROPER NUMBERED FORMAT FOR STEPS TO REPRODUCE
+
+COULD BE CLOSED.
+
 ---
 
+I did:
+
+* [ ] Search for if my issue has already been submitted
+* [ ] Make sure I'm reporting something precise that needs to be fixed
+* [ ] Give my issue a descriptive and concise title
+* [ ] Create a *minimal* working example on JsFiddle or Codepen
+	(or gave a link to a demo on the Selectize docs)
+* [ ] Indicate *precise* steps to reproduce in *numbers* and the result,
+	  like below
+
 [replace me with a short description of issue]
 
 Steps to reproduce:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8bd81c1..8c72eeb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,17 @@
+*  Output friendly error message when Microplguin is missing (#1137).
+   Special thanks to @styxxx for proposing the improvement.
+
+   *Jonathan Allard* (@joallard)
+
+*  Fix open keyboard bug under iOS after closing selection (#1127)
+
+   *@zeitiger*
+
+*  Fix highlighting more than one character (#1099, #1098)
+
+   *@skimi*
+
+
 ## v0.12.2 · 23 June 2016
 *  Fix issue preventing build ("Cannot assign to read only property
    'subarray'") because of bug in uglifyjs. (#1072)
@@ -22,3 +36,5 @@
 
 *  Functions in option `render` can now return a DOM node in addition to
    text. (#617)
+
+   *@topaxi*
diff --git a/Gruntfile.js b/Gruntfile.js
index 8b2af86..44356a5 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -5,8 +5,10 @@ module.exports = function(grunt) {
 	grunt.loadNpmTasks('grunt-contrib-uglify');
 	grunt.loadNpmTasks('grunt-contrib-concat');
 	grunt.loadNpmTasks('grunt-contrib-clean');
+	grunt.loadNpmTasks('grunt-contrib-connect');
 	grunt.loadNpmTasks('grunt-contrib-copy');
 	grunt.loadNpmTasks('grunt-contrib-less');
+	grunt.loadNpmTasks('grunt-contrib-watch');
 	grunt.loadNpmTasks('grunt-replace');
 
 	grunt.registerTask('configure', [
@@ -33,6 +35,11 @@ module.exports = function(grunt) {
 		'compile'
 	]);
 
+	grunt.registerTask('serve', [
+			'connect',
+			'watch'
+	])
+
 	grunt.registerTask('clean_bootstrap2_css', 'Cleans CSS rules ocurring before the header comment.', function() {
 		var file = 'dist/css/selectize.bootstrap2.css';
 		var source = fs.readFileSync(file, 'utf8');
@@ -202,6 +209,9 @@ module.exports = function(grunt) {
 				}
 			}
 		},
+		connect: {
+			keepalive: true
+		},
 		uglify: {
 			main: {
 				options: {
@@ -214,6 +224,15 @@ module.exports = function(grunt) {
 					'dist/js/standalone/selectize.min.js': ['dist/js/standalone/selectize.js']
 				}
 			}
+		},
+		watch: {
+			files: [
+				'src/**/*.js'
+			],
+			tasks: [
+				'concat:js',
+				'build_standalone'
+			]
 		}
 	});
 };
diff --git a/Makefile b/Makefile
index 3dcc4bf..ace646c 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,6 @@ ifeq ($(strip $(version)),)
 	@echo "\033[1;30mmake release version=1.0.0\033[0;39m"
 else
 	sed -i.bak 's/"version": "[^"]*"/"version": "$(version)"/' selectize.jquery.json
-	sed -i.bak 's/"version": "[^"]*"/"version": "$(version)"/' bower.json
 	sed -i.bak 's/"version": "[^"]*"/"version": "$(version)"/' package.json
 	rm *.bak
 	make compile
@@ -31,4 +30,4 @@ else
 	git push origin gh-pages
 	git checkout master
 	@echo "\033[32mv${version} released\033[0;39m"
-endif
\ No newline at end of file
+endif
diff --git a/README.md b/README.md
index 08fb520..1ea2fdf 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,6 @@
-[**Selectize needs your help. I'm looking for maintainers!**](https://github.com/selectize/selectize.js/issues/752)
-
 # selectize.js
 
 [![NPM version](http://img.shields.io/npm/v/selectize.svg?style=flat)](https://www.npmjs.org/package/selectize)
-![Bower version](http://img.shields.io/bower/v/selectize.svg?style=flat)
 [![Build Status](http://img.shields.io/travis/selectize/selectize.js/master.svg?style=flat)](https://travis-ci.org/selectize/selectize.js)
 [![Coverage Status](http://img.shields.io/coveralls/selectize/selectize.js/master.svg?style=flat)](https://coveralls.io/r/selectize/selectize.js)
 
@@ -35,9 +32,17 @@ Selectize is an extensible [jQuery](http://jquery.com/)-based custom <select&
 - [sifter](https://github.com/brianreavis/sifter.js) (bundled in ["standalone" build](dist/js/standalone))
 - [microplugin](https://github.com/brianreavis/microplugin.js) (bundled in ["standalone" build](dist/js/standalone))
 
-### Files
+### Installation and files
+
+All pre-built files needed to use Selectize can be found in the
+["dist"](dist/) folder.
+
+If you're looking to get started with minimal fuss, include
+`standalone/selectize.min.js` (bundles Sifter and Microplugin
+dependencies – also available un-minifed for debugging, just remove the
+`.min` part) and `css/selectize.default.css`.
 
-All pre-built files needed to use Selectize can be found in the ["dist"](dist/) folder.
+Selectize is available at [cdnjs](https://cdnjs.com/libraries/selectize.js).
 
 - [**js/**](dist/js)
 	- [**standalone/**](dist/js/standalone)
@@ -86,10 +91,15 @@ grunt --plugins=remove_button,restore_on_backspace
 ```
 
 ### Contributing
+When issuing a pull request:
 
-When issuing a pull request, *please exclude changes in the "dist"
-folder to avoid merge conflicts*. Please include tests with your feature
-so that we're not tempted to break it in the future!
+* please **do not include/commit changes in the `dist/` folder** to avoid
+  merge conflicts.  A good way to include the right files is to use
+  `git gui` or `git add` when committing to select the files you want to
+  add to your commit.
+
+* please **include tests** with your feature so that we're not tempted to
+  break it in the future!
 
 Add an entry to the top of the CHANGELOG, and update the documentation
 in `docs/` as needed. (Refactors and documentation changes don't need a
@@ -100,7 +110,15 @@ with a concise and descriptive message. One commit means one
 feature/bugfix/thing that has changed, or a diff bringing the code one
 step forward to a better, working state.
 
-Also, please ensure all the tests pass:
+Once your commit is nice and clean, and you want to *discard the other
+changes*, you can use `git checkout .` (that will erase changes to
+tracked files) and `git clean [-i/--interactive]` (to erase untracked
+files).  **However, be careful with those commands, as their function
+is to erase things/changes.**
+
+
+#### Tests
+Please ensure all the tests pass:
 
 ```sh
 $ npm test # phantomjs
@@ -109,6 +127,19 @@ $ BROWSERS=Firefox,Chrome npm test
 $ BROWSERS=Firefox,Chrome,Safari npm test
 ```
 
+#### Local environment
+To run Selectize locally:
+
+```sh
+$ grunt serve
+```
+
+You can then run the examples in `http://localhost:8000/examples/`.
+
+However, be careful not to add the `dist/` files in your commit, as
+Grunt automatically regenerates the files in `dist/` as the source is
+changed.
+
 ## License
 
 Copyright © 2013–2016 [Brian Reavis](http://twitter.com/brianreavis) & [Contributors](https://github.com/selectize/selectize.js/graphs/contributors)
diff --git a/dist/css/selectize.bootstrap2.css b/dist/css/selectize.bootstrap2.css
index 3da0e66..f935217 100644
--- a/dist/css/selectize.bootstrap2.css
+++ b/dist/css/selectize.bootstrap2.css
@@ -1,5 +1,5 @@
 /**
- * selectize.bootstrap2.css (v0.12.2) - Bootstrap 2 Theme
+ * selectize.bootstrap2.css (v0.12.3) - Bootstrap 2 Theme
  * Copyright (c) 2013–2015 Brian Reavis & contributors
  *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
diff --git a/dist/css/selectize.bootstrap3.css b/dist/css/selectize.bootstrap3.css
index c5a8510..30d0ae4 100644
--- a/dist/css/selectize.bootstrap3.css
+++ b/dist/css/selectize.bootstrap3.css
@@ -1,5 +1,5 @@
 /**
- * selectize.bootstrap3.css (v0.12.2) - Bootstrap 3 Theme
+ * selectize.bootstrap3.css (v0.12.3) - Bootstrap 3 Theme
  * Copyright (c) 2013–2015 Brian Reavis & contributors
  *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
diff --git a/dist/css/selectize.css b/dist/css/selectize.css
index a763839..63f526c 100644
--- a/dist/css/selectize.css
+++ b/dist/css/selectize.css
@@ -1,5 +1,5 @@
 /**
- * selectize.css (v0.12.2)
+ * selectize.css (v0.12.3)
  * Copyright (c) 2013–2015 Brian Reavis & contributors
  *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
diff --git a/dist/css/selectize.default.css b/dist/css/selectize.default.css
index 4e4a7a1..b4d4710 100644
--- a/dist/css/selectize.default.css
+++ b/dist/css/selectize.default.css
@@ -1,5 +1,5 @@
 /**
- * selectize.default.css (v0.12.2) - Default Theme
+ * selectize.default.css (v0.12.3) - Default Theme
  * Copyright (c) 2013–2015 Brian Reavis & contributors
  *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
diff --git a/dist/css/selectize.legacy.css b/dist/css/selectize.legacy.css
index dea631c..d4ad422 100644
--- a/dist/css/selectize.legacy.css
+++ b/dist/css/selectize.legacy.css
@@ -1,5 +1,5 @@
 /**
- * selectize.legacy.css (v0.12.2) - Default Theme
+ * selectize.legacy.css (v0.12.3) - Default Theme
  * Copyright (c) 2013–2015 Brian Reavis & contributors
  *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
diff --git a/dist/js/selectize.js b/dist/js/selectize.js
index ce28377..2aa5c96 100644
--- a/dist/js/selectize.js
+++ b/dist/js/selectize.js
@@ -1,5 +1,5 @@
 /**
- * selectize.js (v0.12.2)
+ * selectize.js (v0.12.3)
  * Copyright (c) 2013–2015 Brian Reavis & contributors
  *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
@@ -60,6 +60,20 @@
 		});
 	};
 	
+	/**
+	 * removeHighlight fn copied from highlight v5 and
+	 * edited to remove with() and pass js strict mode
+	 */
+	jQuery.fn.removeHighlight = function() {
+		return this.find("span.highlight").each(function() {
+			this.parentNode.firstChild.nodeName;
+			var parent = this.parentNode;
+			parent.replaceChild(this.firstChild, this);
+			parent.normalize();
+		}).end();
+	};
+	
+	
 	var MicroEvent = function() {};
 	MicroEvent.prototype = {
 		on: function(event, fct){
@@ -122,7 +136,8 @@
 	var TAG_INPUT     = 2;
 	
 	// for now, android support in general is too spotty to support validity
-	var SUPPORTS_VALIDITY_API = !/android/i.test(window.navigator.userAgent) && !!document.createElement('form').validity;
+	var SUPPORTS_VALIDITY_API = !/android/i.test(window.navigator.userAgent) && !!document.createElement('input').validity;
+	
 	
 	var isset = function(object) {
 		return typeof object !== 'undefined';
@@ -452,6 +467,20 @@
 		return tmp.innerHTML;
 	};
 	
+	var logError = function(message, options){
+		if(!options) options = {};
+		var component = "Selectize";
+	
+		console.error(component + ": " + message)
+	
+		if(options.explanation){
+			// console.group is undefined in <IE11
+			if(console.group) console.group();
+			console.error(options.explanation);
+			if(console.group) console.groupEnd();
+		}
+	}
+	
 	
 	var Selectize = function($input, settings) {
 		var key, i, n, dir, input, self = this;
@@ -541,7 +570,18 @@
 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 	
 	MicroEvent.mixin(Selectize);
-	MicroPlugin.mixin(Selectize);
+	
+	if(typeof MicroPlugin !== "undefined"){
+		MicroPlugin.mixin(Selectize);
+	}else{
+		logError("Dependency MicroPlugin is missing",
+			{explanation:
+				"Make sure you either: (1) are using the \"standalone\" "+
+				"version of Selectize, or (2) require MicroPlugin before you "+
+				"load Selectize."}
+		);
+	}
+	
 	
 	// methods
 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -570,6 +610,7 @@
 			var timeout_focus;
 			var classes;
 			var classes_plugins;
+			var inputId;
 	
 			inputMode         = self.settings.mode;
 			classes           = $input.attr('class') || '';
@@ -581,6 +622,11 @@
 			$dropdown         = $('<div>').addClass(settings.dropdownClass).addClass(inputMode).hide().appendTo($dropdown_parent);
 			$dropdown_content = $('<div>').addClass(settings.dropdownContentClass).appendTo($dropdown);
 	
+			if(inputId = $input.attr('id')) {
+				$control_input.attr('id', inputId + '-selectized');
+				$("label[for='"+inputId+"']").attr('for', inputId + '-selectized');
+			}
+	
 			if(self.settings.copyClassesToDropdown) {
 				$dropdown.addClass(classes);
 			}
@@ -856,19 +902,26 @@
 		 */
 		onPaste: function(e) {
 			var self = this;
+	
 			if (self.isFull() || self.isInputHidden || self.isLocked) {
 				e.preventDefault();
-			} else {
-				// If a regex or string is included, this will split the pasted
-				// input and create Items for each separate value
-				if (self.settings.splitOn) {
-					setTimeout(function() {
-						var splitInput = $.trim(self.$control_input.val() || '').split(self.settings.splitOn);
-						for (var i = 0, n = splitInput.length; i < n; i++) {
-							self.createItem(splitInput[i]);
-						}
-					}, 0);
-				}
+				return;
+			}
+	
+			// If a regex or string is included, this will split the pasted
+			// input and create Items for each separate value
+			if (self.settings.splitOn) {
+	
+				// Wait for pasted text to be recognized in value
+				setTimeout(function() {
+					var pastedText = self.$control_input.val();
+					if(!pastedText.match(self.settings.splitOn)){ return }
+	
+					var splitInput = $.trim(pastedText).split(self.settings.splitOn);
+					for (var i = 0, n = splitInput.length; i < n; i++) {
+						self.createItem(splitInput[i]);
+					}
+				}, 0);
 			}
 		},
 	
@@ -1555,6 +1608,7 @@
 	
 			// highlight matching terms inline
 			if (self.settings.highlight && results.query.length && results.tokens.length) {
+				$dropdown_content.removeHighlight();
 				for (i = 0, n = results.tokens.length; i < n; i++) {
 					highlight($dropdown_content, results.tokens[i].regex);
 				}
@@ -2052,12 +2106,26 @@
 		 * and CSS classes.
 		 */
 		refreshState: function() {
-			var invalid, self = this;
-			if (self.isRequired) {
-				if (self.items.length) self.isInvalid = false;
-				self.$control_input.prop('required', invalid);
-			}
-			self.refreshClasses();
+			this.refreshValidityState();
+			this.refreshClasses();
+		},
+	
+		/**
+		 * Update the `required` attribute of both input and control input.
+		 *
+		 * The `required` property needs to be activated on the control input
+		 * for the error to be displayed at the right place. `required` also
+		 * needs to be temporarily deactivated on the input since the input is
+		 * hidden and can't show errors.
+		 */
+		refreshValidityState: function() {
+			if (!this.isRequired) return false;
+	
+			var invalid = !this.items.length;
+	
+			this.isInvalid = invalid;
+			this.$control_input.prop('required', invalid);
+			this.$input.prop('required', !invalid);
 		},
 	
 		/**
@@ -2168,6 +2236,7 @@
 	
 			if (self.settings.mode === 'single' && self.items.length) {
 				self.hideInput();
+				self.$control_input.blur(); // close keyboard on iOS
 			}
 	
 			self.isOpen = false;
diff --git a/dist/js/standalone/selectize.js b/dist/js/standalone/selectize.js
index 26a50ad..e07d88f 100644
--- a/dist/js/standalone/selectize.js
+++ b/dist/js/standalone/selectize.js
@@ -635,7 +635,7 @@
 }));
 
 /**
- * selectize.js (v0.12.2)
+ * selectize.js (v0.12.3)
  * Copyright (c) 2013–2015 Brian Reavis & contributors
  *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
@@ -696,6 +696,20 @@
 		});
 	};
 	
+	/**
+	 * removeHighlight fn copied from highlight v5 and
+	 * edited to remove with() and pass js strict mode
+	 */
+	jQuery.fn.removeHighlight = function() {
+		return this.find("span.highlight").each(function() {
+			this.parentNode.firstChild.nodeName;
+			var parent = this.parentNode;
+			parent.replaceChild(this.firstChild, this);
+			parent.normalize();
+		}).end();
+	};
+	
+	
 	var MicroEvent = function() {};
 	MicroEvent.prototype = {
 		on: function(event, fct){
@@ -758,7 +772,8 @@
 	var TAG_INPUT     = 2;
 	
 	// for now, android support in general is too spotty to support validity
-	var SUPPORTS_VALIDITY_API = !/android/i.test(window.navigator.userAgent) && !!document.createElement('form').validity;
+	var SUPPORTS_VALIDITY_API = !/android/i.test(window.navigator.userAgent) && !!document.createElement('input').validity;
+	
 	
 	var isset = function(object) {
 		return typeof object !== 'undefined';
@@ -1088,6 +1103,20 @@
 		return tmp.innerHTML;
 	};
 	
+	var logError = function(message, options){
+		if(!options) options = {};
+		var component = "Selectize";
+	
+		console.error(component + ": " + message)
+	
+		if(options.explanation){
+			// console.group is undefined in <IE11
+			if(console.group) console.group();
+			console.error(options.explanation);
+			if(console.group) console.groupEnd();
+		}
+	}
+	
 	
 	var Selectize = function($input, settings) {
 		var key, i, n, dir, input, self = this;
@@ -1177,7 +1206,18 @@
 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 	
 	MicroEvent.mixin(Selectize);
-	MicroPlugin.mixin(Selectize);
+	
+	if(typeof MicroPlugin !== "undefined"){
+		MicroPlugin.mixin(Selectize);
+	}else{
+		logError("Dependency MicroPlugin is missing",
+			{explanation:
+				"Make sure you either: (1) are using the \"standalone\" "+
+				"version of Selectize, or (2) require MicroPlugin before you "+
+				"load Selectize."}
+		);
+	}
+	
 	
 	// methods
 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -1206,6 +1246,7 @@
 			var timeout_focus;
 			var classes;
 			var classes_plugins;
+			var inputId;
 	
 			inputMode         = self.settings.mode;
 			classes           = $input.attr('class') || '';
@@ -1217,6 +1258,11 @@
 			$dropdown         = $('<div>').addClass(settings.dropdownClass).addClass(inputMode).hide().appendTo($dropdown_parent);
 			$dropdown_content = $('<div>').addClass(settings.dropdownContentClass).appendTo($dropdown);
 	
+			if(inputId = $input.attr('id')) {
+				$control_input.attr('id', inputId + '-selectized');
+				$("label[for='"+inputId+"']").attr('for', inputId + '-selectized');
+			}
+	
 			if(self.settings.copyClassesToDropdown) {
 				$dropdown.addClass(classes);
 			}
@@ -1492,19 +1538,26 @@
 		 */
 		onPaste: function(e) {
 			var self = this;
+	
 			if (self.isFull() || self.isInputHidden || self.isLocked) {
 				e.preventDefault();
-			} else {
-				// If a regex or string is included, this will split the pasted
-				// input and create Items for each separate value
-				if (self.settings.splitOn) {
-					setTimeout(function() {
-						var splitInput = $.trim(self.$control_input.val() || '').split(self.settings.splitOn);
-						for (var i = 0, n = splitInput.length; i < n; i++) {
-							self.createItem(splitInput[i]);
-						}
-					}, 0);
-				}
+				return;
+			}
+	
+			// If a regex or string is included, this will split the pasted
+			// input and create Items for each separate value
+			if (self.settings.splitOn) {
+	
+				// Wait for pasted text to be recognized in value
+				setTimeout(function() {
+					var pastedText = self.$control_input.val();
+					if(!pastedText.match(self.settings.splitOn)){ return }
+	
+					var splitInput = $.trim(pastedText).split(self.settings.splitOn);
+					for (var i = 0, n = splitInput.length; i < n; i++) {
+						self.createItem(splitInput[i]);
+					}
+				}, 0);
 			}
 		},
 	
@@ -2191,6 +2244,7 @@
 	
 			// highlight matching terms inline
 			if (self.settings.highlight && results.query.length && results.tokens.length) {
+				$dropdown_content.removeHighlight();
 				for (i = 0, n = results.tokens.length; i < n; i++) {
 					highlight($dropdown_content, results.tokens[i].regex);
 				}
@@ -2688,12 +2742,26 @@
 		 * and CSS classes.
 		 */
 		refreshState: function() {
-			var invalid, self = this;
-			if (self.isRequired) {
-				if (self.items.length) self.isInvalid = false;
-				self.$control_input.prop('required', invalid);
-			}
-			self.refreshClasses();
+			this.refreshValidityState();
+			this.refreshClasses();
+		},
+	
+		/**
+		 * Update the `required` attribute of both input and control input.
+		 *
+		 * The `required` property needs to be activated on the control input
+		 * for the error to be displayed at the right place. `required` also
+		 * needs to be temporarily deactivated on the input since the input is
+		 * hidden and can't show errors.
+		 */
+		refreshValidityState: function() {
+			if (!this.isRequired) return false;
+	
+			var invalid = !this.items.length;
+	
+			this.isInvalid = invalid;
+			this.$control_input.prop('required', invalid);
+			this.$input.prop('required', !invalid);
 		},
 	
 		/**
@@ -2804,6 +2872,7 @@
 	
 			if (self.settings.mode === 'single' && self.items.length) {
 				self.hideInput();
+				self.$control_input.blur(); // close keyboard on iOS
 			}
 	
 			self.isOpen = false;
diff --git a/dist/less/selectize.bootstrap2.less b/dist/less/selectize.bootstrap2.less
index 1fef848..fb686dd 100644
--- a/dist/less/selectize.bootstrap2.less
+++ b/dist/less/selectize.bootstrap2.less
@@ -1,5 +1,5 @@
 /**
- * selectize.bootstrap2.css (v0.12.2) - Bootstrap 2 Theme
+ * selectize.bootstrap2.css (v0.12.3) - Bootstrap 2 Theme
  * Copyright (c) 2013–2015 Brian Reavis & contributors
  *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
diff --git a/dist/less/selectize.bootstrap3.less b/dist/less/selectize.bootstrap3.less
index 813e2d8..69541b2 100644
--- a/dist/less/selectize.bootstrap3.less
+++ b/dist/less/selectize.bootstrap3.less
@@ -1,5 +1,5 @@
 /**
- * selectize.bootstrap3.css (v0.12.2) - Bootstrap 3 Theme
+ * selectize.bootstrap3.css (v0.12.3) - Bootstrap 3 Theme
  * Copyright (c) 2013–2015 Brian Reavis & contributors
  *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
diff --git a/dist/less/selectize.default.less b/dist/less/selectize.default.less
index 25faa8f..319b311 100644
--- a/dist/less/selectize.default.less
+++ b/dist/less/selectize.default.less
@@ -1,5 +1,5 @@
 /**
- * selectize.default.css (v0.12.2) - Default Theme
+ * selectize.default.css (v0.12.3) - Default Theme
  * Copyright (c) 2013–2015 Brian Reavis & contributors
  *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
diff --git a/dist/less/selectize.legacy.less b/dist/less/selectize.legacy.less
index 82c422a..395855f 100644
--- a/dist/less/selectize.legacy.less
+++ b/dist/less/selectize.legacy.less
@@ -1,5 +1,5 @@
 /**
- * selectize.legacy.css (v0.12.2) - Default Theme
+ * selectize.legacy.css (v0.12.3) - Default Theme
  * Copyright (c) 2013–2015 Brian Reavis & contributors
  *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
diff --git a/docs/api.md b/docs/api.md
index c767acb..5ac0706 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -1,12 +1,12 @@
 ## Selectize API
 
 Selectize controls can be controlled programmatically via the methods described in this section.
-When initializing the control, the "selectize" property is
+When initializing the control, the `selectize` property is
 added on the original <select> / <input> element—this
 property points to the underlying Selectize instance.
 
 ```js
-// initialize the selectize control
+// initialize the Selectize control
 var $select = $('select').selectize(options);
 
 // fetch the instance
@@ -70,22 +70,25 @@ var selectize = $select[0].selectize;
 	</tr>
 	<tr>
 		<td valign="top"><code>getAdjacentOption(value, direction)</code></td>
-		<td valign="top">Retrieves the jQuery element for the previous or next option, relative to the currently highlighted option. The "direction" argument should be 1 for "next" or -1 for "previous".</td>
+		<td valign="top">Retrieves the jQuery element for the previous or next option, relative to the currently highlighted option. The <code>direction</code> argument should be 1 for "next" or -1 for "previous".</td>
 	</tr>
 	<tr>
 		<td valign="top"><code>refreshOptions(triggerDropdown)</code></td>
 		<td valign="top">Refreshes the list of available options shown in the autocomplete dropdown menu.</td>
 	</tr>
+
+
 	<tr>
 		<th valign="top" colspan="3" align="left"><a href="#methods_items" name="methods_items">Items</a></th>
 	</tr>
+
 	<tr>
 		<th valign="top" width="120px" align="left">Method</th>
 		<th valign="top" align="left">Description</th>
 	</tr>
 	<tr>
 		<td valign="top"><code>clear(silent)</code></td>
-		<td valign="top">Resets / clears all selected items from the control. If "silent" is truthy, no change event will be fired on the original input.</td>
+		<td valign="top">Resets / clears all selected items from the control. If <code>silent</code> is truthy, no change event will be fired on the original input.</td>
 	</tr>
 	<tr>
 		<td valign="top"><code>getItem(value)</code></td>
@@ -93,39 +96,42 @@ var selectize = $select[0].selectize;
 	</tr>
 	<tr>
 		<td valign="top"><code>addItem(value, silent)</code></td>
-		<td valign="top">"Selects" an item. Adds it to the list at the current caret position. If "silent" is truthy, no change event will be fired on the original input.</td>
+		<td valign="top">"Selects" an item. Adds it to the list at the current caret position. If <code>silent</code> is truthy, no change event will be fired on the original input.</td>
 	</tr>
 	<tr>
 		<td valign="top"><code>removeItem(value, silent)</code></td>
-		<td valign="top">Removes the selected item matching the provided value. If "silent" is truthy, no change event will be fired on the original input.</td>
+		<td valign="top">Removes the selected item matching the provided value. If <code>silent</code> is truthy, no change event will be fired on the original input.</td>
 	</tr>
 	<tr>
 		<td valign="top"><code>createItem(value, [triggerDropdown], [callback])</code></td>
-		<td valign="top">Invokes the "create" method provided in the selectize options that should provide the data for the new item, given the user input. Once this completes, it will be added to the item list.</td>
+		<td valign="top">Invokes the <code>create</code> method provided in the Selectize settings that should provide the data for the new item, given the user input. Once this completes, it will be added to the item list.</td>
 	</tr>
 	<tr>
 		<td valign="top"><code>refreshItems()</code></td>
 		<td valign="top">Re-renders the selected item lists.</td>
 	</tr>
+
+
 	<tr>
 		<th valign="top" colspan="3" align="left"><a href="#methods_items" name="methods_optgroups">Optgroups</a></th>
 	</tr>
+
 	<tr>
 		<th valign="top" width="120px" align="left">Method</th>
 		<th valign="top" align="left">Description</th>
 	</tr>
 	<tr>
 		<td valign="top"><code>addOptionGroup(id, data)</code></td>
-		<td valign="top">Registers a new optgroup for options to be bucketed into. The "id" argument refers to a value of the property in option identified by the "optgroupField" setting.</td>
+		<td valign="top">Registers a new optgroup for options to be bucketed into. The <code>id</code> argument refers to a value of the property in option identified by the <code>optgroupField</code> setting.</td>
+	</tr>
+	<tr>
+		<td valign="top"><code>removeOptionGroup(id)</code></td>
+		<td valign="top">Removes a single option group.</td>
+	</tr>
+	<tr>
+		<td valign="top"><code>clearOptionGroups()</code></td>
+		<td valign="top">Removes all existing option groups.</td>
 	</tr>
-    <tr>
-        <td valign="top"><code>removeOptionGroup(id)</code></td>
-        <td valign="top">Removes a single option group.</td>
-    </tr>
-    <tr>
-        <td valign="top"><code>clearOptionGroups()</code></td>
-        <td valign="top">Removes all existing option groups.</td>
-    </tr>
 	<tr>
 		<th valign="top" colspan="3" align="left"><a href="#methods_events" name="methods_events">Events</a></th>
 	</tr>
@@ -149,9 +155,12 @@ var selectize = $select[0].selectize;
 		<td valign="top"><code>trigger(event, ...)</code></td>
 		<td valign="top">Triggers event listeners.</td>
 	</tr>
+
+
 	<tr>
 		<th valign="top" colspan="3" align="left"><a href="#methods_dropdown" name="methods_dropdown">Dropdown</a></th>
 	</tr>
+
 	<tr>
 		<th valign="top" width="120px" align="left">Method</th>
 		<th valign="top" align="left">Description</th>
@@ -168,9 +177,12 @@ var selectize = $select[0].selectize;
 		<td valign="top"><code>positionDropdown()</code></td>
 		<td valign="top">Calculates and applies the appropriate position of the dropdown.</td>
 	</tr>
+
+
 	<tr>
 		<th valign="top" colspan="3" align="left"><a href="#methods_other" name="methods_other">Other</a></th>
 	</tr>
+
 	<tr>
 		<th valign="top" width="120px" align="left">Method</th>
 		<th valign="top" align="left">Description</th>
@@ -181,7 +193,7 @@ var selectize = $select[0].selectize;
 	</tr>
 	<tr>
 		<td valign="top"><code>load(fn)</code></td>
-		<td valign="top">Loads options by invoking the the provided function. The function should accept one argument (callback) and invoke the callback with the results once they are available.</td>
+		<td valign="top">Loads options by invoking the provided function. The function should accept one argument (callback) and invoke the callback with the results once they are available.</td>
 	</tr>
 	<tr>
 		<td valign="top"><code>focus()</code></td>
@@ -209,7 +221,7 @@ var selectize = $select[0].selectize;
 	</tr>
 	<tr>
 		<td valign="top"><code>getValue()</code></td>
-		<td valign="top">Returns the value of the control. If multiple items can be selected (e.g. <a href="usage.md#maxItems"><select multiple></a>, this returns an array. If only one item can be selected, this returns a string.</td>
+		<td valign="top">Returns the value of the control. If multiple items can be selected with a "select" input tag (e.g. <a href="usage.md#maxItems"><select multiple></a>), this returns an array. Otherwise, returns a string (separated by <code>delimiter</code> if "multiple").</td>
 	</tr>
 	<tr>
 		<td valign="top"><code>setValue(value, silent)</code></td>
@@ -217,7 +229,7 @@ var selectize = $select[0].selectize;
 	</tr>
 	<tr>
 		<td valign="top"><code>setCaret(index)</code></td>
-		<td valign="top">Moves the caret to the specified position ("index" being the index in the list of selected items).</td>
+		<td valign="top">Moves the caret to the specified position (<code>index</code> being the index in the list of selected items).</td>
 	</tr>
 	<tr>
 		<td valign="top"><code>isFull()</code></td>
@@ -225,7 +237,12 @@ var selectize = $select[0].selectize;
 	</tr>
 	<tr>
 		<td valign="top"><code>clearCache(template)</code></td>
-		<td valign="top">Clears the render cache. Takes an optional template argument (e.g. "option", "item") to clear only that cache.</td>
+		<td valign="top">Clears the render cache. Takes an optional template argument (e.g. <code>option</code> , <code>item</code>) to clear only that cache.</td>
+	</tr>
+	<tr>
+		<td valign="top"><code>updatePlaceholder()</code></td>
+		<td valign="top">When the `settings.placeholder` value is changed, the new placeholder will be displayed.</td>
+		<!-- Proposed change: accept an optional string. If given, just takes it to update the placeholder. Will avoid to refer to settings. -->
 	</tr>
 </table>
 
@@ -251,7 +268,7 @@ var selectize = $select[0].selectize;
 	</tr>
 	<tr>
 		<td valign="top"><code>tokens</code></td>
-		<td valign="top">An array containing parsed search tokens. A token is an object containing two properties: "string" and "regex".</td>
+		<td valign="top">An array containing parsed search tokens. A token is an object containing two properties: <code>string</code> and <code>regex</code> .</td>
 		<td valign="top"><code>array</code></td>
 	</tr>
 	<tr>
@@ -261,7 +278,7 @@ var selectize = $select[0].selectize;
 	</tr>
 	<tr>
 		<td valign="top"><code>items</code></td>
-		<td valign="top">A list of matched results. Each result is an object containing two properties: "score" and "id".</td>
+		<td valign="top">A list of matched results. Each result is an object containing two properties: <code>score</code> and <code>id</code> .</td>
 		<td valign="top"><code>array</code></td>
 	</tr>
 </table>
diff --git a/docs/events.md b/docs/events.md
index 9b03133..bf65d69 100644
--- a/docs/events.md
+++ b/docs/events.md
@@ -104,7 +104,7 @@ selectize.off('event_name', handler);
 	<tr>
 		<td valign="top"><code>"load"</code></td>
 		<td valign="top"><code>data</code></td>
-		<td valign="top">Invoked when new options have been loaded and added to the control (via the "load" option or "load" API method).</td>
+		<td valign="top">Invoked when new options have been loaded and added to the control (via the <code>load</code>  option or <code>load</code>  API method).</td>
 	</tr>
 	<tr>
 		<td valign="top"><code>"destroy"</code></td>
diff --git a/docs/plugins.md b/docs/plugins.md
index 092f775..1033981 100644
--- a/docs/plugins.md
+++ b/docs/plugins.md
@@ -23,7 +23,7 @@ complete control.
 ```js
 Selectize.define('plugin_name', function(options) {
 	// options: plugin-specific options
-	// this: selectize instance
+	// this: Selectize instance
 });
 ```
 
@@ -63,7 +63,7 @@ like so:
 Selectize.define('plugin_name', function(options) {
 	var self = this;
 
-	// override the setup method to add an extra "click" handler
+	// override the setup method to add an extra `click`  handler
 	this.setup = (function() {
 		var original = self.setup;
 		return function() {
diff --git a/docs/usage.md b/docs/usage.md
index 5b1488b..1b1936d 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -10,21 +10,43 @@ $(function() {
 </script>
 ```
 
-### Options
+### Glossary
+
+- Config / configuration: the initial settings of Selectize, given at initialization.
+- Settings: the current settings of Selectize, might be updated. Accessible with the `setting` property of the Selectize object.
+- Options: the list of objects to display.
+  Each object must have a property with an unique **value** to identify the option; the property name is defined by the `valueField` setting.
+  Option objects must also have a property with the **label** to display (as tag, in the drop down, etc.); the property name is defined by the `labelField` setting.
+  The options can have other properties, ignored, unless referenced by other settings, like `sortField` or `searchField`.
+- Items: the list of selected options. Or more exactly, the list of the values of the selected options.
+
+### Configuration
 
 <table width="100%">
 	<tr>
 		<th valign="top" colspan="4" align="left"><a href="#general" name="general">General</a></th>
 	</tr>
 	<tr>
-		<th valign="top" width="120px" align="left">Option</th>
+		<th valign="top" width="120px" align="left">Setting</th>
 		<th valign="top" align="left">Description</th>
 		<th valign="top" width="60px" align="left">Type</th>
 		<th valign="top" width="60px" align="left">Default</th>
 	</tr>
 	<tr>
 		<td valign="top"><code>options</code></td>
-		<td valign="top">An array of the initial available options. By default this is populated from the original input element.</td>
+		<td valign="top">
+			An array of the initial options available to select; array
+			of objects.
+
+			By default this is populated from the original input
+			element.  If your element is a <select> with
+			<option>s specified this property gets populated
+			automatically.
+
+			Setting this property is convenient if you have your data as
+			an array and want to automatically generate the
+			<option>s.
+		</td>
 		<td valign="top"><code>array</code></td>
 		<td valign="top"><code>[]</code></td>
 	</tr>
@@ -36,35 +58,41 @@ $(function() {
 	</tr>
 	<tr>
 		<td valign="top"><code>delimiter</code></td>
-		<td valign="top">The string to separate items by. This option is only used when Selectize is instantiated from a <input type="text"> element.</td>
+		<td valign="top">The string to separate items by. When typing an item in a multi-selection control allowing creation, then the delimiter, the item is added. If you paste delimiter-separated items in such control, the items are added at once. The delimiter is also used in the <code>getValue</code> API call on a text <input> tag to separate the multiple values.</td>
 		<td valign="top"><code>string</code></td>
 		<td valign="top"><code>','</code></td>
 	</tr>
 	<tr>
-		<td valign="top"><code>diacritics</code></td>
-		<td valign="top">Enable or disable international character support.</td>
-		<td valign="top"><code>boolean</code></td>
-		<td valign="top"><code>true</code></td>
-	</tr>
-	<tr>
 		<td valign="top"><code>create</code></td>
 		<td valign="top">
-			Allows the user to create a new items that aren't in the list of options. This option can be any of the following: "true", "false" (disabled), or a function to process input. The function can take one of two forms: synchronous (with signature <code>function(input){}</code> or asynchronous (with signature <code>function(input, callback)</code>. In the synchronous case, the function should <code>return</code> an object for the options (eg, with defaults: <code>return { 'value': value, ' [...]
-		<td valign="top"><code>mixed</code></td>
+			Allows the user to create new items that aren't in the
+			initial list of options. This setting can be any of the
+			following: <code>true</code>, <code>false</code> (disabled), or a function to
+			process input. The function can take one of two forms:
+			synchronous (with signature <code>function(input){}</code>
+			or asynchronous (with signature <code>function(input,
+			callback)</code>. In the synchronous case, the function
+			should <code>return</code> an object for the options (eg,
+			with defaults: <code>return { 'value': value, 'text': text
+			};</code>). The asynchronous version should invoke the
+			callback with the result in the same format as the object
+			above (eg, <code>callback( { 'value': value, 'text':
+			text});</code>)</td>
+		<td valign="top"><code>boolean/function</code></td>
 		<td valign="top"><code>false</code></td>
 	</tr>
 	<tr>
 		<td valign="top"><code>createOnBlur</code></td>
 		<td valign="top">
-			If true, when user exits the field (clicks outside of input or presses ESC) new option is created and selected (if `create`-option is enabled).
+			If true, when user exits the field (clicks outside of input), a new option is created and selected (if <code>create</code> setting is enabled).
 		<td valign="top"><code>boolean</code></td>
 		<td valign="top"><code>false</code></td>
 	</tr>
 	<tr>
 		<td valign="top"><code>createFilter</code></td>
 		<td valign="top">
-			Specifies a RegExp or String containing a regular expression that the current search filter must match to be allowed to be created.  May also be a predicate function that takes the filter text and returns whether it is allowed.</td>
-		<td valign="top"><code>mixed</code></td>
+			Specifies a RegExp or a string containing a regular expression that the current search filter must match to be allowed to be created. May also be a predicate function that takes the filter text and returns whether it is allowed.</td>
+		<td valign="top"><code>RegExp|string|function</code></td>
 		<td valign="top"><code>null</code></td>
 	</tr>
 	<tr>
@@ -93,7 +121,7 @@ $(function() {
 	</tr>
 	<tr name="maxItems">
 		<td valign="top"><code>maxItems</code></td>
-		<td valign="top">The max number of items the user can select.</td>
+		<td valign="top">The max number of items the user can select. 1 makes the control mono-selection, null allows an unlimited number of items.</td>
 		<td valign="top"><code>int</code></td>
 		<td valign="top"><code>1</code></td>
 	</tr>
@@ -103,15 +131,15 @@ $(function() {
 		<td valign="top"><code>boolean</code></td>
 		<td valign="top"><code>false</code></td>
 	</tr>
-    <tr>
-        <td valign="top"><code>closeAfterSelect</code></td>
-        <td valign="top">If true, the dropdown will be closed after a selection is made.</td>
-        <td valign="top"><code>boolean</code></td>
-        <td valign="top"><code>false</code></td>
-    </tr>
+	<tr>
+		<td valign="top"><code>closeAfterSelect</code></td>
+		<td valign="top">If true, the dropdown will be closed after a selection is made.</td>
+		<td valign="top"><code>boolean</code></td>
+		<td valign="top"><code>false</code></td>
+	</tr>
 	<tr>
 		<td valign="top"><code>allowEmptyOption</code></td>
-		<td valign="top">If true, Selectize will treat any options with a "" value like normal. This defaults to false to accomodate the common <select> practice of having the first empty option act as a placeholder.</td>
+		<td valign="top">If true, Selectize will treat any options with a "" value like normal. This defaults to false to accomodate the common <select> practice of having the first empty option to act as a placeholder.</td>
 		<td valign="top"><code>boolean</code></td>
 		<td valign="top"><code>false</code></td>
 	</tr>
@@ -123,7 +151,7 @@ $(function() {
 	</tr>
 	<tr>
 		<td valign="top"><code>loadThrottle</code></td>
-		<td valign="top">The number of milliseconds to wait before requesting options from the server or null. If null, throttling is disabled.</td>
+		<td valign="top">The number of milliseconds to wait before requesting options from the server or null. If null, throttling is disabled. Useful when loading options dynamically while the user types a search / filter expression.</td>
 		<td valign="top"><code>int</code></td>
 		<td valign="top"><code>300</code></td>
 	</tr>
@@ -134,20 +162,26 @@ $(function() {
 		<td valign="top"><code>'loading'</code></td>
 	</tr>
 	<tr>
+		<td valign="top"><code>placeholder</code></td>
+		<td valign="top">The placeholder of the control (displayed when nothing is selected / typed). Defaults to input element's placeholder, unless this one is specified.</td>
+		<td valign="top"><code>string</code></td>
+		<td valign="top"><code>undefined</code></td>
+	</tr>
+	<tr>
 		<td valign="top"><code>preload</code></td>
-		<td valign="top">If true, the "load" function will be called upon control initialization (with an empty search). Alternatively it can be set to "focus" to call the "load" function when control receives focus.</td>
+		<td valign="top">If true, the <code>load</code> function will be called upon control initialization (with an empty search). Alternatively it can be set to <code>'focus'</code> to call the <code>load</code> function when control receives focus.</td>
 		<td valign="top"><code>boolean/string</code></td>
 		<td valign="top"><code>false</code></td>
 	</tr>
 	<tr>
 		<td valign="top"><code>dropdownParent</code></td>
-		<td valign="top">The element the dropdown menu is appended to. This should be "body" or null. If null, the dropdown will be appended as a child of the selectize control.</td>
+		<td valign="top">The element the dropdown menu is appended to. This should be <code>'body'</code> or <code>null</code>. If null, the dropdown will be appended as a child of the Selectize control.</td>
 		<td valign="top"><code>string</code></td>
 		<td valign="top"><code>null</code></td>
 	</tr>
 	<tr>
 		<td valign="top"><code>addPrecedence</code></td>
-		<td valign="top">Sets if the "Add..." option should be the default selection in the dropdown.</td>
+		<td valign="top">If true, the "Add..." option is the default selection in the dropdown.</td>
 		<td valign="top"><code>boolean</code></td>
 		<td valign="top"><code>false</code></td>
 	</tr>
@@ -158,26 +192,42 @@ $(function() {
 		<td valign="top"><code>false</code></td>
 	</tr>
 	<tr>
+		<td valign="top"><code>diacritics</code></td>
+		<td valign="top">Enable or disable international character support.</td>
+		<td valign="top"><code>boolean</code></td>
+		<td valign="top"><code>true</code></td>
+	</tr>
+
+
+	<tr>
 		<th valign="top" colspan="4" align="left"><a href="#data_searching" name="data_searching">Data / Searching</a></th>
 	</tr>
+
 	<tr>
-		<th valign="top" align="left">Option</th>
+		<th valign="top" align="left">Setting</th>
 		<th valign="top" align="left">Description</th>
 		<th valign="top" align="left">Type</th>
 		<th valign="top" align="left">Default</th>
 	</tr>
+
 	<tr>
 		<td valign="top"><code>options</code></td>
-		<td valign="top">Options available to select; array of objects. If your element is a <select> with <option>s specified this property gets populated automatically. Setting this property is convenient if you have your data as an array and want to automatically generate the <option>s.</td>
+		<td valign="top">See above</td>
+		<td valign="top"><code>array</code></td>
+		<td valign="top"><code>[]</code></td>
+	</tr>
+	<tr>
+		<td valign="top"><code>optgroups</code></td>
+		<td valign="top">
+			Option groups that options will be bucketed into. If your
+			element is a <select> with <optgroup>s this
+			property gets populated automatically. Make sure each object
+			in the array has a property named whatever
+			<code>optgroupValueField</code> is set to.
+		</td>
 		<td valign="top"><code>array</code></td>
 		<td valign="top"><code>[]</code></td>
 	</tr>
-    <tr>
-        <td valign="top"><code>optgroups</code></td>
-        <td valign="top">Option groups that options will be bucketed into. If your element is a <select> with <optgroup>s this property gets populated automatically. Make sure each object in the array has a property named whatever "optgroupValueField" is set to.</td>
-        <td valign="top"><code>array</code></td>
-        <td valign="top"><code>[]</code></td>
-    </tr>
 	<tr>
 		<td valign="top"><code>dataAttr</code></td>
 		<td valign="top">The <option> attribute from which to read JSON data about the option.</td>
@@ -186,7 +236,7 @@ $(function() {
 	</tr>
 	<tr>
 		<td valign="top"><code>valueField</code></td>
-		<td valign="top">The name of the property to use as the "value" when an item is selected.</td>
+		<td valign="top">The name of the property to use as the <code>value</code> when an item is selected.</td>
 		<td valign="top"><code>string</code></td>
 		<td valign="top"><code>'value'</code></td>
 	</tr>
@@ -217,15 +267,11 @@ $(function() {
 	<tr>
 		<td valign="top"><code>sortField</code></td>
 		<td valign="top">
-			A single field or an array of fields to sort by. Each item in the array should be an object containing at
-			least a "field" property. Optionally, "direction" can be set to "asc" or "desc". The
-			order of the array defines the sort precedence.<br><br>
+			<p>A single field or an array of fields to sort by. Each item in the array should be an object containing at least a <code>field</code> property. Optionally, <code>direction</code> can be set to <code>'asc'</code> or <code>'desc'</code>. The order of the array defines the sort precedence.</p>
 
-			Unless present, a special "$score" field will be automatically added to the beginning
-			of the sort list. This will make results sorted primarily by match quality (descending).<br><br>
-			
+			<p>Unless present, a special `$score` field will be automatically added to the beginning of the sort list. This will make results sorted primarily by match quality (descending).</p>
 
-			You can override the "$score" function. For more information, see the <a href="https://github.com/brianreavis/sifter.js#sifterjs">sifter documentation</a>.
+			<p>You can override the `$score` function. For more information, see the <a href="https://github.com/brianreavis/sifter.js#sifterjs">sifter documentation</a>.</p>
 		</td>
 		<td valign="top"><code>string|array</code></td>
 		<td valign="top"><code>'$order'</code></td>
@@ -238,19 +284,19 @@ $(function() {
 	</tr>
 	<tr>
 		<td valign="top"><code>searchConjunction</td>
-		<td valign="top">When searching for multiple terms (separated by a space), this is the operator used. Can be "and" or "or".</td>
+		<td valign="top">When searching for multiple terms (separated by space), this is the operator used. Can be <code>'and'</code> or <code>'or'</code> .</td>
 		<td valign="top"><code>string</code></td>
 		<td valign="top"><code>'and'</code></td>
 	</tr>
 	<tr>
 		<td valign="top"><code>lockOptgroupOrder</td>
-		<td valign="top">If truthy, selectize will make all optgroups be in the same order as they were added (by the "$order" property). Otherwise, it will order based on the score of the results in each.</td>
+		<td valign="top">If truthy, Selectize will make all optgroups be in the same order as they were added (by the `$order` property). Otherwise, it will order based on the score of the results in each.</td>
 		<td valign="top"><code>boolean</code></td>
 		<td valign="top"><code>false</code></td>
 	</tr>
 	<tr>
 		<td valign="top"><code>copyClassesToDropdown</code></td>
-		<td valign="top">Copy the original input classes to the Dropdown element.</td>
+		<td valign="top">Copy the original input classes to the dropdown element.</td>
 		<td valign="top"><code>boolean</code></td>
 		<td valign="top"><code>true</code></td>
 	</tr>
@@ -258,20 +304,20 @@ $(function() {
 		<th valign="top" colspan="4" align="left"><a href="#callbacks" name="callbacks">Callbacks</a></th>
 	</tr>
 	<tr>
-		<th valign="top" align="left">Option</th>
+		<th valign="top" align="left">Setting</th>
 		<th valign="top" align="left">Description</th>
 		<th valign="top" align="left">Type</th>
 		<th valign="top" align="left">Default</th>
 	</tr>
 	<tr>
 		<td valign="top"><code>load(query, callback)</code></td>
-		<td valign="top">Invoked when new options should be loaded from the server.</td>
+		<td valign="top">Invoked when new options should be loaded from the server. Called with the current query string and a callback function to call with the results when they are loaded (or nothing when an error arises).</td>
 		<td valign="top"><code>function</code></td>
 		<td valign="top"><code>null</code></td>
 	</tr>
 	<tr>
 		<td valign="top"><code>score(search)</code></td>
-		<td valign="top">Overrides the scoring function used to sort available options. The provided function should return a <strong>function</strong> that returns a number greater than or equal to zero to represent the "score" of an item (the function's first argument). If 0, the option is declared not a match. The "search" argument is a <a href="#search">Search</a> object. For an example, see the <a href="https://github.com/brianreavis/selectize.js/blob/master/examples/github.html">"GitHub" [...]
+		<td valign="top">Overrides the scoring function used to sort available options. The provided function should return a <strong>function</strong> that returns a number greater than or equal to zero to represent the <code>score</code> of an item (the function's first argument). If 0, the option is declared not a match. The <code>search</code> argument is a <a href="#search">Search</a> object. For an example, see the <a href="https://github.com/brianreavis/selectize.js/blob/master/examples [...]
 		<td valign="top"><code>function</code></td>
 		<td valign="top"><code>null</code></td>
 	</tr>
@@ -281,18 +327,18 @@ $(function() {
 		<td valign="top"><code>function</code></td>
 		<td valign="top"><code>null</code></td>
 	</tr>
-    <tr>
-        <td valign="top"><code>onFocus()</code></td>
-        <td valign="top">Invoked when the control gains focus.</td>
-        <td valign="top"><code>function</code></td>
-        <td valign="top"><code>null</code></td>
-    </tr>
-    <tr>
-        <td valign="top"><code>onBlur()</code></td>
-        <td valign="top">Invoked when the control loses focus.</td>
-        <td valign="top"><code>function</code></td>
-        <td valign="top"><code>null</code></td>
-    </tr>
+	<tr>
+		<td valign="top"><code>onFocus()</code></td>
+		<td valign="top">Invoked when the control gains focus.</td>
+		<td valign="top"><code>function</code></td>
+		<td valign="top"><code>null</code></td>
+	</tr>
+	<tr>
+		<td valign="top"><code>onBlur()</code></td>
+		<td valign="top">Invoked when the control loses focus.</td>
+		<td valign="top"><code>function</code></td>
+		<td valign="top"><code>null</code></td>
+	</tr>
 	<tr>
 		<td valign="top"><code>onChange(value)</code></td>
 		<td valign="top">Invoked when the value of the control changes.</td>
@@ -355,7 +401,7 @@ $(function() {
 	</tr>
 	<tr>
 		<td valign="top"><code>onLoad(data)</code></td>
-		<td valign="top">Invoked when new options have been loaded and added to the control (via the "load" option or "load" API method).</td>
+		<td valign="top">Invoked when new options have been loaded and added to the control (via the <code>load</code> option or <code>load</code> API method).</td>
 		<td valign="top"><code>function</code></td>
 		<td valign="top"><code>null</code></td>
 	</tr>
@@ -366,11 +412,13 @@ $(function() {
 		<td valign="top"><code>render</code></td>
 		<td valign="top">
 			Custom rendering functions. Each function should accept two
-			arguments: "data" and "escape" and return HTML (string or
-			DOM element) with a single root element.
-			The "escape" argument is a function that takes a string and escapes all special HTML characters.
+			arguments: <code>data</code> and <code>escape</code> and return HTML (string
+			or DOM element) with a single root element.
+
+			The <code>escape</code> argument is a function that takes a string and
+			escapes all special HTML characters.
 			This is very important to use to prevent XSS vulnerabilities.
-            <table width="100%">
+			<table width="100%">
 				<tr>
 					<td valign="top"><code>option</code></td>
 					<td valign="top">An option in the dropdown list of available options.</td>
@@ -381,7 +429,7 @@ $(function() {
 				</tr>
 				<tr>
 					<td valign="top"><code>option_create</code></td>
-					<td valign="top">The "create new" option at the bottom of the dropdown. The data contains one property: "input" (which is what the user has typed).</td>
+					<td valign="top">The "create new" option at the bottom of the dropdown. The data contains one property: <code>input</code> (which is what the user has typed).</td>
 				</tr>
 				<tr>
 					<td valign="top"><code>optgroup_header</code></td>
@@ -389,7 +437,7 @@ $(function() {
 				</tr>
 				<tr>
 					<td valign="top"><code>optgroup</code></td>
-					<td valign="top">The wrapper for an optgroup. The "html" property in the data will be the raw html of the optgroup's header and options.</td>
+					<td valign="top">The wrapper for an optgroup. The <code>html</code> property in the data will be the raw html of the optgroup's header and options.</td>
 				</tr>
 			</table>
 		</td>
diff --git a/examples/api.html b/examples/api.html
index 21310c6..6fb456a 100644
--- a/examples/api.html
+++ b/examples/api.html
@@ -12,7 +12,7 @@
 		<link rel="stylesheet" href="css/normalize.css">
 		<link rel="stylesheet" href="css/stylesheet.css">
 		<!--[if IE 8]><script src="js/es5.js"></script><![endif]-->
-		<script src="js/jquery.js"></script>
+		<script src="js/jquery.min.js"></script>
 		<script src="../dist/js/standalone/selectize.js"></script>
 		<script src="js/index.js"></script>
 	</head>
diff --git a/examples/basic.html b/examples/basic.html
index 68ebbb8..f5bb40c 100644
--- a/examples/basic.html
+++ b/examples/basic.html
@@ -12,7 +12,7 @@
 		<link rel="stylesheet" href="css/normalize.css">
 		<link rel="stylesheet" href="css/stylesheet.css">
 		<!--[if IE 8]><script src="js/es5.js"></script><![endif]-->
-		<script src="js/jquery.js"></script>
+		<script src="js/jquery.min.js"></script>
 		<script src="../dist/js/standalone/selectize.js"></script>
 		<script src="js/index.js"></script>
 	</head>
@@ -489,4 +489,4 @@
 			</div>
 		</div>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/examples/cities.html b/examples/cities.html
index e8612c7..8429935 100644
--- a/examples/cities.html
+++ b/examples/cities.html
@@ -11,7 +11,7 @@
 		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1">
 		<link rel="stylesheet" href="css/normalize.css">
 		<link rel="stylesheet" href="css/stylesheet.css">
-		<script src="js/jquery.js"></script>
+		<script src="js/jquery.min.js"></script>
 		<script src="../dist/js/standalone/selectize.js"></script>
 		<script src="js/index.js"></script>
 		<style type="text/css">
@@ -142,4 +142,4 @@
 			</div>
 		</div>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/examples/confirm.html b/examples/confirm.html
index a7327fa..dc7ffb9 100644
--- a/examples/confirm.html
+++ b/examples/confirm.html
@@ -12,7 +12,7 @@
 		<link rel="stylesheet" href="css/normalize.css">
 		<link rel="stylesheet" href="css/stylesheet.css">
 		<!--[if IE 8]><script src="js/es5.js"></script><![endif]-->
-		<script src="js/jquery.js"></script>
+		<script src="js/jquery.min.js"></script>
 		<script src="../dist/js/standalone/selectize.js"></script>
 		<script src="js/index.js"></script>
 	</head>
@@ -38,4 +38,4 @@
 			</div>
 		</div>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/examples/contacts.html b/examples/contacts.html
index e5079d2..f0bd269 100644
--- a/examples/contacts.html
+++ b/examples/contacts.html
@@ -12,7 +12,7 @@
 		<link rel="stylesheet" href="css/normalize.css">
 		<link rel="stylesheet" href="css/stylesheet.css">
 		<!--[if IE 8]><script src="js/es5.js"></script><![endif]-->
-		<script src="js/jquery.js"></script>
+		<script src="js/jquery.min.js"></script>
 		<script src="../dist/js/standalone/selectize.js"></script>
 		<script src="js/index.js"></script>
 		<style type="text/css">
@@ -152,4 +152,4 @@
 			</div>
 		</div>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/examples/create-filter.html b/examples/create-filter.html
index b5f2807..3e57ecc 100644
--- a/examples/create-filter.html
+++ b/examples/create-filter.html
@@ -12,7 +12,7 @@
 		<link rel="stylesheet" href="css/normalize.css">
 		<link rel="stylesheet" href="css/stylesheet.css">
 		<!--[if IE 8]><script src="js/es5.js"></script><![endif]-->
-		<script src="js/jquery.js"></script>
+		<script src="js/jquery.min.js"></script>
 		<script src="../dist/js/standalone/selectize.js"></script>
 		<script src="js/index.js"></script>
 	</head>
diff --git a/examples/customization.html b/examples/customization.html
index ac080e7..b68d53b 100644
--- a/examples/customization.html
+++ b/examples/customization.html
@@ -12,22 +12,22 @@
 		<link rel="stylesheet" href="css/normalize.css">
 		<link rel="stylesheet" href="css/stylesheet.css">
 		<!--[if IE 8]><script src="js/es5.js"></script><![endif]-->
-		<script src="js/jquery.js"></script>
+		<script src="js/jquery.min.js"></script>
 		<script src="../dist/js/standalone/selectize.js"></script>
 		<script src="js/index.js"></script>
 		<style type="text/css">
-		.selectize-control.links .option .title {
+		.selectize-control .option .title {
 			display: block;
 		}
-		.selectize-control.links .option .url {
+		.selectize-control .option .url {
 			font-size: 12px;
 			display: block;
 			color: #a0a0a0;
 		}
-		.selectize-control.links .item a {
+		.selectize-control .item a {
 			color: #006ef5;
 		}
-		.selectize-control.links .item.active a {
+		.selectize-control .item.active a {
 			color: #303030;
 		}
 		</style>
@@ -79,4 +79,4 @@
 			</div>
 		</div>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/examples/dynamic.html b/examples/dynamic.html
index 31b7be9..e46132f 100644
--- a/examples/dynamic.html
+++ b/examples/dynamic.html
@@ -12,7 +12,7 @@
 		<link rel="stylesheet" href="css/normalize.css">
 		<link rel="stylesheet" href="css/stylesheet.css">
 		<!--[if IE 8]><script src="js/es5.js"></script><![endif]-->
-		<script src="js/jquery.js"></script>
+		<script src="js/jquery.min.js"></script>
 		<script src="../dist/js/standalone/selectize.js"></script>
 		<script src="js/index.js"></script>
 	</head>
@@ -45,4 +45,4 @@
 			</div>
 		</div>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/examples/events.html b/examples/events.html
index cb5afc1..2c5b79b 100644
--- a/examples/events.html
+++ b/examples/events.html
@@ -12,7 +12,7 @@
 		<link rel="stylesheet" href="css/normalize.css">
 		<link rel="stylesheet" href="css/stylesheet.css">
 		<!--[if IE 8]><script src="js/es5.js"></script><![endif]-->
-		<script src="js/jquery.js"></script>
+		<script src="js/jquery.min.js"></script>
 		<script src="../dist/js/standalone/selectize.js"></script>
 		<script src="js/index.js"></script>
 	</head>
diff --git a/examples/github.html b/examples/github.html
index ae70611..8cd2a6e 100644
--- a/examples/github.html
+++ b/examples/github.html
@@ -12,7 +12,7 @@
 		<link rel="stylesheet" href="css/normalize.css">
 		<link rel="stylesheet" href="css/stylesheet.css">
 		<!--[if IE 8]><script src="js/es5.js"></script><![endif]-->
-		<script src="js/jquery.js"></script>
+		<script src="js/jquery.min.js"></script>
 		<script src="../dist/js/standalone/selectize.js"></script>
 		<script src="js/index.js"></script>
 		<style type="text/css">
@@ -150,4 +150,4 @@
 			</div>
 		</div>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/examples/lock.html b/examples/lock.html
index dfa24d4..2003cfb 100644
--- a/examples/lock.html
+++ b/examples/lock.html
@@ -12,7 +12,7 @@
 		<link rel="stylesheet" href="css/normalize.css">
 		<link rel="stylesheet" href="css/stylesheet.css">
 		<!--[if IE 8]><script src="js/es5.js"></script><![endif]-->
-		<script src="js/jquery.js"></script>
+		<script src="js/jquery.min.js"></script>
 		<script src="../dist/js/standalone/selectize.js"></script>
 		<script src="js/index.js"></script>
 	</head>
diff --git a/examples/movies.html b/examples/movies.html
index 6b60a06..ed6fa1e 100644
--- a/examples/movies.html
+++ b/examples/movies.html
@@ -12,7 +12,7 @@
 		<link rel="stylesheet" href="css/normalize.css">
 		<link rel="stylesheet" href="css/stylesheet.css">
 		<!--[if IE 8]><script src="js/es5.js"></script><![endif]-->
-		<script src="js/jquery.js"></script>
+		<script src="js/jquery.min.js"></script>
 		<script src="../dist/js/standalone/selectize.js"></script>
 		<script src="js/index.js"></script>
 		<style type="text/css">
@@ -161,4 +161,4 @@
 			</div>
 		</div>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/examples/optgroups.html b/examples/optgroups.html
index 9d54af2..e247a3c 100644
--- a/examples/optgroups.html
+++ b/examples/optgroups.html
@@ -12,7 +12,7 @@
 		<link rel="stylesheet" href="css/normalize.css">
 		<link rel="stylesheet" href="css/stylesheet.css">
 		<!--[if IE 8]><script src="js/es5.js"></script><![endif]-->
-		<script src="js/jquery.js"></script>
+		<script src="js/jquery.min.js"></script>
 		<script src="../dist/js/standalone/selectize.js"></script>
 		<script src="js/index.js"></script>
 		<style type="text/css">
@@ -171,4 +171,4 @@
 			</div>
 		</div>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/examples/performance.html b/examples/performance.html
index d53c5fd..5052a77 100644
--- a/examples/performance.html
+++ b/examples/performance.html
@@ -12,7 +12,7 @@
 		<link rel="stylesheet" href="css/normalize.css">
 		<link rel="stylesheet" href="css/stylesheet.css">
 		<!--[if IE 8]><script src="js/es5.js"></script><![endif]-->
-		<script src="js/jquery.js"></script>
+		<script src="js/jquery.min.js"></script>
 		<script src="../dist/js/standalone/selectize.js"></script>
 		<script src="js/index.js"></script>
 	</head>
diff --git a/examples/plugins.html b/examples/plugins.html
index 8bd8447..06e7f37 100644
--- a/examples/plugins.html
+++ b/examples/plugins.html
@@ -12,7 +12,7 @@
 		<link rel="stylesheet" href="css/normalize.css">
 		<link rel="stylesheet" href="css/stylesheet.css">
 		<!--[if IE 8]><script src="js/es5.js"></script><![endif]-->
-		<script src="js/jquery.js"></script>
+		<script src="js/jquery.min.js"></script>
 		<script src="js/jqueryui.js"></script>
 		<script src="../dist/js/standalone/selectize.js"></script>
 		<script src="js/index.js"></script>
@@ -115,4 +115,4 @@
 			</div>
 		</div>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/examples/required.html b/examples/required.html
index 87b7c72..27c0c56 100644
--- a/examples/required.html
+++ b/examples/required.html
@@ -12,7 +12,7 @@
 		<link rel="stylesheet" href="css/normalize.css">
 		<link rel="stylesheet" href="css/stylesheet.css">
 		<!--[if IE 8]><script src="js/es5.js"></script><![endif]-->
-		<script src="js/jquery.js"></script>
+		<script src="js/jquery.min.js"></script>
 		<script src="../dist/js/standalone/selectize.js"></script>
 		<script src="js/index.js"></script>
 	</head>
@@ -25,7 +25,8 @@
 				<div class="control-group">
 					<form>
 						<label for="select-beast">Beast:</label>
-						<select id="select-beast" required class="demo-default" placeholder="Select a person...">
+						<select id="select-beast" required class="demo-default"
+							placeholder="Select a person..." name="beast">
 							<option value="">Select a person...</option>
 							<option value="4">Thomas Edison</option>
 							<option value="1">Nikola</option>
@@ -50,4 +51,4 @@
 
 		</div>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/examples/rtl.html b/examples/rtl.html
index ce5a152..f3608f7 100644
--- a/examples/rtl.html
+++ b/examples/rtl.html
@@ -12,7 +12,7 @@
 		<link rel="stylesheet" href="css/normalize.css">
 		<link rel="stylesheet" href="css/stylesheet.css">
 		<!--[if IE 8]><script src="js/es5.js"></script><![endif]-->
-		<script src="js/jquery.js"></script>
+		<script src="js/jquery.min.js"></script>
 		<script src="../dist/js/standalone/selectize.js"></script>
 		<script src="js/index.js"></script>
 	</head>
@@ -53,4 +53,4 @@
 
 		</div>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/package.json b/package.json
index 2998b55..9443846 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,7 @@
   ],
   "main": "dist/js/selectize.js",
   "description": "Selectize is a jQuery-based custom <select> UI control. Useful for tagging, contact lists, country selectors, etc.",
-  "version": "0.12.2",
+  "version": "0.12.3",
   "author": "Brian Reavis <brian at thirdroute.com>",
   "license": "Apache-2.0",
   "repository": {
@@ -29,9 +29,11 @@
     "grunt-cli": "^0.1.13",
     "grunt-contrib-clean": "0.5.x",
     "grunt-contrib-concat": "0.3.x",
+    "grunt-contrib-connect": "1.x",
     "grunt-contrib-copy": "0.4.x",
     "grunt-contrib-less": "~0.9.0",
     "grunt-contrib-uglify": "~1.0.1",
+    "grunt-contrib-watch": "1.x",
     "grunt-recess": "0.5.x",
     "grunt-replace": "0.4.x",
     "karma": "^0.12.31",
@@ -42,7 +44,7 @@
     "karma-firefox-launcher": "^0.1.4",
     "karma-mocha": "^0.1.10",
     "karma-mocha-reporter": "^0.3.1",
-    "karma-phantomjs-launcher": "^0.1.4",
+    "karma-phantomjs-launcher": "^1.0.1",
     "karma-safari-launcher": "^0.1.1",
     "karma-sauce-launcher": "^0.2.10"
   },
diff --git a/selectize.jquery.json b/selectize.jquery.json
index 38ffcbb..9314d26 100644
--- a/selectize.jquery.json
+++ b/selectize.jquery.json
@@ -1,6 +1,6 @@
 {
 	"name": "selectize",
-	"version": "0.12.2",
+	"version": "0.12.3",
 	"title": "Selectize.js",
 	"author": {
 		"name": "Brian Reavis",
diff --git a/src/constants.js b/src/constants.js
index b0ac720..ec3a37c 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -21,4 +21,4 @@ var TAG_SELECT    = 1;
 var TAG_INPUT     = 2;
 
 // for now, android support in general is too spotty to support validity
-var SUPPORTS_VALIDITY_API = !/android/i.test(window.navigator.userAgent) && !!document.createElement('form').validity;
\ No newline at end of file
+var SUPPORTS_VALIDITY_API = !/android/i.test(window.navigator.userAgent) && !!document.createElement('input').validity;
diff --git a/src/contrib/highlight.js b/src/contrib/highlight.js
index 888bc90..1cd13c5 100644
--- a/src/contrib/highlight.js
+++ b/src/contrib/highlight.js
@@ -36,4 +36,17 @@ var highlight = function($element, pattern) {
 	return $element.each(function() {
 		highlight(this);
 	});
-};
\ No newline at end of file
+};
+
+/**
+ * removeHighlight fn copied from highlight v5 and
+ * edited to remove with() and pass js strict mode
+ */
+jQuery.fn.removeHighlight = function() {
+	return this.find("span.highlight").each(function() {
+		this.parentNode.firstChild.nodeName;
+		var parent = this.parentNode;
+		parent.replaceChild(this.firstChild, this);
+		parent.normalize();
+	}).end();
+};
diff --git a/src/selectize.js b/src/selectize.js
index fac543c..eb5cfb0 100644
--- a/src/selectize.js
+++ b/src/selectize.js
@@ -86,7 +86,18 @@ var Selectize = function($input, settings) {
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
 MicroEvent.mixin(Selectize);
-MicroPlugin.mixin(Selectize);
+
+if(typeof MicroPlugin !== "undefined"){
+	MicroPlugin.mixin(Selectize);
+}else{
+	logError("Dependency MicroPlugin is missing",
+		{explanation:
+			"Make sure you either: (1) are using the \"standalone\" "+
+			"version of Selectize, or (2) require MicroPlugin before you "+
+			"load Selectize."}
+	);
+}
+
 
 // methods
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -115,6 +126,7 @@ $.extend(Selectize.prototype, {
 		var timeout_focus;
 		var classes;
 		var classes_plugins;
+		var inputId;
 
 		inputMode         = self.settings.mode;
 		classes           = $input.attr('class') || '';
@@ -126,6 +138,11 @@ $.extend(Selectize.prototype, {
 		$dropdown         = $('<div>').addClass(settings.dropdownClass).addClass(inputMode).hide().appendTo($dropdown_parent);
 		$dropdown_content = $('<div>').addClass(settings.dropdownContentClass).appendTo($dropdown);
 
+		if(inputId = $input.attr('id')) {
+			$control_input.attr('id', inputId + '-selectized');
+			$("label[for='"+inputId+"']").attr('for', inputId + '-selectized');
+		}
+
 		if(self.settings.copyClassesToDropdown) {
 			$dropdown.addClass(classes);
 		}
@@ -401,19 +418,26 @@ $.extend(Selectize.prototype, {
 	 */
 	onPaste: function(e) {
 		var self = this;
+
 		if (self.isFull() || self.isInputHidden || self.isLocked) {
 			e.preventDefault();
-		} else {
-			// If a regex or string is included, this will split the pasted
-			// input and create Items for each separate value
-			if (self.settings.splitOn) {
-				setTimeout(function() {
-					var splitInput = $.trim(self.$control_input.val() || '').split(self.settings.splitOn);
-					for (var i = 0, n = splitInput.length; i < n; i++) {
-						self.createItem(splitInput[i]);
-					}
-				}, 0);
-			}
+			return;
+		}
+
+		// If a regex or string is included, this will split the pasted
+		// input and create Items for each separate value
+		if (self.settings.splitOn) {
+
+			// Wait for pasted text to be recognized in value
+			setTimeout(function() {
+				var pastedText = self.$control_input.val();
+				if(!pastedText.match(self.settings.splitOn)){ return }
+
+				var splitInput = $.trim(pastedText).split(self.settings.splitOn);
+				for (var i = 0, n = splitInput.length; i < n; i++) {
+					self.createItem(splitInput[i]);
+				}
+			}, 0);
 		}
 	},
 
@@ -1100,6 +1124,7 @@ $.extend(Selectize.prototype, {
 
 		// highlight matching terms inline
 		if (self.settings.highlight && results.query.length && results.tokens.length) {
+			$dropdown_content.removeHighlight();
 			for (i = 0, n = results.tokens.length; i < n; i++) {
 				highlight($dropdown_content, results.tokens[i].regex);
 			}
@@ -1597,12 +1622,26 @@ $.extend(Selectize.prototype, {
 	 * and CSS classes.
 	 */
 	refreshState: function() {
-		var invalid, self = this;
-		if (self.isRequired) {
-			if (self.items.length) self.isInvalid = false;
-			self.$control_input.prop('required', invalid);
-		}
-		self.refreshClasses();
+		this.refreshValidityState();
+		this.refreshClasses();
+	},
+
+	/**
+	 * Update the `required` attribute of both input and control input.
+	 *
+	 * The `required` property needs to be activated on the control input
+	 * for the error to be displayed at the right place. `required` also
+	 * needs to be temporarily deactivated on the input since the input is
+	 * hidden and can't show errors.
+	 */
+	refreshValidityState: function() {
+		if (!this.isRequired) return false;
+
+		var invalid = !this.items.length;
+
+		this.isInvalid = invalid;
+		this.$control_input.prop('required', invalid);
+		this.$input.prop('required', !invalid);
 	},
 
 	/**
@@ -1713,6 +1752,7 @@ $.extend(Selectize.prototype, {
 
 		if (self.settings.mode === 'single' && self.items.length) {
 			self.hideInput();
+			self.$control_input.blur(); // close keyboard on iOS
 		}
 
 		self.isOpen = false;
diff --git a/src/utils.js b/src/utils.js
index da9f6ee..6a54d76 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -331,3 +331,17 @@ var domToString = function(d) {
 
 	return tmp.innerHTML;
 };
+
+var logError = function(message, options){
+	if(!options) options = {};
+	var component = "Selectize";
+
+	console.error(component + ": " + message)
+
+	if(options.explanation){
+		// console.group is undefined in <IE11
+		if(console.group) console.group();
+		console.error(options.explanation);
+		if(console.group) console.groupEnd();
+	}
+}
diff --git a/test/interaction.js b/test/interaction.js
index e3c49eb..16ab9b2 100644
--- a/test/interaction.js
+++ b/test/interaction.js
@@ -29,17 +29,34 @@
 
 		it('should close dropdown after selection made if closeAfterSelect: true', function(done) {
 			var test = setup_test('<select multiple>' +
-					'<option value="a">A</option>' +
-					'<option value="b">B</option>' +
+				'<option value="a">A</option>' +
+				'<option value="b">B</option>' +
 				'</select>', {closeAfterSelect: true});
 
-				click(test.selectize.$control, function() {
-					click($('[data-value=a]', test.selectize.$dropdown_content), function() {
-						expect(test.selectize.isOpen).to.be.equal(false);
-						expect(test.selectize.isFocused).to.be.equal(true);
-						done();
-					});
+			click(test.selectize.$control, function() {
+				click($('[data-value=a]', test.selectize.$dropdown_content), function() {
+					expect(test.selectize.isOpen).to.be.equal(false);
+					expect(test.selectize.isFocused).to.be.equal(true);
+					done();
 				});
+			});
+		});
+
+		it('should close and blur dropdown after selection made if closeAfterSelect: true and in single mode' , function(done) {
+			var test = setup_test('<select>' +
+				'<option value="a">A</option>' +
+				'<option value="b">B</option>' +
+				'</select>', {closeAfterSelect: true});
+
+			click(test.selectize.$control, function() {
+				expect(test.selectize.isOpen).to.be.equal(true);
+				expect(test.selectize.isFocused).to.be.equal(true);
+				click($('[data-value=a]', test.selectize.$dropdown_content), function() {
+					expect(test.selectize.isOpen).to.be.equal(false);
+					expect(test.selectize.isFocused).to.be.equal(false);
+					done();
+				});
+			});
 		});
 
 		describe('clicking control', function() {
@@ -100,6 +117,43 @@
 
 		});
 
+		describe('clicking label', function() {
+
+			it('should give it focus to select', function(done) {
+				var inputId = "labeledSelect";
+				var label =
+					$('<label for="'+inputId+'">select</label>').appendTo('form');
+
+				var test = setup_test('<select id="'+inputId+'">' +
+					'<option value="a">A</option>' +
+					'<option value="b">B</option>' +
+				'</select>', {});
+
+				syn.click(label)
+					.delay(0, function() {
+						label.remove();
+						expect(test.selectize.isFocused).to.be.equal(true);
+						done();
+					});
+			});
+
+			it('should give it focus to input', function(done) {
+				var inputId = "labeledInput";
+				var label =
+					$('<label for="'+inputId+'">input</label>').appendTo('form');
+
+				var test = setup_test('<input id="'+inputId+'" type="text" value="a,b,c,d">', {});
+
+				syn.click(label)
+					.delay(0, function() {
+						label.remove();
+						expect(test.selectize.isFocused).to.be.equal(true);
+						done();
+					});
+			});
+
+		});
+
 		describe('clicking option', function() {
 
 			it('should select it', function(done) {
diff --git a/test/setup.js b/test/setup.js
index fc99d7a..34d6256 100644
--- a/test/setup.js
+++ b/test/setup.js
@@ -216,6 +216,7 @@
 				$form = test.$select.parents('form');
 				$button = $('<button type="submit">').appendTo($form);
 			});
+
 			afterEach(function() {
 				$form.off('.test_required');
 				$button.remove();
@@ -224,33 +225,52 @@
 			it('should have isRequired property set to true', function() {
 				expect(test.selectize.isRequired).to.be.equal(true);
 			});
+
 			it('should have the required class', function() {
 				expect(test.selectize.$control.hasClass('required')).to.be.equal(true);
 			});
 
+			it('should pass validation if an element is selected',
+			function(done) {
+				test.selectize.addItem('a');
+				$form.one('submit.test_required', function(e) {
+					done();
+				});
+
+				syn.click($button);
+			});
+
 			if ($.fn.selectize.support.validity) {
-				it('should have "invalid" class when validation fails', function(done) {
+				it('should not pass validation if no element is selected',
+				function(done) {
+					$form.one('submit.test_required', function(e) {
+						expect(e.isDefaultPrevented()).to.be.true;
+						done();
+					});
+
+					syn.click($button);
+				});
+
+				it('should have "invalid" class when validation fails',
+			  function(done) {
 					test.$select[0].checkValidity();
+
 					window.setTimeout(function() {
-						expect(test.selectize.$control.hasClass('invalid')).to.be.equal(true);
+						expect(test.selectize.$control.hasClass('invalid')).
+							to.be.true;
 						done();
 					}, 250);
 				});
-				it('should clear the invalid class after an item is selected', function(done) {
+
+				it('should clear the invalid class after an item is selected',
+				function(done) {
 					syn.click($button).delay(0, function() {
 						test.selectize.addItem('a');
-						expect(test.selectize.$control.hasClass('invalid')).to.be.equal(false);
+						expect(test.selectize.$control.hasClass('invalid')).
+							to.be.false;
 						done();
 					});
 				});
-				it('should pass validation if an element is selected', function(done) {
-					test.selectize.addItem('a');
-					$form.one('submit.test_required', function(e) {
-						done();
-					});
-
-					syn.click($button);
-				});
 			}
 		});
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/libjs-jquery-selectize.js.git



More information about the Pkg-javascript-commits mailing list