├── .gitignore ├── Gruntfile.js ├── LICENSE ├── Readme.md ├── bower.json ├── dist ├── otinput.js └── otinput.min.js ├── examples └── otinput.html ├── package.json ├── src ├── formats.src.js └── main.src.js └── test ├── otinput.html └── otinput.test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | grunt.initConfig({ 4 | pkg: grunt.file.readJSON('package.json'), 5 | concat: { 6 | options: { 7 | banner: "/*! <%= pkg.name %> v<%= pkg.version %> */\n(function(){\n'use strict';\n", 8 | footer: '\n}());' 9 | }, 10 | dist: { 11 | src: ['src/**/*.src.js'], 12 | dest: 'dist/<%= pkg.name %>.js' 13 | } 14 | }, 15 | uglify: { 16 | options: {}, 17 | dist: { 18 | files: { 19 | 'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>'] 20 | } 21 | } 22 | }, 23 | qunit: { 24 | files: ['test/**/*.html'] 25 | }, 26 | jshint: { 27 | files: ['src/**/*.src.js'], 28 | options: { 29 | // options here to override JSHint defaults 30 | // ref: http://jshint.com/docs/options/ 31 | curly: true, 32 | eqeqeq: true, 33 | maxparams: 3, 34 | undef: false, 35 | bitwise: true, 36 | globals: { 37 | jQuery: true, 38 | console: true, 39 | module: true, 40 | document: true 41 | } 42 | } 43 | }, 44 | githooks: { 45 | options: { 46 | // Task-specific options go here. 47 | }, 48 | all: { 49 | options: { 50 | // Target-specific options go here 51 | }, 52 | 'pre-commit': 'concat uglify jshint qunit', 53 | } 54 | }, 55 | watch: { 56 | files: ['<%= concat.dist.src %>'], 57 | tasks: ['jshint', 'concat', 'uglify', 'qunit'] 58 | } 59 | }); 60 | 61 | grunt.loadNpmTasks('grunt-contrib-uglify'); 62 | grunt.loadNpmTasks('grunt-contrib-jshint'); 63 | grunt.loadNpmTasks('grunt-contrib-qunit'); 64 | grunt.loadNpmTasks('grunt-contrib-watch'); 65 | grunt.loadNpmTasks('grunt-contrib-concat'); 66 | grunt.loadNpmTasks('grunt-githooks'); 67 | 68 | grunt.registerTask('test', ['qunit']); 69 | grunt.registerTask('default', ['githooks', 'concat', 'uglify', 'jshint', 'qunit']); 70 | grunt.registerTask('watch', ['default', 'watch']); 71 | 72 | }; 73 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Elliot Bentley 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # oTinput 2 | 3 | A dynamic file input form developed for [oTranscribe](http://github.com/otranscribe/otranscribe). Creates simple, user-friendly form for selecting local audio/video files, which can then be played audio or video in-browser. Combine with oTplayer for an awesome combo. 4 | 5 | ## Install 6 | 7 | Download [otinput.js](dist/otinput.js) or [otinput.min.js](dist/otinput.min.js) and include it in your page along with jQuery. 8 | 9 | ## Usage 10 | 11 | Initialise a new instance of oTinput like so: 12 | 13 | ```js 14 | var input = new oTinput({ 15 | element: '.my-input-holder', 16 | onFileChange: function(file){ 17 | console.log('File name is: '+file.name); 18 | }, 19 | onURLSubmit: function(url){ 20 | console.log('URL is: '+url); 21 | } 22 | }); 23 | ``` 24 | 25 | `onFileChange` and `onURLSubmit` are run whenever a valid file or URL is submitted by the user. 26 | 27 | Note that oTinput does **not** include any styles. 28 | 29 | ### Config options 30 | 31 | All of these are optional apart from `element`. 32 | 33 | - `element`: Selector, or element, to contain input buttons. 34 | - `onFileChange(file)` - callback for when file changes. Callback argument is [File object](https://developer.mozilla.org/en/docs/Web/API/File). 35 | - `onFileError(error, file)`: Callback for when file is unsupported or otherwise invalid. Callback arguments are [Error object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) and [File object](https://developer.mozilla.org/en/docs/Web/API/File). 36 | - `onDragover()`: Callback function for when a file is dragged over the input and can be dropped. 37 | - `onDragleave()`: Callback function for when a file is dragged away from the input. 38 | - `onURLSubmit(url)`: Callback function for when valid URL is submitted. Callback argument is the submitted URL 39 | - `onURLError(error, url)`: Callback function for when URL's filetype is unsupported or otherwise invalid. Callback arguments are [Error object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) and the submitted URL. 40 | - `text`: Object used to specify custom replacements to default text. 41 | - `button`: Default is "Choose audio (or video) file". 42 | - `altButton`: Default is "Enter file URL". 43 | - `altInputText`: Default is "Enter URL of audio or video file, or YouTube video:" 44 | - `closeAlt`: Default is "close" 45 | 46 | ### Methods 47 | 48 | - `showURLInput()`: Switch to secondary input for URLs. 49 | - `showFileInput()`: Return to primary input for files. 50 | - `getSupportedFormats()`: Returns an object with properties 'audio' and 'video', each containing arrays of supported filetypes. Can also be used without initialising object. 51 | 52 | var formats = oTplayer.getSupportedFormats(); 53 | formats; // { audio: ["mp3", "wav"], video: ["mp4"] } 54 | formats.audio; // ["mp3", "wav"] 55 | formats.video; // ["mp4"] 56 | 57 | - `isFormatSupported(filetype)`: Returns true if file format is supported by current browser. Can also be used without initialising object: 58 | 59 | oTplayer.isFormatSupported('mp3'); 60 | 61 | ## Browser support 62 | 63 | oTinput requires the [File API](http://caniuse.com/#search=file), so only supports modern browsers. 64 | 65 | ## Building dist folder 66 | 67 | - Install [Node and npm](https://nodejs.org) and [Grunt](http://gruntjs.com) 68 | - Run `npm install` 69 | - Run `grunt` 70 | 71 | ## Running tests 72 | 73 | - Build dist folder 74 | - Run `grunt test` 75 | 76 | ## Version history 77 | 78 | ### v1.0.0 79 | 80 | May 25, 2015 81 | 82 | - Initial release 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "otinput", 3 | "version": "1.0.0", 4 | "authors": [ 5 | "ejb " 6 | ], 7 | "description": "oTranscribe's file input system", 8 | "main": "dist/otinput.js", 9 | "moduleType": [ 10 | "globals" 11 | ], 12 | "license": "MIT", 13 | "ignore": [ 14 | "**/.*", 15 | "node_modules", 16 | "bower_components", 17 | "test", 18 | "tests" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /dist/otinput.js: -------------------------------------------------------------------------------- 1 | /*! otinput v1.0.0 */ 2 | (function(){ 3 | 'use strict'; 4 | oTinput.prototype.getSupportedFormats = function(){ 5 | var potentialFormatsAudio = ['mp3', 'ogg', 'webm', 'wav']; 6 | var potentialFormatsVideo = ['mp4', 'ogg', 'webm']; 7 | var isFormatSupported = this.isFormatSupported || oTinput.isFormatSupported; 8 | var audio = $.map( potentialFormatsAudio, function( format, i ) { 9 | if (isFormatSupported(format)){ 10 | return format; 11 | } 12 | }); 13 | var video = $.map( potentialFormatsVideo, function( format, i ) { 14 | if (isFormatSupported(format)){ 15 | return format; 16 | } 17 | }); 18 | return { 19 | audio: audio, 20 | video: video 21 | }; 22 | }; 23 | oTinput.prototype.isFormatSupported = function( format ){ 24 | var a; 25 | if (typeof format !== 'string') { 26 | var fileType = format.type.split("/")[0]; 27 | a = document.createElement(fileType); 28 | return !!(a.canPlayType && a.canPlayType(format.type).replace(/no/, '')); 29 | } 30 | a = document.createElement('audio'); 31 | return !!(a.canPlayType && a.canPlayType('audio/'+format+';').replace(/no/, '')); 32 | }; 33 | oTinput.getSupportedFormats = oTinput.prototype.getSupportedFormats; 34 | oTinput.isFormatSupported = oTinput.prototype.isFormatSupported; 35 | 36 | oTinput.prototype.parseYoutubeURL = function(url){ 37 | if (url.match) { 38 | var regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/; 39 | var match = url.match(regExp); 40 | if (match&&match[2].length===11){ 41 | return match[2]; 42 | } 43 | } 44 | return false; 45 | }; 46 | oTinput.parseYoutubeURL = oTinput.prototype.parseYoutubeURL; 47 | 48 | function oTinput(config){ 49 | var that = this; 50 | this._text = config.text || {}; 51 | this._onFileChange = config.onFileChange || function(){}; 52 | this._onFileError = config.onFileError || function(){}; 53 | this._onURLSubmit = config.onURLSubmit || function(){}; 54 | this._onURLError = config.onURLError || function(){}; 55 | this._dragover = config.onDragover || function(){}; 56 | this._dragleave = config.onDragleave || function(){}; 57 | this.element = this._setupElement(config.element); 58 | this._setupMouseEvents(); 59 | 60 | $(this.element).find('input[type="file"]').change(function(){ 61 | that._reactToFile(this); 62 | }); 63 | $(this.element).find('.ext-input-field input').on('submit',function(){ 64 | that._reactToURL( $(this).val() ); 65 | }).keypress(function(e){ 66 | if (e.which === 13) { 67 | that._reactToURL( $(this).val() ); 68 | return false; 69 | } 70 | }); 71 | } 72 | window.oTinput = oTinput; 73 | oTinput.prototype._setupElement = function(element){ 74 | var that = this; 75 | if (typeof element === 'undefined') { 76 | throw('must specify container element'); 77 | } 78 | var buttonText = this._text.button || 'Choose audio (or video) file'; 79 | var button = ''; 80 | var fileInputStyle = [ 81 | 'position: absolute', 82 | 'top: 0', 83 | 'left: 0', 84 | 'opacity: 0', 85 | 'width: 100%' 86 | ].join(';'); 87 | var fileInput = ''; 88 | var wrapperStyle = 'position: relative; overflow: hidden;'; 89 | var wrapper = '
'+button+fileInput+'
'; 90 | var altButtonText = this._text.altButton || 'Enter file URL'; 91 | var altButton = ''; 92 | var urlInputText = this._text.altInputText || 'Enter URL of audio or video file, or YouTube video:'; 93 | var urlInputClose = this._text.closeAlt || 'close'; 94 | var urlInput = ''; 95 | $(element).html( wrapper + altButton + urlInput ); 96 | return $(element)[0]; 97 | }; 98 | oTinput.prototype._setupMouseEvents = function(){ 99 | var that = this; 100 | var element = this.element; 101 | var buttonEl = $(element).find('.file-input-wrapper')[0]; 102 | buttonEl.addEventListener('dragover', function(){ 103 | that._dragover(); 104 | }, false); 105 | buttonEl.addEventListener('dragleave', function(){ 106 | that._dragleave(); 107 | }, false); 108 | $(element).find('.alt-input-button').click(function(){ 109 | that.showURLInput(); 110 | }); 111 | $(element).find('.close-ext-input').click(function(){ 112 | that.showFileInput(); 113 | }); 114 | }; 115 | oTinput.prototype._reactToFile = function(input){ 116 | var file = input.files[0]; 117 | if ( this.isFormatSupported(file) ) { 118 | this._onFileChange( file ); 119 | } else { 120 | var err = new Error('Filetype '+file.type+' not supported by this browser'); 121 | this._onFileError(err, file); 122 | } 123 | }; 124 | oTinput.prototype._reactToURL = function(url){ 125 | var input = url.replace(/\s/g,''); 126 | if (this.parseYoutubeURL(input)){ 127 | return this._onURLSubmit( input ); 128 | } 129 | var formatArr = input.split('.'); 130 | var format = formatArr[formatArr.length-1]; 131 | if ( this.isFormatSupported(format) ) { 132 | this._onURLSubmit( input ); 133 | } else { 134 | var err = new Error('Filetype '+format+' not supported by this browser'); 135 | this._onURLError(err, url); 136 | } 137 | }; 138 | oTinput.prototype.showURLInput = function(){ 139 | $(this.element).find('.ext-input-field').show().find('input').focus(); 140 | $(this.element).addClass('ext-input-active'); 141 | }; 142 | oTinput.prototype.showFileInput = function(){ 143 | $(this.element).find('.ext-input-field').hide(); 144 | $(this.element).removeClass('ext-input-active'); 145 | }; 146 | 147 | }()); -------------------------------------------------------------------------------- /dist/otinput.min.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict";function a(a){var b=this;this._text=a.text||{},this._onFileChange=a.onFileChange||function(){},this._onFileError=a.onFileError||function(){},this._onURLSubmit=a.onURLSubmit||function(){},this._onURLError=a.onURLError||function(){},this._dragover=a.onDragover||function(){},this._dragleave=a.onDragleave||function(){},this.element=this._setupElement(a.element),this._setupMouseEvents(),$(this.element).find('input[type="file"]').change(function(){b._reactToFile(this)}),$(this.element).find(".ext-input-field input").on("submit",function(){b._reactToURL($(this).val())}).keypress(function(a){return 13===a.which?(b._reactToURL($(this).val()),!1):void 0})}a.prototype.getSupportedFormats=function(){var b=["mp3","ogg","webm","wav"],c=["mp4","ogg","webm"],d=this.isFormatSupported||a.isFormatSupported,e=$.map(b,function(a,b){return d(a)?a:void 0}),f=$.map(c,function(a,b){return d(a)?a:void 0});return{audio:e,video:f}},a.prototype.isFormatSupported=function(a){var b;if("string"!=typeof a){var c=a.type.split("/")[0];return b=document.createElement(c),!(!b.canPlayType||!b.canPlayType(a.type).replace(/no/,""))}return b=document.createElement("audio"),!(!b.canPlayType||!b.canPlayType("audio/"+a+";").replace(/no/,""))},a.getSupportedFormats=a.prototype.getSupportedFormats,a.isFormatSupported=a.prototype.isFormatSupported,a.prototype.parseYoutubeURL=function(a){if(a.match){var b=/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/,c=a.match(b);if(c&&11===c[2].length)return c[2]}return!1},a.parseYoutubeURL=a.prototype.parseYoutubeURL,window.oTinput=a,a.prototype._setupElement=function(a){if("undefined"==typeof a)throw"must specify container element";var b=this._text.button||"Choose audio (or video) file",c='",d=["position: absolute","top: 0","left: 0","opacity: 0","width: 100%"].join(";"),e='',f="position: relative; overflow: hidden;",g='
'+c+e+"
",h=this._text.altButton||"Enter file URL",i='",j=this._text.altInputText||"Enter URL of audio or video file, or YouTube video:",k=this._text.closeAlt||"close",l='';return $(a).html(g+i+l),$(a)[0]},a.prototype._setupMouseEvents=function(){var a=this,b=this.element,c=$(b).find(".file-input-wrapper")[0];c.addEventListener("dragover",function(){a._dragover()},!1),c.addEventListener("dragleave",function(){a._dragleave()},!1),$(b).find(".alt-input-button").click(function(){a.showURLInput()}),$(b).find(".close-ext-input").click(function(){a.showFileInput()})},a.prototype._reactToFile=function(a){var b=a.files[0];if(this.isFormatSupported(b))this._onFileChange(b);else{var c=new Error("Filetype "+b.type+" not supported by this browser");this._onFileError(c,b)}},a.prototype._reactToURL=function(a){var b=a.replace(/\s/g,"");if(this.parseYoutubeURL(b))return this._onURLSubmit(b);var c=b.split("."),d=c[c.length-1];if(this.isFormatSupported(d))this._onURLSubmit(b);else{var e=new Error("Filetype "+d+" not supported by this browser");this._onURLError(e,a)}},a.prototype.showURLInput=function(){$(this.element).find(".ext-input-field").show().find("input").focus(),$(this.element).addClass("ext-input-active")},a.prototype.showFileInput=function(){$(this.element).find(".ext-input-field").hide(),$(this.element).removeClass("ext-input-active")}}(); -------------------------------------------------------------------------------- /examples/otinput.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Test 6 | 7 | 8 | 9 | https://raw.githubusercontent.com/ejb/progressor.js/gh-pages/demos/discipline.mp3 10 |
https://www.youtube.com/watch?v=N9XKLqGqwLA 11 |
12 | 13 |
14 |
15 | 16 | 17 | 18 | 19 | 56 | 57 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "otinput", 3 | "version": "1.0.0", 4 | "description": "oTranscribe's file input system", 5 | "main": "dist/otinput.js", 6 | "directories": { 7 | "example": "examples", 8 | "test": "test" 9 | }, 10 | "dependencies": {}, 11 | "devDependencies": { 12 | "grunt": "^0.4.5", 13 | "grunt-contrib-concat": "^0.5.1", 14 | "grunt-contrib-jshint": "^0.11.2", 15 | "grunt-contrib-qunit": "^0.7.0", 16 | "grunt-contrib-uglify": "^0.9.1", 17 | "grunt-contrib-watch": "^0.6.1", 18 | "grunt-githooks": "^0.3.1" 19 | }, 20 | "scripts": { 21 | "test": "grunt test" 22 | }, 23 | "author": "", 24 | "license": "MIT" 25 | } 26 | -------------------------------------------------------------------------------- /src/formats.src.js: -------------------------------------------------------------------------------- 1 | oTinput.prototype.getSupportedFormats = function(){ 2 | var potentialFormatsAudio = ['mp3', 'ogg', 'webm', 'wav']; 3 | var potentialFormatsVideo = ['mp4', 'ogg', 'webm']; 4 | var isFormatSupported = this.isFormatSupported || oTinput.isFormatSupported; 5 | var audio = $.map( potentialFormatsAudio, function( format, i ) { 6 | if (isFormatSupported(format)){ 7 | return format; 8 | } 9 | }); 10 | var video = $.map( potentialFormatsVideo, function( format, i ) { 11 | if (isFormatSupported(format)){ 12 | return format; 13 | } 14 | }); 15 | return { 16 | audio: audio, 17 | video: video 18 | }; 19 | }; 20 | oTinput.prototype.isFormatSupported = function( format ){ 21 | var a; 22 | if (typeof format !== 'string') { 23 | var fileType = format.type.split("/")[0]; 24 | a = document.createElement(fileType); 25 | return !!(a.canPlayType && a.canPlayType(format.type).replace(/no/, '')); 26 | } 27 | a = document.createElement('audio'); 28 | return !!(a.canPlayType && a.canPlayType('audio/'+format+';').replace(/no/, '')); 29 | }; 30 | oTinput.getSupportedFormats = oTinput.prototype.getSupportedFormats; 31 | oTinput.isFormatSupported = oTinput.prototype.isFormatSupported; 32 | 33 | oTinput.prototype.parseYoutubeURL = function(url){ 34 | if (url.match) { 35 | var regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/; 36 | var match = url.match(regExp); 37 | if (match&&match[2].length===11){ 38 | return match[2]; 39 | } 40 | } 41 | return false; 42 | }; 43 | oTinput.parseYoutubeURL = oTinput.prototype.parseYoutubeURL; 44 | -------------------------------------------------------------------------------- /src/main.src.js: -------------------------------------------------------------------------------- 1 | function oTinput(config){ 2 | var that = this; 3 | this._text = config.text || {}; 4 | this._onFileChange = config.onFileChange || function(){}; 5 | this._onFileError = config.onFileError || function(){}; 6 | this._onURLSubmit = config.onURLSubmit || function(){}; 7 | this._onURLError = config.onURLError || function(){}; 8 | this._dragover = config.onDragover || function(){}; 9 | this._dragleave = config.onDragleave || function(){}; 10 | this.element = this._setupElement(config.element); 11 | this._setupMouseEvents(); 12 | 13 | $(this.element).find('input[type="file"]').change(function(){ 14 | that._reactToFile(this); 15 | }); 16 | $(this.element).find('.ext-input-field input').on('submit',function(){ 17 | that._reactToURL( $(this).val() ); 18 | }).keypress(function(e){ 19 | if (e.which === 13) { 20 | that._reactToURL( $(this).val() ); 21 | return false; 22 | } 23 | }); 24 | } 25 | window.oTinput = oTinput; 26 | oTinput.prototype._setupElement = function(element){ 27 | var that = this; 28 | if (typeof element === 'undefined') { 29 | throw('must specify container element'); 30 | } 31 | var buttonText = this._text.button || 'Choose audio (or video) file'; 32 | var button = ''; 33 | var fileInputStyle = [ 34 | 'position: absolute', 35 | 'top: 0', 36 | 'left: 0', 37 | 'opacity: 0', 38 | 'width: 100%' 39 | ].join(';'); 40 | var fileInput = ''; 41 | var wrapperStyle = 'position: relative; overflow: hidden;'; 42 | var wrapper = '
'+button+fileInput+'
'; 43 | var altButtonText = this._text.altButton || 'Enter file URL'; 44 | var altButton = ''; 45 | var urlInputText = this._text.altInputText || 'Enter URL of audio or video file, or YouTube video:'; 46 | var urlInputClose = this._text.closeAlt || 'close'; 47 | var urlInput = ''; 48 | $(element).html( wrapper + altButton + urlInput ); 49 | return $(element)[0]; 50 | }; 51 | oTinput.prototype._setupMouseEvents = function(){ 52 | var that = this; 53 | var element = this.element; 54 | var buttonEl = $(element).find('.file-input-wrapper')[0]; 55 | buttonEl.addEventListener('dragover', function(){ 56 | that._dragover(); 57 | }, false); 58 | buttonEl.addEventListener('dragleave', function(){ 59 | that._dragleave(); 60 | }, false); 61 | $(element).find('.alt-input-button').click(function(){ 62 | that.showURLInput(); 63 | }); 64 | $(element).find('.close-ext-input').click(function(){ 65 | that.showFileInput(); 66 | }); 67 | }; 68 | oTinput.prototype._reactToFile = function(input){ 69 | var file = input.files[0]; 70 | if ( this.isFormatSupported(file) ) { 71 | this._onFileChange( file ); 72 | } else { 73 | var err = new Error('Filetype '+file.type+' not supported by this browser'); 74 | this._onFileError(err, file); 75 | } 76 | }; 77 | oTinput.prototype._reactToURL = function(url){ 78 | var input = url.replace(/\s/g,''); 79 | if (this.parseYoutubeURL(input)){ 80 | return this._onURLSubmit( input ); 81 | } 82 | var formatArr = input.split('.'); 83 | var format = formatArr[formatArr.length-1]; 84 | if ( this.isFormatSupported(format) ) { 85 | this._onURLSubmit( input ); 86 | } else { 87 | var err = new Error('Filetype '+format+' not supported by this browser'); 88 | this._onURLError(err, url); 89 | } 90 | }; 91 | oTinput.prototype.showURLInput = function(){ 92 | $(this.element).find('.ext-input-field').show().find('input').focus(); 93 | $(this.element).addClass('ext-input-active'); 94 | }; 95 | oTinput.prototype.showFileInput = function(){ 96 | $(this.element).find('.ext-input-field').hide(); 97 | $(this.element).removeClass('ext-input-active'); 98 | }; 99 | -------------------------------------------------------------------------------- /test/otinput.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Test 6 | 7 | 8 | 9 | 10 |
11 | 12 |
13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/otinput.test.js: -------------------------------------------------------------------------------- 1 | var exMp3 = 'https://raw.githubusercontent.com/ejb/progressor.js/gh-pages/demos/discipline.mp3'; 2 | var exYt = 'https://www.youtube.com/watch?v=N9XKLqGqwLA'; 3 | 4 | QUnit.test( "Returns list of supported file formats", function( assert ) { 5 | assert.equal( typeof oTinput.getSupportedFormats().audio.length, 'number' ); 6 | assert.equal( typeof oTinput.getSupportedFormats().video.length, 'number' ); 7 | }); 8 | 9 | QUnit.test( "Tests file format", function( assert ) { 10 | assert.ok( !oTinput.isFormatSupported('blah') ); 11 | }); 12 | 13 | QUnit.test( "Sets up element", function( assert ) { 14 | var input = new oTinput({ 15 | element: '.test' 16 | }); 17 | assert.equal( $('.test input').attr('type'), 'file' ); 18 | }); 19 | 20 | QUnit.test( "Show/hide external element input", function( assert ) { 21 | var input = new oTinput({ 22 | element: '.test' 23 | }); 24 | $('.alt-input-button').click(); 25 | assert.equal( $('.ext-input-field').css('display'), 'block' ); 26 | $('.close-ext-input').click(); 27 | assert.equal( $('.ext-input-field').css('display'), 'none' ); 28 | input.showURLInput(); 29 | assert.equal( $('.ext-input-field').css('display'), 'block' ); 30 | input.showFileInput(); 31 | assert.equal( $('.ext-input-field').css('display'), 'none' ); 32 | }); 33 | 34 | /* 35 | 36 | QUnit.test( "Load external file", function( assert ) { 37 | var done = assert.async(); 38 | var input = new oTinput({ 39 | element: '.test', 40 | onURLSubmit: function(url){ 41 | assert.equal(url, exMp3); 42 | done(); 43 | } 44 | }); 45 | input._reactToURL( exMp3 ); 46 | }); 47 | 48 | QUnit.test( "Load youtube video", function( assert ) { 49 | var input = new oTinput({ 50 | element: '.test' 51 | }); 52 | $('.alt-input-button').click(); 53 | $('.ext-input-field input').val(exYt).submit(); 54 | }); 55 | 56 | */ 57 | 58 | --------------------------------------------------------------------------------