ソースを参照

Upgrade to release v2.4.0

Kartik Visweswaran 10 年 前
コミット
7be21df85e
11 ファイル変更463 行追加255 行削除
  1. 33 0
      CHANGE.md
  2. 1 1
      LICENSE.md
  3. 204 107
      README.md
  4. 3 2
      bower.json
  5. 2 2
      composer.json
  6. 6 6
      css/fileinput.css
  7. 1 1
      css/fileinput.min.css
  8. 1 0
      examples/index.html
  9. 0 0
      examples/small.ogg
  10. 211 135
      js/fileinput.js
  11. 1 1
      js/fileinput.min.js

+ 33 - 0
CHANGE.md

@@ -1,3 +1,36 @@
+version 2.4.0
+=============
+**Date:** 20-Sep-2014
+
+> **Note:** There are BC Breaking Changes with release v2.4.0.
+
+With release v2.4.0, the plugin has been revamped to support and configure a wide variety of file formats for preview. This may break some
+backward compatibility (BC) for older versions that use custom templates. 
+
+The following are the major changes with release v2.4.0:
+
+- Plugin has been revamped to build preview intelligence based on various file preview types. The inbuilt file support types are categorized as 
+  `image`, `text`, `html`, `video`,  `audio`, `flash`, `object`, and `other`.
+- `allowedPreviewTypes`: You can now configure which all file types are allowed to be shown as a preview. This defaults to `['image', 'html', 'text', 'video', 'audio', 'flash', 'object']`.
+   Thus all file types are treated as an object to preview by default. For exampleTo preview only `image` and `video`, you can set this to `['image', 'video']`.
+- `allowedPreviewMimeTypes`: In addition to `allowedPreviewTypes`, you can also control which all mime types can be displayed for preview. This defaults to null,
+   meaning all mime types are supported.
+- `layoutTemplates`: Allows you to configure all layout template settings within one property. The layout objects that can be configured are: `main1`, `main2`,
+   `preview`, `caption`, and `modal`.
+- `previewTemplates`: All preview templates for **each preview type** have been combined into one property, instead of separate templates for image, text etc. 
+   The keys are the formats as set in `allowedPreviewTypes` and values are the templates used for previewing. There are default prebuilt templates for each 
+   preview file type (`generic`, `image`, `text`, `html`, `video`,  `audio`, `flash`, `object`, and `other`). The `generic` template is used only for displaying
+   `initialPreview` content using direct markup.
+- `previewSettings`: Allows you to configure width and height for each preview image type. The plugin has default widths and heights predefined for each type i.e
+   `image`, `text`, `html`, `video`,  `audio`, `flash`, and `object`.
+- `fileTypeSettings`: Allows you to configure and identify each preview file type using a callback. The plugin has default callbacks predefined to identify each type i.e
+   `image`, `text`, `html`, `video`,  `audio`, `flash`, and `object`.
+- Replacing tags within templates has been enhanced. With this release it will automatically check for multiple occurrences of each tag to replace within a template string.
+
+> NOTE: Flash preview will require Shockwave flash to be installed and supported by the client browser. The flash preview currently works successfully with webkit browsers only. Video & Audio formats are however supported by all modern browsers 
+that support the HTML5 `video`/`audio` tags. Note that browsers have limited number of video/audio formats supported by the HTML5 video element (e.g. mp4, webm, ogg, mp3, wav). The size of video files are recommended to be small (to be controlled 
+through `maxFileSize` property) so that it does not affect the preview performance. You can copy a few files from the `examples` directory of this plugin repo, to test a few examples of flash and video files.
+
 version 2.3.0
 version 2.3.0
 =============
 =============
 **Date:** 19-Sep-2014
 **Date:** 19-Sep-2014

+ 1 - 1
LICENSE.md

@@ -1,4 +1,4 @@
-Copyright (c) 2013, Kartik Visweswaran  
+Copyright (c) 2014, Kartik Visweswaran  
 Krajee.com  
 Krajee.com  
 All rights reserved.  
 All rights reserved.  
 
 

+ 204 - 107
README.md

@@ -1,12 +1,13 @@
 bootstrap-fileinput
 bootstrap-fileinput
 ====================
 ====================
 
 
-An enhanced HTML 5 file input for Bootstrap 3.x with file preview for images and text, multiple selection, and more. This plugin is inspired by [this blog article](http://www.abeautifulsite.net/blog/2013/08/whipping-file-inputs-into-shape-with-bootstrap-3/) and [Jasny's File Input plugin](http://jasny.github.io/bootstrap/javascript/#fileinput). The plugin enhances these concepts and simplifies the widget initialization with simple HTML markup on a file input. It also offers support for multiple file preview and previewing a wide variety of files
-(i.e. images, text, flash, and video file types).
+An enhanced HTML 5 file input for Bootstrap 3.x with file preview for various files, offers multiple selection, and more. This plugin is inspired by [this blog article](http://www.abeautifulsite.net/blog/2013/08/whipping-file-inputs-into-shape-with-bootstrap-3/) and [Jasny's File Input plugin](http://jasny.github.io/bootstrap/javascript/#fileinput). 
+The plugin enhances these concepts and simplifies the widget initialization with simple HTML markup on a file input. It offers support for previewing a 
+wide variety of files i.e. images, text, html, video, audio, flash, and objects.
 
 
-![File Input Screenshot](https://lh5.googleusercontent.com/-gnX0zXygMns/VBtHCRLJFVI/AAAAAAAAAM8/55zosZYXd_k/w597-h375-no/FileInput.jpg)
+![File Input Screenshot](https://lh4.googleusercontent.com/-wlx-wTVFSwE/VBwt8S8uLpI/AAAAAAAAAN8/bV9h6Emp05g/w597-h448-no/FileInput.jpg)
 
 
-> NOTE: The latest version of the plugin v2.3.0 has been released. Refer the [CHANGE LOG](https://github.com/kartik-v/bootstrap-fileinput/blob/master/CHANGE.md) for details.
+> NOTE: The latest version of the plugin v2.4.0 has been released. Refer the [CHANGE LOG](https://github.com/kartik-v/bootstrap-fileinput/blob/master/CHANGE.md) for details.
 
 
 ## Features  
 ## Features  
 
 
@@ -35,10 +36,37 @@ An enhanced HTML 5 file input for Bootstrap 3.x with file preview for images and
 13. Disabled and readonly file input support.
 13. Disabled and readonly file input support.
 14. Size of the entire plugin is less than 6KB if gzipped. The minified assets are less than 21KB (about 18KB for the minified JS and 3KB for the minified CSS).
 14. Size of the entire plugin is less than 6KB if gzipped. The minified assets are less than 21KB (about 18KB for the minified JS and 3KB for the minified CSS).
 
 
-> **Note:** With release v2.3.0, the plugin now supports preview of flash and video files. Flash preview will require Shockwave flash to be installed and supported by the client browser. 
-The flash preview currently works successfully with webkit browsers due to its unique local url creation support. Videos are however supported by all modern browsers 
-that support the HTML5 `video` tag. Note that browsers have limited number of video formats supported by the HTML5 video element (e.g. mp4, webm, ogg). The size of video files are recommended to be small (controlled through `maxFileSize` property) for not affecting your 
-browser preview performance. You can copy a few files from the `examples` directory of this plugin repo, to test a few examples of flash and video files.
+### New features since v2.4.0
+
+> **Note:** There are BC Breaking Changes with release v2.4.0.
+
+With release v2.4.0, the plugin has been revamped to support and configure a wide variety of file formats for preview. This may break some
+backward compatibility (BC) for older versions that use custom templates. 
+
+The following are the major changes with release v2.4.0:
+
+- Completely templatized and extensible to allow configuration of the file-input the way the developer wants.
+- Plugin has been revamped to build preview intelligence based on various file preview types. The inbuilt file support types are categorized as 
+  `image`, `text`, `html`, `video`,  `audio`, `flash`, `object`, and `other`.
+- `allowedPreviewTypes`: You can now configure which all file types are allowed to be shown as a preview. This defaults to `['image', 'html', 'text', 'video', 'audio', 'flash', 'object']`.
+   Thus all file types are treated as an object to preview by default. For exampleTo preview only `image` and `video`, you can set this to `['image', 'video']`.
+- `allowedPreviewMimeTypes`: In addition to `allowedPreviewTypes`, you can also control which all mime types can be displayed for preview. This defaults to null,
+   meaning all mime types are supported.
+- `layoutTemplates`: Allows you to configure all layout template settings within one property. The layout objects that can be configured are: `main1`, `main2`,
+   `preview`, `caption`, and `modal`.
+- `previewTemplates`: All preview templates for **each preview type** have been combined into one property, instead of separate templates for image, text etc. 
+   The keys are the formats as set in `allowedPreviewTypes` and values are the templates used for previewing. There are default prebuilt templates for each 
+   preview file type (`generic`, `image`, `text`, `html`, `video`,  `audio`, `flash`, `object`, and `other`). The `generic` template is used only for displaying
+   `initialPreview` content using direct markup.
+- `previewSettings`: Allows you to configure width and height for each preview image type. The plugin has default widths and heights predefined for each type i.e
+   `image`, `text`, `html`, `video`,  `audio`, `flash`, and `object`.
+- `fileTypeSettings`: Allows you to configure and identify each preview file type using a callback. The plugin has default callbacks predefined to identify each type i.e
+   `image`, `text`, `html`, `video`,  `audio`, `flash`, and `object`.
+- Replacing tags within templates has been enhanced. With this release it will automatically check for multiple occurrences of each tag to replace within a template string.
+
+> NOTE: Flash preview will require Shockwave flash to be installed and supported by the client browser. The flash preview currently works successfully with webkit browsers only. Video & Audio formats are however supported by all modern browsers 
+that support the HTML5 `video`/`audio` tags. Note that browsers have limited number of video/audio formats supported by the HTML5 video element (e.g. mp4, webm, ogg, mp3, wav). The size of video files are recommended to be small (to be controlled 
+through `maxFileSize` property) so that it does not affect the preview performance. You can copy a few files from the `examples` directory of this plugin repo, to test a few examples of flash and video files.
 
 
 ## Demo
 ## Demo
 
 
@@ -213,122 +241,191 @@ _boolean_ whether you wish to overwrite the initial preview content and caption
 will be overwritten, when new file is uploaded or when files are cleared. Setting it to `false` will help displaying a saved image or file from database always - 
 will be overwritten, when new file is uploaded or when files are cleared. Setting it to `false` will help displaying a saved image or file from database always - 
 useful especially when using the `multiple` file upload feature.
 useful especially when using the `multiple` file upload feature.
  
  
-#### captionTemplate
-_string_ the template used to render the caption. The following template variables will be parsed:
+#### layoutTemplates
 
 
-- `{class}`: the CSS class as set in the `captionClass` property.
+_object_ the templates configuration for rendering each part of the layout. You can set the following templates to control the widget layout:
 
 
-The `captionTemplate` if not set will default to:
-```html
-<div tabindex="-1" class="form-control file-caption {class}">
-   <span class="glyphicon glyphicon-file"></span> <span class="file-caption-name"></span>
-</div>
-```
-
-#### previewTemplate
-_string_ the template used to render the preview. The following template variables will be parsed:
-
-- `{class}`: the CSS class as set in the `previewClass` property.
-
-The `previewTemplate` if not set will default to:
-```html
-<div class="file-preview {class}">
-   <div class="close fileinput-remove text-right">&times;</div>
-   <div class="file-preview-thumbnails"></div>
-   <div class="clearfix"></div>
-   <div class="file-preview-status text-center text-success"></div>
-</div>
-```
+`main1`: the template for rendering the widget with caption.
+`main2`: the template for rendering the widget without caption.
+`preview`: the template for rendering the preview.
+`caption`: the template for rendering the caption.
+`modal`: the template for rendering the modal (for text file preview zooming).
 
 
-#### previewGenericTemplate
-_string_ the generic preview template markup used within the preview container. Defaults to `IMAGE_TEMPLATE` as shown below.
-The following variables will be parsed:
+The `main1`, `preview` and `caption` templates can understand the following special tags which will be replaced:
 
 
-- `{content}`: the file preview content
-- `{previewId}`: the previewed file container identifier
+- `{class}`: the CSS class as set in the `mainClass`, `captionClass` or `previewClass` properties.
 
 
-```html
-<div class="file-preview-frame" id="{previewId}">
-    {content}
-</div>
-```
-
-#### previewImageTemplate
-_string_ the template markup for previewing image files within the preview container. Defaults to `IMAGE_TEMPLATE` as shown below.
-The following variables will be parsed:
-
-- `{content}`: the file preview content
-- `{previewId}`: the previewed file container identifier
-
-```html
-<div class="file-preview-frame" id="{previewId}">
-    {content}
-</div>
-```
+The `layoutTemplates` if not set will default to:
 
 
-#### previewTextTemplate
-_string_ the template markup for previewing text files within the preview container. Defaults to `TEXT_TEMPLATE` as shown below.
-The following variables will be parsed:
-
-- `{strText}`: the file text content
-- `{caption}`: the file name to be displayed on hover
-- `{previewId}`: the previewed file container identifier
+```js
+{
+    main1: '{preview}\n' +
+        '<div class="input-group {class}">\n' +
+        '   {caption}\n' +
+        '   <div class="input-group-btn">\n' +
+        '       {remove}\n' +
+        '       {upload}\n' +
+        '       {browse}\n' +
+        '   </div>\n' +
+        '</div>',
+    main2: '{preview}\n{remove}\n{upload}\n{browse}\n',
+    preview: '<div class="file-preview {class}">\n' +
+        '   <div class="close fileinput-remove text-right">&times;</div>\n' +
+        '   <div class="file-preview-thumbnails"></div>\n' +
+        '   <div class="clearfix"></div>' +
+        '   <div class="file-preview-status text-center text-success"></div>\n' +
+        '</div>',
+    caption: '<div tabindex="-1" class="form-control file-caption {class}">\n' +
+        '   <span class="glyphicon glyphicon-file kv-caption-icon"></span><div class="file-caption-name"></div>\n' +
+        '</div>',
+    modal: '<div id="{id}" class="modal fade">\n' +
+        '  <div class="modal-dialog modal-lg">\n' +
+        '    <div class="modal-content">\n' +
+        '      <div class="modal-header">\n' +
+        '        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>\n' +
+        '        <h3 class="modal-title">Detailed Preview <small>{title}</small></h3>\n' +
+        '      </div>\n' +
+        '      <div class="modal-body">\n' +
+        '        <textarea class="form-control" style="font-family:Monaco,Consolas,monospace; height: {height}px;" readonly>{body}</textarea>\n' +
+        '      </div>\n' +
+        '    </div>\n' +
+        '  </div>\n' +
+        '</div>\n'    
+};
+```
+
+#### previewTemplates
+
+_object_ the templates configuration for rendering each preview file type. The following file types are recognized:
+
+`image`: the preview template for image files.
+`text`: the  preview template for text files.
+`html`: the preview template for html files.
+`video`: the preview template for video files (supported by HTML 5 video tag).
+`audio`: the preview template for audio files (supported by HTML 5 audio tag).
+`flash`: the preview template for flash files (supported currently on webkit browsers).
+`object`: the preview template for all other files - by default treated as object. To disable this behavior, configure the `allowedPreviewTypes` property.
+`generic`: this template is used ONLY for rendering the `initialPreview` markup content passed directly as a raw format. 
+
+As noted, if you are coming from an earlier release (before v2.4.0), all preview templates have now been combined into one property, instead of separate templates for image, text etc. 
+
+The `previewTemplates` if not set will default to:
 
 
-```html
-<div class="file-preview-frame" id="{previewId}">
-    <div class="file-preview-text" title="{caption}">
-        {strText}
-    </div>
-</div>
+```js
+{
+    generic: '<div class="file-preview-frame" id="{previewId}">\n' +
+        '   {content}\n' +
+        '</div>\n',
+    html: '<div class="file-preview-frame" id="{previewId}">\n' +
+        '    <object data="{data}" type="{type}" width="{width}" height="{height}">\n' +
+        '       ' + DEFAULT_PREVIEW + '\n' +
+        '    </object>\n' + PREVIEW_LABEL + 
+        '</div>',
+    image: '<div class="file-preview-frame" id="{previewId}">\n' +
+        '   <img src="{data}" class="file-preview-image" title="{caption}" alt="{caption}" ' + STYLE_SETTING + '>\n' +
+        '</div>\n',
+    text: '<div class="file-preview-frame" id="{previewId}">\n' +
+        '   <div class="file-preview-text" title="{caption}" ' + STYLE_SETTING + '>\n' +
+        '       {data}\n' + 
+        '   </div>\n' + 
+        '</div>\n',
+    video: '<div class="file-preview-frame" id="{previewId}" title="{caption}" ' + STYLE_SETTING + '>\n' +
+        '   <video width="{width}" height="{height}" controls>\n' +
+        '       <source src="{data}" type="{type}">\n' +
+        '       ' + DEFAULT_PREVIEW + '\n' +
+        '   </video>\n' + PREVIEW_LABEL + 
+        '</div>\n',
+    audio: '<div class="file-preview-frame" id="{previewId}" title="{caption}" ' + STYLE_SETTING + '>\n' +
+        '   <audio controls>\n' +
+        '       <source src="{data}" type="{type}">\n' +
+        '       ' + DEFAULT_PREVIEW + '\n' +
+        '   </audio>\n' + PREVIEW_LABEL + 
+        '</div>\n',
+    flash: '<div class="file-preview-frame" id="{previewId}" title="{caption}" ' + STYLE_SETTING + '>\n' +
+        '   <object type="application/x-shockwave-flash" width="{width}" height="{height}" data="{data}">\n' +
+        OBJECT_PARAMS + '       ' + DEFAULT_PREVIEW + '\n' +
+        '   </object>\n' + PREVIEW_LABEL + 
+        '</div>\n',
+    object: '<div class="file-preview-frame" id="{previewId}" title="{caption}" ' + STYLE_SETTING + '>\n' +
+        '    <object data="{data}" type="{type}" width="{width}" height="{height}">\n' +
+        '      <param name="movie" value="{caption}" />\n' +
+        OBJECT_PARAMS + '           ' + DEFAULT_PREVIEW + '\n' +
+        '   </object>\n' + PREVIEW_LABEL + 
+        '</div>',
+    other: '<div class="file-preview-frame" id="{previewId}" title="{caption}" ' + STYLE_SETTING + '>\n' +
+        '   ' + DEFAULT_PREVIEW + '\n' + PREVIEW_LABEL + 
+        '</div>',
+}
+```
+
+#### allowedPreviewTypes
+
+_array_ the list of allowed preview types for your widget. This by default supports all file types for preview. The plugin by default treats each
+file as an object if it does not match any of the previous types. To disable this behavior, you can remove `object` from the list of `allowedPreviewTypes`
+OR fine tune it through `allowedPreviewMimeTypes`.
+
+This is by default setup as following:
+```js
+['image', 'html', 'text', 'video', 'audio', 'flash', 'object']
 ```
 ```
 
 
-#### previewFlashTemplate
-_string_ the template markup for previewing flash files within the preview container. Defaults to `FLASH_TEMPLATE` as shown below.
-The following variables will be parsed:
+#### allowedPreviewMimeTypes
 
 
-- `{previewId}`: the previewed file container identifier
-- `{caption}`: the file name to be displayed on hover
-- `{media}`: the flash content to be previewed
+_array_ the list of allowed mime types for preview. This is set to null by default which means all possible mime types are allowed. This setting works in combination
+with `allowedPreviewTypes` to filter only the needed file types allowed for preview. You can check this [list of allowed mime types](http://www.sitepoint.com/web-foundations/mime-types-complete-list/)
+to add to this list if needed.
 
 
-```html
-<div class="file-preview-frame" id="{previewId}" title="{caption}">
-    <object type="application/x-shockwave-flash" data="{media}" width="320" height="240">
-        <param name="movie" value="{media}" />
-        <param name="quality" value="high" />
-    </object>
-</div>
-```
+#### previewSettings
 
 
-#### previewVideoTemplate
-_string_ the template markup for previewing video files within the preview container. Defaults to `VIDEO_TEMPLATE` as shown below.
-The following variables will be parsed:
+_object_ the format settings (width and height) for rendering each preview file type. This is by default setup as following:
 
 
-- `{previewId}`: the previewed file container identifier
-- `{caption}`: the file name to be displayed on hover
-- `{media}`: the flash content to be previewed
-- `{type}`: the type of video file to be previewed
-
-```html
-<div class="file-preview-frame" id="{previewId}" title="{caption}">
-    <source src="{media}" type="{type}">
-    <small>The video format of "{caption}" is not supported by your browser for preview (must be one mp4, webm, 3gp, ogg).</small>
-</div>
+```js
+{
+    image: {width: "auto", height: "160px"},
+    html: {width: "320px", height: "180px"},
+    text: {width: "160px", height: "160px"},
+    video: {width: "320px", height: "240px"},
+    audio: {width: "320px", height: "80px"},
+    flash: {width: "320px", height: "240px"},
+    object: {width: "320px", height: "300px"},
+    other: {width: "160px", height: "120px"}
+}
 ```
 ```
 
 
-#### previewOtherTemplate
-_string_ the template markup for previewing all other files within the preview container. Defaults to `OTHER_TEMPLATE` as shown below.
-The following variables will be parsed:
+#### fileTypeSettings
 
 
-- `{caption}`: the file name to be displayed 
-- `{previewId}`: the previewed file container identifier
+_object_ the settings to validate and identify each file type when a file is selected for upload. This is a list of callbacks, which accepts the file mime type and file name as a parameter.
+This is by default setup as following:
 
 
-```html
-<div class="file-preview-frame" id="{previewId}">
-   <div class="file-preview-other">
-       <h2><i class="glyphicon glyphicon-file"></i></h2>
-       {caption}
-   </div>
-</div>
+```js
+// vType: is the file mime type
+// vName: is the file name
+{
+    image: function(vType, vName) {
+        return (typeof vType !== "undefined") ? vType.match('image.*') : vName.match(/\.(gif|png|jpe?g)$/i);
+    },
+    html: function(vType, vName) {
+        return (typeof vType !== "undefined") ? vType == 'text/html' : vName.match(/\.(htm|html)$/i);
+    },
+    text: function(vType, vName) {
+        return (typeof vType !== "undefined") ? vType.match('text.*') : vName.match(/\.(txt|md|csv|nfo|php|ini)$/i);
+    },
+    video: function (vType, vName) {
+        return (typeof vType !== "undefined" && vType.match(/\.video\/(ogg|mp4|webm)$/i)) || vName.match(/\.(og?|mp4|webm)$/i);
+    },
+    audio: function (vType, vName) {
+        return (typeof vType !== "undefined" && vType.match(/\.audio\/(ogg|mp3|wav)$/i)) || vName.match(/\.(ogg|mp3|wav)$/i);
+    },
+    flash: function (vType, vName) {
+        return (typeof vType !== "undefined" && vType == 'application/x-shockwave-flash') || vName.match(/\.(swf)$/i);
+    },
+    object: function (vType, vName) {
+        return true;
+    },
+    other: function (vType, vName) {
+        return true;
+    },
+}
 ```
 ```
 
 
 #### browseLabel
 #### browseLabel

+ 3 - 2
bower.json

@@ -1,6 +1,6 @@
 {
 {
     "name": "bootstrap-fileinput",
     "name": "bootstrap-fileinput",
-    "version": "2.3.0",
+    "version": "2.4.0",
     "homepage": "https://github.com/kartik-v/bootstrap-fileinput",
     "homepage": "https://github.com/kartik-v/bootstrap-fileinput",
     "authors": [
     "authors": [
         "Kartik Visweswaran <[email protected]>"
         "Kartik Visweswaran <[email protected]>"
@@ -16,7 +16,8 @@
         "input",
         "input",
         "preview",
         "preview",
         "image",
         "image",
-        "upload"
+        "upload",
+        "multiple"
     ],
     ],
     "dependencies": {
     "dependencies": {
         "jquery": ">= 1.9.0",
         "jquery": ">= 1.9.0",

+ 2 - 2
composer.json

@@ -1,7 +1,7 @@
 {
 {
     "name": "kartik-v/bootstrap-fileinput",
     "name": "kartik-v/bootstrap-fileinput",
-    "description": "An enhanced HTML 5 file input for Bootstrap 3.x with file preview, multiple selection, and more features.",
-    "keywords": ["bootstrap", "jquery", "file", "input", "preview", "upload", "image"],
+    "description": "An enhanced HTML 5 file input for Bootstrap 3.x with features for file preview for many file types, multiple selection, and more.",
+    "keywords": ["bootstrap", "jquery", "file", "input", "preview", "upload", "image", "multiple"],
     "homepage": "https://github.com/kartik-v/bootstrap-fileinput",
     "homepage": "https://github.com/kartik-v/bootstrap-fileinput",
     "license": "BSD 3-Clause",
     "license": "BSD 3-Clause",
     "authors": [
     "authors": [

+ 6 - 6
css/fileinput.css

@@ -1,7 +1,7 @@
 /*!
 /*!
  * @copyright Copyright &copy; Kartik Visweswaran, Krajee.com, 2014
  * @copyright Copyright &copy; Kartik Visweswaran, Krajee.com, 2014
  * @package bootstrap-fileinput
  * @package bootstrap-fileinput
- * @version 2.3.0
+ * @version 2.4.0
  *
  *
  * File input styling for Bootstrap 3.0
  * File input styling for Bootstrap 3.0
  * Built for Yii Framework 2.0
  * Built for Yii Framework 2.0
@@ -101,14 +101,14 @@
 }
 }
 
 
 .file-preview-image {
 .file-preview-image {
-    height: 150px;
+    height: 160px;
     vertical-align: text-center;
     vertical-align: text-center;
 }
 }
 
 
 .file-preview-text {
 .file-preview-text {
     display: table-cell;
     display: table-cell;
-    width: 150px;
-    height: 150px;
+    width: 160px;
+    height: 160px;
     color: #428bca;
     color: #428bca;
     font-size: 11px;
     font-size: 11px;
     vertical-align: middle;
     vertical-align: middle;
@@ -117,8 +117,8 @@
 
 
 .file-preview-other {
 .file-preview-other {
     display: table-cell;
     display: table-cell;
-    width: 150px;
-    height: 150px;
+    width: 160px;
+    height: 160px;
     font-family: Monaco, Consolas, monospace;
     font-family: Monaco, Consolas, monospace;
     font-size: 11px;
     font-size: 11px;
     vertical-align: middle;
     vertical-align: middle;

+ 1 - 1
css/fileinput.min.css

@@ -1,7 +1,7 @@
 /*!
 /*!
  * @copyright Copyright &copy; Kartik Visweswaran, Krajee.com, 2014
  * @copyright Copyright &copy; Kartik Visweswaran, Krajee.com, 2014
  * @package bootstrap-fileinput
  * @package bootstrap-fileinput
- * @version 2.3.0
+ * @version 2.4.0
  *
  *
  * File input styling for Bootstrap 3.0
  * File input styling for Bootstrap 3.0
  * Built for Yii Framework 2.0
  * Built for Yii Framework 2.0

+ 1 - 0
examples/index.html

@@ -1,4 +1,5 @@
 <!DOCTYPE html>
 <!DOCTYPE html>
+<!-- release v2.4.0, copyright 2014 Kartik Visweswaran -->
 <html lang="en">
 <html lang="en">
     <head>
     <head>
         <meta charset="UTF-8"/>
         <meta charset="UTF-8"/>

+ 0 - 0
examples/small.ogv → examples/small.ogg


+ 211 - 135
js/fileinput.js

@@ -1,6 +1,6 @@
 /*!
 /*!
  * @copyright Copyright &copy; Kartik Visweswaran, Krajee.com, 2014
  * @copyright Copyright &copy; Kartik Visweswaran, Krajee.com, 2014
- * @version 2.3.0
+ * @version 2.4.0
  *
  *
  * File input styled for Bootstrap 3.0 that utilizes HTML5 File Input's advanced 
  * File input styled for Bootstrap 3.0 that utilizes HTML5 File Input's advanced 
  * features including the FileReader API. This plugin is inspired by the blog article at
  * features including the FileReader API. This plugin is inspired by the blog article at
@@ -16,7 +16,20 @@
  * For more Yii related demos visit http://demos.krajee.com
  * For more Yii related demos visit http://demos.krajee.com
  */
  */
 (function ($) {
 (function ($) {
-    var MAIN_TEMPLATE_1 = '{preview}\n' +
+    var STYLE_SETTING = 'style="width:{width};height:{height};"';
+    var PREVIEW_LABEL = '   <div class="text-center"><small>{caption}</small></div>\n';
+    var OBJECT_PARAMS = '      <param name="controller" value="true" />\n' +
+        '      <param name="allowFullScreen" value="true" />\n' +
+        '      <param name="allowScriptAccess" value="always" />\n' +
+        '      <param name="autoPlay" value="false" />\n' +
+        '      <param name="autoStart" value="false" />\n'+
+        '      <param name="quality" value="high" />\n';
+
+    var DEFAULT_PREVIEW = '<div class="file-preview-other" ' + STYLE_SETTING + '>\n' +
+        '       <h2><i class="glyphicon glyphicon-file"></i></h2>\n' +
+        '   </div>';
+    var defaultLayoutTemplates = {
+        main1: '{preview}\n' +
             '<div class="input-group {class}">\n' +
             '<div class="input-group {class}">\n' +
             '   {caption}\n' +
             '   {caption}\n' +
             '   <div class="input-group-btn">\n' +
             '   <div class="input-group-btn">\n' +
@@ -25,21 +38,17 @@
             '       {browse}\n' +
             '       {browse}\n' +
             '   </div>\n' +
             '   </div>\n' +
             '</div>',
             '</div>',
-
-        MAIN_TEMPLATE_2 = '{preview}\n{remove}\n{upload}\n{browse}\n',
-
-        PREVIEW_TEMPLATE = '<div class="file-preview {class}">\n' +
+        main2: '{preview}\n{remove}\n{upload}\n{browse}\n',
+        preview: '<div class="file-preview {class}">\n' +
             '   <div class="close fileinput-remove text-right">&times;</div>\n' +
             '   <div class="close fileinput-remove text-right">&times;</div>\n' +
             '   <div class="file-preview-thumbnails"></div>\n' +
             '   <div class="file-preview-thumbnails"></div>\n' +
             '   <div class="clearfix"></div>' +
             '   <div class="clearfix"></div>' +
             '   <div class="file-preview-status text-center text-success"></div>\n' +
             '   <div class="file-preview-status text-center text-success"></div>\n' +
             '</div>',
             '</div>',
-
-        CAPTION_TEMPLATE = '<div tabindex="-1" class="form-control file-caption {class}">\n' +
+        caption: '<div tabindex="-1" class="form-control file-caption {class}">\n' +
             '   <span class="glyphicon glyphicon-file kv-caption-icon"></span><div class="file-caption-name"></div>\n' +
             '   <span class="glyphicon glyphicon-file kv-caption-icon"></span><div class="file-caption-name"></div>\n' +
             '</div>',
             '</div>',
-
-        MODAL_TEMPLATE = '<div id="{id}" class="modal fade">\n' +
+        modal: '<div id="{id}" class="modal fade">\n' +
             '  <div class="modal-dialog modal-lg">\n' +
             '  <div class="modal-dialog modal-lg">\n' +
             '    <div class="modal-content">\n' +
             '    <div class="modal-content">\n' +
             '      <div class="modal-header">\n' +
             '      <div class="modal-header">\n' +
@@ -51,64 +60,105 @@
             '      </div>\n' +
             '      </div>\n' +
             '    </div>\n' +
             '    </div>\n' +
             '  </div>\n' +
             '  </div>\n' +
-            '</div>\n',
-
-        IMAGE_TEMPLATE = '<div class="file-preview-frame" id="{previewId}">\n' +
+            '</div>\n'    
+    };
+    var defaultPreviewTypes = ['image', 'html', 'text', 'video', 'audio', 'flash', 'object'];
+    var defaultPreviewTemplates = {
+        generic: '<div class="file-preview-frame" id="{previewId}">\n' +
             '   {content}\n' +
             '   {content}\n' +
             '</div>\n',
             '</div>\n',
-
-        TEXT_TEMPLATE = '<div class="file-preview-frame" id="{previewId}">\n' +
-            '   <div class="file-preview-text" title="{caption}">\n' +
-            '       {strText}\n' +
-            '   </div>\n' +
+        html: '<div class="file-preview-frame" id="{previewId}">\n' +
+            '    <object data="{data}" type="{type}" width="{width}" height="{height}">\n' +
+            '       ' + DEFAULT_PREVIEW + '\n' +
+            '    </object>\n' + PREVIEW_LABEL + 
+            '</div>',
+        image: '<div class="file-preview-frame" id="{previewId}">\n' +
+            '   <img src="{data}" class="file-preview-image" title="{caption}" alt="{caption}" ' + STYLE_SETTING + '>\n' +
             '</div>\n',
             '</div>\n',
-
-        FLASH_TEMPLATE = '<div class="file-preview-frame" id="{previewId}" title="{caption}">\n' +
-            '   <object type="application/x-shockwave-flash" data="{media}" width="320" height="240">\n' +
-            '       <param name="movie" value="{media}" />\n' +
-            '       <param name="quality" value="high" />\n' +
-            '   </object>\n' +
+        text: '<div class="file-preview-frame" id="{previewId}">\n' +
+            '   <div class="file-preview-text" title="{caption}" ' + STYLE_SETTING + '>\n' +
+            '       {data}\n' + 
+            '   </div>\n' + 
             '</div>\n',
             '</div>\n',
-            
-        VIDEO_TEMPLATE = '<div class="file-preview-frame" id="{previewId}" title="{caption}">\n' +
-            '   <video width="320" height="240" controls>\n' +
-            '       <source src="{media}" type="{type}">\n' +
-            '       <small>The video format of "{caption}" is not supported by your browser for preview (must be one mp4, webm, 3gp, ogg).</small>' +
-            '   </video>\n' +
+        video: '<div class="file-preview-frame" id="{previewId}" title="{caption}" ' + STYLE_SETTING + '>\n' +
+            '   <video width="{width}" height="{height}" controls>\n' +
+            '       <source src="{data}" type="{type}">\n' +
+            '       ' + DEFAULT_PREVIEW + '\n' +
+            '   </video>\n' + PREVIEW_LABEL + 
             '</div>\n',
             '</div>\n',
-
-        OTHER_TEMPLATE = '<div class="file-preview-frame" id="{previewId}">\n' +
-            '   <div class="file-preview-other">\n' +
-            '       <h2><i class="glyphicon glyphicon-file"></i></h2>\n' +
-            '           {caption}\n' +
-            '   </div>\n' +
+        audio: '<div class="file-preview-frame" id="{previewId}" title="{caption}" ' + STYLE_SETTING + '>\n' +
+            '   <audio controls>\n' +
+            '       <source src="{data}" type="{type}">\n' +
+            '       ' + DEFAULT_PREVIEW + '\n' +
+            '   </audio>\n' + PREVIEW_LABEL + 
+            '</div>\n',
+        flash: '<div class="file-preview-frame" id="{previewId}" title="{caption}" ' + STYLE_SETTING + '>\n' +
+            '   <object type="application/x-shockwave-flash" width="{width}" height="{height}" data="{data}">\n' +
+            OBJECT_PARAMS + '       ' + DEFAULT_PREVIEW + '\n' +
+            '   </object>\n' + PREVIEW_LABEL + 
+            '</div>\n',
+        object: '<div class="file-preview-frame" id="{previewId}" title="{caption}" ' + STYLE_SETTING + '>\n' +
+            '    <object data="{data}" type="{type}" width="{width}" height="{height}">\n' +
+            '      <param name="movie" value="{caption}" />\n' +
+            OBJECT_PARAMS + '           ' + DEFAULT_PREVIEW + '\n' +
+            '   </object>\n' + PREVIEW_LABEL + 
             '</div>',
             '</div>',
-
-        isEmpty = function (value, trim) {
+        other: '<div class="file-preview-frame" id="{previewId}" title="{caption}" ' + STYLE_SETTING + '>\n' +
+            '   ' + DEFAULT_PREVIEW + '\n' + PREVIEW_LABEL + 
+            '</div>',
+    };
+    var defaultPreviewSettings = {
+        image: {width: "auto", height: "160px"},
+        html: {width: "320px", height: "180px"},
+        text: {width: "160px", height: "160px"},
+        video: {width: "320px", height: "240px"},
+        audio: {width: "320px", height: "80px"},
+        flash: {width: "320px", height: "240px"},
+        object: {width: "320px", height: "300px"},
+        other: {width: "160px", height: "120px"}
+    };
+    var defaultFileTypeSettings = {
+        image: function(vType, vName) {
+            return (typeof vType !== "undefined") ? vType.match('image.*') : vName.match(/\.(gif|png|jpe?g)$/i);
+        },
+        html: function(vType, vName) {
+            return (typeof vType !== "undefined") ? vType == 'text/html' : vName.match(/\.(htm|html)$/i);
+        },
+        text: function(vType, vName) {
+            return (typeof vType !== "undefined") ? vType.match('text.*') : vName.match(/\.(txt|md|csv|nfo|php|ini)$/i);
+        },
+        video: function (vType, vName) {
+            return (typeof vType !== "undefined" && vType.match(/\.video\/(ogg|mp4|webm)$/i)) || vName.match(/\.(og?|mp4|webm)$/i);
+        },
+        audio: function (vType, vName) {
+            return (typeof vType !== "undefined" && vType.match(/\.audio\/(ogg|mp3|wav)$/i)) || vName.match(/\.(ogg|mp3|wav)$/i);
+        },
+        flash: function (vType, vName) {
+            return (typeof vType !== "undefined" && vType == 'application/x-shockwave-flash') || vName.match(/\.(swf)$/i);
+        },
+        object: function (vType, vName) {
+            return true;
+        },
+        other: function (vType, vName) {
+            return true;
+        },
+    };
+    var isEmpty = function (value, trim) {
             return value === null || value === undefined || value == []
             return value === null || value === undefined || value == []
             || value === '' || trim && $.trim(value) === '';
             || value === '' || trim && $.trim(value) === '';
         },
         },
         isArray = function (a) {
         isArray = function (a) {
             return Array.isArray(a) || Object.prototype.toString.call(a) === '[object Array]';
             return Array.isArray(a) || Object.prototype.toString.call(a) === '[object Array]';
         },
         },
+        isSet = function (needle, haystack) {
+            return (typeof haystack == 'object' && typeof haystack[needle] !== 'undefined');
+        },
         getValue = function (options, param, value) {
         getValue = function (options, param, value) {
             return (isEmpty(options) || isEmpty(options[param])) ? value : options[param];
             return (isEmpty(options) || isEmpty(options[param])) ? value : options[param];
         },
         },
         getElement = function (options, param, value) {
         getElement = function (options, param, value) {
             return (isEmpty(options) || isEmpty(options[param])) ? value : $(options[param]);
             return (isEmpty(options) || isEmpty(options[param])) ? value : $(options[param]);
         },
         },
-        isImageFile = function (type, name) {
-            return (typeof type !== "undefined") ? type.match('image.*') : name.match(/\.(gif|png|jpe?g)$/i);
-        },
-        isTextFile = function (type, name) {
-            return (typeof type !== "undefined") ? type.match('text.*') : name.match(/\.(txt|md|csv|htm|html|php|ini)$/i);
-        },
-        isVideoFile = function (type, name) {
-            return (typeof type !== "undefined") ? type.match('video.*') : name.match(/\.(ogg|mp4|webm|3gp|flv)$/i);
-        },
-        isFlashFile = function (type, name) {
-            return typeof type !== "undefined" && type == 'application/x-shockwave-flash' || type.match(/\.(swf)$/i);
-        },
         uniqId = function () {
         uniqId = function () {
             return Math.round(new Date().getTime() + (Math.random() * 100));
             return Math.round(new Date().getTime() + (Math.random() * 100));
         },
         },
@@ -150,24 +200,20 @@
             self.initialPreviewCount = options.initialPreviewCount;
             self.initialPreviewCount = options.initialPreviewCount;
             self.initialPreviewContent = options.initialPreviewContent;
             self.initialPreviewContent = options.initialPreviewContent;
             self.overwriteInitial = options.overwriteInitial;
             self.overwriteInitial = options.overwriteInitial;
+            self.layoutTemplates = options.layoutTemplates;
+            self.previewTemplates = options.previewTemplates;
+            self.allowedPreviewTypes = isEmpty(options.allowedPreviewTypes) ? defaultPreviewTypes : options.allowedPreviewTypes;
+            self.allowedPreviewMimeTypes = options.allowedPreviewMimeTypes;
+            self.previewSettings = options.previewSettings;
+            self.fileTypeSettings = options.fileTypeSettings;
             self.showRemove = options.showRemove;
             self.showRemove = options.showRemove;
             self.showUpload = options.showUpload;
             self.showUpload = options.showUpload;
             self.captionClass = options.captionClass;
             self.captionClass = options.captionClass;
             self.previewClass = options.previewClass;
             self.previewClass = options.previewClass;
             self.mainClass = options.mainClass;
             self.mainClass = options.mainClass;
-            if (isEmpty(options.mainTemplate)) {
-                self.mainTemplate = self.showCaption ? MAIN_TEMPLATE_1 : MAIN_TEMPLATE_2;
-            } else {
-                self.mainTemplate = options.mainTemplate;
-            }
-            self.previewTemplate = (self.showPreview) ? options.previewTemplate : '';
-            self.previewGenericTemplate = options.previewGenericTemplate;
-            self.previewImageTemplate = options.previewImageTemplate;
-            self.previewFlashTemplate = options.previewFlashTemplate;
-            self.previewVideoTemplate = options.previewVideoTemplate;
-            self.previewTextTemplate = options.previewTextTemplate;
-            self.previewOtherTemplate = options.previewOtherTemplate;
-            self.captionTemplate = options.captionTemplate;
+            self.mainTemplate = self.showCaption ? self.getLayoutTemplate('main1') : self.getLayoutTemplate('main2');
+            self.captionTemplate = self.getLayoutTemplate('caption');
+            self.previewGenericTemplate = self.getPreviewTemplate('generic');
             self.browseLabel = options.browseLabel;
             self.browseLabel = options.browseLabel;
             self.browseIcon = options.browseIcon;
             self.browseIcon = options.browseIcon;
             self.browseClass = options.browseClass;
             self.browseClass = options.browseClass;
@@ -209,6 +255,12 @@
             self.options = options;
             self.options = options;
             self.$element.removeClass('file-loading');
             self.$element.removeClass('file-loading');
         },
         },
+        getLayoutTemplate: function(t) {
+            return isSet(t, self.layoutTemplates) ? self.layoutTemplates[t] : defaultLayoutTemplates[t];
+        },
+        getPreviewTemplate: function(t) {
+            return isSet(t, self.previewTemplates) ? self.previewTemplates[t] : defaultPreviewTemplates[t];
+        },
         listen: function () {
         listen: function () {
             var self = this, $el = self.$element, $cap = self.$captionContainer, $btnFile = self.$btnFile;
             var self = this, $el = self.$element, $cap = self.$captionContainer, $btnFile = self.$btnFile;
             $el.on('change', $.proxy(self.change, self));
             $el.on('change', $.proxy(self.change, self));
@@ -263,6 +315,18 @@
             self.$captionContainer.attr('title', caption);
             self.$captionContainer.attr('title', caption);
             self.$container.removeClass('file-input-new');
             self.$container.removeClass('file-input-new');
         },
         },
+        clearObjects: function() {
+            var self = this, $preview = self.$preview;
+            $preview.find('video audio').each(function() {
+                 this.pause();
+                 delete(this);
+                 $(this).remove();
+            });
+            $preview.find('img object div').each(function() {
+                delete(this);
+                $(this).remove();
+            });
+        },
         clear: function (e) {
         clear: function (e) {
             var self = this;
             var self = this;
             if (e) {
             if (e) {
@@ -286,6 +350,7 @@
                 self.$caption.html(self.original.caption);
                 self.$caption.html(self.original.caption);
                 self.$container.removeClass('file-input-new');
                 self.$container.removeClass('file-input-new');
             } else {
             } else {
+                self.clearObjects();
                 self.$preview.html('');
                 self.$preview.html('');
                 var cap = (!self.overwriteInitial && self.initialCaption.length > 0) ?
                 var cap = (!self.overwriteInitial && self.initialCaption.length > 0) ?
                     self.original.caption : '';
                     self.original.caption : '';
@@ -370,23 +435,63 @@
                     self.addError(self.msgFilePreviewError.replace(/\{name\}/g, caption));
                     self.addError(self.msgFilePreviewError.replace(/\{name\}/g, caption));
             }
             }
         },
         },
-        loadImage: function (file, caption) {
-            var self = this, $img = $(document.createElement("img"));
-            $img.attr({
-                src: vUrl.createObjectURL(file),
-                class: 'file-preview-image',
-                title: caption,
-                alt: caption,
-                onload: function (e) {
-                    vUrl.revokeObjectURL($img.src);
+        parseFileType: function(file) {
+            var isValid, vType;
+            for (var i = 0; i < defaultPreviewTypes.length; i++) {
+                cat = defaultPreviewTypes[i];
+                isValid = isSet(cat, self.fileTypeSettings) ? self.fileTypeSettings[cat] : defaultFileTypeSettings[cat];
+                vType = isValid(file.type, file.name) ? cat : '';
+                if (vType != '') {
+                    return vType;
                 }
                 }
+            }
+            return 'other';
+        },
+        previewDefault: function(file, previewId) {
+            var self = this, data = vUrl.createObjectURL(file), $obj = $('#' + previewId),
+                previewOtherTemplate = isSet('other', self.previewTemplates) ? self.previewTemplates['other'] : defaultPreviewTemplates['other'];
+            self.$preview.append("\n" + previewOtherTemplate
+                .replace(/\{previewId\}/g, previewId)
+                .replace(/\{caption\}/g, file.name)
+                .replace(/\{type\}/g, file.type)
+                .replace(/\{data\}/g, data));
+            $obj.on('load', function(e) {
+                vUrl.revokeObjectURL($obj.attr('data'));
             });
             });
-            // autosize if image width exceeds preview width
-            if ($img.width() >= self.$preview.width()) {
-                $img.attr({width: "100%", height: "auto"});
+        },
+        previewFile: function(file, theFile, previewId, data) {
+            var self = this, i, cat = self.parseFileType(file), caption = file.name, data, obj, content, 
+                types = self.allowedPreviewTypes, mimes = self.allowedPreviewMimeTypes, fType = file.type, 
+                template = isSet(cat, self.previewTemplates) ? self.previewTemplates[cat] : defaultPreviewTemplates[cat], 
+                config = isSet(cat, self.previewSettings) ? self.previewSettings[cat] : defaultPreviewSettings[cat],
+                wrapLen = parseInt(self.wrapTextLength), wrapInd = self.wrapIndicator, $preview = self.$preview, 
+                chkTypes = types.indexOf(cat) >=0, chkMimes = isEmpty(mimes) || (!isEmpty(mimes) && isSet(file.type, mimes));
+            if (chkTypes && chkMimes) {
+                if (cat == 'text') {
+                    var strText = theFile.target.result;
+                    vUrl.revokeObjectURL(data);
+                    if (strText.length > wrapLen) {
+                        var id = uniqId(), height = window.innerHeight * .75,
+                            modal = self.getLayoutTemplate('modal').replace(/\{id\}/g, id).replace(/\{title\}/g,
+                                caption).replace(/\{body\}/g, strText).replace(/\{height\}/g, height);
+                        wrapInd = wrapInd.replace(/\{title\}/g, caption).replace(/\{dialog\}/g,
+                            "$('#" + id + "').modal('show')");
+                        strText = strText.substring(0, (wrapLen - 1)) + wrapInd;
+                    }
+                    content = template
+                        .replace(/\{previewId\}/g, previewId).replace(/\{caption\}/g, caption)
+                        .replace(/\{type\}/g, file.type).replace(/\{data\}/g, strText)
+                        .replace(/\{width\}/g, config.width).replace(/\{height\}/g, config.height);
+                } else {
+                    content = template
+                        .replace(/\{previewId\}/g, previewId).replace(/\{caption\}/g, caption)
+                        .replace(/\{type\}/g, file.type).replace(/\{data\}/g, data)
+                        .replace(/\{width\}/g, config.width).replace(/\{height\}/g, config.height);
+                }
+                $preview.append("\n" + content);
+            } else {
+                self.previewDefault(file, previewId);
             }
             }
-            var $imgContent = $(document.createElement("div")).append($img);
-            return $imgContent.html();
         },
         },
         readFiles: function (files) {
         readFiles: function (files) {
             this.reader = new FileReader();
             this.reader = new FileReader();
@@ -394,7 +499,8 @@
                 $container = self.$previewContainer, $status = self.$previewStatus, msgLoading = self.msgLoading,
                 $container = self.$previewContainer, $status = self.$previewStatus, msgLoading = self.msgLoading,
                 msgProgress = self.msgProgress, msgSelected = self.msgSelected, fileType = self.previewFileType,
                 msgProgress = self.msgProgress, msgSelected = self.msgSelected, fileType = self.previewFileType,
                 wrapLen = parseInt(self.wrapTextLength), wrapInd = self.wrapIndicator,
                 wrapLen = parseInt(self.wrapTextLength), wrapInd = self.wrapIndicator,
-                previewInitId = "preview-" + uniqId(), numFiles = files.length;
+                previewInitId = "preview-" + uniqId(), numFiles = files.length,
+                isText = isSet('text', self.fileTypeSettings) ? self.fileTypeSettings['text'] : defaultFileTypeSettings['text'];
 
 
             function readFile(i) {
             function readFile(i) {
                 if (i >= numFiles) {
                 if (i >= numFiles) {
@@ -402,10 +508,8 @@
                     $status.html('');
                     $status.html('');
                     return;
                     return;
                 }
                 }
-                var previewId = previewInitId + "-" + i;
-                var file = files[i], caption = file.name, isImg = isImageFile(file.type, file.name),
-                    isFlash = isFlashFile(file.type, file.name), isVideo = isVideoFile(file.type, file.name),
-                    isTxt = isTextFile(file.type, file.name), fileSize = (file.size ? file.size : 0) / 1000;
+                var previewId = previewInitId + "-" + i, file = files[i], caption = file.name, 
+                    fileSize = (file.size ? file.size : 0) / 1000, previewData = vUrl.createObjectURL(file);
                 fileSize = fileSize.toFixed(2);
                 fileSize = fileSize.toFixed(2);
                 if (self.maxFileSize > 0 && fileSize > self.maxFileSize) {
                 if (self.maxFileSize > 0 && fileSize > self.maxFileSize) {
                     var msg = self.msgSizeTooLarge.replace(/\{name\}/g, caption).replace(/\{size\}/g,
                     var msg = self.msgSizeTooLarge.replace(/\{name\}/g, caption).replace(/\{size\}/g,
@@ -413,80 +517,54 @@
                     self.isError = self.showError(msg, file, previewId, i);
                     self.isError = self.showError(msg, file, previewId, i);
                     return;
                     return;
                 }
                 }
-                var chkPreview = ($preview.length > 0 && typeof FileReader !== "undefined" && (isImg || isTxt || isFlash || isVideo));
-                if (chkPreview) {
+                if (!self.showPreview) {
+                    setTimeout(readFile(i + 1), 1000);
+                    return;
+                }
+                if ($preview.length > 0 && typeof FileReader !== "undefined") {
                     $status.html(msgLoading.replace(/\{index\}/g, i + 1).replace(/\{files\}/g, numFiles));
                     $status.html(msgLoading.replace(/\{index\}/g, i + 1).replace(/\{files\}/g, numFiles));
                     $container.addClass('loading');
                     $container.addClass('loading');
                     reader.onerror = function (evt) {
                     reader.onerror = function (evt) {
                         self.errorHandler(evt, caption);
                         self.errorHandler(evt, caption);
                     };
                     };
                     reader.onload = function (theFile) {
                     reader.onload = function (theFile) {
-                        var content = '', modal = '';
-                        if (isTxt) {
-                            var strText = theFile.target.result;
-                            if (strText.length > wrapLen) {
-                                var id = uniqId(), height = window.innerHeight * .75,
-                                    modal = MODAL_TEMPLATE.replace(/\{id\}/g, id).replace(/\{title\}/g,
-                                        caption).replace(/\{body\}/g, strText).replace(/\{height\}/g, height);
-                                wrapInd = wrapInd.replace(/\{title\}/g, caption).replace(/\{dialog\}/g,
-                                    "$('#" + id + "').modal('show')");
-                                strText = strText.substring(0, (wrapLen - 1)) + wrapInd;
-                            }
-                            content = self.previewTextTemplate.replace(/\{previewId\}/g,
-                                previewId).replace(/\{caption\}/g, caption).replace(/\{strText\}/g, strText) + modal;
-                        } else {
-                            if (isFlash) {
-                                var media = vUrl.createObjectURL(file);
-                                content = self.previewFlashTemplate.replace(/\{previewId\}/g,
-                                    previewId).replace(/\{caption\}/g, caption).replace(/\{media\}/g, media);
-                            } else {
-                                if (isVideo) {
-                                    var media = vUrl.createObjectURL(file);
-                                    content = self.previewVideoTemplate.replace(/\{previewId\}/g,
-                                        previewId).replace(/\{caption\}/g, caption).replace(/\{type\}/g,
-                                        file.type).replace(/\{media\}/g, media);
-                                } else {
-                                    content = self.previewImageTemplate.replace(/\{previewId\}/g,
-                                        previewId).replace(/\{content\}/g, self.loadImage(file, caption));
-                                }
-                            }
-                        }
-                        $preview.append("\n" + content);
+                        self.previewFile(file, theFile, previewId, previewData);
                     };
                     };
                     reader.onloadend = function (e) {
                     reader.onloadend = function (e) {
-                        var msg = msgProgress.replace(/\{index\}/g, i + 1).replace(/\{files\}/g,
-                            numFiles).replace(/\{percent\}/g, 100).replace(/\{name\}/g, file.name);
+                        var msg = msgProgress
+                            .replace(/\{index\}/g, i + 1).replace(/\{files\}/g, numFiles)
+                            .replace(/\{percent\}/g, 100).replace(/\{name\}/g, caption);
                         setTimeout(function () {
                         setTimeout(function () {
                             $status.html(msg);
                             $status.html(msg);
+                            vUrl.revokeObjectURL(previewData);
                         }, 1000);
                         }, 1000);
                         setTimeout(function () {
                         setTimeout(function () {
-                            readFile(i + 1)
+                            readFile(i + 1);
                         }, 1500);
                         }, 1500);
                         $el.trigger('fileloaded', [file, previewId, i]);
                         $el.trigger('fileloaded', [file, previewId, i]);
                     };
                     };
                     reader.onprogress = function (data) {
                     reader.onprogress = function (data) {
                         if (data.lengthComputable) {
                         if (data.lengthComputable) {
                             var progress = parseInt(((data.loaded / data.total) * 100), 10);
                             var progress = parseInt(((data.loaded / data.total) * 100), 10);
-                            var msg = msgProgress.replace(/\{index\}/g, i + 1).replace(/\{files\}/g,
-                                numFiles).replace(/\{percent\}/g, progress).replace(/\{name\}/g, file.name);
+                            var msg = msgProgress
+                                .replace(/\{index\}/g, i + 1).replace(/\{files\}/g, numFiles)
+                                .replace(/\{percent\}/g, progress).replace(/\{name\}/g, caption);
                             setTimeout(function () {
                             setTimeout(function () {
                                 $status.html(msg);
                                 $status.html(msg);
                             }, 1000);
                             }, 1000);
                         }
                         }
                     };
                     };
-                    if (isTxt) {
+                    if (isText(file.type, caption)) {
                         reader.readAsText(file);
                         reader.readAsText(file);
                     } else {
                     } else {
                         reader.readAsArrayBuffer(file);
                         reader.readAsArrayBuffer(file);
                     }
                     }
                 } else {
                 } else {
-                    $preview.append("\n" + self.previewOtherTemplate.replace(/\{previewId\}/g,
-                        previewId).replace(/\{caption\}/g, caption));
+                    self.previewDefault(file, previewId);
                     $el.trigger('fileloaded', [file, previewId, i]);
                     $el.trigger('fileloaded', [file, previewId, i]);
                     setTimeout(readFile(i + 1), 1000);
                     setTimeout(readFile(i + 1), 1000);
                 }
                 }
             }
             }
-
             readFile(0);
             readFile(0);
         },
         },
         change: function (e) {
         change: function (e) {
@@ -552,7 +630,7 @@
         },
         },
         renderMain: function () {
         renderMain: function () {
             var self = this;
             var self = this;
-            var preview = self.previewTemplate.replace(/\{class\}/g, self.previewClass);
+            var preview = self.showPreview ? self.getLayoutTemplate('preview').replace(/\{class\}/g, self.previewClass) : '';
             var css = self.isDisabled ? self.captionClass + ' file-caption-disabled' : self.captionClass;
             var css = self.isDisabled ? self.captionClass + ' file-caption-disabled' : self.captionClass;
             var caption = self.captionTemplate.replace(/\{class\}/g, css + ' kv-fileinput-caption');
             var caption = self.captionTemplate.replace(/\{class\}/g, css + ' kv-fileinput-caption');
             return self.mainTemplate.replace(/\{class\}/g, self.mainClass).
             return self.mainTemplate.replace(/\{class\}/g, self.mainClass).
@@ -633,9 +711,9 @@
         showPreview: true,
         showPreview: true,
         showRemove: true,
         showRemove: true,
         showUpload: true,
         showUpload: true,
-        captionClass: '',
-        previewClass: '',
         mainClass: '',
         mainClass: '',
+        previewClass: '',
+        captionClass: '',
         mainTemplate: null,
         mainTemplate: null,
         initialDelimiter: '*$$*',
         initialDelimiter: '*$$*',
         initialPreview: '',
         initialPreview: '',
@@ -643,14 +721,12 @@
         initialPreviewCount: 0,
         initialPreviewCount: 0,
         initialPreviewContent: '',
         initialPreviewContent: '',
         overwriteInitial: true,
         overwriteInitial: true,
-        previewTemplate: PREVIEW_TEMPLATE,
-        previewGenericTemplate: IMAGE_TEMPLATE,
-        previewImageTemplate: IMAGE_TEMPLATE,
-        previewFlashTemplate: FLASH_TEMPLATE,
-        previewVideoTemplate: VIDEO_TEMPLATE,
-        previewTextTemplate: TEXT_TEMPLATE,
-        previewOtherTemplate: OTHER_TEMPLATE,
-        captionTemplate: CAPTION_TEMPLATE,
+        layoutTemplates: defaultLayoutTemplates,
+        previewTemplates: defaultPreviewTemplates,
+        allowedPreviewTypes: defaultPreviewTypes,
+        allowedPreviewMimeTypes: null,
+        previewSettings: defaultPreviewSettings,
+        fileTypeSettings: defaultFileTypeSettings,
         browseLabel: 'Browse &hellip;',
         browseLabel: 'Browse &hellip;',
         browseIcon: '<i class="glyphicon glyphicon-folder-open"></i> &nbsp;',
         browseIcon: '<i class="glyphicon glyphicon-folder-open"></i> &nbsp;',
         browseClass: 'btn btn-primary',
         browseClass: 'btn btn-primary',

ファイルの差分が大きいため隠しています
+ 1 - 1
js/fileinput.min.js


この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません