diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..6253224 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "singleQuote": true +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3bdbcd9..e8c6c79 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,11 +1,10 @@ #Setup + 1. [Fork **superplaceholder.js**](https://help.github.com/articles/fork-a-repo) and clone it on your system. 2. Create a new branch out off `master` for your fix/feature. `git checkout new-feature master` #Things to remember -- Use tabs. No spaces. - Do not fix multiple issues in a single commit. Keep them one thing per commit so that they can be picked easily incase only few commits require to be merged. - Before submitting a patch, rebase your branch on upstream `master` to make life easier for the merger. - **DO NOT** commit library builds (`dist/superplaceholder.js` & `dist/superplaceholder.min.js`) in your commits. - diff --git a/Gruntfile.js b/Gruntfile.js index f6fa4e2..bfd11f1 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,55 +1,52 @@ /*global module:false*/ module.exports = function(grunt) { + // Project configuration. + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), - // Project configuration. - grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), + meta: { + banner: + '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' + + '<%= grunt.template.today("yyyy-mm-dd") + "\\n" %>' + + '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' + + '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' + + ' Licensed <%= _.map(pkg.licenses, "type").join(", ") %> */\n\n' + }, + jshint: { + files: ['Gruntfile.js', 'src/<%= pkg.name %>.js'], + options: { + browser: true, + devel: true, + laxbreak: true + } + }, + uglify: { + dist: { + files: { + 'dist/<%= pkg.name %>.min.js': ['src/<%= pkg.name %>.js'] + } + } + }, + concat: { + options: { + banner: '<%= meta.banner %>' + }, + lib: { + src: ['src/<%= pkg.name %>.js'], + dest: 'dist/<%= pkg.name %>.js' + }, + minLib: { + src: ['dist/<%= pkg.name %>.min.js'], + dest: 'dist/<%= pkg.name %>.min.js' + } + } + }); - meta: { - banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' + - '<%= grunt.template.today("yyyy-mm-dd") + "\\n" %>' + - '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' + - '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' + - ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n\n' - }, - jshint: { - files: ['Gruntfile.js', 'src/<%= pkg.name %>.js'], - options: { - browser: true, - devel: true - } - }, - uglify: { - dist: { - files: { - 'dist/<%= pkg.name %>.min.js': [ 'src/<%= pkg.name %>.js' ] - } - } - }, - concat: { - options: { - banner: '<%= meta.banner %>' - }, - lib: { - src: ['src/<%= pkg.name %>.js'], - dest: 'dist/<%= pkg.name %>.js' - }, - minLib: { - src: ['dist/<%= pkg.name %>.min.js'], - dest: 'dist/<%= pkg.name %>.min.js' - } - } - }); + // Dependencies + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-contrib-concat'); - // Dependencies - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-contrib-concat'); - - grunt.registerTask('build',[ - 'jshint', - 'uglify', - 'concat' - ]); - grunt.registerTask('default','build'); + grunt.registerTask('build', ['jshint', 'uglify', 'concat']); + grunt.registerTask('default', 'build'); }; diff --git a/README.md b/README.md index 055b8df..1cd9e4b 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,9 @@ Installation **superplaceholder.js** is *less than 1KB* minified & gzipped. -- Bower: `bower install superplaceholder` -- NPM: `npm install superplaceholder` +- **NPM**: `npm install superplaceholder` +- **Yarn**: `yarn add superplacholder` +- **Bower**: `bower install superplaceholder` - [Download zip](https://github.com/chinchang/superplaceholder.js/archive/master.zip). **Note**: **superplaceholder.js** supports AMD and commonJS module pattern out of the box. @@ -59,20 +60,42 @@ superplaceholder({ // delay between sentences (in milliseconds) sentenceDelay: 1000, // should start on input focus. Set false to autostart - startOnFocus: true, + startOnFocus: true, // [DEPRECATED] // loop through passed sentences - loop: true, + loop: false, // Initially shuffle the passed sentences shuffle: false, // Show cursor or not. Shows by default showCursor: true, // String to show as cursor - cursor: '|' + cursor: '|', + // Control onFocus behaviour. Default is `superplaceholder.Actions.START` + onFocusAction: superplaceholder.Actions.[NOTHING|START|STOP] + // Control onBlur behaviour. Default is `superplaceholder.Actions.STOP` + onBlurAction: superplaceholder.Actions.[NOTHING|START|STOP] } -}; }); ``` +Manually Controlling a superplaceholder instance: + +```js +// Complete manual control +const instance = superplaceholder({ + el: document.querySelector('input'), + sentences: [ 'Any format works', 'http://yahoo.com', 'www.facebook.com', 'airbnb.com' ], + options: { + onFocusAction: superplaceholder.Actions.NOTHING + onBlurAction: superplaceholder.Actions.NOTHING + } +}); + +// Later, whenever you want +instance.start(); +instance.stop(); +instance.destroy(); // to completely remove superplaceholder from an input +``` + Browser Support ----- @@ -95,5 +118,5 @@ See the [Changelog](https://github.com/chinchang/superplaceholder.js/wiki/Change License ----- -Copyright (c) 2016 Kushagra Gour, http://kushagragour.in +Copyright (c) 2019 Kushagra Gour, https://kushagragour.in This work is licensed under a [Creative Commons Attribution-NoDerivatives 4.0 International License](http://creativecommons.org/licenses/by-nd/4.0/). diff --git a/assets/logo.png b/assets/logo.png index 428bbd5..5ab0bf0 100644 Binary files a/assets/logo.png and b/assets/logo.png differ diff --git a/assets/superplaceholder.gif b/assets/superplaceholder.gif index 8f1a271..f5eab38 100644 Binary files a/assets/superplaceholder.gif and b/assets/superplaceholder.gif differ diff --git a/assets/superplaceholder.png b/assets/superplaceholder.png index 9f4b9af..0fd3b74 100644 Binary files a/assets/superplaceholder.png and b/assets/superplaceholder.png differ diff --git a/demo.html b/demo.html index cd6db03..5518dca 100644 --- a/demo.html +++ b/demo.html @@ -1,24 +1,26 @@ - - - - superplaceholder.js - Super charge your input placeholders - - - - - - - - -
- -

superplaceholder.js

-
-

Super charge your placeholders

- Download (<1KB minified & gzipped) + -

URL Inputs

-
- - -
+ +
+ +

superplaceholder.js

+
+

Super charge your placeholders

+ Download (<1KB + minified & gzipped)

URL Inputs

+
+ + +
-

Signup forms

-
- -
-
- -
+

Signup forms

+
+ +
+
+ +
- - - + + superplaceholder({ + el: inp3, + sentences: ['Any format works', 'http://yahoo.com', 'www.facebook.com', 'airbnb.com'], + options: { + letterDelay: 80, + loop: true, + startOnFocus: false + } + }) + + + - - + \ No newline at end of file diff --git a/dist/superplaceholder.js b/dist/superplaceholder.js index ac5c370..9d3b82e 100644 --- a/dist/superplaceholder.js +++ b/dist/superplaceholder.js @@ -1,125 +1,221 @@ -/*! superplaceholder.js - v0.1.1 - 2016-03-06 +/*! superplaceholder.js - v1.0.0 - 2019-01-04 * http://kushagragour.in/lab/superplaceholderjs/ -* Copyright (c) 2016 Kushagra Gour; Licensed CC-BY-ND-4.0 */ - -;(function () { - var test = document.createElement('input'); - var isPlaceHolderSupported = ('placeholder' in test); - - // Helpers - function extend(obj1, obj2) { - var obj = {}; - for (var key in obj1) { - obj[key] = obj2[key] === undefined ? obj1[key] : obj2[key]; - } - return obj; - } - - var defaults = { - letterDelay: 100, //milliseconds - sentenceDelay: 1000, //milliseconds - loop: false, - startOnFocus: true, - shuffle: false, - showCursor: true, - cursor: '|' - }; - - // Constructor: PlaceHolder - function PlaceHolder(el, texts, options) { - this.el = el; - this.texts = texts; - options = options || {}; - this.options = extend(defaults, options); - this.timeouts = []; - this.begin(); - } - - PlaceHolder.prototype.begin = function() { - var self = this, - temp, - randomIndex; - self.originalPlaceholder = self.el.getAttribute('placeholder'); - if (self.options.shuffle) { - for (var i = self.texts.length; i--;) { - randomIndex = ~~(Math.random() * i); - temp = self.texts[randomIndex]; - self.texts[randomIndex] = self.texts[i]; - self.texts[i] = temp; - } - } - - if (self.options.startOnFocus) { - self.el.addEventListener('focus', function () { - self.processText(0); - }); - self.el.addEventListener('blur', function () { - self.cleanUp(); - }); - } - else { - self.processText(0); - } - }; - - PlaceHolder.prototype.cleanUp = function () { - // Stop timeouts - for (var i = this.timeouts.length; i--;) { - clearTimeout(this.timeouts[i]); - } - this.el.setAttribute('placeholder', this.originalPlaceholder); - this.timeouts.length = 0; - }; - - PlaceHolder.prototype.typeString = function (str, callback) { - var self = this, - timeout; - - if (!str) { return false; } - function setTimeoutCallback(index) { - // Add cursor `|` after current substring unless we are showing last - // character of the string. - self.el.setAttribute('placeholder', str.substr(0, index + 1) + (index === str.length - 1 || !self.options.showCursor ? '' : self.options.cursor)); - if (index === str.length - 1) { - callback(); - } - } - for (var i = 0; i < str.length; i++) { - timeout = setTimeout(setTimeoutCallback, i * self.options.letterDelay, i); - self.timeouts.push(timeout); - } - }; - - PlaceHolder.prototype.processText = function(index) { - var self = this, - timeout; - - self.typeString(self.texts[index], function () { - timeout = setTimeout(function () { - self.processText(self.options.loop ? ((index + 1) % self.texts.length) : (index + 1)); - }, self.options.sentenceDelay); - self.timeouts.push(timeout); - }); - }; - - var superplaceholder = function (params) { - if (!isPlaceHolderSupported) { return; } - new PlaceHolder(params.el, params.sentences, params.options); - }; - - // open to the world. - // commonjs - if( typeof exports === 'object' ) { - module.exports = superplaceholder; - } - // AMD module - else if( typeof define === 'function' && define.amd ) { - define(function () { - return superplaceholder; - }); - } - // Browser global - else { - window.superplaceholder = superplaceholder; - } +* Copyright (c) 2019 Kushagra Gour; Licensed CC-BY-ND-4.0 */ + +(function() { + var test = document.createElement('input'); + var isPlaceHolderSupported = 'placeholder' in test; + + // Helpers + function extend(obj1, obj2) { + var obj = {}; + for (var key in obj1) { + obj[key] = obj2[key] === undefined ? obj1[key] : obj2[key]; + } + return obj; + } + + var Actions = Object.freeze({ + START: 'start', + STOP: 'stop', + NOTHING: false + }); + + var defaults = { + letterDelay: 100, //milliseconds + sentenceDelay: 1000, //milliseconds + loop: false, + startOnFocus: true, + shuffle: false, + showCursor: true, + cursor: '|', + autoStart: false, + onFocusAction: Actions.START, + onBlurAction: Actions.STOP + }; + + // Constructor: PlaceHolder + function PlaceHolder(el, texts, options) { + this.el = el; + this.texts = texts; + options = options || {}; + this.options = extend(defaults, options); + // Translate deprecated `startOnFocus` option to new ones. + if (!this.options.startOnFocus) { + // TODO: add deprecation message + console.warn( + 'Superplaceholder.js: `startOnFocus` option has been deprecated. Please use `onFocusAction`, `onBlurAction` and `autoStart`' + ); + + this.options.autoStart = true; + this.options.onFocusAction = Actions.NOTHING; + this.options.onBlurAction = Actions.NOTHING; + } + this.timeouts = []; + this.isPlaying = false; + + var temp, randomIndex; + if (this.options.shuffle) { + for (var i = this.texts.length; i--; ) { + randomIndex = ~~(Math.random() * i); + temp = this.texts[randomIndex]; + this.texts[randomIndex] = this.texts[i]; + this.texts[i] = temp; + } + } + + this.begin(); + } + + PlaceHolder.prototype.begin = function() { + var self = this; + self.originalPlaceholder = self.el.getAttribute('placeholder'); + + if (self.options.onFocusAction || self.options.onBlurAction) { + // Store to unbind later + self.listeners = { + focus: self.onFocus.bind(self), + blur: self.onBlur.bind(self) + }; + self.el.addEventListener('focus', self.listeners.focus); + self.el.addEventListener('blur', self.listeners.blur); + } + if (self.options.autoStart) { + self.processText(0); + } + }; + + PlaceHolder.prototype.onFocus = function() { + if (this.options.onFocusAction === Actions.START) { + if (this.isInProgress()) { + return; + } + this.processText(0); + } else if (this.options.onFocusAction === Actions.STOP) { + this.cleanUp(); + } + }; + + PlaceHolder.prototype.onBlur = function() { + if (this.options.onBlurAction === Actions.STOP) { + this.cleanUp(); + } else if (this.options.onBlurAction === Actions.START) { + if (this.isInProgress()) { + return; + } + this.processText(0); + } + }; + + PlaceHolder.prototype.cleanUp = function() { + // Stop timeouts + for (var i = this.timeouts.length; i--; ) { + clearTimeout(this.timeouts[i]); + } + // null means there was no placeholder attribute initially. + if (this.originalPlaceholder === null) { + this.el.removeAttribute('placeholder'); + } else { + this.el.setAttribute('placeholder', this.originalPlaceholder); + } + this.timeouts.length = 0; + this.isPlaying = false; + }; + + PlaceHolder.prototype.isInProgress = function() { + return this.isPlaying; + }; + + PlaceHolder.prototype.typeString = function(str, callback) { + var self = this, + timeout; + + if (!str) { + return false; + } + + function setTimeoutCallback(index) { + // Add cursor `|` after current substring unless we are showing last + // character of the string. + self.el.setAttribute( + 'placeholder', + str.substr(0, index + 1) + + (index === str.length - 1 || !self.options.showCursor + ? '' + : self.options.cursor) + ); + // Call the completion callback when last character is being printed + if (index === str.length - 1) { + callback(); + } + } + for (var i = 0; i < str.length; i++) { + timeout = setTimeout(setTimeoutCallback, i * self.options.letterDelay, i); + self.timeouts.push(timeout); + } + }; + + PlaceHolder.prototype.processText = function(index) { + var self = this, + timeout; + + this.isPlaying = true; + + self.typeString(self.texts[index], function() { + // Empty the timeouts array + self.timeouts.length = 0; + if (!self.options.loop && !self.texts[index + 1]) { + self.isPlaying = false; + } + timeout = setTimeout(function() { + self.processText( + self.options.loop ? (index + 1) % self.texts.length : index + 1 + ); + }, self.options.sentenceDelay); + self.timeouts.push(timeout); + }); + }; + + var superplaceholder = function(params) { + if (!isPlaceHolderSupported) { + return; + } + var instance = new PlaceHolder(params.el, params.sentences, params.options); + return { + start: function() { + if (instance.isInProgress()) { + return; + } + instance.processText(0); + }, + stop: function() { + instance.cleanUp(); + }, + destroy: function() { + instance.cleanUp(); + for (var eventName in instance.listeners) { + instance.el.removeEventListener( + eventName, + instance.listeners[eventName] + ); + } + } + }; + }; + + superplaceholder.Actions = Actions; + + // open to the world. + // commonjs + if (typeof exports === 'object') { + module.exports = superplaceholder; + } else if (typeof define === 'function' && define.amd) { + // AMD module + define(function() { + return superplaceholder; + }); + } else { + // Browser global + window.superplaceholder = superplaceholder; + } })(); diff --git a/dist/superplaceholder.min.js b/dist/superplaceholder.min.js index 241aef5..a3d8830 100644 --- a/dist/superplaceholder.min.js +++ b/dist/superplaceholder.min.js @@ -1,5 +1,5 @@ -/*! superplaceholder.js - v0.1.1 - 2016-03-06 +/*! superplaceholder.js - v1.0.0 - 2019-01-04 * http://kushagragour.in/lab/superplaceholderjs/ -* Copyright (c) 2016 Kushagra Gour; Licensed CC-BY-ND-4.0 */ +* Copyright (c) 2019 Kushagra Gour; Licensed CC-BY-ND-4.0 */ -!function(){function a(a,b){var c={};for(var d in a)c[d]=void 0===b[d]?a[d]:b[d];return c}function b(b,c,d){this.el=b,this.texts=c,d=d||{},this.options=a(e,d),this.timeouts=[],this.begin()}var c=document.createElement("input"),d="placeholder"in c,e={letterDelay:100,sentenceDelay:1e3,loop:!1,startOnFocus:!0,shuffle:!1,showCursor:!0,cursor:"|"};b.prototype.begin=function(){var a,b,c=this;if(c.originalPlaceholder=c.el.getAttribute("placeholder"),c.options.shuffle)for(var d=c.texts.length;d--;)b=~~(Math.random()*d),a=c.texts[b],c.texts[b]=c.texts[d],c.texts[d]=a;c.options.startOnFocus?(c.el.addEventListener("focus",function(){c.processText(0)}),c.el.addEventListener("blur",function(){c.cleanUp()})):c.processText(0)},b.prototype.cleanUp=function(){for(var a=this.timeouts.length;a--;)clearTimeout(this.timeouts[a]);this.el.setAttribute("placeholder",this.originalPlaceholder),this.timeouts.length=0},b.prototype.typeString=function(a,b){function c(c){e.el.setAttribute("placeholder",a.substr(0,c+1)+(c!==a.length-1&&e.options.showCursor?e.options.cursor:"")),c===a.length-1&&b()}var d,e=this;if(!a)return!1;for(var f=0;f< str.length; i++) { - timeout = setTimeout(setTimeoutCallback, i * self.options.letterDelay, i); - self.timeouts.push(timeout); - } - }; - - PlaceHolder.prototype.processText = function(index) { - var self = this, - timeout; - - self.typeString(self.texts[index], function () { - timeout = setTimeout(function () { - self.processText(self.options.loop ? ((index + 1) % self.texts.length) : (index + 1)); - }, self.options.sentenceDelay); - self.timeouts.push(timeout); - }); - }; - - var superplaceholder = function (params) { - if (!isPlaceHolderSupported) { return; } - new PlaceHolder(params.el, params.sentences, params.options); - }; - - // open to the world. - // commonjs - if( typeof exports === 'object' ) { - module.exports = superplaceholder; - } - // AMD module - else if( typeof define === 'function' && define.amd ) { - define(function () { - return superplaceholder; - }); - } - // Browser global - else { - window.superplaceholder = superplaceholder; - } +(function() { + var test = document.createElement('input'); + var isPlaceHolderSupported = 'placeholder' in test; + + // Helpers + function extend(obj1, obj2) { + var obj = {}; + for (var key in obj1) { + obj[key] = obj2[key] === undefined ? obj1[key] : obj2[key]; + } + return obj; + } + + var Actions = Object.freeze({ + START: 'start', + STOP: 'stop', + NOTHING: false + }); + + var defaults = { + letterDelay: 100, //milliseconds + sentenceDelay: 1000, //milliseconds + loop: false, + startOnFocus: true, + shuffle: false, + showCursor: true, + cursor: '|', + autoStart: false, + onFocusAction: Actions.START, + onBlurAction: Actions.STOP + }; + + // Constructor: PlaceHolder + function PlaceHolder(el, texts, options) { + this.el = el; + this.texts = texts; + options = options || {}; + this.options = extend(defaults, options); + // Translate deprecated `startOnFocus` option to new ones. + if (!this.options.startOnFocus) { + // TODO: add deprecation message + console.warn( + 'Superplaceholder.js: `startOnFocus` option has been deprecated. Please use `onFocusAction`, `onBlurAction` and `autoStart`' + ); + + this.options.autoStart = true; + this.options.onFocusAction = Actions.NOTHING; + this.options.onBlurAction = Actions.NOTHING; + } + this.timeouts = []; + this.isPlaying = false; + + var temp, randomIndex; + if (this.options.shuffle) { + for (var i = this.texts.length; i--; ) { + randomIndex = ~~(Math.random() * i); + temp = this.texts[randomIndex]; + this.texts[randomIndex] = this.texts[i]; + this.texts[i] = temp; + } + } + + this.begin(); + } + + PlaceHolder.prototype.begin = function() { + var self = this; + self.originalPlaceholder = self.el.getAttribute('placeholder'); + + if (self.options.onFocusAction || self.options.onBlurAction) { + // Store to unbind later + self.listeners = { + focus: self.onFocus.bind(self), + blur: self.onBlur.bind(self) + }; + self.el.addEventListener('focus', self.listeners.focus); + self.el.addEventListener('blur', self.listeners.blur); + } + if (self.options.autoStart) { + self.processText(0); + } + }; + + PlaceHolder.prototype.onFocus = function() { + if (this.options.onFocusAction === Actions.START) { + if (this.isInProgress()) { + return; + } + this.processText(0); + } else if (this.options.onFocusAction === Actions.STOP) { + this.cleanUp(); + } + }; + + PlaceHolder.prototype.onBlur = function() { + if (this.options.onBlurAction === Actions.STOP) { + this.cleanUp(); + } else if (this.options.onBlurAction === Actions.START) { + if (this.isInProgress()) { + return; + } + this.processText(0); + } + }; + + PlaceHolder.prototype.cleanUp = function() { + // Stop timeouts + for (var i = this.timeouts.length; i--; ) { + clearTimeout(this.timeouts[i]); + } + // null means there was no placeholder attribute initially. + if (this.originalPlaceholder === null) { + this.el.removeAttribute('placeholder'); + } else { + this.el.setAttribute('placeholder', this.originalPlaceholder); + } + this.timeouts.length = 0; + this.isPlaying = false; + }; + + PlaceHolder.prototype.isInProgress = function() { + return this.isPlaying; + }; + + PlaceHolder.prototype.typeString = function(str, callback) { + var self = this, + timeout; + + if (!str) { + return false; + } + + function setTimeoutCallback(index) { + // Add cursor `|` after current substring unless we are showing last + // character of the string. + self.el.setAttribute( + 'placeholder', + str.substr(0, index + 1) + + (index === str.length - 1 || !self.options.showCursor + ? '' + : self.options.cursor) + ); + // Call the completion callback when last character is being printed + if (index === str.length - 1) { + callback(); + } + } + for (var i = 0; i < str.length; i++) { + timeout = setTimeout(setTimeoutCallback, i * self.options.letterDelay, i); + self.timeouts.push(timeout); + } + }; + + PlaceHolder.prototype.processText = function(index) { + var self = this, + timeout; + + this.isPlaying = true; + + self.typeString(self.texts[index], function() { + // Empty the timeouts array + self.timeouts.length = 0; + if (!self.options.loop && !self.texts[index + 1]) { + self.isPlaying = false; + } + timeout = setTimeout(function() { + self.processText( + self.options.loop ? (index + 1) % self.texts.length : index + 1 + ); + }, self.options.sentenceDelay); + self.timeouts.push(timeout); + }); + }; + + var superplaceholder = function(params) { + if (!isPlaceHolderSupported) { + return; + } + var instance = new PlaceHolder(params.el, params.sentences, params.options); + return { + start: function() { + if (instance.isInProgress()) { + return; + } + instance.processText(0); + }, + stop: function() { + instance.cleanUp(); + }, + destroy: function() { + instance.cleanUp(); + for (var eventName in instance.listeners) { + instance.el.removeEventListener( + eventName, + instance.listeners[eventName] + ); + } + } + }; + }; + + superplaceholder.Actions = Actions; + + // open to the world. + // commonjs + if (typeof exports === 'object') { + module.exports = superplaceholder; + } else if (typeof define === 'function' && define.amd) { + // AMD module + define(function() { + return superplaceholder; + }); + } else { + // Browser global + window.superplaceholder = superplaceholder; + } })();