Commit 57c5e2fc7ceff219093f1174b933aa9b36cf7cd6
1 parent
ccb466c6
主播
Showing
26 changed files
with
4064 additions
and
127 deletions
Too many changes to show.
To preserve performance only 26 of 301 files are displayed.
.classpath
| 1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | -<classpath> | ||
| 3 | - <classpathentry kind="src" output="target/classes" path="src/main/java"> | ||
| 4 | - <attributes> | ||
| 5 | - <attribute name="optional" value="true"/> | ||
| 6 | - <attribute name="maven.pomderived" value="true"/> | ||
| 7 | - </attributes> | ||
| 8 | - </classpathentry> | ||
| 9 | - <classpathentry kind="src" output="target/test-classes" path="src/test/java"> | ||
| 10 | - <attributes> | ||
| 11 | - <attribute name="optional" value="true"/> | ||
| 12 | - <attribute name="maven.pomderived" value="true"/> | ||
| 13 | - </attributes> | ||
| 14 | - </classpathentry> | ||
| 15 | - <classpathentry including="**/*.java" kind="src" path="src/main/resources"/> | ||
| 16 | - <classpathentry kind="src" path="src/main/resources/i18n"/> | ||
| 17 | - <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> | ||
| 18 | - <attributes> | ||
| 19 | - <attribute name="maven.pomderived" value="true"/> | ||
| 20 | - <attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/> | ||
| 21 | - </attributes> | ||
| 22 | - </classpathentry> | ||
| 23 | - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"> | ||
| 24 | - <attributes> | ||
| 25 | - <attribute name="maven.pomderived" value="true"/> | ||
| 26 | - </attributes> | ||
| 27 | - </classpathentry> | ||
| 28 | - <classpathentry kind="output" path="target/classes"/> | ||
| 29 | -</classpath> | 1 | +<?xml version="1.0" encoding="UTF-8"?> |
| 2 | +<classpath> | ||
| 3 | + <classpathentry kind="src" output="target/classes" path="src/main/java"> | ||
| 4 | + <attributes> | ||
| 5 | + <attribute name="optional" value="true"/> | ||
| 6 | + <attribute name="maven.pomderived" value="true"/> | ||
| 7 | + </attributes> | ||
| 8 | + </classpathentry> | ||
| 9 | + <classpathentry kind="src" output="target/test-classes" path="src/test/java"> | ||
| 10 | + <attributes> | ||
| 11 | + <attribute name="optional" value="true"/> | ||
| 12 | + <attribute name="maven.pomderived" value="true"/> | ||
| 13 | + </attributes> | ||
| 14 | + </classpathentry> | ||
| 15 | + <classpathentry including="**/*.java" kind="src" path="src/main/resources"/> | ||
| 16 | + <classpathentry kind="src" path="src/main/resources/i18n"/> | ||
| 17 | + <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> | ||
| 18 | + <attributes> | ||
| 19 | + <attribute name="maven.pomderived" value="true"/> | ||
| 20 | + <attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/> | ||
| 21 | + </attributes> | ||
| 22 | + </classpathentry> | ||
| 23 | + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"> | ||
| 24 | + <attributes> | ||
| 25 | + <attribute name="maven.pomderived" value="true"/> | ||
| 26 | + </attributes> | ||
| 27 | + </classpathentry> | ||
| 28 | + <classpathentry kind="output" path="target/classes"/> | ||
| 29 | +</classpath> |
.gitignore
0 → 100644
| 1 | +/target/ |
.settings/org.eclipse.wst.common.component
| 1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | -<project-modules id="moduleCoreId" project-version="1.5.0"> | ||
| 3 | - <wb-module deploy-name="cnlive_live_web"> | ||
| 4 | - <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/> | ||
| 5 | - <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/> | ||
| 6 | - <wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/> | ||
| 7 | - <wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/> | ||
| 8 | - <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources/i18n"/> | ||
| 9 | - <dependent-module archiveName="cnlive_live_model-0.0.1-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/cnlive_live_model/cnlive_live_model"> | ||
| 10 | - <dependency-type>uses</dependency-type> | ||
| 11 | - </dependent-module> | ||
| 12 | - <dependent-module archiveName="smart-plugin-rest-1.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/smart-plugin-rest/smart-plugin-rest"> | ||
| 13 | - <dependency-type>uses</dependency-type> | ||
| 14 | - </dependent-module> | ||
| 15 | - <dependent-module archiveName="cnlive_ks3-1.0-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/cnlive_ks3/cnlive_ks3"> | ||
| 16 | - <dependency-type>uses</dependency-type> | ||
| 17 | - </dependent-module> | ||
| 18 | - <dependent-module archiveName="smart-framework-4.0.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/smart-framework/smart-framework"> | ||
| 19 | - <dependency-type>uses</dependency-type> | ||
| 20 | - </dependent-module> | ||
| 21 | - <dependent-module archiveName="smart-plugin-dbcp-1.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/smart-plugin-dbcp/smart-plugin-dbcp"> | ||
| 22 | - <dependency-type>uses</dependency-type> | ||
| 23 | - </dependent-module> | ||
| 24 | - <dependent-module archiveName="smart-plugin-i18n-1.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/smart-plugin-i18n/smart-plugin-i18n"> | ||
| 25 | - <dependency-type>uses</dependency-type> | ||
| 26 | - </dependent-module> | ||
| 27 | - <dependent-module archiveName="cnlive_mam_commons-0.0.1-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/cnlive_mam_commons/cnlive_mam_commons"> | ||
| 28 | - <dependency-type>uses</dependency-type> | ||
| 29 | - </dependent-module> | ||
| 30 | - <property name="java-output-path" value="/cnlive_live_web/target/classes"/> | ||
| 31 | - <property name="context-root" value="cnlive_live_web"/> | ||
| 32 | - </wb-module> | ||
| 33 | -</project-modules> | 1 | +<?xml version="1.0" encoding="UTF-8"?> |
| 2 | +<project-modules id="moduleCoreId" project-version="1.5.0"> | ||
| 3 | + <wb-module deploy-name="cnlive_live_web"> | ||
| 4 | + <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/> | ||
| 5 | + <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/> | ||
| 6 | + <wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/> | ||
| 7 | + <wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/> | ||
| 8 | + <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources/i18n"/> | ||
| 9 | + <dependent-module archiveName="cnlive_live_model-0.0.1-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/cnlive_live_model/cnlive_live_model"> | ||
| 10 | + <dependency-type>uses</dependency-type> | ||
| 11 | + </dependent-module> | ||
| 12 | + <dependent-module archiveName="cnlive_ks3-1.0-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/cnlive_ks3/cnlive_ks3"> | ||
| 13 | + <dependency-type>uses</dependency-type> | ||
| 14 | + </dependent-module> | ||
| 15 | + <dependent-module archiveName="smart-framework-4.0.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/smart-framework/smart-framework"> | ||
| 16 | + <dependency-type>uses</dependency-type> | ||
| 17 | + </dependent-module> | ||
| 18 | + <dependent-module archiveName="smart-plugin-dbcp-1.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/smart-plugin-dbcp/smart-plugin-dbcp"> | ||
| 19 | + <dependency-type>uses</dependency-type> | ||
| 20 | + </dependent-module> | ||
| 21 | + <dependent-module archiveName="smart-plugin-rest-1.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/smart-plugin-rest/smart-plugin-rest"> | ||
| 22 | + <dependency-type>uses</dependency-type> | ||
| 23 | + </dependent-module> | ||
| 24 | + <dependent-module archiveName="smart-plugin-i18n-1.0.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/smart-plugin-i18n/smart-plugin-i18n"> | ||
| 25 | + <dependency-type>uses</dependency-type> | ||
| 26 | + </dependent-module> | ||
| 27 | + <dependent-module archiveName="cnlive_mam_commons-0.0.1-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/cnlive_mam_commons/cnlive_mam_commons"> | ||
| 28 | + <dependency-type>uses</dependency-type> | ||
| 29 | + </dependent-module> | ||
| 30 | + <property name="java-output-path" value="/cnlive_live_web/target/classes"/> | ||
| 31 | + <property name="context-root" value="cnlive_live_web"/> | ||
| 32 | + </wb-module> | ||
| 33 | +</project-modules> |
pom.xml
| @@ -41,12 +41,6 @@ | @@ -41,12 +41,6 @@ | ||
| 41 | <artifactId>javax.servlet-api</artifactId> | 41 | <artifactId>javax.servlet-api</artifactId> |
| 42 | <version>3.0.1</version> | 42 | <version>3.0.1</version> |
| 43 | </dependency> | 43 | </dependency> |
| 44 | - <dependency> | ||
| 45 | - <groupId>junit</groupId> | ||
| 46 | - <artifactId>junit</artifactId> | ||
| 47 | - <version>3.8.1</version> | ||
| 48 | - <scope>test</scope> | ||
| 49 | - </dependency> | ||
| 50 | <!-- jstl --> | 44 | <!-- jstl --> |
| 51 | <dependency> | 45 | <dependency> |
| 52 | <groupId>javax.servlet</groupId> | 46 | <groupId>javax.servlet</groupId> |
| @@ -60,11 +54,6 @@ | @@ -60,11 +54,6 @@ | ||
| 60 | <version>0.0.1-SNAPSHOT</version> | 54 | <version>0.0.1-SNAPSHOT</version> |
| 61 | </dependency> | 55 | </dependency> |
| 62 | <dependency> | 56 | <dependency> |
| 63 | - <groupId>org.smart4j</groupId> | ||
| 64 | - <artifactId>smart-plugin-rest</artifactId> | ||
| 65 | - <version>1.0</version> | ||
| 66 | - </dependency> | ||
| 67 | - <dependency> | ||
| 68 | <groupId>com.cnlive</groupId> | 57 | <groupId>com.cnlive</groupId> |
| 69 | <artifactId>cnlive_media_tools</artifactId> | 58 | <artifactId>cnlive_media_tools</artifactId> |
| 70 | <version>1.0.0</version> | 59 | <version>1.0.0</version> |
src/main/java/com/cnlive/mz/live/LiveUtils.java deleted
100644 → 0
| 1 | -package com.cnlive.mz.live; | ||
| 2 | - | ||
| 3 | -import java.util.Calendar; | ||
| 4 | - | ||
| 5 | -/** | ||
| 6 | - * 当前项目公共类 | ||
| 7 | - * | ||
| 8 | - * @author liujicheng | ||
| 9 | - * | ||
| 10 | - */ | ||
| 11 | -public class LiveUtils { | ||
| 12 | - public static String SESSION_KEY_NAME = "userName"; | ||
| 13 | - public static String SESSION_KEY_ID = "userId"; | ||
| 14 | - | ||
| 15 | - public static String SESSION_ROLE_ID = "roleId"; | ||
| 16 | - | ||
| 17 | - public static void main(String[] args) { | ||
| 18 | - String s = new LiveUtils().getRecentMonths(); | ||
| 19 | - System.out.println(s); | ||
| 20 | - } | ||
| 21 | - | ||
| 22 | - public static String getRecentMonths() { | ||
| 23 | - int month = Calendar.getInstance().get(Calendar.MONTH); | ||
| 24 | - StringBuffer sb = new StringBuffer(); | ||
| 25 | - if (month < 12) { | ||
| 26 | - month = month + 1; | ||
| 27 | - } | ||
| 28 | - for (int i = 1; i <= month; i++) { | ||
| 29 | - String m = "'" + i + "月" + "'"; | ||
| 30 | - sb.append(m); | ||
| 31 | - if (i != month) { | ||
| 32 | - sb.append(","); | ||
| 33 | - } | ||
| 34 | - } | ||
| 35 | - return sb.toString(); | ||
| 36 | - } | ||
| 37 | - | ||
| 38 | -} |
src/main/java/com/cnlive/mz/live/action/ActivityAction.java
| @@ -9,7 +9,6 @@ | @@ -9,7 +9,6 @@ | ||
| 9 | 9 | ||
| 10 | package com.cnlive.mz.live.action; | 10 | package com.cnlive.mz.live.action; |
| 11 | 11 | ||
| 12 | -import java.io.IOException; | ||
| 13 | import java.util.HashMap; | 12 | import java.util.HashMap; |
| 14 | import java.util.List; | 13 | import java.util.List; |
| 15 | import java.util.Map; | 14 | import java.util.Map; |
| @@ -25,16 +24,13 @@ import org.smart4j.framework.mvc.bean.View; | @@ -25,16 +24,13 @@ import org.smart4j.framework.mvc.bean.View; | ||
| 25 | import org.smart4j.framework.util.CastUtil; | 24 | import org.smart4j.framework.util.CastUtil; |
| 26 | 25 | ||
| 27 | import com.cnlive.mz.commons.Constants; | 26 | import com.cnlive.mz.commons.Constants; |
| 28 | -import com.cnlive.mz.live.LiveUtils; | ||
| 29 | -import com.cnlive.mz.live.bean.Mp4File; | 27 | +import com.cnlive.mz.live.common.LiveUtils; |
| 30 | import com.cnlive.mz.live.entity.TActivity; | 28 | import com.cnlive.mz.live.entity.TActivity; |
| 31 | -import com.cnlive.mz.live.entity.TActivityLog; | ||
| 32 | import com.cnlive.mz.live.entity.TChannel; | 29 | import com.cnlive.mz.live.entity.TChannel; |
| 33 | import com.cnlive.mz.live.entity.TDefaultVideo; | 30 | import com.cnlive.mz.live.entity.TDefaultVideo; |
| 34 | import com.cnlive.mz.live.entity.TWowza; | 31 | import com.cnlive.mz.live.entity.TWowza; |
| 35 | import com.cnlive.mz.live.entity.VActivityWidthUser; | 32 | import com.cnlive.mz.live.entity.VActivityWidthUser; |
| 36 | import com.cnlive.mz.live.entity.VChannel; | 33 | import com.cnlive.mz.live.entity.VChannel; |
| 37 | -import com.cnlive.mz.live.entity.VWowzaStream; | ||
| 38 | import com.cnlive.mz.live.service.TActivityService; | 34 | import com.cnlive.mz.live.service.TActivityService; |
| 39 | import com.cnlive.mz.live.service.TChannelService; | 35 | import com.cnlive.mz.live.service.TChannelService; |
| 40 | import com.cnlive.mz.live.service.TSignalService; | 36 | import com.cnlive.mz.live.service.TSignalService; |
src/main/java/com/cnlive/mz/live/action/ChannelAction.java
| @@ -20,8 +20,8 @@ import org.smart4j.framework.util.CastUtil; | @@ -20,8 +20,8 @@ import org.smart4j.framework.util.CastUtil; | ||
| 20 | 20 | ||
| 21 | import com.cnlive.mz.commons.CnliveUtil; | 21 | import com.cnlive.mz.commons.CnliveUtil; |
| 22 | import com.cnlive.mz.commons.Constants; | 22 | import com.cnlive.mz.commons.Constants; |
| 23 | -import com.cnlive.mz.live.LiveUtils; | ||
| 24 | import com.cnlive.mz.live.bean.TWowzaSignalBean; | 23 | import com.cnlive.mz.live.bean.TWowzaSignalBean; |
| 24 | +import com.cnlive.mz.live.common.LiveUtils; | ||
| 25 | import com.cnlive.mz.live.entity.TChannel; | 25 | import com.cnlive.mz.live.entity.TChannel; |
| 26 | import com.cnlive.mz.live.entity.TWowza; | 26 | import com.cnlive.mz.live.entity.TWowza; |
| 27 | import com.cnlive.mz.live.entity.VChannel; | 27 | import com.cnlive.mz.live.entity.VChannel; |
src/main/java/com/cnlive/mz/live/action/IndexAction.java
| @@ -25,7 +25,7 @@ import org.smart4j.framework.mvc.bean.Result; | @@ -25,7 +25,7 @@ import org.smart4j.framework.mvc.bean.Result; | ||
| 25 | import org.smart4j.framework.mvc.bean.View; | 25 | import org.smart4j.framework.mvc.bean.View; |
| 26 | import org.smart4j.framework.util.CastUtil; | 26 | import org.smart4j.framework.util.CastUtil; |
| 27 | 27 | ||
| 28 | -import com.cnlive.mz.live.LiveUtils; | 28 | +import com.cnlive.mz.live.common.LiveUtils; |
| 29 | import com.cnlive.mz.live.entity.TActivity; | 29 | import com.cnlive.mz.live.entity.TActivity; |
| 30 | import com.cnlive.mz.live.entity.TUser; | 30 | import com.cnlive.mz.live.entity.TUser; |
| 31 | import com.cnlive.mz.live.entity.VChannel; | 31 | import com.cnlive.mz.live.entity.VChannel; |
src/main/java/com/cnlive/mz/live/action/LiveAction.java
0 → 100644
| 1 | +/** | ||
| 2 | + * Project Name:cnlive_live_web | ||
| 3 | + * File Name:RoomAction.java | ||
| 4 | + * Package Name:com.cnlive.mz.live.action | ||
| 5 | + * Date:2016年4月25日下午1:12:48 | ||
| 6 | + * Copyright (c) 2016, cnlive.com All Rights Reserved. | ||
| 7 | + * | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +package com.cnlive.mz.live.action; | ||
| 11 | + | ||
| 12 | +import java.util.List; | ||
| 13 | + | ||
| 14 | +import org.smart4j.framework.dao.bean.Pager; | ||
| 15 | +import org.smart4j.framework.ioc.annotation.Inject; | ||
| 16 | +import org.smart4j.framework.mvc.DataContext; | ||
| 17 | +import org.smart4j.framework.mvc.annotation.Action; | ||
| 18 | +import org.smart4j.framework.mvc.annotation.Request; | ||
| 19 | +import org.smart4j.framework.mvc.bean.View; | ||
| 20 | +import org.smart4j.framework.util.CastUtil; | ||
| 21 | + | ||
| 22 | +import com.cnlive.mz.commons.Constants; | ||
| 23 | +import com.cnlive.mz.live.common.LiveUtils; | ||
| 24 | +import com.cnlive.mz.live.entity.TLive; | ||
| 25 | +import com.cnlive.mz.live.entity.TRoom; | ||
| 26 | +import com.cnlive.mz.live.service.TLiveService; | ||
| 27 | +import com.cnlive.mz.live.service.TRoomService; | ||
| 28 | + | ||
| 29 | +/** | ||
| 30 | + * TODO: 机构主播和个人主播发起直播活动 <br/> | ||
| 31 | + * Date: 2016年4月25日 下午1:12:48 <br/> | ||
| 32 | + * | ||
| 33 | + * @author liujicheng | ||
| 34 | + * @version V1.0 | ||
| 35 | + * @since JDK 1.6 | ||
| 36 | + */ | ||
| 37 | +@Action | ||
| 38 | +public class LiveAction { | ||
| 39 | + @Inject | ||
| 40 | + private TLiveService tLiveService; | ||
| 41 | + @Inject | ||
| 42 | + private TRoomService tRoomService; | ||
| 43 | + | ||
| 44 | + @Request.Get("/live/preload") | ||
| 45 | + public View preload() { | ||
| 46 | + int user_id = CastUtil.castInt(DataContext.getRequest().getSession().getAttribute(LiveUtils.SESSION_KEY_ID)); | ||
| 47 | + View view = new View("live/live_add.jsp"); | ||
| 48 | + List<TRoom> tRooms = tRoomService.getTRooms(user_id); | ||
| 49 | + view.data("tRooms", tRooms); | ||
| 50 | + return view; | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + @Request.Get("/live/list/{page_number}") | ||
| 54 | + public View list(int page_number) { | ||
| 55 | + int user_id = CastUtil.castInt(DataContext.getRequest().getSession().getAttribute(LiveUtils.SESSION_KEY_ID)); | ||
| 56 | + System.out.println(user_id); | ||
| 57 | + Pager<TLive> tLive = tLiveService.getTLivePager(page_number, Constants.PAGE_SIZE, user_id); | ||
| 58 | + return new View("live/live_management.jsp").data("tLive", tLive); | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | +} |
src/main/java/com/cnlive/mz/live/action/RoomAction.java
0 → 100644
| 1 | +/** | ||
| 2 | + * Project Name:cnlive_live_web | ||
| 3 | + * File Name:RoomAction.java | ||
| 4 | + * Package Name:com.cnlive.mz.live.action | ||
| 5 | + * Date:2016年4月25日下午1:12:48 | ||
| 6 | + * Copyright (c) 2016, cnlive.com All Rights Reserved. | ||
| 7 | + * | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +package com.cnlive.mz.live.action; | ||
| 11 | + | ||
| 12 | +import org.smart4j.framework.dao.bean.Pager; | ||
| 13 | +import org.smart4j.framework.ioc.annotation.Inject; | ||
| 14 | +import org.smart4j.framework.mvc.DataContext; | ||
| 15 | +import org.smart4j.framework.mvc.annotation.Action; | ||
| 16 | +import org.smart4j.framework.mvc.annotation.Request; | ||
| 17 | +import org.smart4j.framework.mvc.bean.Multiparts; | ||
| 18 | +import org.smart4j.framework.mvc.bean.Params; | ||
| 19 | +import org.smart4j.framework.mvc.bean.Result; | ||
| 20 | +import org.smart4j.framework.mvc.bean.View; | ||
| 21 | +import org.smart4j.framework.util.CastUtil; | ||
| 22 | + | ||
| 23 | +import com.cnlive.mz.commons.Constants; | ||
| 24 | +import com.cnlive.mz.live.common.LiveUtils; | ||
| 25 | +import com.cnlive.mz.live.entity.TRoom; | ||
| 26 | +import com.cnlive.mz.live.service.TRoomService; | ||
| 27 | + | ||
| 28 | +/** | ||
| 29 | + * TODO: 这里用一句话描述当前类的作用 Date: 2016年4月25日 下午1:12:48 <br/> | ||
| 30 | + * | ||
| 31 | + * @author liujicheng | ||
| 32 | + * @version V1.0 | ||
| 33 | + * @since JDK 1.6 | ||
| 34 | + */ | ||
| 35 | +@Action | ||
| 36 | +public class RoomAction { | ||
| 37 | + @Inject | ||
| 38 | + private TRoomService tRoomService; | ||
| 39 | + int user_id = 0; | ||
| 40 | + | ||
| 41 | + @Request.Get("/room/list/{page_number}") | ||
| 42 | + public View list(int page_number) { | ||
| 43 | + // int user_id = | ||
| 44 | + // CastUtil.castInt(DataContext.getRequest().getSession().getAttribute(LiveUtils.SESSION_KEY_ID)); | ||
| 45 | + Pager<TRoom> tRooms = tRoomService.getTRoomPager(page_number, Constants.PAGE_SIZE, user_id); | ||
| 46 | + return new View("room/room_management.jsp").data("tRooms", tRooms); | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + @Request.Get("/room/delete/{id}") | ||
| 50 | + public Result delete(int id) { | ||
| 51 | + int user_id = CastUtil.castInt(DataContext.getRequest().getSession().getAttribute(LiveUtils.SESSION_KEY_ID)); | ||
| 52 | + boolean success = tRoomService.delete(id, user_id); | ||
| 53 | + return new Result(success); | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + // 查看读取 | ||
| 57 | + @Request.Get("/room/edit/{id}") | ||
| 58 | + public View edit(int id) { | ||
| 59 | + TRoom tRoom = tRoomService.getTRoomById(id); | ||
| 60 | + View view = new View("room/room_add.jsp"); | ||
| 61 | + view.data("tRoom", tRoom); | ||
| 62 | + return view; | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + @Request.Post("/room/add") | ||
| 66 | + public Result add(Params params, Multiparts multiparts) { | ||
| 67 | + int user_id = CastUtil.castInt(DataContext.getRequest().getSession().getAttribute(LiveUtils.SESSION_KEY_ID)); | ||
| 68 | + tRoomService.save(user_id, params, multiparts); | ||
| 69 | + return new Result(true); | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + // 查看读取 | ||
| 73 | + @Request.Get("/room/pload") | ||
| 74 | + public View pload() { | ||
| 75 | + View view = new View("room/room_add.jsp"); | ||
| 76 | + return view; | ||
| 77 | + } | ||
| 78 | +} |
src/main/java/com/cnlive/mz/live/aspect/ActionAspect.java
| @@ -4,8 +4,6 @@ import java.lang.reflect.Method; | @@ -4,8 +4,6 @@ import java.lang.reflect.Method; | ||
| 4 | 4 | ||
| 5 | import javax.servlet.http.HttpServletRequest; | 5 | import javax.servlet.http.HttpServletRequest; |
| 6 | 6 | ||
| 7 | -import org.slf4j.Logger; | ||
| 8 | -import org.slf4j.LoggerFactory; | ||
| 9 | import org.smart4j.framework.aop.AspectProxy; | 7 | import org.smart4j.framework.aop.AspectProxy; |
| 10 | import org.smart4j.framework.aop.annotation.Aspect; | 8 | import org.smart4j.framework.aop.annotation.Aspect; |
| 11 | import org.smart4j.framework.mvc.DataContext; | 9 | import org.smart4j.framework.mvc.DataContext; |
src/main/java/com/cnlive/mz/live/aspect/AuthFilter.java
| @@ -5,7 +5,6 @@ import java.io.IOException; | @@ -5,7 +5,6 @@ import java.io.IOException; | ||
| 5 | import javax.servlet.Filter; | 5 | import javax.servlet.Filter; |
| 6 | import javax.servlet.FilterChain; | 6 | import javax.servlet.FilterChain; |
| 7 | import javax.servlet.FilterConfig; | 7 | import javax.servlet.FilterConfig; |
| 8 | -import javax.servlet.ServletContext; | ||
| 9 | import javax.servlet.ServletException; | 8 | import javax.servlet.ServletException; |
| 10 | import javax.servlet.ServletRequest; | 9 | import javax.servlet.ServletRequest; |
| 11 | import javax.servlet.ServletResponse; | 10 | import javax.servlet.ServletResponse; |
| @@ -15,11 +14,8 @@ import javax.servlet.http.HttpServletResponse; | @@ -15,11 +14,8 @@ import javax.servlet.http.HttpServletResponse; | ||
| 15 | import javax.servlet.http.HttpSession; | 14 | import javax.servlet.http.HttpSession; |
| 16 | 15 | ||
| 17 | import org.smart4j.framework.core.ConfigHelper; | 16 | import org.smart4j.framework.core.ConfigHelper; |
| 18 | -import org.smart4j.framework.orm.DataSet; | ||
| 19 | 17 | ||
| 20 | -import com.cnlive.mz.live.LiveUtils; | ||
| 21 | -import com.cnlive.mz.live.entity.TActivity; | ||
| 22 | -import com.cnlive.mz.live.entity.TUser; | 18 | +import com.cnlive.mz.live.common.LiveUtils; |
| 23 | 19 | ||
| 24 | /* | 20 | /* |
| 25 | * | 21 | * |
src/main/resources/smart.properties
| @@ -8,7 +8,7 @@ smart.framework.custom.ds_factory=org.smart4j.plugin.dbcp.DbcpDataSourceFactory | @@ -8,7 +8,7 @@ smart.framework.custom.ds_factory=org.smart4j.plugin.dbcp.DbcpDataSourceFactory | ||
| 8 | 8 | ||
| 9 | smart.framework.jdbc.type=mysql | 9 | smart.framework.jdbc.type=mysql |
| 10 | smart.framework.jdbc.driver=com.mysql.jdbc.Driver | 10 | smart.framework.jdbc.driver=com.mysql.jdbc.Driver |
| 11 | -smart.framework.jdbc.url=jdbc:mysql://101.251.198.175:3306/cnlive_live?autoReconnect=true&failOverReadOnly=false | 11 | +smart.framework.jdbc.url=jdbc:mysql://124.193.218.90:3306/cnlive_live?autoReconnect=true&failOverReadOnly=false |
| 12 | smart.framework.jdbc.username=cnlive_oa | 12 | smart.framework.jdbc.username=cnlive_oa |
| 13 | smart.framework.jdbc.password=H8rf#_3@ccx9( | 13 | smart.framework.jdbc.password=H8rf#_3@ccx9( |
| 14 | # | 14 | # |
src/main/webapp/pages/common/js.jsp
| @@ -23,7 +23,14 @@ | @@ -23,7 +23,14 @@ | ||
| 23 | <script src="${BASE}/static/assets/plugins/timepicker/bootstrap-timepicker.min.js" type="text/javascript"></script> | 23 | <script src="${BASE}/static/assets/plugins/timepicker/bootstrap-timepicker.min.js" type="text/javascript"></script> |
| 24 | <!-- iCheck 1.0.1 --> | 24 | <!-- iCheck 1.0.1 --> |
| 25 | <script src="${BASE}/static/assets/plugins/iCheck/icheck.min.js" type="text/javascript"></script> | 25 | <script src="${BASE}/static/assets/plugins/iCheck/icheck.min.js" type="text/javascript"></script> |
| 26 | - <script src="${BASE}/static/assets/plugins/slimScroll/jquery.slimscroll.min.js" type="text/javascript"></script> | 26 | +<script src="${BASE}/static/assets/plugins/slimScroll/jquery.slimscroll.min.js" type="text/javascript"></script> |
| 27 | + | ||
| 28 | +<link rel="stylesheet" href="${BASE}/static/assets/plugins/fileinput/fileinput.css" /> | ||
| 29 | +<link rel="stylesheet" href="${BASE}/static/assets/plugins/fileinput/fileinput.min.css" /> | ||
| 30 | +<script src="${BASE}/static/assets/plugins/fileinput/fileinput.js"></script> | ||
| 31 | +<script src="${BASE}/static/assets/plugins/fileinput/fileinput.min.js"></script> | ||
| 32 | +<script src="${BASE}/static/assets/plugins/fileinput/fileinput_locale_zh.js"></script> | ||
| 33 | + | ||
| 27 | <!--###########--> | 34 | <!--###########--> |
| 28 | <script src="${BASE}/static/assets/cnlive/js/channel.js" type="text/javascript"></script> | 35 | <script src="${BASE}/static/assets/cnlive/js/channel.js" type="text/javascript"></script> |
| 29 | <script src="${BASE}/static/assets/cnlive/js/signal.js" type="text/javascript"></script> | 36 | <script src="${BASE}/static/assets/cnlive/js/signal.js" type="text/javascript"></script> |
src/main/webapp/pages/common/left.jsp
| @@ -41,6 +41,15 @@ | @@ -41,6 +41,15 @@ | ||
| 41 | <li> | 41 | <li> |
| 42 | <a href="${BASE}/signal/list/1"><i class="fa fa-circle-o text-red"></i>信源管理</a> | 42 | <a href="${BASE}/signal/list/1"><i class="fa fa-circle-o text-red"></i>信源管理</a> |
| 43 | </li> | 43 | </li> |
| 44 | + | ||
| 45 | + <!-- 主播 --> | ||
| 46 | + <li class="header">系统设置</li> | ||
| 47 | + <li> | ||
| 48 | + <a href="${BASE}/room/list/1"><i class="fa fa-circle-o text-yellow"></i>直播间管理</a> | ||
| 49 | + </li> | ||
| 50 | + <li> | ||
| 51 | + <a href="${BASE}/live/list/1"><i class="fa fa-circle-o text-yellow"></i>直播活动</a> | ||
| 52 | + </li> | ||
| 44 | </c:if> | 53 | </c:if> |
| 45 | <c:if test="${sessionScope.roleId=='0'}"> | 54 | <c:if test="${sessionScope.roleId=='0'}"> |
| 46 | <li class="header">导航栏</li> | 55 | <li class="header">导航栏</li> |
src/main/webapp/pages/live/live_add.jsp
0 → 100644
| 1 | +<%@ page language="java" pageEncoding="UTF-8"%> | ||
| 2 | +<%@ include file="/pages/common/taglib.jsp"%> | ||
| 3 | +<!DOCTYPE html> | ||
| 4 | +<html> | ||
| 5 | +<head> | ||
| 6 | +<meta charset="UTF-8"> | ||
| 7 | +<title>新建活动 | <f:message key="common.title" /></title> | ||
| 8 | +<meta | ||
| 9 | + content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' | ||
| 10 | + name='viewport'> | ||
| 11 | +<%@ include file="/pages/common/css.jsp"%> | ||
| 12 | + | ||
| 13 | +<style type="text/css"> | ||
| 14 | + span.error{ | ||
| 15 | + padding-left: 15px; | ||
| 16 | + color: red; | ||
| 17 | + } | ||
| 18 | + </style> | ||
| 19 | +<link | ||
| 20 | + href="http://www.bootcss.com/p/bootstrap-datetimepicker/bootstrap-datetimepicker/css/datetimepicker.css" | ||
| 21 | + rel="stylesheet"> | ||
| 22 | + <script type="text/javascript" charset="utf-8" src="${BASE}/static/assets/ueditor/ueditor.config.js"></script> | ||
| 23 | + <script type="text/javascript" charset="utf-8" src="${BASE}/static/assets/ueditor/ueditor.all.min.js"> </script> | ||
| 24 | + <script type="text/javascript" charset="utf-8" src="${BASE}/static/assets/ueditor/lang/zh-cn/zh-cn.js"></script> | ||
| 25 | + | ||
| 26 | +</head> | ||
| 27 | +<body class="skin-blue fixed "> | ||
| 28 | + <div class="wrapper"> | ||
| 29 | + <%@ include file="/pages/common/top.jsp"%> | ||
| 30 | + <%@ include file="/pages/common/left.jsp"%> | ||
| 31 | + <div class="content-wrapper"> | ||
| 32 | + <section class="content-header"> | ||
| 33 | + <h1>${empty tActivity.id ? '新建活动':'编辑活动'} | ||
| 34 | + <small>${tActivity.name}</small> <small class="label label-warning" | ||
| 35 | + style="display: none" id="info_tab_span"><i | ||
| 36 | + class="fa fa-bell-o"></i>保存成功</small> | ||
| 37 | + </h1> | ||
| 38 | + <ol class="breadcrumb"> | ||
| 39 | + <li><a><i class="fa fa-dashboard"></i> 首页</a></li> | ||
| 40 | + <li class="active">新增活动</li> | ||
| 41 | + </ol> | ||
| 42 | + </section> | ||
| 43 | + <!-- Main content --> | ||
| 44 | + <section class="content"> | ||
| 45 | + <form id="create_form" enctype="multipart/form-data" method="post"> | ||
| 46 | + <div class="row"> | ||
| 47 | + <!-- right column --> | ||
| 48 | + <div class="col-md-12"> | ||
| 49 | + <!-- general form elements disabled --> | ||
| 50 | + <div class="box box-warning"> | ||
| 51 | + <div class="box-body"> | ||
| 52 | + <div class="form-group"> | ||
| 53 | + <label> 活动名称 </label> | ||
| 54 | + <div class="input-group"> | ||
| 55 | + <span class="input-group-addon"><i class="fa fa-font"></i> | ||
| 56 | + </span> <input type="text" value="${tActivity.name }" name="name" | ||
| 57 | + id="name" class="form-control"> | ||
| 58 | + <input type="text" id="activity_id" name="activity_id" value="${tActivity.id}" hidden=""> | ||
| 59 | + </div> | ||
| 60 | + </div> | ||
| 61 | + <div class="form-group"> | ||
| 62 | + <label> 直播时间 </label> | ||
| 63 | + <div class="row"> | ||
| 64 | + <div class="col-lg-6"> | ||
| 65 | + <div class="input-group"> | ||
| 66 | + <span class="input-group-addon"> 开始时间 </span> <input | ||
| 67 | + type="text" class="form-control form_datetime" | ||
| 68 | + value="<fmt:formatDate value="${tActivity.start_time}" pattern="yyyy-MM-dd HH:mm"/>" | ||
| 69 | + name="start_time" id="start_time" | ||
| 70 | + data-inputmask="'alias': 'yyyy-MM-dd HH:mm'" data-mask="" /> | ||
| 71 | + </div> | ||
| 72 | + </div> | ||
| 73 | + <div class="col-lg-6"> | ||
| 74 | + <div class="input-group"> | ||
| 75 | + <span class="input-group-addon"> 结束时间</span> <input | ||
| 76 | + type="text" class="form-control form_datetime" | ||
| 77 | + value="<fmt:formatDate value="${tActivity.end_time}" pattern="yyyy-MM-dd HH:mm"/>" | ||
| 78 | + name="end_time" id="end_time" | ||
| 79 | + data-inputmask="'alias': 'yyyy-MM-dd HH:mm'" data-mask=""> | ||
| 80 | + </div> | ||
| 81 | + </div> | ||
| 82 | + </div> | ||
| 83 | + </div> | ||
| 84 | + <div class="form-group"> | ||
| 85 | + <label>海报 </label> | ||
| 86 | + <div class="input-group"> | ||
| 87 | + <span class="input-group-addon"><i | ||
| 88 | + class="fa fa-file-word-o"></i> </span> <input id="input-22" type="file" name="input-22" accept="image/*" class="file-loading"> | ||
| 89 | + </div> | ||
| 90 | + </div> | ||
| 91 | + <div class="form-group"> | ||
| 92 | + <label> 播出直播间 </label> | ||
| 93 | + <div class="box box-warning"> | ||
| 94 | + <div class="box-body"> | ||
| 95 | + <div class="form-group"> | ||
| 96 | + <select class="form-control" name="t_default_video_id" | ||
| 97 | + id="t_default_video_id"> | ||
| 98 | + <c:forEach var="item" items="${tRooms}" | ||
| 99 | + varStatus="stat"> | ||
| 100 | + <option id="t_room_id_${item.id}" ${item.id==tLive.t_room_id ? 'selected="selected"':''} value="${item.id}">${item.name}</option> | ||
| 101 | + </c:forEach> | ||
| 102 | + </select> | ||
| 103 | + </div> | ||
| 104 | + </div> | ||
| 105 | + </div>> | ||
| 106 | + </div> | ||
| 107 | + | ||
| 108 | + <div class="form-group"> | ||
| 109 | + <label>活动简述 </label> | ||
| 110 | + <div class="input-group"> | ||
| 111 | + <span class="input-group-addon"><i | ||
| 112 | + class="fa fa-file-word-o"></i> </span> <script id="editor" type="text/plain" style="width:1024px;height:500px;"></script> | ||
| 113 | + </div> | ||
| 114 | + </div> | ||
| 115 | + <div class="box-footer"> | ||
| 116 | + <button type="button" id="t_activity_save_btn" | ||
| 117 | + name="t_activity_save_btn" onclick="toSubmit();" | ||
| 118 | + class="btn btn-success"> | ||
| 119 | + <i class="fa fa-save "></i> 保存 | ||
| 120 | + </button> | ||
| 121 | + </div> | ||
| 122 | + </div> | ||
| 123 | + </div> | ||
| 124 | + </div> | ||
| 125 | + </div> | ||
| 126 | + </form> | ||
| 127 | + </div> | ||
| 128 | + </section> | ||
| 129 | + </div> | ||
| 130 | + </div> | ||
| 131 | + <%@ include file="/pages/common/bottom.jsp"%> | ||
| 132 | +</div> | ||
| 133 | + <!-- 信号选择结束 --> | ||
| 134 | + <%@ include file="/pages/common/js.jsp"%> | ||
| 135 | + | ||
| 136 | + <script type="text/javascript"> | ||
| 137 | + | ||
| 138 | + $(document).on('ready', function() { | ||
| 139 | + $("#input-22").fileinput({ | ||
| 140 | + previewFileType: "image", | ||
| 141 | + browseClass: "btn btn-success", | ||
| 142 | + browseLabel: "Pick Image", | ||
| 143 | + browseIcon: "<i class=\"glyphicon glyphicon-picture\"></i> ", | ||
| 144 | + removeClass: "btn btn-danger", | ||
| 145 | + removeLabel: "Delete", | ||
| 146 | + removeIcon: "<i class=\"glyphicon glyphicon-trash\"></i> ", | ||
| 147 | + uploadClass: "btn btn-info", | ||
| 148 | + uploadLabel: "Upload", | ||
| 149 | + uploadIcon: "<i class=\"glyphicon glyphicon-upload\"></i> " | ||
| 150 | + }); | ||
| 151 | + }); | ||
| 152 | + | ||
| 153 | + | ||
| 154 | + $(function () { | ||
| 155 | + //Money Euro | ||
| 156 | + $("[data-mask]").inputmask(); | ||
| 157 | + }); | ||
| 158 | + | ||
| 159 | + $(function () { | ||
| 160 | + $("#datemask").inputmask("dd/mm/yyyy", {"placeholder": "dd/mm/yyyy"}); | ||
| 161 | + //Datemask2 mm/dd/yyyy | ||
| 162 | + $("#datemask2").inputmask("mm/dd/yyyy", {"placeholder": "mm/dd/yyyy"}); | ||
| 163 | + //Money Euro | ||
| 164 | + $("[data-mask]").inputmask(); | ||
| 165 | + | ||
| 166 | + //Date range picker | ||
| 167 | + $('#reservation').daterangepicker(); | ||
| 168 | + //Date range picker with time picker | ||
| 169 | + $('#reservationtime').daterangepicker({timePicker: true, timePickerIncrement: 30, format: 'MM/DD/YYYY h:mm A'}); | ||
| 170 | + //Date range as a button | ||
| 171 | + $('#daterange-btn').daterangepicker( | ||
| 172 | + { | ||
| 173 | + ranges: { | ||
| 174 | + 'Today': [moment(), moment()], | ||
| 175 | + 'Yesterday': [moment().subtract('days', 1), moment().subtract('days', 1)], | ||
| 176 | + 'Last 7 Days': [moment().subtract('days', 6), moment()], | ||
| 177 | + 'Last 30 Days': [moment().subtract('days', 29), moment()], | ||
| 178 | + 'This Month': [moment().startOf('month'), moment().endOf('month')], | ||
| 179 | + 'Last Month': [moment().subtract('month', 1).startOf('month'), moment().subtract('month', 1).endOf('month')] | ||
| 180 | + }, | ||
| 181 | + startDate: moment().subtract('days', 29), | ||
| 182 | + endDate: moment() | ||
| 183 | + }, | ||
| 184 | + function (start, end) { | ||
| 185 | + $('#reportrange span').html(start.format('MMMM D, YYYY') + ' - ' + end.format('MMMM D, YYYY')); | ||
| 186 | + } | ||
| 187 | + ); | ||
| 188 | + }); | ||
| 189 | + </script> | ||
| 190 | + | ||
| 191 | + | ||
| 192 | + <!-- Le javascript | ||
| 193 | + ================================================== --> | ||
| 194 | + <script | ||
| 195 | + src="http://www.bootcss.com/p/bootstrap-datetimepicker/bootstrap-datetimepicker/js/bootstrap-datetimepicker.min.js"></script> | ||
| 196 | + | ||
| 197 | + <script type="text/javascript"> | ||
| 198 | + $(".form_datetime").datetimepicker({ | ||
| 199 | + //format: "dd MM yyyy - hh:ii", | ||
| 200 | + format: "yyyy-mm-dd hh:ii", | ||
| 201 | + autoclose: true, | ||
| 202 | + todayBtn: true, | ||
| 203 | + pickerPosition: "bottom-right" | ||
| 204 | + }); | ||
| 205 | +</script> | ||
| 206 | + | ||
| 207 | +<script type="text/javascript"> | ||
| 208 | + | ||
| 209 | + //实例化编辑器 | ||
| 210 | + //建议使用工厂方法getEditor创建和引用编辑器实例,如果在某个闭包下引用该编辑器,直接调用UE.getEditor('editor')就能拿到相关的实例 | ||
| 211 | + var ue = UE.getEditor('editor',{ | ||
| 212 | + autoHeightEnabled: true, | ||
| 213 | + autoFloatEnabled: true | ||
| 214 | + }); | ||
| 215 | + | ||
| 216 | + | ||
| 217 | + function isFocus(e){ | ||
| 218 | + alert(UE.getEditor('editor').isFocus()); | ||
| 219 | + UE.dom.domUtils.preventDefault(e) | ||
| 220 | + } | ||
| 221 | + function setblur(e){ | ||
| 222 | + UE.getEditor('editor').blur(); | ||
| 223 | + UE.dom.domUtils.preventDefault(e) | ||
| 224 | + } | ||
| 225 | + function insertHtml() { | ||
| 226 | + var value = prompt('插入html代码', ''); | ||
| 227 | + UE.getEditor('editor').execCommand('insertHtml', value) | ||
| 228 | + } | ||
| 229 | + function createEditor() { | ||
| 230 | + enableBtn(); | ||
| 231 | + UE.getEditor('editor'); | ||
| 232 | + } | ||
| 233 | + function getAllHtml() { | ||
| 234 | + alert(UE.getEditor('editor').getAllHtml()) | ||
| 235 | + } | ||
| 236 | + function getContent() { | ||
| 237 | + var arr = []; | ||
| 238 | + arr.push("使用editor.getContent()方法可以获得编辑器的内容"); | ||
| 239 | + arr.push("内容为:"); | ||
| 240 | + arr.push(UE.getEditor('editor').getContent()); | ||
| 241 | + alert(arr.join("\n")); | ||
| 242 | + } | ||
| 243 | + function getPlainTxt() { | ||
| 244 | + var arr = []; | ||
| 245 | + arr.push("使用editor.getPlainTxt()方法可以获得编辑器的带格式的纯文本内容"); | ||
| 246 | + arr.push("内容为:"); | ||
| 247 | + arr.push(UE.getEditor('editor').getPlainTxt()); | ||
| 248 | + alert(arr.join('\n')) | ||
| 249 | + } | ||
| 250 | + function setContent(isAppendTo) { | ||
| 251 | + var arr = []; | ||
| 252 | + arr.push("使用editor.setContent('欢迎使用ueditor')方法可以设置编辑器的内容"); | ||
| 253 | + UE.getEditor('editor').setContent('欢迎使用ueditor', isAppendTo); | ||
| 254 | + alert(arr.join("\n")); | ||
| 255 | + } | ||
| 256 | + function setDisabled() { | ||
| 257 | + UE.getEditor('editor').setDisabled('fullscreen'); | ||
| 258 | + disableBtn("enable"); | ||
| 259 | + } | ||
| 260 | + | ||
| 261 | + function setEnabled() { | ||
| 262 | + UE.getEditor('editor').setEnabled(); | ||
| 263 | + enableBtn(); | ||
| 264 | + } | ||
| 265 | + | ||
| 266 | + function getText() { | ||
| 267 | + //当你点击按钮时编辑区域已经失去了焦点,如果直接用getText将不会得到内容,所以要在选回来,然后取得内容 | ||
| 268 | + var range = UE.getEditor('editor').selection.getRange(); | ||
| 269 | + range.select(); | ||
| 270 | + var txt = UE.getEditor('editor').selection.getText(); | ||
| 271 | + alert(txt) | ||
| 272 | + } | ||
| 273 | + | ||
| 274 | + function getContentTxt() { | ||
| 275 | + var arr = []; | ||
| 276 | + arr.push("使用editor.getContentTxt()方法可以获得编辑器的纯文本内容"); | ||
| 277 | + arr.push("编辑器的纯文本内容为:"); | ||
| 278 | + arr.push(UE.getEditor('editor').getContentTxt()); | ||
| 279 | + alert(arr.join("\n")); | ||
| 280 | + } | ||
| 281 | + function hasContent() { | ||
| 282 | + var arr = []; | ||
| 283 | + arr.push("使用editor.hasContents()方法判断编辑器里是否有内容"); | ||
| 284 | + arr.push("判断结果为:"); | ||
| 285 | + arr.push(UE.getEditor('editor').hasContents()); | ||
| 286 | + alert(arr.join("\n")); | ||
| 287 | + } | ||
| 288 | + function setFocus() { | ||
| 289 | + UE.getEditor('editor').focus(); | ||
| 290 | + } | ||
| 291 | + function deleteEditor() { | ||
| 292 | + disableBtn(); | ||
| 293 | + UE.getEditor('editor').destroy(); | ||
| 294 | + } | ||
| 295 | + function disableBtn(str) { | ||
| 296 | + var div = document.getElementById('btns'); | ||
| 297 | + var btns = UE.dom.domUtils.getElementsByTagName(div, "button"); | ||
| 298 | + for (var i = 0, btn; btn = btns[i++];) { | ||
| 299 | + if (btn.id == str) { | ||
| 300 | + UE.dom.domUtils.removeAttributes(btn, ["disabled"]); | ||
| 301 | + } else { | ||
| 302 | + btn.setAttribute("disabled", "true"); | ||
| 303 | + } | ||
| 304 | + } | ||
| 305 | + } | ||
| 306 | + function enableBtn() { | ||
| 307 | + var div = document.getElementById('btns'); | ||
| 308 | + var btns = UE.dom.domUtils.getElementsByTagName(div, "button"); | ||
| 309 | + for (var i = 0, btn; btn = btns[i++];) { | ||
| 310 | + UE.dom.domUtils.removeAttributes(btn, ["disabled"]); | ||
| 311 | + } | ||
| 312 | + } | ||
| 313 | + | ||
| 314 | + function getLocalData () { | ||
| 315 | + alert(UE.getEditor('editor').execCommand( "getlocaldata" )); | ||
| 316 | + } | ||
| 317 | + | ||
| 318 | + function clearLocalData () { | ||
| 319 | + UE.getEditor('editor').execCommand( "clearlocaldata" ); | ||
| 320 | + alert("已清空草稿箱") | ||
| 321 | + } | ||
| 322 | + | ||
| 323 | + | ||
| 324 | + $(function() { | ||
| 325 | + $('#create_form').ajaxForm({ | ||
| 326 | + type : 'post', | ||
| 327 | + url : '../live/save', | ||
| 328 | + enctype : 'multipart/form-data', | ||
| 329 | + beforeSubmit : function() { | ||
| 330 | + return true; | ||
| 331 | + }, | ||
| 332 | + error : function(XMLHttpRequest, textStatus, errorThrown) { | ||
| 333 | + alert("错误"); | ||
| 334 | + }, | ||
| 335 | + success : function(result) { | ||
| 336 | + location.href = '../live/list/1'; | ||
| 337 | + } | ||
| 338 | + }); | ||
| 339 | + }); | ||
| 340 | + | ||
| 341 | + | ||
| 342 | +</script> | ||
| 343 | +</body> | ||
| 344 | +</html> |
src/main/webapp/pages/live/live_management.jsp
0 → 100644
| 1 | +<%@ page language="java" pageEncoding="UTF-8"%> | ||
| 2 | +<%@ include file="/pages/common/taglib.jsp"%> | ||
| 3 | +<!DOCTYPE html> | ||
| 4 | +<html> | ||
| 5 | +<head> | ||
| 6 | +<meta charset="UTF-8"> | ||
| 7 | +<title>活动管理 | <f:message key="common.title" /></title> | ||
| 8 | +<meta | ||
| 9 | + content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' | ||
| 10 | + name='viewport'> | ||
| 11 | +<%@ include file="/pages/common/css.jsp"%> | ||
| 12 | +</head> | ||
| 13 | +<body class="skin-blue fixed "> | ||
| 14 | + <div class="wrapper"> | ||
| 15 | + <%@ include file="/pages/common/top.jsp"%> | ||
| 16 | + <%@ include file="/pages/common/left.jsp"%> | ||
| 17 | + <div class="content-wrapper"> | ||
| 18 | + <!-- Content Header (Page header) --> | ||
| 19 | + <section class="content-header"> | ||
| 20 | + <h1> | ||
| 21 | + 活动管理<small><a href="../../live/preload"><i | ||
| 22 | + class="fa fa-plus"></i>新增活动</a> </small> | ||
| 23 | + <small class="label label-warning" style="display: none" | ||
| 24 | + id="info_tab_span"><i class="fa fa-bell-o"></i></small> | ||
| 25 | + </h1> | ||
| 26 | + | ||
| 27 | + <ol class="breadcrumb"> | ||
| 28 | + <li><a><i class="fa fa-dashboard"></i> 首页</a></li> | ||
| 29 | + <li class="active">活动管理</li> | ||
| 30 | + </ol> | ||
| 31 | + </section> | ||
| 32 | + <!-- Main content --> | ||
| 33 | + <section class="content"> | ||
| 34 | + <div class="row"> | ||
| 35 | + <div class="col-xs-12"> | ||
| 36 | + <div class="box box-warning"> | ||
| 37 | + <div class="box-header with-border"> | ||
| 38 | + <h3 class="box-title"></h3> | ||
| 39 | + <div class="box-tools"> | ||
| 40 | + <div class="input-group"> | ||
| 41 | + <form action="../search/1" method="post"> | ||
| 42 | + <div class="input-group"> | ||
| 43 | + <input type="text" name="search_text" id="search_text" | ||
| 44 | + class="form-control input-sm" style="width: 150px;" | ||
| 45 | + placeholder="Search" /> | ||
| 46 | + <button id="t_activity_search_btn" type="submit" | ||
| 47 | + class="btn btn-sm btn-default"> | ||
| 48 | + <i class="fa fa-search"></i>搜索 | ||
| 49 | + </button> | ||
| 50 | + </div> | ||
| 51 | + </form> | ||
| 52 | + </div> | ||
| 53 | + </div> | ||
| 54 | + </div> | ||
| 55 | + <!-- /.box-header --> | ||
| 56 | + <div class="box-body"> | ||
| 57 | + <table class="table table-bordered"> | ||
| 58 | + <tr> | ||
| 59 | + <th>活动名称</th> | ||
| 60 | + <th>开始时间</th> | ||
| 61 | + <th>结束时间</th> | ||
| 62 | + <th>状态</th> | ||
| 63 | + <th>修改</th> | ||
| 64 | + <th>删除</th> | ||
| 65 | + </tr> | ||
| 66 | + <c:forEach var="item" items="${tLive.recordList}" | ||
| 67 | + varStatus="stat"> | ||
| 68 | + <tr> | ||
| 69 | + <td><a href="${BASE}/activity/preview/${item.id}">${item.title}</a> | ||
| 70 | + </td> | ||
| 71 | + <td><fmt:formatDate value="${item.start_time}" | ||
| 72 | + pattern="yyyy-MM-dd HH:mm" /></td> | ||
| 73 | + <td>${item.end_time}</td> | ||
| 74 | + <td> | ||
| 75 | + | ||
| 76 | + </td> | ||
| 77 | + <td> | ||
| 78 | + <button class="btn btn-default btn-sm" | ||
| 79 | + onclick="t_activity_edit(${item.id});"> | ||
| 80 | + <i class="fa fa-edit"></i> | ||
| 81 | + </button> | ||
| 82 | + </td> | ||
| 83 | + <td> | ||
| 84 | + <button class="btn btn-danger btn-sm" | ||
| 85 | + onclick="t_activity_delete(${item.id});"> | ||
| 86 | + <i class="fa fa-close"></i> | ||
| 87 | + </button> | ||
| 88 | + </td> | ||
| 89 | + </tr> | ||
| 90 | + </c:forEach> | ||
| 91 | + </table> | ||
| 92 | + </div> | ||
| 93 | + <!-- /.box-body --> | ||
| 94 | + <div class="box-footer clearfix"> | ||
| 95 | + <center> | ||
| 96 | + <tag:pager id="product_pager" pager="${tLive}" /> | ||
| 97 | + </center> | ||
| 98 | + </div> | ||
| 99 | + </div> | ||
| 100 | + </div> | ||
| 101 | + </div> | ||
| 102 | + </div> | ||
| 103 | + <%@ include file="/pages/common/bottom.jsp"%> | ||
| 104 | + </div> | ||
| 105 | + <%@ include file="/pages/common/js.jsp"%> | ||
| 106 | +</body> | ||
| 107 | +</html> |
src/main/webapp/pages/room/room_add.jsp
0 → 100644
| 1 | +<%@ page language="java" pageEncoding="UTF-8"%> | ||
| 2 | +<%@ include file="/pages/common/taglib.jsp"%> | ||
| 3 | +<!DOCTYPE html> | ||
| 4 | +<html> | ||
| 5 | +<head> | ||
| 6 | +<meta charset="UTF-8"> | ||
| 7 | +<title>新建直播间 | <f:message key="common.title" /></title> | ||
| 8 | +<meta | ||
| 9 | + content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' | ||
| 10 | + name='viewport'> | ||
| 11 | +<%@ include file="/pages/common/css.jsp"%> | ||
| 12 | +<link href="${BASE}/static/assets/plugins/uploadfile/css/fileinput.css" | ||
| 13 | + media="all" rel="stylesheet" type="text/css" /> | ||
| 14 | +<!--[if IE]> | ||
| 15 | + <script src="http://libs.useso.com/js/html5shiv/3.7/html5shiv.min.js"></script> | ||
| 16 | + <![endif]--> | ||
| 17 | +</head> | ||
| 18 | +<body class="skin-blue sidebar-mini"> | ||
| 19 | + <div class="wrapper"> | ||
| 20 | + <%@ include file="/pages/common/top.jsp"%> | ||
| 21 | + <%@ include file="/pages/common/left.jsp"%> | ||
| 22 | + <div class="content-wrapper"> | ||
| 23 | + <!-- Content Header (Page header) --> | ||
| 24 | + <section class="content-header"> | ||
| 25 | + <h1> | ||
| 26 | + ${empty tRoom.id ? '新建直播间':'编辑直播间'} <small>${tRoom.name}</small> <small | ||
| 27 | + class="label label-warning" style="display: none" | ||
| 28 | + id="info_tab_span"><i class="fa fa-bell-o"></i>保存成功</small> | ||
| 29 | + </h1> | ||
| 30 | + <ol class="breadcrumb"> | ||
| 31 | + <li><a><i class="fa fa-dashboard"></i> 首页</a></li> | ||
| 32 | + <li class="active">新增直播间</li> | ||
| 33 | + </ol> | ||
| 34 | + </section> | ||
| 35 | + <!-- Main content --> | ||
| 36 | + <section class="content"> | ||
| 37 | + <div class="row"> | ||
| 38 | + <div class="col-md-12"> | ||
| 39 | + <form id="create_form" enctype="multipart/form-data" method="post"> | ||
| 40 | + <div class="box box-success"> | ||
| 41 | + <div class="box-body"> | ||
| 42 | + <div class="form-group"> | ||
| 43 | + <label>直播间名称 </label> | ||
| 44 | + <div class="input-group"> | ||
| 45 | + <span class="input-group-addon"><i class="fa fa-font"></i> | ||
| 46 | + </span> <input type="text" class="form-control" | ||
| 47 | + value="${tRoom.name}" id="name" name="name"> | ||
| 48 | + </div> | ||
| 49 | + </div> | ||
| 50 | + <div class="form-group"> | ||
| 51 | + <label>海报 </label> | ||
| 52 | + <div class="input-group"> | ||
| 53 | + <div class="input-group-addon"> | ||
| 54 | + <i class="fa fa-file-image-o"></i> | ||
| 55 | + </div> | ||
| 56 | + <input id="input-22" type="file" name="input-22" | ||
| 57 | + accept="image/*" class="file-loading"> | ||
| 58 | + </div> | ||
| 59 | + </div> | ||
| 60 | + </div> | ||
| 61 | + <button type="submit" id="t_channel_save_btn" | ||
| 62 | + class="btn btn-primary"> | ||
| 63 | + <i class="fa fa-save "></i> 保存 | ||
| 64 | + </button> | ||
| 65 | + </form> | ||
| 66 | + </div> | ||
| 67 | + </div> | ||
| 68 | + </section> | ||
| 69 | + </div> | ||
| 70 | + <%@ include file="/pages/common/bottom.jsp"%> | ||
| 71 | + </div> | ||
| 72 | + <%@ include file="/pages/common/js.jsp"%> | ||
| 73 | + <script src="${BASE}/static/assets/cnlive/js/Math.uuid.js"></script> | ||
| 74 | + <script src="${BASE}/static/assets/cnlive/js/ajax_rest.js"></script> | ||
| 75 | + <script | ||
| 76 | + src="${BASE}/static/assets/cnlive/js/validate/validate_channel.js" | ||
| 77 | + type="text/javascript"></script> | ||
| 78 | + <script src="${BASE}/static/assets/plugins/uploadfile/js/fileinput.js" | ||
| 79 | + type="text/javascript"></script> | ||
| 80 | + <script | ||
| 81 | + src="${BASE}/static/assets/plugins/uploadfile/js/fileinput_locale_zh.js" | ||
| 82 | + type="text/javascript"></script> | ||
| 83 | + | ||
| 84 | + <script type="text/javascript"> | ||
| 85 | + $(document).on('ready', function() { | ||
| 86 | + $("#input-22").fileinput({ | ||
| 87 | + previewFileType: "image", | ||
| 88 | + browseClass: "btn btn-success", | ||
| 89 | + browseLabel: "Pick Image", | ||
| 90 | + browseIcon: "<i class=\"glyphicon glyphicon-picture\"></i> ", | ||
| 91 | + removeClass: "btn btn-danger", | ||
| 92 | + removeLabel: "Delete", | ||
| 93 | + removeIcon: "<i class=\"glyphicon glyphicon-trash\"></i> ", | ||
| 94 | + uploadClass: "btn btn-info", | ||
| 95 | + uploadLabel: "Upload", | ||
| 96 | + uploadIcon: "<i class=\"glyphicon glyphicon-upload\"></i> " | ||
| 97 | + }); | ||
| 98 | + }); | ||
| 99 | + | ||
| 100 | + $(function() { | ||
| 101 | + $('#create_form').ajaxForm({ | ||
| 102 | + type : 'post', | ||
| 103 | + url : '../live/save', | ||
| 104 | + enctype : 'multipart/form-data', | ||
| 105 | + beforeSubmit : function() { | ||
| 106 | + return true; | ||
| 107 | + }, | ||
| 108 | + error : function(XMLHttpRequest, textStatus, errorThrown) { | ||
| 109 | + alert("错误"); | ||
| 110 | + }, | ||
| 111 | + success : function(result) { | ||
| 112 | + location.href = '../live/list/1'; | ||
| 113 | + } | ||
| 114 | + }); | ||
| 115 | + }); | ||
| 116 | + | ||
| 117 | + </script> | ||
| 118 | +</body> | ||
| 119 | +</html> |
src/main/webapp/pages/room/room_management.jsp
0 → 100644
| 1 | +<%@ page language="java" pageEncoding="UTF-8"%> | ||
| 2 | +<%@ include file="/pages/common/taglib.jsp"%> | ||
| 3 | +<!DOCTYPE html> | ||
| 4 | +<html> | ||
| 5 | +<head> | ||
| 6 | +<meta charset="UTF-8"> | ||
| 7 | +<title>直播间管理 | <f:message key="common.title"/></title> | ||
| 8 | +<meta | ||
| 9 | + content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' | ||
| 10 | + name='viewport'> | ||
| 11 | +<%@ include file="/pages/common/css.jsp"%> | ||
| 12 | +</head> | ||
| 13 | +<body class="skin-blue sidebar-mini"> | ||
| 14 | + <div class="wrapper"> | ||
| 15 | + <%@ include file="/pages/common/top.jsp"%> | ||
| 16 | + <%@ include file="/pages/common/left.jsp"%> | ||
| 17 | + <div class="content-wrapper"> | ||
| 18 | + <!-- Content Header (Page header) --> | ||
| 19 | + <section class="content-header"> | ||
| 20 | + <h1> | ||
| 21 | + 直播间管理 <small><a href="../../room/pload"><i | ||
| 22 | + class="fa fa-plus"></i>新增直播间</a> </small> | ||
| 23 | + <small class="label label-warning" style="display: none" | ||
| 24 | + id="info_tab_span"><i class="fa fa-bell-o"></i></small> | ||
| 25 | + </h1> | ||
| 26 | + <ol class="breadcrumb"> | ||
| 27 | + <li><a><i class="fa fa-dashboard"></i> 首页</a></li> | ||
| 28 | + <li><a>直播间管理</a></li> | ||
| 29 | + </ol> | ||
| 30 | + </section> | ||
| 31 | + <!-- Main content --> | ||
| 32 | + <section class="content"> | ||
| 33 | + <div class="row"> | ||
| 34 | + <div class="col-xs-12"> | ||
| 35 | + <div class="box box-success"> | ||
| 36 | + <div class="box-header with-border"> | ||
| 37 | + <!-- <h3 class="box-title"></h3> --> | ||
| 38 | + <div class="box-tools"> | ||
| 39 | + <div class="input-group"> | ||
| 40 | + </div> | ||
| 41 | + </div> | ||
| 42 | + </div> | ||
| 43 | + <!-- /.box-header --> | ||
| 44 | + <div class="box-body"> | ||
| 45 | + <table class="table table-bordered"> | ||
| 46 | + <tr> | ||
| 47 | + <th>名称</th> | ||
| 48 | + <th>状态</th> | ||
| 49 | + <th>stream name</th> | ||
| 50 | + <th>修改</th> | ||
| 51 | + <th>删除</th> | ||
| 52 | + </tr> | ||
| 53 | + <c:forEach var="item" items="${tRooms.recordList}" | ||
| 54 | + varStatus="stat"> | ||
| 55 | + <tr> | ||
| 56 | + <td> ${item.name}</td> | ||
| 57 | + <td> ${item.t_status_id}</td> | ||
| 58 | + <td>${item.stream_name}</td> | ||
| 59 | + <td> | ||
| 60 | + <button class="btn btn-default btn-sm" | ||
| 61 | + onclick="t_channel_edit(${item.id});"> | ||
| 62 | + <i class="fa fa-edit"></i> | ||
| 63 | + </button> | ||
| 64 | + </td> | ||
| 65 | + <td> | ||
| 66 | + <button class="btn btn-danger btn-sm" | ||
| 67 | + onclick="t_channel_delete(${item.id});"> | ||
| 68 | + <i class="fa fa-close"></i> | ||
| 69 | + </button> | ||
| 70 | + </td> | ||
| 71 | + </tr> | ||
| 72 | + </c:forEach> | ||
| 73 | + </table> | ||
| 74 | + </div> | ||
| 75 | + <!-- /.box-body --> | ||
| 76 | + <div class="box-footer clearfix "> | ||
| 77 | + <center> | ||
| 78 | + <tag:pager id="product_pager" pager="${tRooms}" /> | ||
| 79 | + </center> | ||
| 80 | + </div> | ||
| 81 | + </div> | ||
| 82 | + <!-- /.box --> | ||
| 83 | + </div> | ||
| 84 | + </div> | ||
| 85 | + </div> | ||
| 86 | + <%@ include file="/pages/common/bottom.jsp"%> | ||
| 87 | + </div> | ||
| 88 | + <%@ include file="/pages/common/js.jsp"%> | ||
| 89 | +</body> | ||
| 90 | +</html> |
src/main/webapp/pages/room/room_preview.jsp
0 → 100644
| 1 | +<%@ page language="java" pageEncoding="UTF-8"%> | ||
| 2 | +<%@ include file="/pages/common/taglib.jsp"%> | ||
| 3 | +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||
| 4 | +<html> | ||
| 5 | +<head> | ||
| 6 | +<meta charset="UTF-8"> | ||
| 7 | +<title>直播间预览 | <f:message key="common.title"/></title> | ||
| 8 | +<meta | ||
| 9 | + content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' | ||
| 10 | + name='viewport'> | ||
| 11 | +<%@ include file="/pages/common/css.jsp"%> | ||
| 12 | +<script src="${BASE}/static/assets/jwplayer/jwplayer.js"></script> | ||
| 13 | +<script src="${BASE}/static/assets/jwplayer/jwplayer.html5.js"></script> | ||
| 14 | +<script type="text/javascript"> | ||
| 15 | + jwplayer.key = "MGAzpXRYxGnaVXhH8jSdKXzDe7ucAAvZGWggIA=="; | ||
| 16 | +</script> | ||
| 17 | +</head> | ||
| 18 | + | ||
| 19 | +<body class="skin-blue fixed sidebar-mini"> | ||
| 20 | + <div class="wrapper"> | ||
| 21 | + <%@ include file="/pages/common/top.jsp"%> | ||
| 22 | + <%@ include file="/pages/common/left.jsp"%> | ||
| 23 | + <!-- Content Wrapper. Contains page content --> | ||
| 24 | + <div class="content-wrapper"> | ||
| 25 | + <!-- Content Header (Page header) --> | ||
| 26 | + <section class="content-header"> | ||
| 27 | + <h1>频道预览<small>${tChannel.name_zh}</small></h1> | ||
| 28 | + <ol class="breadcrumb"> | ||
| 29 | + <li><a><i class="fa fa-dashboard"></i> 首页</a></li> | ||
| 30 | + <li><a href="../list/1">频道管理</a></li> | ||
| 31 | + <li class="active">新增预览</li> | ||
| 32 | + </ol> | ||
| 33 | + </section> | ||
| 34 | + <section class="content"> | ||
| 35 | + <div class="row"> | ||
| 36 | + <div class="col-md-6"> | ||
| 37 | + <div class="box"> | ||
| 38 | + <div class="box-header with-border"> | ||
| 39 | + <h3 class="box-title">${isLive==true ? '直播活动信号':'滚播信号'}</h3> | ||
| 40 | + </div> | ||
| 41 | + <div class="box-body"> | ||
| 42 | + <input type="hidden" name="play_url_1" id="play_url_1" | ||
| 43 | + value="${tWowzaSignalBean.tWowzaStream.publish_url}" /> <span | ||
| 44 | + class="mailbox-attachment-icon has-img" id="player_span_1"> | ||
| 45 | + Loading the player... </span> | ||
| 46 | + </div> | ||
| 47 | + <div class="mailbox-attachment-info"> | ||
| 48 | + <a class="mailbox-attachment-name">stream_name:${tWowzaSignalBean.tWowzaStream.stream_name}<br>application_name:${tWowzaSignalBean.tWowzaStream.application_name } <br>lan_ip:${tWowzaSignalBean.tWowza.lan_ip } </a> | ||
| 49 | + | ||
| 50 | + </div> | ||
| 51 | + <div class="box-footer clearfix"> | ||
| 52 | + <!-- <ul class="pagination pagination-sm no-margin pull-right"> | ||
| 53 | + <li> | ||
| 54 | + <button class="btn btn-info btn-sm" id="play_button_1" | ||
| 55 | + onclick="play_1();">载入/断开</button> | ||
| 56 | + </li> | ||
| 57 | + </ul> --> | ||
| 58 | + </div> | ||
| 59 | + </div> | ||
| 60 | + </div> | ||
| 61 | + | ||
| 62 | + <div class="col-md-6"> | ||
| 63 | + <div class="box"> | ||
| 64 | + <div class="box-header with-border"> | ||
| 65 | + <h3 class="box-title">ips 播放地址</h3> | ||
| 66 | + </div> | ||
| 67 | + <div class="box-body"> | ||
| 68 | + <input type="hidden" name="play_url_2" id="play_url_2" | ||
| 69 | + value="${tChannel.play_url}" /> <span | ||
| 70 | + class="mailbox-attachment-icon has-img" id="player_span_2"> | ||
| 71 | + Loading the player... </span> | ||
| 72 | + </div> | ||
| 73 | + <div class="mailbox-attachment-info"> | ||
| 74 | + <a class="mailbox-attachment-name"> </a> | ||
| 75 | + </div> | ||
| 76 | + <div class="box-footer clearfix"> | ||
| 77 | + <!-- <ul class="pagination pagination-sm no-margin pull-right"> | ||
| 78 | + <li> | ||
| 79 | + <button class="btn btn-info btn-sm" id="play_button_2" | ||
| 80 | + onclick="play_2();">载入/断开</button> | ||
| 81 | + </li> | ||
| 82 | + </ul> --> | ||
| 83 | + </div> | ||
| 84 | + </div> | ||
| 85 | + </div> | ||
| 86 | + </div> | ||
| 87 | + </div> | ||
| 88 | + </section> | ||
| 89 | + </div> | ||
| 90 | + <%@ include file="/pages/common/bottom.jsp"%> | ||
| 91 | + <%@ include file="/pages/common/js.jsp"%> | ||
| 92 | + <script src="${BASE}/static/assets/cnlive/js/player_2.js"></script> | ||
| 93 | +</body> | ||
| 94 | +</html> |
src/main/webapp/static/assets/plugins/fileinput/fileinput.css
0 → 100644
| 1 | +/*! | ||
| 2 | + * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2015 | ||
| 3 | + * @package bootstrap-fileinput | ||
| 4 | + * @version 4.2.9 | ||
| 5 | + * | ||
| 6 | + * File input styling for Bootstrap 3.0 | ||
| 7 | + * Built for Yii Framework 2.0 | ||
| 8 | + * Author: Kartik Visweswaran | ||
| 9 | + * Year: 2015 | ||
| 10 | + * For more Yii related demos visit http://demos.krajee.com | ||
| 11 | + */ | ||
| 12 | +.file-loading { | ||
| 13 | + top: 0; | ||
| 14 | + right: 0; | ||
| 15 | + width: 25px; | ||
| 16 | + height: 25px; | ||
| 17 | + font-size: 999px; | ||
| 18 | + text-align: right; | ||
| 19 | + color: #fff; | ||
| 20 | + background: transparent url('../img/loading.gif') top left no-repeat; | ||
| 21 | + border: none; | ||
| 22 | +} | ||
| 23 | + | ||
| 24 | +.file-object { | ||
| 25 | + margin: 0 0 -5px 0; | ||
| 26 | + padding: 0; | ||
| 27 | +} | ||
| 28 | + | ||
| 29 | +.btn-file { | ||
| 30 | + position: relative; | ||
| 31 | + overflow: hidden; | ||
| 32 | +} | ||
| 33 | + | ||
| 34 | +.btn-file input[type=file] { | ||
| 35 | + position: absolute; | ||
| 36 | + top: 0; | ||
| 37 | + right: 0; | ||
| 38 | + min-width: 100%; | ||
| 39 | + min-height: 100%; | ||
| 40 | + text-align: right; | ||
| 41 | + opacity: 0; | ||
| 42 | + background: none repeat scroll 0 0 transparent; | ||
| 43 | + cursor: inherit; | ||
| 44 | + display: block; | ||
| 45 | +} | ||
| 46 | + | ||
| 47 | +.file-caption-name { | ||
| 48 | + display: inline-block; | ||
| 49 | + overflow: hidden; | ||
| 50 | + height: 20px; | ||
| 51 | + word-break: break-all; | ||
| 52 | +} | ||
| 53 | + | ||
| 54 | +.input-group-lg .file-caption-name { | ||
| 55 | + height: 25px; | ||
| 56 | +} | ||
| 57 | + | ||
| 58 | +.file-preview-detail-modal { | ||
| 59 | + text-align: left; | ||
| 60 | +} | ||
| 61 | + | ||
| 62 | +.file-error-message { | ||
| 63 | + color: #a94442; | ||
| 64 | + background-color: #f2dede; | ||
| 65 | + margin: 5px; | ||
| 66 | + border: 1px solid #ebccd1; | ||
| 67 | + border-radius: 4px; | ||
| 68 | + padding: 15px; | ||
| 69 | +} | ||
| 70 | + | ||
| 71 | +.file-error-message pre, .file-error-message ul { | ||
| 72 | + margin: 0; | ||
| 73 | + text-align: left; | ||
| 74 | +} | ||
| 75 | + | ||
| 76 | +.file-error-message pre { | ||
| 77 | + margin: 5px 0; | ||
| 78 | +} | ||
| 79 | + | ||
| 80 | +.file-caption-disabled { | ||
| 81 | + background-color: #EEEEEE; | ||
| 82 | + cursor: not-allowed; | ||
| 83 | + opacity: 1; | ||
| 84 | +} | ||
| 85 | + | ||
| 86 | +.file-preview { | ||
| 87 | + border-radius: 5px; | ||
| 88 | + border: 1px solid #ddd; | ||
| 89 | + padding: 5px; | ||
| 90 | + width: 100%; | ||
| 91 | + margin-bottom: 5px; | ||
| 92 | +} | ||
| 93 | + | ||
| 94 | +.file-preview-frame { | ||
| 95 | + display: table; | ||
| 96 | + margin: 8px; | ||
| 97 | + height: 160px; | ||
| 98 | + border: 1px solid #ddd; | ||
| 99 | + box-shadow: 1px 1px 5px 0 #a2958a; | ||
| 100 | + padding: 6px; | ||
| 101 | + float: left; | ||
| 102 | + text-align: center; | ||
| 103 | + vertical-align: middle; | ||
| 104 | +} | ||
| 105 | + | ||
| 106 | +.file-preview-frame:not(.file-preview-error):hover { | ||
| 107 | + box-shadow: 3px 3px 5px 0 #333; | ||
| 108 | +} | ||
| 109 | + | ||
| 110 | +.file-preview-image { | ||
| 111 | + height: 160px; | ||
| 112 | + vertical-align: middle; | ||
| 113 | +} | ||
| 114 | + | ||
| 115 | +.file-preview-text { | ||
| 116 | + text-align: left; | ||
| 117 | + width: 160px; | ||
| 118 | + margin-bottom: 2px; | ||
| 119 | + color: #428bca; | ||
| 120 | + background: #fff; | ||
| 121 | + overflow-x: hidden; | ||
| 122 | +} | ||
| 123 | + | ||
| 124 | +.file-preview-other { | ||
| 125 | + display: table-cell; | ||
| 126 | + text-align: center; | ||
| 127 | + vertical-align: middle; | ||
| 128 | + width: 160px; | ||
| 129 | + height: 160px; | ||
| 130 | + border: 2px solid #999; | ||
| 131 | + border-radius: 30px; | ||
| 132 | +} | ||
| 133 | + | ||
| 134 | +.file-preview-other:hover { | ||
| 135 | + opacity: 0.8; | ||
| 136 | +} | ||
| 137 | + | ||
| 138 | +.file-actions, .file-other-error { | ||
| 139 | + text-align: left; | ||
| 140 | +} | ||
| 141 | + | ||
| 142 | +.file-icon-lg { | ||
| 143 | + font-size: 1.2em; | ||
| 144 | +} | ||
| 145 | + | ||
| 146 | +.file-icon-2x { | ||
| 147 | + font-size: 2.4em; | ||
| 148 | +} | ||
| 149 | + | ||
| 150 | +.file-icon-4x { | ||
| 151 | + font-size: 4.8em; | ||
| 152 | +} | ||
| 153 | + | ||
| 154 | +.file-input-new .file-preview, .file-input-new .close, .file-input-new .glyphicon-file, | ||
| 155 | +.file-input-new .fileinput-remove-button, .file-input-new .fileinput-upload-button, | ||
| 156 | +.file-input-ajax-new .fileinput-remove-button, .file-input-ajax-new .fileinput-upload-button { | ||
| 157 | + display: none; | ||
| 158 | +} | ||
| 159 | + | ||
| 160 | +.file-thumb-loading { | ||
| 161 | + background: transparent url('../img/loading.gif') no-repeat scroll center center content-box !important; | ||
| 162 | +} | ||
| 163 | + | ||
| 164 | +.file-actions { | ||
| 165 | + margin-top: 15px; | ||
| 166 | +} | ||
| 167 | + | ||
| 168 | +.file-footer-buttons { | ||
| 169 | + float: right; | ||
| 170 | +} | ||
| 171 | + | ||
| 172 | +.file-upload-indicator { | ||
| 173 | + padding-top: 2px; | ||
| 174 | + cursor: default; | ||
| 175 | + opacity: 0.8; | ||
| 176 | + width: 60%; | ||
| 177 | +} | ||
| 178 | + | ||
| 179 | +.file-upload-indicator:hover { | ||
| 180 | + font-weight: bold; | ||
| 181 | + opacity: 1; | ||
| 182 | +} | ||
| 183 | + | ||
| 184 | +.file-footer-caption { | ||
| 185 | + display: block; | ||
| 186 | + white-space: nowrap; | ||
| 187 | + overflow: hidden; | ||
| 188 | + text-overflow: ellipsis; | ||
| 189 | + width: 160px; | ||
| 190 | + text-align: center; | ||
| 191 | + padding-top: 4px; | ||
| 192 | + font-size: 11px; | ||
| 193 | + color: #777; | ||
| 194 | + margin: 5px auto 10px auto; | ||
| 195 | +} | ||
| 196 | + | ||
| 197 | +.file-preview-error { | ||
| 198 | + opacity: 0.65; | ||
| 199 | + box-shadow: none; | ||
| 200 | +} | ||
| 201 | + | ||
| 202 | +.file-preview-frame:not(.file-preview-error) .file-footer-caption:hover { | ||
| 203 | + color: #000; | ||
| 204 | +} | ||
| 205 | + | ||
| 206 | +.file-drop-zone { | ||
| 207 | + border: 1px dashed #aaa; | ||
| 208 | + border-radius: 4px; | ||
| 209 | + height: 100%; | ||
| 210 | + text-align: center; | ||
| 211 | + vertical-align: middle; | ||
| 212 | + margin: 12px 15px 12px 12px; | ||
| 213 | + padding: 5px; | ||
| 214 | +} | ||
| 215 | + | ||
| 216 | +.file-drop-zone-title { | ||
| 217 | + color: #aaa; | ||
| 218 | + font-size: 40px; | ||
| 219 | + padding: 85px 10px; | ||
| 220 | +} | ||
| 221 | + | ||
| 222 | +.file-highlighted { | ||
| 223 | + border: 2px dashed #999 !important; | ||
| 224 | + background-color: #f0f0f0; | ||
| 225 | +} | ||
| 226 | + | ||
| 227 | +.file-uploading { | ||
| 228 | + background: url('../img/loading-sm.gif') no-repeat center bottom 10px; | ||
| 229 | + opacity: 0.65; | ||
| 230 | +} | ||
| 231 | + | ||
| 232 | +.file-thumb-progress .progress, .file-thumb-progress .progress-bar { | ||
| 233 | + height: 10px; | ||
| 234 | + font-size: 9px; | ||
| 235 | + line-height: 10px; | ||
| 236 | +} | ||
| 237 | + | ||
| 238 | +.file-thumbnail-footer { | ||
| 239 | + position: relative; | ||
| 240 | +} | ||
| 241 | + | ||
| 242 | +.file-thumb-progress { | ||
| 243 | + position: absolute; | ||
| 244 | + top: 22px; | ||
| 245 | + left: 0; | ||
| 246 | + right: 0; | ||
| 247 | +} | ||
| 248 | + | ||
| 249 | +/* IE 10 fix */ | ||
| 250 | +.btn-file ::-ms-browse { | ||
| 251 | + width:100%; | ||
| 252 | + height:100%; | ||
| 253 | +} | ||
| 0 | \ No newline at end of file | 254 | \ No newline at end of file |
src/main/webapp/static/assets/plugins/fileinput/fileinput.js
0 → 100644
| 1 | +/*! | ||
| 2 | + * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2015 | ||
| 3 | + * @version 4.2.9 | ||
| 4 | + * | ||
| 5 | + * File input styled for Bootstrap 3.0 that utilizes HTML5 File Input's advanced | ||
| 6 | + * features including the FileReader API. | ||
| 7 | + * | ||
| 8 | + * The plugin drastically enhances the HTML file input to preview multiple files on the client before | ||
| 9 | + * upload. In addition it provides the ability to preview content of images, text, videos, audio, html, | ||
| 10 | + * flash and other objects. It also offers the ability to upload and delete files using AJAX, and add | ||
| 11 | + * files in batches (i.e. preview, append, or remove before upload). | ||
| 12 | + * | ||
| 13 | + * Author: Kartik Visweswaran | ||
| 14 | + * Copyright: 2015, Kartik Visweswaran, Krajee.com | ||
| 15 | + * For more JQuery plugins visit http://plugins.krajee.com | ||
| 16 | + * For more Yii related demos visit http://demos.krajee.com | ||
| 17 | + */ | ||
| 18 | +(function (factory) { | ||
| 19 | + "use strict"; | ||
| 20 | + if (typeof define === 'function' && define.amd) { // jshint ignore:line | ||
| 21 | + // AMD. Register as an anonymous module. | ||
| 22 | + define(['jquery'], factory); // jshint ignore:line | ||
| 23 | + } else { // noinspection JSUnresolvedVariable | ||
| 24 | + if (typeof module === 'object' && module.exports) { // jshint ignore:line | ||
| 25 | + // Node/CommonJS | ||
| 26 | + // noinspection JSUnresolvedVariable | ||
| 27 | + module.exports = factory(require('jquery')); // jshint ignore:line | ||
| 28 | + } else { | ||
| 29 | + // Browser globals | ||
| 30 | + factory(window.jQuery); | ||
| 31 | + } | ||
| 32 | + } | ||
| 33 | +}(function ($) { | ||
| 34 | + "use strict"; | ||
| 35 | + | ||
| 36 | + $.fn.fileinputLocales = {}; | ||
| 37 | + | ||
| 38 | + var isIE, isEdge, handler, previewCache, getNum, hasFileAPISupport, hasDragDropSupport, hasFileUploadSupport, addCss, | ||
| 39 | + STYLE_SETTING, OBJECT_PARAMS, DEFAULT_PREVIEW, defaultFileActionSettings, tMain1, tMain2, tPreview, tIcon, tClose, | ||
| 40 | + tCaption, tBtnDefault, tBtnLink, tBtnBrowse, tModal, tProgress, tFooter, tActions, tActionDelete, tActionUpload, | ||
| 41 | + tZoom, tGeneric, tHtml, tImage, tText, tVideo, tAudio, tFlash, tObject, tOther, defaultLayoutTemplates, | ||
| 42 | + defaultPreviewTemplates, defaultPreviewTypes, defaultPreviewSettings, defaultFileTypeSettings, isEmpty, isArray, | ||
| 43 | + isSet, getElement, uniqId, htmlEncode, replaceTags, objUrl, FileInput; | ||
| 44 | + | ||
| 45 | + isIE = function (ver) { | ||
| 46 | + // check for IE versions < 11 | ||
| 47 | + if (navigator.appName !== 'Microsoft Internet Explorer') { | ||
| 48 | + return false; | ||
| 49 | + } | ||
| 50 | + if (ver === 10) { | ||
| 51 | + return new RegExp('msie\\s' + ver, 'i').test(navigator.userAgent); | ||
| 52 | + } | ||
| 53 | + var div = document.createElement("div"), status; | ||
| 54 | + div.innerHTML = "<!--[if IE " + ver + "]> <i></i> <![endif]-->"; | ||
| 55 | + status = div.getElementsByTagName("i").length; | ||
| 56 | + document.body.appendChild(div); | ||
| 57 | + div.parentNode.removeChild(div); | ||
| 58 | + return status; | ||
| 59 | + }; | ||
| 60 | + isEdge = function () { | ||
| 61 | + return new RegExp('Edge\/[0-9]+', 'i').test(navigator.userAgent); | ||
| 62 | + }; | ||
| 63 | + handler = function ($el, event, callback, skipNS) { | ||
| 64 | + var ev = skipNS ? event : event + '.fileinput'; | ||
| 65 | + $el.off(ev).on(ev, callback); | ||
| 66 | + }; | ||
| 67 | + previewCache = { | ||
| 68 | + data: {}, | ||
| 69 | + init: function (obj) { | ||
| 70 | + var content = obj.initialPreview, id = obj.id; | ||
| 71 | + if (content.length > 0 && !isArray(content)) { | ||
| 72 | + content = content.split(obj.initialPreviewDelimiter); | ||
| 73 | + } | ||
| 74 | + previewCache.data[id] = { | ||
| 75 | + content: content, | ||
| 76 | + config: obj.initialPreviewConfig, | ||
| 77 | + tags: obj.initialPreviewThumbTags, | ||
| 78 | + delimiter: obj.initialPreviewDelimiter, | ||
| 79 | + template: obj.previewGenericTemplate, | ||
| 80 | + msg: function (n) { | ||
| 81 | + return obj.getMsgSelected(n); | ||
| 82 | + }, | ||
| 83 | + initId: obj.previewInitId, | ||
| 84 | + footer: obj.getLayoutTemplate('footer').replace(/\{progress}/g, obj.renderThumbProgress()), | ||
| 85 | + isDelete: obj.initialPreviewShowDelete, | ||
| 86 | + caption: obj.initialCaption, | ||
| 87 | + actions: function (showUpload, showDelete, disabled, url, key) { | ||
| 88 | + return obj.renderFileActions(showUpload, showDelete, disabled, url, key); | ||
| 89 | + } | ||
| 90 | + }; | ||
| 91 | + }, | ||
| 92 | + fetch: function (id) { | ||
| 93 | + return previewCache.data[id].content.filter(function (n) { | ||
| 94 | + return n !== null; | ||
| 95 | + }); | ||
| 96 | + }, | ||
| 97 | + count: function (id, all) { | ||
| 98 | + return !!previewCache.data[id] && !!previewCache.data[id].content ? | ||
| 99 | + (all ? previewCache.data[id].content.length : previewCache.fetch(id).length) : 0; | ||
| 100 | + }, | ||
| 101 | + get: function (id, i, isDisabled) { | ||
| 102 | + var ind = 'init_' + i, data = previewCache.data[id], config = data.config[i], | ||
| 103 | + previewId = data.initId + '-' + ind, out, $tmp, frameClass = ' file-preview-initial'; | ||
| 104 | + /** @namespace config.frameClass */ | ||
| 105 | + /** @namespace config.frameAttr */ | ||
| 106 | + isDisabled = isDisabled === undefined ? true : isDisabled; | ||
| 107 | + if (data.content[i] === null) { | ||
| 108 | + return ''; | ||
| 109 | + } | ||
| 110 | + if (!isEmpty(config) && !isEmpty(config.frameClass)) { | ||
| 111 | + frameClass += ' ' + config.frameClass; | ||
| 112 | + } | ||
| 113 | + out = data.template | ||
| 114 | + .replace(/\{previewId}/g, previewId) | ||
| 115 | + .replace(/\{frameClass}/g, frameClass) | ||
| 116 | + .replace(/\{fileindex}/g, ind) | ||
| 117 | + .replace(/\{content}/g, data.content[i]) | ||
| 118 | + .replace(/\{footer}/g, previewCache.footer(id, i, isDisabled)); | ||
| 119 | + if (data.tags.length && data.tags[i]) { | ||
| 120 | + out = replaceTags(out, data.tags[i]); | ||
| 121 | + } | ||
| 122 | + if (!isEmpty(config) && !isEmpty(config.frameAttr)) { | ||
| 123 | + $tmp = $(document.createElement('div')).html(out); | ||
| 124 | + $tmp.find('.file-preview-initial').attr(config.frameAttr); | ||
| 125 | + out = $tmp.html(); | ||
| 126 | + $tmp.remove(); | ||
| 127 | + } | ||
| 128 | + return out; | ||
| 129 | + }, | ||
| 130 | + add: function (id, content, config, tags, append) { | ||
| 131 | + var data = $.extend(true, {}, previewCache.data[id]), index; | ||
| 132 | + if (!isArray(content)) { | ||
| 133 | + content = content.split(data.delimiter); | ||
| 134 | + } | ||
| 135 | + if (append) { | ||
| 136 | + index = data.content.push(content) - 1; | ||
| 137 | + data.config[index] = config; | ||
| 138 | + data.tags[index] = tags; | ||
| 139 | + } else { | ||
| 140 | + index = content.length; | ||
| 141 | + data.content = content; | ||
| 142 | + data.config = config; | ||
| 143 | + data.tags = tags; | ||
| 144 | + } | ||
| 145 | + previewCache.data[id] = data; | ||
| 146 | + return index; | ||
| 147 | + }, | ||
| 148 | + set: function (id, content, config, tags, append) { | ||
| 149 | + var data = $.extend(true, {}, previewCache.data[id]), i, chk; | ||
| 150 | + if (!content || !content.length) { | ||
| 151 | + return; | ||
| 152 | + } | ||
| 153 | + if (!isArray(content)) { | ||
| 154 | + content = content.split(data.delimiter); | ||
| 155 | + } | ||
| 156 | + chk = content.filter(function (n) { | ||
| 157 | + return n !== null; | ||
| 158 | + }); | ||
| 159 | + if (!chk.length) { | ||
| 160 | + return; | ||
| 161 | + } | ||
| 162 | + if (data.content === undefined) { | ||
| 163 | + data.content = []; | ||
| 164 | + } | ||
| 165 | + if (data.config === undefined) { | ||
| 166 | + data.config = []; | ||
| 167 | + } | ||
| 168 | + if (data.tags === undefined) { | ||
| 169 | + data.tags = []; | ||
| 170 | + } | ||
| 171 | + if (append) { | ||
| 172 | + for (i = 0; i < content.length; i++) { | ||
| 173 | + if (content[i]) { | ||
| 174 | + data.content.push(content[i]); | ||
| 175 | + } | ||
| 176 | + } | ||
| 177 | + for (i = 0; i < config.length; i++) { | ||
| 178 | + if (config[i]) { | ||
| 179 | + data.config.push(config[i]); | ||
| 180 | + } | ||
| 181 | + } | ||
| 182 | + for (i = 0; i < tags.length; i++) { | ||
| 183 | + if (tags[i]) { | ||
| 184 | + data.tags.push(tags[i]); | ||
| 185 | + } | ||
| 186 | + } | ||
| 187 | + } else { | ||
| 188 | + data.content = content; | ||
| 189 | + data.config = config; | ||
| 190 | + data.tags = tags; | ||
| 191 | + } | ||
| 192 | + previewCache.data[id] = data; | ||
| 193 | + }, | ||
| 194 | + unset: function (id, index) { | ||
| 195 | + var chk = previewCache.count(id); | ||
| 196 | + if (!chk) { | ||
| 197 | + return; | ||
| 198 | + } | ||
| 199 | + if (chk === 1) { | ||
| 200 | + previewCache.data[id].content = []; | ||
| 201 | + previewCache.data[id].config = []; | ||
| 202 | + return; | ||
| 203 | + } | ||
| 204 | + previewCache.data[id].content[index] = null; | ||
| 205 | + previewCache.data[id].config[index] = null; | ||
| 206 | + }, | ||
| 207 | + out: function (id) { | ||
| 208 | + var html = '', data = previewCache.data[id], caption, len = previewCache.count(id, true); | ||
| 209 | + if (len === 0) { | ||
| 210 | + return {content: '', caption: ''}; | ||
| 211 | + } | ||
| 212 | + for (var i = 0; i < len; i++) { | ||
| 213 | + html += previewCache.get(id, i); | ||
| 214 | + } | ||
| 215 | + caption = data.msg(previewCache.count(id)); | ||
| 216 | + return {content: html, caption: caption}; | ||
| 217 | + }, | ||
| 218 | + footer: function (id, i, isDisabled) { | ||
| 219 | + var data = previewCache.data[id]; | ||
| 220 | + isDisabled = isDisabled === undefined ? true : isDisabled; | ||
| 221 | + if (data.config.length === 0 || isEmpty(data.config[i])) { | ||
| 222 | + return ''; | ||
| 223 | + } | ||
| 224 | + var config = data.config[i], | ||
| 225 | + caption = isSet('caption', config) ? config.caption : '', | ||
| 226 | + width = isSet('width', config) ? config.width : 'auto', | ||
| 227 | + url = isSet('url', config) ? config.url : false, | ||
| 228 | + key = isSet('key', config) ? config.key : null, | ||
| 229 | + disabled = (url === false) && isDisabled, | ||
| 230 | + actions = data.isDelete ? data.actions(false, true, disabled, url, key) : '', | ||
| 231 | + footer = data.footer.replace(/\{actions}/g, actions); | ||
| 232 | + return footer.replace(/\{caption}/g, caption) | ||
| 233 | + .replace(/\{width}/g, width) | ||
| 234 | + .replace(/\{indicator}/g, '') | ||
| 235 | + .replace(/\{indicatorTitle}/g, ''); | ||
| 236 | + } | ||
| 237 | + }; | ||
| 238 | + getNum = function (num, def) { | ||
| 239 | + def = def || 0; | ||
| 240 | + if (typeof num === "number") { | ||
| 241 | + return num; | ||
| 242 | + } | ||
| 243 | + if (typeof num === "string") { | ||
| 244 | + num = parseFloat(num); | ||
| 245 | + } | ||
| 246 | + return isNaN(num) ? def : num; | ||
| 247 | + }; | ||
| 248 | + hasFileAPISupport = function () { | ||
| 249 | + return window.File && window.FileReader; | ||
| 250 | + }; | ||
| 251 | + hasDragDropSupport = function () { | ||
| 252 | + var div = document.createElement('div'); | ||
| 253 | + /** @namespace div.draggable */ | ||
| 254 | + /** @namespace div.ondragstart */ | ||
| 255 | + /** @namespace div.ondrop */ | ||
| 256 | + return !isIE(9) && !isEdge() && // Fix for MS Edge drag & drop support bug | ||
| 257 | + (div.draggable !== undefined || (div.ondragstart !== undefined && div.ondrop !== undefined)); | ||
| 258 | + }; | ||
| 259 | + hasFileUploadSupport = function () { | ||
| 260 | + return hasFileAPISupport() && window.FormData; | ||
| 261 | + }; | ||
| 262 | + addCss = function ($el, css) { | ||
| 263 | + $el.removeClass(css).addClass(css); | ||
| 264 | + }; | ||
| 265 | + STYLE_SETTING = 'style="width:{width};height:{height};"'; | ||
| 266 | + OBJECT_PARAMS = ' <param name="controller" value="true" />\n' + | ||
| 267 | + ' <param name="allowFullScreen" value="true" />\n' + | ||
| 268 | + ' <param name="allowScriptAccess" value="always" />\n' + | ||
| 269 | + ' <param name="autoPlay" value="false" />\n' + | ||
| 270 | + ' <param name="autoStart" value="false" />\n' + | ||
| 271 | + ' <param name="quality" value="high" />\n'; | ||
| 272 | + DEFAULT_PREVIEW = '<div class="file-preview-other">\n' + | ||
| 273 | + ' <span class="{previewFileIconClass}">{previewFileIcon}</span>\n' + | ||
| 274 | + '</div>'; | ||
| 275 | + defaultFileActionSettings = { | ||
| 276 | + removeIcon: '<i class="glyphicon glyphicon-trash text-danger"></i>', | ||
| 277 | + removeClass: 'btn btn-xs btn-default', | ||
| 278 | + removeTitle: 'Remove file', | ||
| 279 | + uploadIcon: '<i class="glyphicon glyphicon-upload text-info"></i>', | ||
| 280 | + uploadClass: 'btn btn-xs btn-default', | ||
| 281 | + uploadTitle: 'Upload file', | ||
| 282 | + indicatorNew: '<i class="glyphicon glyphicon-hand-down text-warning"></i>', | ||
| 283 | + indicatorSuccess: '<i class="glyphicon glyphicon-ok-sign text-success"></i>', | ||
| 284 | + indicatorError: '<i class="glyphicon glyphicon-exclamation-sign text-danger"></i>', | ||
| 285 | + indicatorLoading: '<i class="glyphicon glyphicon-hand-up text-muted"></i>', | ||
| 286 | + indicatorNewTitle: 'Not uploaded yet', | ||
| 287 | + indicatorSuccessTitle: 'Uploaded', | ||
| 288 | + indicatorErrorTitle: 'Upload Error', | ||
| 289 | + indicatorLoadingTitle: 'Uploading ...' | ||
| 290 | + }; | ||
| 291 | + tMain1 = '{preview}\n' + | ||
| 292 | + '<div class="kv-upload-progress hide"></div>\n' + | ||
| 293 | + '<div class="input-group {class}">\n' + | ||
| 294 | + ' {caption}\n' + | ||
| 295 | + ' <div class="input-group-btn">\n' + | ||
| 296 | + ' {remove}\n' + | ||
| 297 | + ' {cancel}\n' + | ||
| 298 | + ' {upload}\n' + | ||
| 299 | + ' {browse}\n' + | ||
| 300 | + ' </div>\n' + | ||
| 301 | + '</div>'; | ||
| 302 | + tMain2 = '{preview}\n<div class="kv-upload-progress hide"></div>\n{remove}\n{cancel}\n{upload}\n{browse}\n'; | ||
| 303 | + tPreview = '<div class="file-preview {class}">\n' + | ||
| 304 | + ' {close}' + | ||
| 305 | + ' <div class="{dropClass}">\n' + | ||
| 306 | + ' <div class="file-preview-thumbnails">\n' + | ||
| 307 | + ' </div>\n' + | ||
| 308 | + ' <div class="clearfix"></div>' + | ||
| 309 | + ' <div class="file-preview-status text-center text-success"></div>\n' + | ||
| 310 | + ' <div class="kv-fileinput-error"></div>\n' + | ||
| 311 | + ' </div>\n' + | ||
| 312 | + '</div>'; | ||
| 313 | + tClose = '<div class="close fileinput-remove">×</div>\n'; | ||
| 314 | + tIcon = '<span class="glyphicon glyphicon-file kv-caption-icon"></span>'; | ||
| 315 | + tCaption = '<div tabindex="500" class="form-control file-caption {class}">\n' + | ||
| 316 | + ' <div class="file-caption-name"></div>\n' + | ||
| 317 | + '</div>\n'; | ||
| 318 | + //noinspection HtmlUnknownAttribute | ||
| 319 | + tBtnDefault = '<button type="{type}" tabindex="500" title="{title}" class="{css}" {status}>{icon}{label}</button>'; | ||
| 320 | + tBtnLink = '<a href="{href}" tabindex="500" title="{title}" class="{css}" {status}>{icon}{label}</a>'; | ||
| 321 | + tBtnBrowse = '<div tabindex="500" class="{css}" {status}>{icon}{label}</div>'; | ||
| 322 | + tModal = '<div id="{id}" class="file-preview-detail-modal modal fade" tabindex="-1">\n' + | ||
| 323 | + ' <div class="modal-dialog modal-lg">\n' + | ||
| 324 | + ' <div class="modal-content">\n' + | ||
| 325 | + ' <div class="modal-header">\n' + | ||
| 326 | + ' <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>\n' + | ||
| 327 | + ' <h3 class="modal-title">{heading} <small>{title}</small></h3>\n' + | ||
| 328 | + ' </div>\n' + | ||
| 329 | + ' <div class="modal-body">\n' + | ||
| 330 | + ' <pre>{body}</pre>\n' + | ||
| 331 | + ' </div>\n' + | ||
| 332 | + ' </div>\n' + | ||
| 333 | + ' </div>\n' + | ||
| 334 | + '</div>'; | ||
| 335 | + tProgress = '<div class="progress">\n' + | ||
| 336 | + ' <div class="{class}" role="progressbar"' + | ||
| 337 | + ' aria-valuenow="{percent}" aria-valuemin="0" aria-valuemax="100" style="width:{percent}%;">\n' + | ||
| 338 | + ' {percent}%\n' + | ||
| 339 | + ' </div>\n' + | ||
| 340 | + '</div>'; | ||
| 341 | + tFooter = '<div class="file-thumbnail-footer">\n' + | ||
| 342 | + ' <div class="file-footer-caption" title="{caption}">{caption}</div>\n' + | ||
| 343 | + ' {progress} {actions}\n' + | ||
| 344 | + '</div>'; | ||
| 345 | + tActions = '<div class="file-actions">\n' + | ||
| 346 | + ' <div class="file-footer-buttons">\n' + | ||
| 347 | + ' {upload}{delete}{other}' + | ||
| 348 | + ' </div>\n' + | ||
| 349 | + ' <div class="file-upload-indicator" title="{indicatorTitle}">{indicator}</div>\n' + | ||
| 350 | + ' <div class="clearfix"></div>\n' + | ||
| 351 | + '</div>'; | ||
| 352 | + tActionDelete = '<button type="button" class="kv-file-remove {removeClass}" ' + | ||
| 353 | + 'title="{removeTitle}" {dataUrl}{dataKey}>{removeIcon}</button>\n'; | ||
| 354 | + tActionUpload = '<button type="button" class="kv-file-upload {uploadClass}" title="{uploadTitle}">' + | ||
| 355 | + ' {uploadIcon}\n</button>\n'; | ||
| 356 | + tZoom = '<button type="button" class="btn btn-default btn-xs btn-block" title="{zoomTitle}: {caption}" onclick="{dialog}">\n' + | ||
| 357 | + ' {zoomInd}\n' + | ||
| 358 | + '</button>\n'; | ||
| 359 | + tGeneric = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}">\n' + | ||
| 360 | + ' {content}\n' + | ||
| 361 | + ' {footer}\n' + | ||
| 362 | + '</div>\n'; | ||
| 363 | + tHtml = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}">\n' + | ||
| 364 | + ' <object class="file-object" data="{data}" type="{type}" width="{width}" height="{height}">\n' + | ||
| 365 | + ' ' + DEFAULT_PREVIEW + '\n' + | ||
| 366 | + ' </object>\n' + | ||
| 367 | + ' {footer}\n' + | ||
| 368 | + '</div>'; | ||
| 369 | + tImage = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}">\n' + | ||
| 370 | + ' <img src="{data}" class="file-preview-image" title="{caption}" alt="{caption}" ' + STYLE_SETTING + '>\n' + | ||
| 371 | + ' {footer}\n' + | ||
| 372 | + '</div>\n'; | ||
| 373 | + tText = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}">\n' + | ||
| 374 | + ' <pre class="file-preview-text" title="{caption}" ' + STYLE_SETTING + '>{data}</pre>\n' + | ||
| 375 | + ' {zoom}\n' + | ||
| 376 | + ' {footer}\n' + | ||
| 377 | + '</div>'; | ||
| 378 | + tVideo = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}"' + | ||
| 379 | + ' title="{caption}" ' + STYLE_SETTING + '>\n' + | ||
| 380 | + ' <video width="{width}" height="{height}" controls>\n' + | ||
| 381 | + ' <source src="{data}" type="{type}">\n' + | ||
| 382 | + ' ' + DEFAULT_PREVIEW + '\n' + | ||
| 383 | + ' </video>\n' + | ||
| 384 | + ' {footer}\n' + | ||
| 385 | + '</div>\n'; | ||
| 386 | + tAudio = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}"' + | ||
| 387 | + ' title="{caption}" ' + STYLE_SETTING + '>\n' + | ||
| 388 | + ' <audio controls>\n' + | ||
| 389 | + ' <source src="' + '{data}' + '" type="{type}">\n' + | ||
| 390 | + ' ' + DEFAULT_PREVIEW + '\n' + | ||
| 391 | + ' </audio>\n' + | ||
| 392 | + ' {footer}\n' + | ||
| 393 | + '</div>'; | ||
| 394 | + tFlash = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}"' + | ||
| 395 | + ' title="{caption}" ' + STYLE_SETTING + '>\n' + | ||
| 396 | + ' <object class="file-object" type="application/x-shockwave-flash" width="{width}" height="{height}" data="{data}">\n' + | ||
| 397 | + OBJECT_PARAMS + ' ' + DEFAULT_PREVIEW + '\n' + | ||
| 398 | + ' </object>\n' + | ||
| 399 | + ' {footer}\n' + | ||
| 400 | + '</div>\n'; | ||
| 401 | + tObject = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}"' + | ||
| 402 | + ' title="{caption}" ' + STYLE_SETTING + '>\n' + | ||
| 403 | + ' <object class="file-object" data="{data}" type="{type}" width="{width}" height="{height}">\n' + | ||
| 404 | + ' <param name="movie" value="{caption}" />\n' + | ||
| 405 | + OBJECT_PARAMS + ' ' + DEFAULT_PREVIEW + '\n' + | ||
| 406 | + ' </object>\n' + | ||
| 407 | + ' {footer}\n' + | ||
| 408 | + '</div>'; | ||
| 409 | + tOther = '<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}"' + | ||
| 410 | + ' title="{caption}" ' + STYLE_SETTING + '>\n' + | ||
| 411 | + ' <div class="file-preview-other-frame">\n' + | ||
| 412 | + ' ' + DEFAULT_PREVIEW + '\n' + | ||
| 413 | + ' </div>\n' + | ||
| 414 | + ' <div class="file-preview-other-footer">{footer}</div>\n' + | ||
| 415 | + '</div>'; | ||
| 416 | + defaultLayoutTemplates = { | ||
| 417 | + main1: tMain1, | ||
| 418 | + main2: tMain2, | ||
| 419 | + preview: tPreview, | ||
| 420 | + close: tClose, | ||
| 421 | + zoom: tZoom, | ||
| 422 | + icon: tIcon, | ||
| 423 | + caption: tCaption, | ||
| 424 | + modal: tModal, | ||
| 425 | + progress: tProgress, | ||
| 426 | + footer: tFooter, | ||
| 427 | + actions: tActions, | ||
| 428 | + actionDelete: tActionDelete, | ||
| 429 | + actionUpload: tActionUpload, | ||
| 430 | + btnDefault: tBtnDefault, | ||
| 431 | + btnLink: tBtnLink, | ||
| 432 | + btnBrowse: tBtnBrowse | ||
| 433 | + }; | ||
| 434 | + defaultPreviewTemplates = { | ||
| 435 | + generic: tGeneric, | ||
| 436 | + html: tHtml, | ||
| 437 | + image: tImage, | ||
| 438 | + text: tText, | ||
| 439 | + video: tVideo, | ||
| 440 | + audio: tAudio, | ||
| 441 | + flash: tFlash, | ||
| 442 | + object: tObject, | ||
| 443 | + other: tOther | ||
| 444 | + }; | ||
| 445 | + defaultPreviewTypes = ['image', 'html', 'text', 'video', 'audio', 'flash', 'object']; | ||
| 446 | + defaultPreviewSettings = { | ||
| 447 | + image: {width: "auto", height: "160px"}, | ||
| 448 | + html: {width: "213px", height: "160px"}, | ||
| 449 | + text: {width: "160px", height: "136px"}, | ||
| 450 | + video: {width: "213px", height: "160px"}, | ||
| 451 | + audio: {width: "213px", height: "80px"}, | ||
| 452 | + flash: {width: "213px", height: "160px"}, | ||
| 453 | + object: {width: "160px", height: "160px"}, | ||
| 454 | + other: {width: "160px", height: "160px"} | ||
| 455 | + }; | ||
| 456 | + defaultFileTypeSettings = { | ||
| 457 | + image: function (vType, vName) { | ||
| 458 | + return (vType !== undefined) ? vType.match('image.*') : vName.match(/\.(gif|png|jpe?g)$/i); | ||
| 459 | + }, | ||
| 460 | + html: function (vType, vName) { | ||
| 461 | + return (vType !== undefined) ? vType === 'text/html' : vName.match(/\.(htm|html)$/i); | ||
| 462 | + }, | ||
| 463 | + text: function (vType, vName) { | ||
| 464 | + return (vType !== undefined && vType.match('text.*')) || vName.match( | ||
| 465 | + /\.(txt|md|csv|nfo|ini|json|php|js|css)$/i); | ||
| 466 | + }, | ||
| 467 | + video: function (vType, vName) { | ||
| 468 | + return (vType !== undefined && vType.match(/\.video\/(ogg|mp4|webm|3gp)$/i)) || vName.match( | ||
| 469 | + /\.(og?|mp4|webm|3gp)$/i); | ||
| 470 | + }, | ||
| 471 | + audio: function (vType, vName) { | ||
| 472 | + return (vType !== undefined && vType.match(/\.audio\/(ogg|mp3|wav)$/i)) || vName.match(/\.(ogg|mp3|wav)$/i); | ||
| 473 | + }, | ||
| 474 | + flash: function (vType, vName) { | ||
| 475 | + return (vType !== undefined && vType === 'application/x-shockwave-flash') || vName.match(/\.(swf)$/i); | ||
| 476 | + }, | ||
| 477 | + object: function () { | ||
| 478 | + return true; | ||
| 479 | + }, | ||
| 480 | + other: function () { | ||
| 481 | + return true; | ||
| 482 | + } | ||
| 483 | + }; | ||
| 484 | + isEmpty = function (value, trim) { | ||
| 485 | + return value === undefined || value === null || value.length === 0 || (trim && $.trim(value) === ''); | ||
| 486 | + }; | ||
| 487 | + isArray = function (a) { | ||
| 488 | + return Array.isArray(a) || Object.prototype.toString.call(a) === '[object Array]'; | ||
| 489 | + }; | ||
| 490 | + isSet = function (needle, haystack) { | ||
| 491 | + return (typeof haystack === 'object' && needle in haystack); | ||
| 492 | + }; | ||
| 493 | + getElement = function (options, param, value) { | ||
| 494 | + return (isEmpty(options) || isEmpty(options[param])) ? value : $(options[param]); | ||
| 495 | + }; | ||
| 496 | + uniqId = function () { | ||
| 497 | + return Math.round(new Date().getTime() + (Math.random() * 100)); | ||
| 498 | + }; | ||
| 499 | + htmlEncode = function (str) { | ||
| 500 | + return str.replace(/&/g, '&') | ||
| 501 | + .replace(/</g, '<') | ||
| 502 | + .replace(/>/g, '>') | ||
| 503 | + .replace(/"/g, '"') | ||
| 504 | + .replace(/'/g, '''); | ||
| 505 | + }; | ||
| 506 | + replaceTags = function (str, tags) { | ||
| 507 | + var out = str; | ||
| 508 | + if (!tags) { | ||
| 509 | + return out; | ||
| 510 | + } | ||
| 511 | + $.each(tags, function (key, value) { | ||
| 512 | + if (typeof value === "function") { | ||
| 513 | + value = value(); | ||
| 514 | + } | ||
| 515 | + out = out.split(key).join(value); | ||
| 516 | + }); | ||
| 517 | + return out; | ||
| 518 | + }; | ||
| 519 | + //noinspection JSUnresolvedVariable | ||
| 520 | + objUrl = window.URL || window.webkitURL; | ||
| 521 | + FileInput = function (element, options) { | ||
| 522 | + var self = this; | ||
| 523 | + self.$element = $(element); | ||
| 524 | + if (!self.validate()) { | ||
| 525 | + return; | ||
| 526 | + } | ||
| 527 | + self.isPreviewable = hasFileAPISupport(); | ||
| 528 | + self.isIE9 = isIE(9); | ||
| 529 | + self.isIE10 = isIE(10); | ||
| 530 | + if (self.isPreviewable || self.isIE9) { | ||
| 531 | + self.init(options); | ||
| 532 | + self.listen(); | ||
| 533 | + } else { | ||
| 534 | + self.$element.removeClass('file-loading'); | ||
| 535 | + } | ||
| 536 | + }; | ||
| 537 | + | ||
| 538 | + FileInput.prototype = { | ||
| 539 | + constructor: FileInput, | ||
| 540 | + validate: function () { | ||
| 541 | + var self = this, $exception; | ||
| 542 | + if (self.$element.attr('type') === 'file') { | ||
| 543 | + return true; | ||
| 544 | + } | ||
| 545 | + $exception = '<div class="help-block alert alert-warning">' + | ||
| 546 | + '<h4>Invalid Input Type</h4>' + | ||
| 547 | + 'You must set an input <code>type = file</code> for <b>bootstrap-fileinput</b> plugin to initialize.' + | ||
| 548 | + '</div>'; | ||
| 549 | + self.$element.after($exception); | ||
| 550 | + return false; | ||
| 551 | + }, | ||
| 552 | + init: function (options) { | ||
| 553 | + var self = this, $el = self.$element, t; | ||
| 554 | + $.each(options, function (key, value) { | ||
| 555 | + switch (key) { | ||
| 556 | + case 'minFileCount': | ||
| 557 | + case 'maxFileCount': | ||
| 558 | + case 'maxFileSize': | ||
| 559 | + self[key] = getNum(value); | ||
| 560 | + break; | ||
| 561 | + default: | ||
| 562 | + self[key] = value; | ||
| 563 | + break; | ||
| 564 | + } | ||
| 565 | + }); | ||
| 566 | + self.fileInputCleared = false; | ||
| 567 | + self.fileBatchCompleted = true; | ||
| 568 | + if (!self.isPreviewable) { | ||
| 569 | + self.showPreview = false; | ||
| 570 | + } | ||
| 571 | + self.uploadFileAttr = !isEmpty($el.attr('name')) ? $el.attr('name') : 'file_data'; | ||
| 572 | + self.reader = null; | ||
| 573 | + self.formdata = {}; | ||
| 574 | + self.clearStack(); | ||
| 575 | + self.uploadCount = 0; | ||
| 576 | + self.uploadStatus = {}; | ||
| 577 | + self.uploadLog = []; | ||
| 578 | + self.uploadAsyncCount = 0; | ||
| 579 | + self.loadedImages = []; | ||
| 580 | + self.totalImagesCount = 0; | ||
| 581 | + self.ajaxRequests = []; | ||
| 582 | + self.isError = false; | ||
| 583 | + self.ajaxAborted = false; | ||
| 584 | + self.cancelling = false; | ||
| 585 | + t = self.getLayoutTemplate('progress'); | ||
| 586 | + self.progressTemplate = t.replace('{class}', self.progressClass); | ||
| 587 | + self.progressCompleteTemplate = t.replace('{class}', self.progressCompleteClass); | ||
| 588 | + self.dropZoneEnabled = hasDragDropSupport() && self.dropZoneEnabled; | ||
| 589 | + self.isDisabled = self.$element.attr('disabled') || self.$element.attr('readonly'); | ||
| 590 | + self.isUploadable = hasFileUploadSupport() && !isEmpty(self.uploadUrl); | ||
| 591 | + self.slug = typeof options.slugCallback === "function" ? options.slugCallback : self.slugDefault; | ||
| 592 | + self.mainTemplate = self.showCaption ? self.getLayoutTemplate('main1') : self.getLayoutTemplate('main2'); | ||
| 593 | + self.captionTemplate = self.getLayoutTemplate('caption'); | ||
| 594 | + self.previewGenericTemplate = self.getPreviewTemplate('generic'); | ||
| 595 | + if (self.resizeImage && (self.maxImageWidth || self.maxImageHeight)) { | ||
| 596 | + self.imageCanvas = document.createElement('canvas'); | ||
| 597 | + self.imageCanvasContext = self.imageCanvas.getContext('2d'); | ||
| 598 | + } | ||
| 599 | + if (isEmpty(self.$element.attr('id'))) { | ||
| 600 | + self.$element.attr('id', uniqId()); | ||
| 601 | + } | ||
| 602 | + if (self.$container === undefined) { | ||
| 603 | + self.$container = self.createContainer(); | ||
| 604 | + } else { | ||
| 605 | + self.refreshContainer(); | ||
| 606 | + } | ||
| 607 | + self.$progress = self.$container.find('.kv-upload-progress'); | ||
| 608 | + self.$btnUpload = self.$container.find('.fileinput-upload'); | ||
| 609 | + self.$captionContainer = getElement(options, 'elCaptionContainer', self.$container.find('.file-caption')); | ||
| 610 | + self.$caption = getElement(options, 'elCaptionText', self.$container.find('.file-caption-name')); | ||
| 611 | + self.$previewContainer = getElement(options, 'elPreviewContainer', self.$container.find('.file-preview')); | ||
| 612 | + self.$preview = getElement(options, 'elPreviewImage', self.$container.find('.file-preview-thumbnails')); | ||
| 613 | + self.$previewStatus = getElement(options, 'elPreviewStatus', self.$container.find('.file-preview-status')); | ||
| 614 | + self.$errorContainer = getElement(options, 'elErrorContainer', | ||
| 615 | + self.$previewContainer.find('.kv-fileinput-error')); | ||
| 616 | + if (!isEmpty(self.msgErrorClass)) { | ||
| 617 | + addCss(self.$errorContainer, self.msgErrorClass); | ||
| 618 | + } | ||
| 619 | + self.$errorContainer.hide(); | ||
| 620 | + self.fileActionSettings = $.extend(defaultFileActionSettings, options.fileActionSettings); | ||
| 621 | + self.previewInitId = "preview-" + uniqId(); | ||
| 622 | + self.id = self.$element.attr('id'); | ||
| 623 | + previewCache.init(self); | ||
| 624 | + self.initPreview(true); | ||
| 625 | + self.initPreviewDeletes(); | ||
| 626 | + self.options = options; | ||
| 627 | + self.setFileDropZoneTitle(); | ||
| 628 | + self.$element.removeClass('file-loading'); | ||
| 629 | + if (self.$element.attr('disabled')) { | ||
| 630 | + self.disable(); | ||
| 631 | + } | ||
| 632 | + }, | ||
| 633 | + parseError: function (jqXHR, errorThrown, fileName) { | ||
| 634 | + var self = this, errMsg = $.trim(errorThrown + ''), | ||
| 635 | + dot = errMsg.slice(-1) === '.' ? '' : '.', | ||
| 636 | + text = jqXHR.responseJSON !== undefined && jqXHR.responseJSON.error !== undefined ? | ||
| 637 | + jqXHR.responseJSON.error : jqXHR.responseText; | ||
| 638 | + if (self.cancelling && self.msgUploadAborted) { | ||
| 639 | + errMsg = self.msgUploadAborted; | ||
| 640 | + } | ||
| 641 | + if (self.showAjaxErrorDetails && text) { | ||
| 642 | + text = $.trim(text.replace(/\n\s*\n/g, '\n')); | ||
| 643 | + text = text.length > 0 ? '<pre>' + text + '</pre>' : ''; | ||
| 644 | + errMsg += dot + text; | ||
| 645 | + } else { | ||
| 646 | + errMsg += dot; | ||
| 647 | + } | ||
| 648 | + self.cancelling = false; | ||
| 649 | + return fileName ? '<b>' + fileName + ': </b>' + errMsg : errMsg; | ||
| 650 | + }, | ||
| 651 | + raise: function (event, params) { | ||
| 652 | + var self = this, e = $.Event(event); | ||
| 653 | + if (params !== undefined) { | ||
| 654 | + self.$element.trigger(e, params); | ||
| 655 | + } else { | ||
| 656 | + self.$element.trigger(e); | ||
| 657 | + } | ||
| 658 | + if (e.isDefaultPrevented()) { | ||
| 659 | + return false; | ||
| 660 | + } | ||
| 661 | + if (!e.result) { | ||
| 662 | + return e.result; | ||
| 663 | + } | ||
| 664 | + switch (event) { | ||
| 665 | + // ignore these events | ||
| 666 | + case 'filebatchuploadcomplete': | ||
| 667 | + case 'filebatchuploadsuccess': | ||
| 668 | + case 'fileuploaded': | ||
| 669 | + case 'fileclear': | ||
| 670 | + case 'filecleared': | ||
| 671 | + case 'filereset': | ||
| 672 | + case 'fileerror': | ||
| 673 | + case 'filefoldererror': | ||
| 674 | + case 'fileuploaderror': | ||
| 675 | + case 'filebatchuploaderror': | ||
| 676 | + case 'filedeleteerror': | ||
| 677 | + case 'filecustomerror': | ||
| 678 | + case 'filesuccessremove': | ||
| 679 | + break; | ||
| 680 | + // receive data response via `filecustomerror` event` | ||
| 681 | + default: | ||
| 682 | + self.ajaxAborted = e.result; | ||
| 683 | + break; | ||
| 684 | + } | ||
| 685 | + return true; | ||
| 686 | + }, | ||
| 687 | + getLayoutTemplate: function (t) { | ||
| 688 | + var self = this, | ||
| 689 | + template = isSet(t, self.layoutTemplates) ? self.layoutTemplates[t] : defaultLayoutTemplates[t]; | ||
| 690 | + if (isEmpty(self.customLayoutTags)) { | ||
| 691 | + return template; | ||
| 692 | + } | ||
| 693 | + return replaceTags(template, self.customLayoutTags); | ||
| 694 | + }, | ||
| 695 | + getPreviewTemplate: function (t) { | ||
| 696 | + var self = this, | ||
| 697 | + template = isSet(t, self.previewTemplates) ? self.previewTemplates[t] : defaultPreviewTemplates[t]; | ||
| 698 | + if (isEmpty(self.customPreviewTags)) { | ||
| 699 | + return template; | ||
| 700 | + } | ||
| 701 | + return replaceTags(template, self.customPreviewTags); | ||
| 702 | + }, | ||
| 703 | + parseFilePreviewIcon: function (content, fname) { | ||
| 704 | + var self = this, ext, icn = self.previewFileIcon; | ||
| 705 | + if (fname && fname.indexOf('.') > -1) { | ||
| 706 | + ext = fname.split('.').pop(); | ||
| 707 | + if (self.previewFileIconSettings && self.previewFileIconSettings[ext]) { | ||
| 708 | + icn = self.previewFileIconSettings[ext]; | ||
| 709 | + } | ||
| 710 | + if (self.previewFileExtSettings) { | ||
| 711 | + $.each(self.previewFileExtSettings, function (key, func) { | ||
| 712 | + if (self.previewFileIconSettings[key] && func(ext)) { | ||
| 713 | + icn = self.previewFileIconSettings[key]; | ||
| 714 | + } | ||
| 715 | + }); | ||
| 716 | + } | ||
| 717 | + } | ||
| 718 | + if (content.indexOf('{previewFileIcon}') > -1) { | ||
| 719 | + return content.replace(/\{previewFileIconClass}/g, self.previewFileIconClass).replace( | ||
| 720 | + /\{previewFileIcon}/g, icn); | ||
| 721 | + } | ||
| 722 | + return content; | ||
| 723 | + }, | ||
| 724 | + getOutData: function (jqXHR, responseData, filesData) { | ||
| 725 | + var self = this; | ||
| 726 | + jqXHR = jqXHR || {}; | ||
| 727 | + responseData = responseData || {}; | ||
| 728 | + filesData = filesData || self.filestack.slice(0) || {}; | ||
| 729 | + return { | ||
| 730 | + form: self.formdata, | ||
| 731 | + files: filesData, | ||
| 732 | + filenames: self.filenames, | ||
| 733 | + extra: self.getExtraData(), | ||
| 734 | + response: responseData, | ||
| 735 | + reader: self.reader, | ||
| 736 | + jqXHR: jqXHR | ||
| 737 | + }; | ||
| 738 | + }, | ||
| 739 | + listen: function () { | ||
| 740 | + var self = this, $el = self.$element, $cap = self.$captionContainer, $btnFile = self.$btnFile, | ||
| 741 | + $form = $el.closest('form'), $cont = self.$container; | ||
| 742 | + handler($el, 'change', $.proxy(self.change, self)); | ||
| 743 | + handler($btnFile, 'click', function () { | ||
| 744 | + self.raise('filebrowse'); | ||
| 745 | + if (self.isError && !self.isUploadable) { | ||
| 746 | + self.clear(); | ||
| 747 | + } | ||
| 748 | + $cap.focus(); | ||
| 749 | + }); | ||
| 750 | + handler($form, 'reset', $.proxy(self.reset, self)); | ||
| 751 | + handler($cont.find('.fileinput-remove:not([disabled])'), 'click', $.proxy(self.clear, self)); | ||
| 752 | + handler($cont.find('.fileinput-cancel'), 'click', $.proxy(self.cancel, self)); | ||
| 753 | + if (self.isUploadable && self.dropZoneEnabled && self.showPreview) { | ||
| 754 | + self.initDragDrop(); | ||
| 755 | + } | ||
| 756 | + if (!self.isUploadable) { | ||
| 757 | + handler($form, 'submit', $.proxy(self.submitForm, self)); | ||
| 758 | + } | ||
| 759 | + handler(self.$container.find('.fileinput-upload'), 'click', function (e) { | ||
| 760 | + var $btn = $(this), $form, isEnabled = !$btn.hasClass('disabled') && isEmpty($btn.attr('disabled')); | ||
| 761 | + if (!self.isUploadable) { | ||
| 762 | + if (isEnabled && $btn.attr('type') !== 'submit') { | ||
| 763 | + $form = $btn.closest('form'); | ||
| 764 | + // downgrade to normal form submit if possible | ||
| 765 | + if ($form.length) { | ||
| 766 | + $form.trigger('submit'); | ||
| 767 | + } | ||
| 768 | + e.preventDefault(); | ||
| 769 | + } | ||
| 770 | + return; | ||
| 771 | + } | ||
| 772 | + e.preventDefault(); | ||
| 773 | + if (isEnabled) { | ||
| 774 | + self.upload(); | ||
| 775 | + } | ||
| 776 | + }); | ||
| 777 | + }, | ||
| 778 | + submitForm: function () { | ||
| 779 | + var self = this, $el = self.$element, files = $el.get(0).files; | ||
| 780 | + if (files && self.minFileCount > 0 && self.getFileCount(files.length) < self.minFileCount) { | ||
| 781 | + self.noFilesError({}); | ||
| 782 | + return false; | ||
| 783 | + } | ||
| 784 | + return !self.abort({}); | ||
| 785 | + }, | ||
| 786 | + abort: function (params) { | ||
| 787 | + var self = this, data; | ||
| 788 | + if (self.ajaxAborted && typeof self.ajaxAborted === "object" && self.ajaxAborted.message !== undefined) { | ||
| 789 | + data = $.extend(self.getOutData(), params); | ||
| 790 | + data.abortData = self.ajaxAborted.data || {}; | ||
| 791 | + data.abortMessage = self.ajaxAborted.message; | ||
| 792 | + self.cancel(); | ||
| 793 | + self.setProgress(100); | ||
| 794 | + self.showUploadError(self.ajaxAborted.message, data, 'filecustomerror'); | ||
| 795 | + return true; | ||
| 796 | + } | ||
| 797 | + return false; | ||
| 798 | + }, | ||
| 799 | + noFilesError: function (params) { | ||
| 800 | + var self = this, label = self.minFileCount > 1 ? self.filePlural : self.fileSingle, | ||
| 801 | + msg = self.msgFilesTooLess.replace('{n}', self.minFileCount).replace('{files}', label), | ||
| 802 | + $error = self.$errorContainer; | ||
| 803 | + self.addError(msg); | ||
| 804 | + self.isError = true; | ||
| 805 | + self.updateFileDetails(0); | ||
| 806 | + $error.fadeIn(800); | ||
| 807 | + self.raise('fileerror', [params]); | ||
| 808 | + self.clearFileInput(); | ||
| 809 | + addCss(self.$container, 'has-error'); | ||
| 810 | + }, | ||
| 811 | + setProgress: function (p, $el) { | ||
| 812 | + var self = this, pct = Math.min(p, 100), | ||
| 813 | + template = pct < 100 ? self.progressTemplate : self.progressCompleteTemplate; | ||
| 814 | + $el = $el || self.$progress; | ||
| 815 | + if (!isEmpty(template)) { | ||
| 816 | + $el.html(template.replace(/\{percent}/g, pct)); | ||
| 817 | + } | ||
| 818 | + }, | ||
| 819 | + lock: function () { | ||
| 820 | + var self = this; | ||
| 821 | + self.resetErrors(); | ||
| 822 | + self.disable(); | ||
| 823 | + if (self.showRemove) { | ||
| 824 | + addCss(self.$container.find('.fileinput-remove'), 'hide'); | ||
| 825 | + } | ||
| 826 | + if (self.showCancel) { | ||
| 827 | + self.$container.find('.fileinput-cancel').removeClass('hide'); | ||
| 828 | + } | ||
| 829 | + self.raise('filelock', [self.filestack, self.getExtraData()]); | ||
| 830 | + }, | ||
| 831 | + unlock: function (reset) { | ||
| 832 | + var self = this; | ||
| 833 | + if (reset === undefined) { | ||
| 834 | + reset = true; | ||
| 835 | + } | ||
| 836 | + self.enable(); | ||
| 837 | + if (self.showCancel) { | ||
| 838 | + addCss(self.$container.find('.fileinput-cancel'), 'hide'); | ||
| 839 | + } | ||
| 840 | + if (self.showRemove) { | ||
| 841 | + self.$container.find('.fileinput-remove').removeClass('hide'); | ||
| 842 | + } | ||
| 843 | + if (reset) { | ||
| 844 | + self.resetFileStack(); | ||
| 845 | + } | ||
| 846 | + self.raise('fileunlock', [self.filestack, self.getExtraData()]); | ||
| 847 | + }, | ||
| 848 | + resetFileStack: function () { | ||
| 849 | + var self = this, i = 0, newstack = [], newnames = []; | ||
| 850 | + self.getThumbs().each(function () { | ||
| 851 | + var $thumb = $(this), ind = $thumb.attr('data-fileindex'), | ||
| 852 | + file = self.filestack[ind]; | ||
| 853 | + if (ind === -1) { | ||
| 854 | + return; | ||
| 855 | + } | ||
| 856 | + if (file !== undefined) { | ||
| 857 | + newstack[i] = file; | ||
| 858 | + newnames[i] = self.getFileName(file); | ||
| 859 | + $thumb.attr({ | ||
| 860 | + 'id': self.previewInitId + '-' + i, | ||
| 861 | + 'data-fileindex': i | ||
| 862 | + }); | ||
| 863 | + i++; | ||
| 864 | + } else { | ||
| 865 | + $thumb.attr({ | ||
| 866 | + 'id': 'uploaded-' + uniqId(), | ||
| 867 | + 'data-fileindex': '-1' | ||
| 868 | + }); | ||
| 869 | + } | ||
| 870 | + }); | ||
| 871 | + self.filestack = newstack; | ||
| 872 | + self.filenames = newnames; | ||
| 873 | + }, | ||
| 874 | + destroy: function () { | ||
| 875 | + var self = this, $cont = self.$container; | ||
| 876 | + $cont.find('.file-drop-zone').off(); | ||
| 877 | + self.$element.insertBefore($cont).off('.fileinput').removeData(); | ||
| 878 | + $cont.off().remove(); | ||
| 879 | + }, | ||
| 880 | + refresh: function (options) { | ||
| 881 | + var self = this, $el = self.$element; | ||
| 882 | + options = options ? $.extend(self.options, options) : self.options; | ||
| 883 | + self.destroy(); | ||
| 884 | + $el.fileinput(options); | ||
| 885 | + if ($el.val()) { | ||
| 886 | + $el.trigger('change.fileinput'); | ||
| 887 | + } | ||
| 888 | + }, | ||
| 889 | + initDragDrop: function () { | ||
| 890 | + var self = this, $zone = self.$container.find('.file-drop-zone'), | ||
| 891 | + allEvents = 'dragenter.fileinput dragover.fileinput drop.fileinput'; | ||
| 892 | + handler($zone, 'dragenter.fileinput dragover.fileinput', function (e) { | ||
| 893 | + var hasFiles = $.inArray('Files', e.originalEvent.dataTransfer.types) > -1; | ||
| 894 | + e.stopPropagation(); | ||
| 895 | + e.preventDefault(); | ||
| 896 | + if (self.isDisabled || !hasFiles) { | ||
| 897 | + e.originalEvent.dataTransfer.effectAllowed = 'none'; | ||
| 898 | + e.originalEvent.dataTransfer.dropEffect = 'none'; | ||
| 899 | + return; | ||
| 900 | + } | ||
| 901 | + addCss($(this), 'file-highlighted'); | ||
| 902 | + }, true); | ||
| 903 | + handler($zone, 'dragleave', function (e) { | ||
| 904 | + e.stopPropagation(); | ||
| 905 | + e.preventDefault(); | ||
| 906 | + if (self.isDisabled) { | ||
| 907 | + return; | ||
| 908 | + } | ||
| 909 | + $(this).removeClass('file-highlighted'); | ||
| 910 | + }); | ||
| 911 | + handler($zone, 'drop', function (e) { | ||
| 912 | + e.preventDefault(); | ||
| 913 | + /** @namespace e.originalEvent.dataTransfer */ | ||
| 914 | + if (self.isDisabled || isEmpty(e.originalEvent.dataTransfer.files)) { | ||
| 915 | + return; | ||
| 916 | + } | ||
| 917 | + self.change(e, 'dragdrop'); | ||
| 918 | + $(this).removeClass('file-highlighted'); | ||
| 919 | + }); | ||
| 920 | + handler($(document), allEvents, function (e) { | ||
| 921 | + e.stopPropagation(); | ||
| 922 | + e.preventDefault(); | ||
| 923 | + }, true); | ||
| 924 | + }, | ||
| 925 | + setFileDropZoneTitle: function () { | ||
| 926 | + var self = this, $zone = self.$container.find('.file-drop-zone'); | ||
| 927 | + $zone.find('.' + self.dropZoneTitleClass).remove(); | ||
| 928 | + if (!self.isUploadable || !self.showPreview || $zone.length === 0 || self.getFileStack().length > 0 || !self.dropZoneEnabled) { | ||
| 929 | + return; | ||
| 930 | + } | ||
| 931 | + if ($zone.find('.file-preview-frame').length === 0 && isEmpty(self.defaultPreviewContent)) { | ||
| 932 | + $zone.prepend('<div class="' + self.dropZoneTitleClass + '">' + self.dropZoneTitle + '</div>'); | ||
| 933 | + } | ||
| 934 | + self.$container.removeClass('file-input-new'); | ||
| 935 | + addCss(self.$container, 'file-input-ajax-new'); | ||
| 936 | + }, | ||
| 937 | + errorsExist: function () { | ||
| 938 | + var self = this, $err; | ||
| 939 | + if (self.$errorContainer.find('li').length) { | ||
| 940 | + return true; | ||
| 941 | + } | ||
| 942 | + $err = $(document.createElement('div')).html(self.$errorContainer.html()); | ||
| 943 | + $err.find('span.kv-error-close').remove(); | ||
| 944 | + $err.find('ul').remove(); | ||
| 945 | + return $.trim($err.text()).length ? true : false; | ||
| 946 | + }, | ||
| 947 | + getMsgSelected: function (n) { | ||
| 948 | + var self = this, strFiles = n === 1 ? self.fileSingle : self.filePlural; | ||
| 949 | + return self.msgSelected.replace('{n}', n).replace('{files}', strFiles); | ||
| 950 | + }, | ||
| 951 | + renderThumbProgress: function () { | ||
| 952 | + return '<div class="file-thumb-progress hide">' + this.progressTemplate.replace(/\{percent}/g, | ||
| 953 | + '0') + '</div>'; | ||
| 954 | + }, | ||
| 955 | + renderFileFooter: function (caption, width) { | ||
| 956 | + var self = this, config = self.fileActionSettings, footer, out, template = self.getLayoutTemplate('footer'); | ||
| 957 | + if (self.isUploadable) { | ||
| 958 | + footer = template.replace(/\{actions}/g, self.renderFileActions(true, true, false, false, false)); | ||
| 959 | + out = footer.replace(/\{caption}/g, caption) | ||
| 960 | + .replace(/\{width}/g, width) | ||
| 961 | + .replace(/\{progress}/g, self.renderThumbProgress()) | ||
| 962 | + .replace(/\{indicator}/g, config.indicatorNew) | ||
| 963 | + .replace(/\{indicatorTitle}/g, config.indicatorNewTitle); | ||
| 964 | + } else { | ||
| 965 | + out = template.replace(/\{actions}/g, '') | ||
| 966 | + .replace(/\{caption}/g, caption) | ||
| 967 | + .replace(/\{progress}/g, '') | ||
| 968 | + .replace(/\{width}/g, width) | ||
| 969 | + .replace(/\{indicator}/g, '') | ||
| 970 | + .replace(/\{indicatorTitle}/g, ''); | ||
| 971 | + } | ||
| 972 | + out = replaceTags(out, self.previewThumbTags); | ||
| 973 | + return out; | ||
| 974 | + }, | ||
| 975 | + renderFileActions: function (showUpload, showDelete, disabled, url, key) { | ||
| 976 | + if (!showUpload && !showDelete) { | ||
| 977 | + return ''; | ||
| 978 | + } | ||
| 979 | + var self = this, | ||
| 980 | + vUrl = url === false ? '' : ' data-url="' + url + '"', | ||
| 981 | + vKey = key === false ? '' : ' data-key="' + key + '"', | ||
| 982 | + btnDelete = self.getLayoutTemplate('actionDelete'), | ||
| 983 | + btnUpload = '', | ||
| 984 | + template = self.getLayoutTemplate('actions'), | ||
| 985 | + otherButtons = self.otherActionButtons.replace(/\{dataKey}/g, vKey), | ||
| 986 | + config = self.fileActionSettings, | ||
| 987 | + removeClass = disabled ? config.removeClass + ' disabled' : config.removeClass; | ||
| 988 | + btnDelete = btnDelete | ||
| 989 | + .replace(/\{removeClass}/g, removeClass) | ||
| 990 | + .replace(/\{removeIcon}/g, config.removeIcon) | ||
| 991 | + .replace(/\{removeTitle}/g, config.removeTitle) | ||
| 992 | + .replace(/\{dataUrl}/g, vUrl) | ||
| 993 | + .replace(/\{dataKey}/g, vKey); | ||
| 994 | + if (showUpload) { | ||
| 995 | + btnUpload = self.getLayoutTemplate('actionUpload') | ||
| 996 | + .replace(/\{uploadClass}/g, config.uploadClass) | ||
| 997 | + .replace(/\{uploadIcon}/g, config.uploadIcon) | ||
| 998 | + .replace(/\{uploadTitle}/g, config.uploadTitle); | ||
| 999 | + } | ||
| 1000 | + return template | ||
| 1001 | + .replace(/\{delete}/g, btnDelete) | ||
| 1002 | + .replace(/\{upload}/g, btnUpload) | ||
| 1003 | + .replace(/\{other}/g, otherButtons); | ||
| 1004 | + }, | ||
| 1005 | + setThumbStatus: function ($thumb, status) { | ||
| 1006 | + var self = this; | ||
| 1007 | + if (!self.showPreview) { | ||
| 1008 | + return; | ||
| 1009 | + } | ||
| 1010 | + var icon = 'indicator' + status, msg = icon + 'Title', | ||
| 1011 | + css = 'file-preview-' + status.toLowerCase(), | ||
| 1012 | + $indicator = $thumb.find('.file-upload-indicator'), | ||
| 1013 | + config = self.fileActionSettings; | ||
| 1014 | + $thumb.removeClass('file-preview-success file-preview-error file-preview-loading'); | ||
| 1015 | + if (status === 'Error') { | ||
| 1016 | + $thumb.find('.kv-file-upload').attr('disabled', true); | ||
| 1017 | + } | ||
| 1018 | + $indicator.html(config[icon]); | ||
| 1019 | + $indicator.attr('title', config[msg]); | ||
| 1020 | + $thumb.addClass(css); | ||
| 1021 | + }, | ||
| 1022 | + clearPreview: function () { | ||
| 1023 | + var self = this, $thumbs = !self.showUploadedThumbs ? self.$preview.find('.file-preview-frame') : | ||
| 1024 | + self.$preview.find('.file-preview-frame:not(.file-preview-success)'); | ||
| 1025 | + $thumbs.remove(); | ||
| 1026 | + if (!self.$preview.find('.file-preview-frame').length || !self.showPreview) { | ||
| 1027 | + self.resetUpload(); | ||
| 1028 | + } | ||
| 1029 | + self.validateDefaultPreview(); | ||
| 1030 | + }, | ||
| 1031 | + initPreview: function (isInit) { | ||
| 1032 | + var self = this, cap = self.initialCaption || '', out; | ||
| 1033 | + if (!previewCache.count(self.id)) { | ||
| 1034 | + self.clearPreview(); | ||
| 1035 | + if (isInit) { | ||
| 1036 | + self.setCaption(cap); | ||
| 1037 | + } else { | ||
| 1038 | + self.initCaption(); | ||
| 1039 | + } | ||
| 1040 | + return; | ||
| 1041 | + } | ||
| 1042 | + out = previewCache.out(self.id); | ||
| 1043 | + cap = isInit && self.initialCaption ? self.initialCaption : out.caption; | ||
| 1044 | + self.$preview.html(out.content); | ||
| 1045 | + self.setCaption(cap); | ||
| 1046 | + if (!isEmpty(out.content)) { | ||
| 1047 | + self.$container.removeClass('file-input-new'); | ||
| 1048 | + } | ||
| 1049 | + }, | ||
| 1050 | + initPreviewDeletes: function () { | ||
| 1051 | + var self = this, deleteExtraData = self.deleteExtraData || {}, | ||
| 1052 | + resetProgress = function () { | ||
| 1053 | + var hasFiles = self.isUploadable ? previewCache.count(self.id) : self.$element.get(0).files.length; | ||
| 1054 | + if (self.$preview.find('.kv-file-remove').length === 0 && !hasFiles) { | ||
| 1055 | + self.reset(); | ||
| 1056 | + self.initialCaption = ''; | ||
| 1057 | + } | ||
| 1058 | + }; | ||
| 1059 | + | ||
| 1060 | + self.$preview.find('.kv-file-remove').each(function () { | ||
| 1061 | + var $el = $(this), vUrl = $el.data('url') || self.deleteUrl, vKey = $el.data('key'); | ||
| 1062 | + if (isEmpty(vUrl) || vKey === undefined) { | ||
| 1063 | + return; | ||
| 1064 | + } | ||
| 1065 | + var $frame = $el.closest('.file-preview-frame'), cache = previewCache.data[self.id], | ||
| 1066 | + settings, params, index = $frame.data('fileindex'), config, extraData; | ||
| 1067 | + index = parseInt(index.replace('init_', '')); | ||
| 1068 | + config = isEmpty(cache.config) && isEmpty(cache.config[index]) ? null : cache.config[index]; | ||
| 1069 | + extraData = isEmpty(config) || isEmpty(config.extra) ? deleteExtraData : config.extra; | ||
| 1070 | + if (typeof extraData === "function") { | ||
| 1071 | + extraData = extraData(); | ||
| 1072 | + } | ||
| 1073 | + params = {id: $el.attr('id'), key: vKey, extra: extraData}; | ||
| 1074 | + settings = $.extend({ | ||
| 1075 | + url: vUrl, | ||
| 1076 | + type: 'POST', | ||
| 1077 | + dataType: 'json', | ||
| 1078 | + data: $.extend({key: vKey}, extraData), | ||
| 1079 | + beforeSend: function (jqXHR) { | ||
| 1080 | + self.ajaxAborted = false; | ||
| 1081 | + self.raise('filepredelete', [vKey, jqXHR, extraData]); | ||
| 1082 | + if (self.ajaxAborted) { | ||
| 1083 | + jqXHR.abort(); | ||
| 1084 | + } else { | ||
| 1085 | + addCss($frame, 'file-uploading'); | ||
| 1086 | + addCss($el, 'disabled'); | ||
| 1087 | + } | ||
| 1088 | + }, | ||
| 1089 | + success: function (data, textStatus, jqXHR) { | ||
| 1090 | + var n, cap; | ||
| 1091 | + if (isEmpty(data) || isEmpty(data.error)) { | ||
| 1092 | + previewCache.unset(self.id, index); | ||
| 1093 | + n = previewCache.count(self.id); | ||
| 1094 | + cap = n > 0 ? self.getMsgSelected(n) : ''; | ||
| 1095 | + self.raise('filedeleted', [vKey, jqXHR, extraData]); | ||
| 1096 | + self.setCaption(cap); | ||
| 1097 | + } else { | ||
| 1098 | + params.jqXHR = jqXHR; | ||
| 1099 | + params.response = data; | ||
| 1100 | + self.showError(data.error, params, 'filedeleteerror'); | ||
| 1101 | + $frame.removeClass('file-uploading'); | ||
| 1102 | + $el.removeClass('disabled'); | ||
| 1103 | + resetProgress(); | ||
| 1104 | + return; | ||
| 1105 | + } | ||
| 1106 | + $frame.removeClass('file-uploading').addClass('file-deleted'); | ||
| 1107 | + $frame.fadeOut('slow', function () { | ||
| 1108 | + self.clearObjects($frame); | ||
| 1109 | + $frame.remove(); | ||
| 1110 | + resetProgress(); | ||
| 1111 | + if (!n && self.getFileStack().length === 0) { | ||
| 1112 | + self.setCaption(''); | ||
| 1113 | + self.reset(); | ||
| 1114 | + } | ||
| 1115 | + }); | ||
| 1116 | + }, | ||
| 1117 | + error: function (jqXHR, textStatus, errorThrown) { | ||
| 1118 | + var errMsg = self.parseError(jqXHR, errorThrown); | ||
| 1119 | + params.jqXHR = jqXHR; | ||
| 1120 | + params.response = {}; | ||
| 1121 | + self.showError(errMsg, params, 'filedeleteerror'); | ||
| 1122 | + $frame.removeClass('file-uploading'); | ||
| 1123 | + resetProgress(); | ||
| 1124 | + } | ||
| 1125 | + }, self.ajaxDeleteSettings); | ||
| 1126 | + handler($el, 'click', function () { | ||
| 1127 | + if (!self.validateMinCount()) { | ||
| 1128 | + return false; | ||
| 1129 | + } | ||
| 1130 | + $.ajax(settings); | ||
| 1131 | + }); | ||
| 1132 | + }); | ||
| 1133 | + }, | ||
| 1134 | + clearObjects: function ($el) { | ||
| 1135 | + $el.find('video audio').each(function () { | ||
| 1136 | + this.pause(); | ||
| 1137 | + $(this).remove(); | ||
| 1138 | + }); | ||
| 1139 | + $el.find('img object div').each(function () { | ||
| 1140 | + $(this).remove(); | ||
| 1141 | + }); | ||
| 1142 | + }, | ||
| 1143 | + clearFileInput: function () { | ||
| 1144 | + var self = this, $el = self.$element, $srcFrm, $tmpFrm, $tmpEl; | ||
| 1145 | + if (isEmpty($el.val())) { | ||
| 1146 | + return; | ||
| 1147 | + } | ||
| 1148 | + // Fix for IE ver < 11, that does not clear file inputs | ||
| 1149 | + // Requires a sequence of steps to prevent IE crashing but | ||
| 1150 | + // still allow clearing of the file input. | ||
| 1151 | + if (self.isIE9 || self.isIE10) { | ||
| 1152 | + $srcFrm = $el.closest('form'); | ||
| 1153 | + $tmpFrm = $(document.createElement('form')); | ||
| 1154 | + $tmpEl = $(document.createElement('div')); | ||
| 1155 | + $el.before($tmpEl); | ||
| 1156 | + if ($srcFrm.length) { | ||
| 1157 | + $srcFrm.after($tmpFrm); | ||
| 1158 | + } else { | ||
| 1159 | + $tmpEl.after($tmpFrm); | ||
| 1160 | + } | ||
| 1161 | + $tmpFrm.append($el).trigger('reset'); | ||
| 1162 | + $tmpEl.before($el).remove(); | ||
| 1163 | + $tmpFrm.remove(); | ||
| 1164 | + } else { // normal input clear behavior for other sane browsers | ||
| 1165 | + $el.val(''); | ||
| 1166 | + } | ||
| 1167 | + self.fileInputCleared = true; | ||
| 1168 | + }, | ||
| 1169 | + resetUpload: function () { | ||
| 1170 | + var self = this; | ||
| 1171 | + self.uploadCache = {content: [], config: [], tags: [], append: true}; | ||
| 1172 | + self.uploadCount = 0; | ||
| 1173 | + self.uploadStatus = {}; | ||
| 1174 | + self.uploadLog = []; | ||
| 1175 | + self.uploadAsyncCount = 0; | ||
| 1176 | + self.loadedImages = []; | ||
| 1177 | + self.totalImagesCount = 0; | ||
| 1178 | + self.$btnUpload.removeAttr('disabled'); | ||
| 1179 | + self.setProgress(0); | ||
| 1180 | + addCss(self.$progress, 'hide'); | ||
| 1181 | + self.resetErrors(false); | ||
| 1182 | + self.ajaxAborted = false; | ||
| 1183 | + self.ajaxRequests = []; | ||
| 1184 | + self.resetCanvas(); | ||
| 1185 | + }, | ||
| 1186 | + resetCanvas: function () { | ||
| 1187 | + var self = this; | ||
| 1188 | + if (self.canvas && self.imageCanvasContext) { | ||
| 1189 | + self.imageCanvasContext.clearRect(0, 0, self.canvas.width, self.canvas.height); | ||
| 1190 | + } | ||
| 1191 | + }, | ||
| 1192 | + cancel: function () { | ||
| 1193 | + var self = this, xhr = self.ajaxRequests, len = xhr.length, i; | ||
| 1194 | + if (len > 0) { | ||
| 1195 | + for (i = 0; i < len; i += 1) { | ||
| 1196 | + self.cancelling = true; | ||
| 1197 | + xhr[i].abort(); | ||
| 1198 | + } | ||
| 1199 | + } | ||
| 1200 | + self.getThumbs().each(function () { | ||
| 1201 | + var $thumb = $(this), ind = $thumb.attr('data-fileindex'); | ||
| 1202 | + $thumb.removeClass('file-uploading'); | ||
| 1203 | + if (self.filestack[ind] !== undefined) { | ||
| 1204 | + $thumb.find('.kv-file-upload').removeClass('disabled').removeAttr('disabled'); | ||
| 1205 | + $thumb.find('.kv-file-remove').removeClass('disabled').removeAttr('disabled'); | ||
| 1206 | + } | ||
| 1207 | + self.unlock(); | ||
| 1208 | + }); | ||
| 1209 | + }, | ||
| 1210 | + cleanMemory: function ($thumb) { | ||
| 1211 | + var data = $thumb.is('img') ? $thumb.attr('src') : $thumb.find('source').attr('src'); | ||
| 1212 | + /** @namespace objUrl.revokeObjectURL */ | ||
| 1213 | + objUrl.revokeObjectURL(data); | ||
| 1214 | + }, | ||
| 1215 | + hasInitialPreview: function () { | ||
| 1216 | + var self = this; | ||
| 1217 | + return !self.overwriteInitial && previewCache.count(self.id); | ||
| 1218 | + }, | ||
| 1219 | + clear: function () { | ||
| 1220 | + var self = this, cap; | ||
| 1221 | + self.$btnUpload.removeAttr('disabled'); | ||
| 1222 | + self.getThumbs().find('video,audio,img').each(function () { | ||
| 1223 | + self.cleanMemory($(this)); | ||
| 1224 | + }); | ||
| 1225 | + self.resetUpload(); | ||
| 1226 | + self.clearStack(); | ||
| 1227 | + self.clearFileInput(); | ||
| 1228 | + self.resetErrors(true); | ||
| 1229 | + self.raise('fileclear'); | ||
| 1230 | + if (self.hasInitialPreview()) { | ||
| 1231 | + self.showFileIcon(); | ||
| 1232 | + self.resetPreview(); | ||
| 1233 | + self.initPreviewDeletes(); | ||
| 1234 | + self.$container.removeClass('file-input-new'); | ||
| 1235 | + } else { | ||
| 1236 | + self.getThumbs().each(function () { | ||
| 1237 | + self.clearObjects($(this)); | ||
| 1238 | + }); | ||
| 1239 | + if (self.isUploadable) { | ||
| 1240 | + previewCache.data[self.id] = {}; | ||
| 1241 | + } | ||
| 1242 | + self.$preview.html(''); | ||
| 1243 | + cap = (!self.overwriteInitial && self.initialCaption.length > 0) ? self.initialCaption : ''; | ||
| 1244 | + self.setCaption(cap); | ||
| 1245 | + self.$caption.attr('title', ''); | ||
| 1246 | + addCss(self.$container, 'file-input-new'); | ||
| 1247 | + self.validateDefaultPreview(); | ||
| 1248 | + } | ||
| 1249 | + if (self.$container.find('.file-preview-frame').length === 0) { | ||
| 1250 | + if (!self.initCaption()) { | ||
| 1251 | + self.$captionContainer.find('.kv-caption-icon').hide(); | ||
| 1252 | + } | ||
| 1253 | + } | ||
| 1254 | + self.hideFileIcon(); | ||
| 1255 | + self.raise('filecleared'); | ||
| 1256 | + self.$captionContainer.focus(); | ||
| 1257 | + self.setFileDropZoneTitle(); | ||
| 1258 | + }, | ||
| 1259 | + resetPreview: function () { | ||
| 1260 | + var self = this, out, cap; | ||
| 1261 | + if (previewCache.count(self.id)) { | ||
| 1262 | + out = previewCache.out(self.id); | ||
| 1263 | + self.$preview.html(out.content); | ||
| 1264 | + cap = self.initialCaption ? self.initialCaption : out.caption; | ||
| 1265 | + self.setCaption(cap); | ||
| 1266 | + } else { | ||
| 1267 | + self.clearPreview(); | ||
| 1268 | + self.initCaption(); | ||
| 1269 | + } | ||
| 1270 | + }, | ||
| 1271 | + clearDefaultPreview: function () { | ||
| 1272 | + var self = this; | ||
| 1273 | + self.$preview.find('.file-default-preview').remove(); | ||
| 1274 | + }, | ||
| 1275 | + validateDefaultPreview: function () { | ||
| 1276 | + var self = this; | ||
| 1277 | + if (!self.showPreview || isEmpty(self.defaultPreviewContent)) { | ||
| 1278 | + return; | ||
| 1279 | + } | ||
| 1280 | + self.$preview.html('<div class="file-default-preview">' + self.defaultPreviewContent + '</div>'); | ||
| 1281 | + self.$container.removeClass('file-input-new'); | ||
| 1282 | + }, | ||
| 1283 | + resetPreviewThumbs: function (isAjax) { | ||
| 1284 | + var self = this, out; | ||
| 1285 | + if (isAjax) { | ||
| 1286 | + self.clearPreview(); | ||
| 1287 | + self.clearStack(); | ||
| 1288 | + return; | ||
| 1289 | + } | ||
| 1290 | + if (self.hasInitialPreview()) { | ||
| 1291 | + out = previewCache.out(self.id); | ||
| 1292 | + self.$preview.html(out.content); | ||
| 1293 | + self.setCaption(out.caption); | ||
| 1294 | + self.initPreviewDeletes(); | ||
| 1295 | + } else { | ||
| 1296 | + self.clearPreview(); | ||
| 1297 | + } | ||
| 1298 | + }, | ||
| 1299 | + reset: function () { | ||
| 1300 | + var self = this; | ||
| 1301 | + self.resetPreview(); | ||
| 1302 | + self.$container.find('.fileinput-filename').text(''); | ||
| 1303 | + self.raise('filereset'); | ||
| 1304 | + addCss(self.$container, 'file-input-new'); | ||
| 1305 | + if (self.$preview.find('.file-preview-frame').length || self.isUploadable && self.dropZoneEnabled) { | ||
| 1306 | + self.$container.removeClass('file-input-new'); | ||
| 1307 | + } | ||
| 1308 | + self.setFileDropZoneTitle(); | ||
| 1309 | + self.clearStack(); | ||
| 1310 | + self.formdata = {}; | ||
| 1311 | + }, | ||
| 1312 | + disable: function () { | ||
| 1313 | + var self = this; | ||
| 1314 | + self.isDisabled = true; | ||
| 1315 | + self.raise('filedisabled'); | ||
| 1316 | + self.$element.attr('disabled', 'disabled'); | ||
| 1317 | + self.$container.find(".kv-fileinput-caption").addClass("file-caption-disabled"); | ||
| 1318 | + self.$container.find(".btn-file, .fileinput-remove, .fileinput-upload, .file-preview-frame button").attr( | ||
| 1319 | + "disabled", | ||
| 1320 | + true); | ||
| 1321 | + self.initDragDrop(); | ||
| 1322 | + }, | ||
| 1323 | + enable: function () { | ||
| 1324 | + var self = this; | ||
| 1325 | + self.isDisabled = false; | ||
| 1326 | + self.raise('fileenabled'); | ||
| 1327 | + self.$element.removeAttr('disabled'); | ||
| 1328 | + self.$container.find(".kv-fileinput-caption").removeClass("file-caption-disabled"); | ||
| 1329 | + self.$container.find( | ||
| 1330 | + ".btn-file, .fileinput-remove, .fileinput-upload, .file-preview-frame button").removeAttr("disabled"); | ||
| 1331 | + self.initDragDrop(); | ||
| 1332 | + }, | ||
| 1333 | + getThumbs: function (css) { | ||
| 1334 | + css = css || ''; | ||
| 1335 | + return this.$preview.find('.file-preview-frame:not(.file-preview-initial)' + css); | ||
| 1336 | + }, | ||
| 1337 | + getExtraData: function (previewId, index) { | ||
| 1338 | + var self = this, data = self.uploadExtraData; | ||
| 1339 | + if (typeof self.uploadExtraData === "function") { | ||
| 1340 | + data = self.uploadExtraData(previewId, index); | ||
| 1341 | + } | ||
| 1342 | + return data; | ||
| 1343 | + }, | ||
| 1344 | + uploadExtra: function (previewId, index) { | ||
| 1345 | + var self = this, data = self.getExtraData(previewId, index); | ||
| 1346 | + if (data.length === 0) { | ||
| 1347 | + return; | ||
| 1348 | + } | ||
| 1349 | + $.each(data, function (key, value) { | ||
| 1350 | + self.formdata.append(key, value); | ||
| 1351 | + }); | ||
| 1352 | + }, | ||
| 1353 | + setAsyncUploadStatus: function (previewId, pct, total) { | ||
| 1354 | + var self = this, sum = 0; | ||
| 1355 | + self.setProgress(pct, $('#' + previewId).find('.file-thumb-progress')); | ||
| 1356 | + self.uploadStatus[previewId] = pct; | ||
| 1357 | + $.each(self.uploadStatus, function (key, value) { | ||
| 1358 | + sum += value; | ||
| 1359 | + }); | ||
| 1360 | + self.setProgress(Math.ceil(sum / total)); | ||
| 1361 | + | ||
| 1362 | + }, | ||
| 1363 | + initXhr: function (xhrobj, previewId, fileCount) { | ||
| 1364 | + var self = this; | ||
| 1365 | + if (xhrobj.upload) { | ||
| 1366 | + xhrobj.upload.addEventListener('progress', function (event) { | ||
| 1367 | + var pct = 0, position = event.loaded || event.position, total = event.total; | ||
| 1368 | + /** @namespace event.lengthComputable */ | ||
| 1369 | + if (event.lengthComputable) { | ||
| 1370 | + pct = Math.ceil(position / total * 100); | ||
| 1371 | + } | ||
| 1372 | + if (previewId) { | ||
| 1373 | + self.setAsyncUploadStatus(previewId, pct, fileCount); | ||
| 1374 | + } else { | ||
| 1375 | + self.setProgress(Math.ceil(pct)); | ||
| 1376 | + } | ||
| 1377 | + }, false); | ||
| 1378 | + } | ||
| 1379 | + return xhrobj; | ||
| 1380 | + }, | ||
| 1381 | + ajaxSubmit: function (fnBefore, fnSuccess, fnComplete, fnError, previewId, index) { | ||
| 1382 | + var self = this, settings; | ||
| 1383 | + self.raise('filepreajax', [previewId, index]); | ||
| 1384 | + self.uploadExtra(previewId, index); | ||
| 1385 | + settings = $.extend({ | ||
| 1386 | + xhr: function () { | ||
| 1387 | + var xhrobj = $.ajaxSettings.xhr(); | ||
| 1388 | + return self.initXhr(xhrobj, previewId, self.getFileStack().length); | ||
| 1389 | + }, | ||
| 1390 | + url: self.uploadUrl, | ||
| 1391 | + type: 'POST', | ||
| 1392 | + dataType: 'json', | ||
| 1393 | + data: self.formdata, | ||
| 1394 | + cache: false, | ||
| 1395 | + processData: false, | ||
| 1396 | + contentType: false, | ||
| 1397 | + beforeSend: fnBefore, | ||
| 1398 | + success: fnSuccess, | ||
| 1399 | + complete: fnComplete, | ||
| 1400 | + error: fnError | ||
| 1401 | + }, self.ajaxSettings); | ||
| 1402 | + self.ajaxRequests.push($.ajax(settings)); | ||
| 1403 | + }, | ||
| 1404 | + initUploadSuccess: function (out, $thumb, allFiles) { | ||
| 1405 | + var self = this, append, data, index, $newThumb, content, config, tags, i; | ||
| 1406 | + if (!self.showPreview || typeof out !== 'object' || $.isEmptyObject(out)) { | ||
| 1407 | + return; | ||
| 1408 | + } | ||
| 1409 | + if (out.initialPreview !== undefined && out.initialPreview.length > 0) { | ||
| 1410 | + self.hasInitData = true; | ||
| 1411 | + content = out.initialPreview || []; | ||
| 1412 | + config = out.initialPreviewConfig || []; | ||
| 1413 | + tags = out.initialPreviewThumbTags || []; | ||
| 1414 | + append = out.append === undefined || out.append ? true : false; | ||
| 1415 | + self.overwriteInitial = false; | ||
| 1416 | + if ($thumb !== undefined) { | ||
| 1417 | + if (!allFiles) { | ||
| 1418 | + index = previewCache.add(self.id, content, config[0], tags[0], append); | ||
| 1419 | + data = previewCache.get(self.id, index, false); | ||
| 1420 | + $newThumb = $(data).hide(); | ||
| 1421 | + $thumb.after($newThumb).fadeOut('slow', function () { | ||
| 1422 | + $newThumb.fadeIn('slow').css('display:inline-block'); | ||
| 1423 | + self.initPreviewDeletes(); | ||
| 1424 | + self.clearFileInput(); | ||
| 1425 | + $thumb.remove(); | ||
| 1426 | + }); | ||
| 1427 | + } else { | ||
| 1428 | + i = $thumb.attr('data-fileindex'); | ||
| 1429 | + self.uploadCache.content[i] = content[0]; | ||
| 1430 | + self.uploadCache.config[i] = config[0]; | ||
| 1431 | + self.uploadCache.tags[i] = tags[0]; | ||
| 1432 | + self.uploadCache.append = append; | ||
| 1433 | + } | ||
| 1434 | + } else { | ||
| 1435 | + previewCache.set(self.id, content, config, tags, append); | ||
| 1436 | + self.initPreview(); | ||
| 1437 | + self.initPreviewDeletes(); | ||
| 1438 | + } | ||
| 1439 | + } | ||
| 1440 | + }, | ||
| 1441 | + initSuccessThumbs: function () { | ||
| 1442 | + var self = this; | ||
| 1443 | + if (!self.showPreview) { | ||
| 1444 | + return; | ||
| 1445 | + } | ||
| 1446 | + self.getThumbs('.file-preview-success').each(function () { | ||
| 1447 | + var $thumb = $(this), $remove = $thumb.find('.kv-file-remove'); | ||
| 1448 | + $remove.removeAttr('disabled'); | ||
| 1449 | + handler($remove, 'click', function () { | ||
| 1450 | + var out = self.raise('filesuccessremove', [$thumb.attr('id'), $thumb.data('fileindex')]); | ||
| 1451 | + self.cleanMemory($thumb); | ||
| 1452 | + if (out === false) { | ||
| 1453 | + return; | ||
| 1454 | + } | ||
| 1455 | + $thumb.fadeOut('slow', function () { | ||
| 1456 | + $thumb.remove(); | ||
| 1457 | + if (!self.$preview.find('.file-preview-frame').length) { | ||
| 1458 | + self.reset(); | ||
| 1459 | + } | ||
| 1460 | + }); | ||
| 1461 | + }); | ||
| 1462 | + }); | ||
| 1463 | + }, | ||
| 1464 | + checkAsyncComplete: function () { | ||
| 1465 | + var self = this, previewId, i; | ||
| 1466 | + for (i = 0; i < self.filestack.length; i++) { | ||
| 1467 | + if (self.filestack[i]) { | ||
| 1468 | + previewId = self.previewInitId + "-" + i; | ||
| 1469 | + if ($.inArray(previewId, self.uploadLog) === -1) { | ||
| 1470 | + return false; | ||
| 1471 | + } | ||
| 1472 | + } | ||
| 1473 | + } | ||
| 1474 | + return (self.uploadAsyncCount === self.uploadLog.length); | ||
| 1475 | + }, | ||
| 1476 | + uploadSingle: function (i, files, allFiles) { | ||
| 1477 | + var self = this, total = self.getFileStack().length, formdata = new FormData(), outData, | ||
| 1478 | + previewId = self.previewInitId + "-" + i, $thumb, chkComplete, $btnUpload, $btnDelete, | ||
| 1479 | + hasPostData = self.filestack.length > 0 || !$.isEmptyObject(self.uploadExtraData), | ||
| 1480 | + fnBefore, fnSuccess, fnComplete, fnError, updateUploadLog, params = {id: previewId, index: i}; | ||
| 1481 | + self.formdata = formdata; | ||
| 1482 | + if (self.showPreview) { | ||
| 1483 | + $thumb = $('#' + previewId + ':not(.file-preview-initial)'); | ||
| 1484 | + $btnUpload = $thumb.find('.kv-file-upload'); | ||
| 1485 | + $btnDelete = $thumb.find('.kv-file-remove'); | ||
| 1486 | + $('#' + previewId).find('.file-thumb-progress').removeClass('hide'); | ||
| 1487 | + } | ||
| 1488 | + if (total === 0 || !hasPostData || ($btnUpload && $btnUpload.hasClass('disabled')) || self.abort(params)) { | ||
| 1489 | + return; | ||
| 1490 | + } | ||
| 1491 | + updateUploadLog = function (i, previewId) { | ||
| 1492 | + self.updateStack(i, undefined); | ||
| 1493 | + self.uploadLog.push(previewId); | ||
| 1494 | + if (self.checkAsyncComplete()) { | ||
| 1495 | + self.fileBatchCompleted = true; | ||
| 1496 | + } | ||
| 1497 | + }; | ||
| 1498 | + chkComplete = function () { | ||
| 1499 | + if (!self.fileBatchCompleted) { | ||
| 1500 | + return; | ||
| 1501 | + } | ||
| 1502 | + setTimeout(function () { | ||
| 1503 | + if (self.showPreview) { | ||
| 1504 | + previewCache.set( | ||
| 1505 | + self.id, | ||
| 1506 | + self.uploadCache.content, | ||
| 1507 | + self.uploadCache.config, | ||
| 1508 | + self.uploadCache.tags, | ||
| 1509 | + self.uploadCache.append | ||
| 1510 | + ); | ||
| 1511 | + if (self.hasInitData) { | ||
| 1512 | + self.initPreview(); | ||
| 1513 | + self.initPreviewDeletes(); | ||
| 1514 | + } | ||
| 1515 | + } | ||
| 1516 | + self.unlock(); | ||
| 1517 | + self.clearFileInput(); | ||
| 1518 | + self.raise('filebatchuploadcomplete', [self.filestack, self.getExtraData()]); | ||
| 1519 | + self.uploadCount = 0; | ||
| 1520 | + self.uploadStatus = {}; | ||
| 1521 | + self.uploadLog = []; | ||
| 1522 | + self.setProgress(100); | ||
| 1523 | + }, 100); | ||
| 1524 | + }; | ||
| 1525 | + fnBefore = function (jqXHR) { | ||
| 1526 | + outData = self.getOutData(jqXHR); | ||
| 1527 | + self.fileBatchCompleted = false; | ||
| 1528 | + if (self.showPreview) { | ||
| 1529 | + if (!$thumb.hasClass('file-preview-success')) { | ||
| 1530 | + self.setThumbStatus($thumb, 'Loading'); | ||
| 1531 | + addCss($thumb, 'file-uploading'); | ||
| 1532 | + } | ||
| 1533 | + $btnUpload.attr('disabled', true); | ||
| 1534 | + $btnDelete.attr('disabled', true); | ||
| 1535 | + } | ||
| 1536 | + if (!allFiles) { | ||
| 1537 | + self.lock(); | ||
| 1538 | + } | ||
| 1539 | + self.raise('filepreupload', [outData, previewId, i]); | ||
| 1540 | + params = $.extend(params, outData); | ||
| 1541 | + if (self.abort(params)) { | ||
| 1542 | + jqXHR.abort(); | ||
| 1543 | + self.setProgress(100); | ||
| 1544 | + } | ||
| 1545 | + }; | ||
| 1546 | + fnSuccess = function (data, textStatus, jqXHR) { | ||
| 1547 | + outData = self.getOutData(jqXHR, data); | ||
| 1548 | + params = $.extend(params, outData); | ||
| 1549 | + setTimeout(function () { | ||
| 1550 | + if (isEmpty(data) || isEmpty(data.error)) { | ||
| 1551 | + if (self.showPreview) { | ||
| 1552 | + self.setThumbStatus($thumb, 'Success'); | ||
| 1553 | + $btnUpload.hide(); | ||
| 1554 | + self.initUploadSuccess(data, $thumb, allFiles); | ||
| 1555 | + } | ||
| 1556 | + self.raise('fileuploaded', [outData, previewId, i]); | ||
| 1557 | + if (!allFiles) { | ||
| 1558 | + self.updateStack(i, undefined); | ||
| 1559 | + } else { | ||
| 1560 | + updateUploadLog(i, previewId); | ||
| 1561 | + } | ||
| 1562 | + } else { | ||
| 1563 | + self.setThumbStatus($thumb, 'Error'); | ||
| 1564 | + self.showUploadError(data.error, params); | ||
| 1565 | + if (allFiles) { | ||
| 1566 | + updateUploadLog(i, previewId); | ||
| 1567 | + } | ||
| 1568 | + } | ||
| 1569 | + }, 100); | ||
| 1570 | + }; | ||
| 1571 | + fnComplete = function () { | ||
| 1572 | + setTimeout(function () { | ||
| 1573 | + if (self.showPreview) { | ||
| 1574 | + $btnUpload.removeAttr('disabled'); | ||
| 1575 | + $btnDelete.removeAttr('disabled'); | ||
| 1576 | + $thumb.removeClass('file-uploading'); | ||
| 1577 | + } | ||
| 1578 | + if (!allFiles) { | ||
| 1579 | + self.unlock(false); | ||
| 1580 | + self.clearFileInput(); | ||
| 1581 | + } else { | ||
| 1582 | + chkComplete(); | ||
| 1583 | + } | ||
| 1584 | + self.initSuccessThumbs(); | ||
| 1585 | + }, 100); | ||
| 1586 | + }; | ||
| 1587 | + fnError = function (jqXHR, textStatus, errorThrown) { | ||
| 1588 | + var errMsg = self.parseError(jqXHR, errorThrown, (allFiles ? files[i].name : null)); | ||
| 1589 | + setTimeout(function () { | ||
| 1590 | + if (allFiles) { | ||
| 1591 | + updateUploadLog(i, previewId); | ||
| 1592 | + } | ||
| 1593 | + self.uploadStatus[previewId] = 100; | ||
| 1594 | + self.setThumbStatus($thumb, 'Error'); | ||
| 1595 | + params = $.extend(params, self.getOutData(jqXHR)); | ||
| 1596 | + self.showUploadError(errMsg, params); | ||
| 1597 | + }, 100); | ||
| 1598 | + }; | ||
| 1599 | + formdata.append(self.uploadFileAttr, files[i], self.filenames[i]); | ||
| 1600 | + formdata.append('file_id', i); | ||
| 1601 | + self.ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, previewId, i); | ||
| 1602 | + }, | ||
| 1603 | + uploadBatch: function () { | ||
| 1604 | + var self = this, files = self.filestack, total = files.length, params = {}, | ||
| 1605 | + hasPostData = self.filestack.length > 0 || !$.isEmptyObject(self.uploadExtraData), | ||
| 1606 | + setAllUploaded, fnBefore, fnSuccess, fnComplete, fnError; | ||
| 1607 | + self.formdata = new FormData(); | ||
| 1608 | + if (total === 0 || !hasPostData || self.abort(params)) { | ||
| 1609 | + return; | ||
| 1610 | + } | ||
| 1611 | + setAllUploaded = function () { | ||
| 1612 | + $.each(files, function (key) { | ||
| 1613 | + self.updateStack(key, undefined); | ||
| 1614 | + }); | ||
| 1615 | + self.clearFileInput(); | ||
| 1616 | + }; | ||
| 1617 | + fnBefore = function (jqXHR) { | ||
| 1618 | + self.lock(); | ||
| 1619 | + var outData = self.getOutData(jqXHR); | ||
| 1620 | + if (self.showPreview) { | ||
| 1621 | + self.getThumbs().each(function () { | ||
| 1622 | + var $thumb = $(this), $btnUpload = $thumb.find('.kv-file-upload'), | ||
| 1623 | + $btnDelete = $thumb.find('.kv-file-remove'); | ||
| 1624 | + if (!$thumb.hasClass('file-preview-success')) { | ||
| 1625 | + self.setThumbStatus($thumb, 'Loading'); | ||
| 1626 | + addCss($thumb, 'file-uploading'); | ||
| 1627 | + } | ||
| 1628 | + $btnUpload.attr('disabled', true); | ||
| 1629 | + $btnDelete.attr('disabled', true); | ||
| 1630 | + }); | ||
| 1631 | + } | ||
| 1632 | + self.raise('filebatchpreupload', [outData]); | ||
| 1633 | + if (self.abort(outData)) { | ||
| 1634 | + jqXHR.abort(); | ||
| 1635 | + self.setProgress(100); | ||
| 1636 | + } | ||
| 1637 | + }; | ||
| 1638 | + fnSuccess = function (data, textStatus, jqXHR) { | ||
| 1639 | + /** @namespace data.errorkeys */ | ||
| 1640 | + var outData = self.getOutData(jqXHR, data), $thumbs = self.getThumbs(), key = 0, | ||
| 1641 | + keys = isEmpty(data) || isEmpty(data.errorkeys) ? [] : data.errorkeys; | ||
| 1642 | + if (isEmpty(data) || isEmpty(data.error)) { | ||
| 1643 | + self.raise('filebatchuploadsuccess', [outData]); | ||
| 1644 | + setAllUploaded(); | ||
| 1645 | + if (self.showPreview) { | ||
| 1646 | + $thumbs.each(function () { | ||
| 1647 | + var $thumb = $(this), $btnUpload = $thumb.find('.kv-file-upload'); | ||
| 1648 | + $thumb.find('.kv-file-upload').hide(); | ||
| 1649 | + self.setThumbStatus($thumb, 'Success'); | ||
| 1650 | + $thumb.removeClass('file-uploading'); | ||
| 1651 | + $btnUpload.removeAttr('disabled'); | ||
| 1652 | + }); | ||
| 1653 | + self.initUploadSuccess(data); | ||
| 1654 | + } else { | ||
| 1655 | + self.reset(); | ||
| 1656 | + } | ||
| 1657 | + } else { | ||
| 1658 | + if (self.showPreview) { | ||
| 1659 | + $thumbs.each(function () { | ||
| 1660 | + var $thumb = $(this), $btnDelete = $thumb.find('.kv-file-remove'), | ||
| 1661 | + $btnUpload = $thumb.find('.kv-file-upload'); | ||
| 1662 | + $thumb.removeClass('file-uploading'); | ||
| 1663 | + $btnUpload.removeAttr('disabled'); | ||
| 1664 | + $btnDelete.removeAttr('disabled'); | ||
| 1665 | + if (keys.length === 0) { | ||
| 1666 | + self.setThumbStatus($thumb, 'Error'); | ||
| 1667 | + return; | ||
| 1668 | + } | ||
| 1669 | + if ($.inArray(key, keys) !== -1) { | ||
| 1670 | + self.setThumbStatus($thumb, 'Error'); | ||
| 1671 | + } else { | ||
| 1672 | + $thumb.find('.kv-file-upload').hide(); | ||
| 1673 | + self.setThumbStatus($thumb, 'Success'); | ||
| 1674 | + self.updateStack(key, undefined); | ||
| 1675 | + } | ||
| 1676 | + key++; | ||
| 1677 | + }); | ||
| 1678 | + self.initUploadSuccess(data); | ||
| 1679 | + } | ||
| 1680 | + self.showUploadError(data.error, outData, 'filebatchuploaderror'); | ||
| 1681 | + } | ||
| 1682 | + }; | ||
| 1683 | + fnComplete = function () { | ||
| 1684 | + self.setProgress(100); | ||
| 1685 | + self.unlock(); | ||
| 1686 | + self.initSuccessThumbs(); | ||
| 1687 | + self.clearFileInput(); | ||
| 1688 | + self.raise('filebatchuploadcomplete', [self.filestack, self.getExtraData()]); | ||
| 1689 | + }; | ||
| 1690 | + fnError = function (jqXHR, textStatus, errorThrown) { | ||
| 1691 | + var outData = self.getOutData(jqXHR), errMsg = self.parseError(jqXHR, errorThrown); | ||
| 1692 | + self.showUploadError(errMsg, outData, 'filebatchuploaderror'); | ||
| 1693 | + self.uploadFileCount = total - 1; | ||
| 1694 | + if (!self.showPreview) { | ||
| 1695 | + return; | ||
| 1696 | + } | ||
| 1697 | + self.getThumbs().each(function () { | ||
| 1698 | + var $thumb = $(this), key = $thumb.attr('data-fileindex'); | ||
| 1699 | + $thumb.removeClass('file-uploading'); | ||
| 1700 | + if (self.filestack[key] !== undefined) { | ||
| 1701 | + self.setThumbStatus($thumb, 'Error'); | ||
| 1702 | + } | ||
| 1703 | + }); | ||
| 1704 | + self.getThumbs().removeClass('file-uploading'); | ||
| 1705 | + self.getThumbs(' .kv-file-upload').removeAttr('disabled'); | ||
| 1706 | + self.getThumbs(' .kv-file-delete').removeAttr('disabled'); | ||
| 1707 | + }; | ||
| 1708 | + $.each(files, function (key, data) { | ||
| 1709 | + if (!isEmpty(files[key])) { | ||
| 1710 | + self.formdata.append(self.uploadFileAttr, data, self.filenames[key]); | ||
| 1711 | + } | ||
| 1712 | + }); | ||
| 1713 | + self.ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError); | ||
| 1714 | + }, | ||
| 1715 | + uploadExtraOnly: function () { | ||
| 1716 | + var self = this, params = {}, fnBefore, fnSuccess, fnComplete, fnError; | ||
| 1717 | + self.formdata = new FormData(); | ||
| 1718 | + if (self.abort(params)) { | ||
| 1719 | + return; | ||
| 1720 | + } | ||
| 1721 | + fnBefore = function (jqXHR) { | ||
| 1722 | + self.lock(); | ||
| 1723 | + var outData = self.getOutData(jqXHR); | ||
| 1724 | + self.raise('filebatchpreupload', [outData]); | ||
| 1725 | + self.setProgress(50); | ||
| 1726 | + params.data = outData; | ||
| 1727 | + params.xhr = jqXHR; | ||
| 1728 | + if (self.abort(params)) { | ||
| 1729 | + jqXHR.abort(); | ||
| 1730 | + self.setProgress(100); | ||
| 1731 | + } | ||
| 1732 | + }; | ||
| 1733 | + fnSuccess = function (data, textStatus, jqXHR) { | ||
| 1734 | + var outData = self.getOutData(jqXHR, data); | ||
| 1735 | + if (isEmpty(data) || isEmpty(data.error)) { | ||
| 1736 | + self.raise('filebatchuploadsuccess', [outData]); | ||
| 1737 | + self.clearFileInput(); | ||
| 1738 | + self.initUploadSuccess(data); | ||
| 1739 | + } else { | ||
| 1740 | + self.showUploadError(data.error, outData, 'filebatchuploaderror'); | ||
| 1741 | + } | ||
| 1742 | + }; | ||
| 1743 | + fnComplete = function () { | ||
| 1744 | + self.setProgress(100); | ||
| 1745 | + self.unlock(); | ||
| 1746 | + self.clearFileInput(); | ||
| 1747 | + self.raise('filebatchuploadcomplete', [self.filestack, self.getExtraData()]); | ||
| 1748 | + }; | ||
| 1749 | + fnError = function (jqXHR, textStatus, errorThrown) { | ||
| 1750 | + var outData = self.getOutData(jqXHR), errMsg = self.parseError(jqXHR, errorThrown); | ||
| 1751 | + params.data = outData; | ||
| 1752 | + self.showUploadError(errMsg, outData, 'filebatchuploaderror'); | ||
| 1753 | + }; | ||
| 1754 | + self.ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError); | ||
| 1755 | + }, | ||
| 1756 | + upload: function () { | ||
| 1757 | + var self = this, totLen = self.getFileStack().length, params = {}, | ||
| 1758 | + i, outData, len, hasExtraData = !$.isEmptyObject(self.getExtraData()); | ||
| 1759 | + if (self.minFileCount > 0 && self.getFileCount(totLen) < self.minFileCount) { | ||
| 1760 | + self.noFilesError(params); | ||
| 1761 | + return; | ||
| 1762 | + } | ||
| 1763 | + if (!self.isUploadable || self.isDisabled || (totLen === 0 && !hasExtraData)) { | ||
| 1764 | + return; | ||
| 1765 | + } | ||
| 1766 | + self.resetUpload(); | ||
| 1767 | + self.$progress.removeClass('hide'); | ||
| 1768 | + self.uploadCount = 0; | ||
| 1769 | + self.uploadStatus = {}; | ||
| 1770 | + self.uploadLog = []; | ||
| 1771 | + self.lock(); | ||
| 1772 | + self.setProgress(2); | ||
| 1773 | + if (totLen === 0 && hasExtraData) { | ||
| 1774 | + self.uploadExtraOnly(); | ||
| 1775 | + return; | ||
| 1776 | + } | ||
| 1777 | + len = self.filestack.length; | ||
| 1778 | + self.hasInitData = false; | ||
| 1779 | + if (self.uploadAsync) { | ||
| 1780 | + outData = self.getOutData(); | ||
| 1781 | + self.raise('filebatchpreupload', [outData]); | ||
| 1782 | + self.fileBatchCompleted = false; | ||
| 1783 | + self.uploadCache = {content: [], config: [], tags: [], append: true}; | ||
| 1784 | + self.uploadAsyncCount = self.getFileStack().length; | ||
| 1785 | + for (i = 0; i < len; i++) { | ||
| 1786 | + self.uploadCache.content[i] = null; | ||
| 1787 | + self.uploadCache.config[i] = null; | ||
| 1788 | + self.uploadCache.tags[i] = null; | ||
| 1789 | + } | ||
| 1790 | + for (i = 0; i < len; i++) { | ||
| 1791 | + if (self.filestack[i] !== undefined) { | ||
| 1792 | + self.uploadSingle(i, self.filestack, true); | ||
| 1793 | + } | ||
| 1794 | + } | ||
| 1795 | + return; | ||
| 1796 | + } | ||
| 1797 | + self.uploadBatch(); | ||
| 1798 | + }, | ||
| 1799 | + initFileActions: function () { | ||
| 1800 | + var self = this; | ||
| 1801 | + if (!self.showPreview) { | ||
| 1802 | + return; | ||
| 1803 | + } | ||
| 1804 | + self.$preview.find('.kv-file-remove').each(function () { | ||
| 1805 | + var $el = $(this), $frame = $el.closest('.file-preview-frame'), hasError, | ||
| 1806 | + id = $frame.attr('id'), ind = $frame.attr('data-fileindex'), n, cap, status; | ||
| 1807 | + handler($el, 'click', function () { | ||
| 1808 | + status = self.raise('filepreremove', [id, ind]); | ||
| 1809 | + if (status === false || !self.validateMinCount()) { | ||
| 1810 | + return false; | ||
| 1811 | + } | ||
| 1812 | + hasError = $frame.hasClass('file-preview-error'); | ||
| 1813 | + self.cleanMemory($frame); | ||
| 1814 | + $frame.fadeOut('slow', function () { | ||
| 1815 | + self.updateStack(ind, undefined); | ||
| 1816 | + self.clearObjects($frame); | ||
| 1817 | + $frame.remove(); | ||
| 1818 | + if (id && hasError) { | ||
| 1819 | + self.$errorContainer.find('li[data-file-id="' + id + '"]').fadeOut('fast', function () { | ||
| 1820 | + $(this).remove(); | ||
| 1821 | + if (!self.errorsExist()) { | ||
| 1822 | + self.resetErrors(); | ||
| 1823 | + } | ||
| 1824 | + }); | ||
| 1825 | + } | ||
| 1826 | + var filestack = self.getFileStack(true), len = filestack.length, chk = previewCache.count( | ||
| 1827 | + self.id), | ||
| 1828 | + hasThumb = self.showPreview && self.$preview.find('.file-preview-frame').length; | ||
| 1829 | + self.clearFileInput(); | ||
| 1830 | + if (len === 0 && chk === 0 && !hasThumb) { | ||
| 1831 | + self.reset(); | ||
| 1832 | + } else { | ||
| 1833 | + n = chk + len; | ||
| 1834 | + cap = n > 1 ? self.getMsgSelected(n) : (filestack[0] ? self.getFileNames()[0] : ''); | ||
| 1835 | + self.setCaption(cap); | ||
| 1836 | + } | ||
| 1837 | + self.raise('fileremoved', [id, ind]); | ||
| 1838 | + }); | ||
| 1839 | + }); | ||
| 1840 | + }); | ||
| 1841 | + self.$preview.find('.kv-file-upload').each(function () { | ||
| 1842 | + var $el = $(this); | ||
| 1843 | + handler($el, 'click', function () { | ||
| 1844 | + var $frame = $el.closest('.file-preview-frame'), | ||
| 1845 | + ind = $frame.attr('data-fileindex'); | ||
| 1846 | + if (!$frame.hasClass('file-preview-error')) { | ||
| 1847 | + self.uploadSingle(ind, self.filestack, false); | ||
| 1848 | + } | ||
| 1849 | + }); | ||
| 1850 | + }); | ||
| 1851 | + }, | ||
| 1852 | + hideFileIcon: function () { | ||
| 1853 | + if (this.overwriteInitial) { | ||
| 1854 | + this.$captionContainer.find('.kv-caption-icon').hide(); | ||
| 1855 | + } | ||
| 1856 | + }, | ||
| 1857 | + showFileIcon: function () { | ||
| 1858 | + this.$captionContainer.find('.kv-caption-icon').show(); | ||
| 1859 | + }, | ||
| 1860 | + addError: function (msg) { | ||
| 1861 | + var self = this, $error = self.$errorContainer; | ||
| 1862 | + if (msg && $error.length) { | ||
| 1863 | + $error.html(self.errorCloseButton + msg); | ||
| 1864 | + $error.find('.kv-error-close').off('click').on('click', function () { | ||
| 1865 | + $error.fadeOut('slow'); | ||
| 1866 | + }); | ||
| 1867 | + } | ||
| 1868 | + }, | ||
| 1869 | + resetErrors: function (fade) { | ||
| 1870 | + var self = this, $error = self.$errorContainer; | ||
| 1871 | + self.isError = false; | ||
| 1872 | + self.$container.removeClass('has-error'); | ||
| 1873 | + $error.html(''); | ||
| 1874 | + if (fade) { | ||
| 1875 | + $error.fadeOut('slow'); | ||
| 1876 | + } else { | ||
| 1877 | + $error.hide(); | ||
| 1878 | + } | ||
| 1879 | + }, | ||
| 1880 | + showFolderError: function (folders) { | ||
| 1881 | + var self = this, $error = self.$errorContainer; | ||
| 1882 | + if (!folders) { | ||
| 1883 | + return; | ||
| 1884 | + } | ||
| 1885 | + self.addError(self.msgFoldersNotAllowed.replace(/\{n}/g, folders)); | ||
| 1886 | + $error.fadeIn(800); | ||
| 1887 | + addCss(self.$container, 'has-error'); | ||
| 1888 | + self.raise('filefoldererror', [folders]); | ||
| 1889 | + }, | ||
| 1890 | + showUploadError: function (msg, params, event) { | ||
| 1891 | + var self = this, $error = self.$errorContainer, ev = event || 'fileuploaderror', | ||
| 1892 | + e = params && params.id ? '<li data-file-id="' + params.id + '">' + msg + '</li>' : '<li>' + msg + '</li>'; | ||
| 1893 | + if ($error.find('ul').length === 0) { | ||
| 1894 | + self.addError('<ul>' + e + '</ul>'); | ||
| 1895 | + } else { | ||
| 1896 | + $error.find('ul').append(e); | ||
| 1897 | + } | ||
| 1898 | + $error.fadeIn(800); | ||
| 1899 | + self.raise(ev, [params]); | ||
| 1900 | + self.$container.removeClass('file-input-new'); | ||
| 1901 | + addCss(self.$container, 'has-error'); | ||
| 1902 | + return true; | ||
| 1903 | + }, | ||
| 1904 | + showError: function (msg, params, event) { | ||
| 1905 | + var self = this, $error = self.$errorContainer, ev = event || 'fileerror'; | ||
| 1906 | + params = params || {}; | ||
| 1907 | + params.reader = self.reader; | ||
| 1908 | + self.addError(msg); | ||
| 1909 | + $error.fadeIn(800); | ||
| 1910 | + self.raise(ev, [params]); | ||
| 1911 | + if (!self.isUploadable) { | ||
| 1912 | + self.clearFileInput(); | ||
| 1913 | + } | ||
| 1914 | + self.$container.removeClass('file-input-new'); | ||
| 1915 | + addCss(self.$container, 'has-error'); | ||
| 1916 | + self.$btnUpload.attr('disabled', true); | ||
| 1917 | + return true; | ||
| 1918 | + }, | ||
| 1919 | + errorHandler: function (evt, caption) { | ||
| 1920 | + var self = this, err = evt.target.error; | ||
| 1921 | + /** @namespace err.NOT_FOUND_ERR */ | ||
| 1922 | + /** @namespace err.SECURITY_ERR */ | ||
| 1923 | + /** @namespace err.NOT_READABLE_ERR */ | ||
| 1924 | + if (err.code === err.NOT_FOUND_ERR) { | ||
| 1925 | + self.showError(self.msgFileNotFound.replace('{name}', caption)); | ||
| 1926 | + } else if (err.code === err.SECURITY_ERR) { | ||
| 1927 | + self.showError(self.msgFileSecured.replace('{name}', caption)); | ||
| 1928 | + } else if (err.code === err.NOT_READABLE_ERR) { | ||
| 1929 | + self.showError(self.msgFileNotReadable.replace('{name}', caption)); | ||
| 1930 | + } else if (err.code === err.ABORT_ERR) { | ||
| 1931 | + self.showError(self.msgFilePreviewAborted.replace('{name}', caption)); | ||
| 1932 | + } else { | ||
| 1933 | + self.showError(self.msgFilePreviewError.replace('{name}', caption)); | ||
| 1934 | + } | ||
| 1935 | + }, | ||
| 1936 | + parseFileType: function (file) { | ||
| 1937 | + var self = this, isValid, vType, cat, i; | ||
| 1938 | + for (i = 0; i < defaultPreviewTypes.length; i += 1) { | ||
| 1939 | + cat = defaultPreviewTypes[i]; | ||
| 1940 | + isValid = isSet(cat, self.fileTypeSettings) ? self.fileTypeSettings[cat] : defaultFileTypeSettings[cat]; | ||
| 1941 | + vType = isValid(file.type, file.name) ? cat : ''; | ||
| 1942 | + if (!isEmpty(vType)) { | ||
| 1943 | + return vType; | ||
| 1944 | + } | ||
| 1945 | + } | ||
| 1946 | + return 'other'; | ||
| 1947 | + }, | ||
| 1948 | + previewDefault: function (file, previewId, isDisabled) { | ||
| 1949 | + if (!this.showPreview) { | ||
| 1950 | + return; | ||
| 1951 | + } | ||
| 1952 | + var self = this, frameClass = '', fname = file ? file.name : '', | ||
| 1953 | + /** @namespace objUrl.createObjectURL */ | ||
| 1954 | + data = objUrl.createObjectURL(file), ind = previewId.slice(previewId.lastIndexOf('-') + 1), | ||
| 1955 | + config = self.previewSettings.other || defaultPreviewSettings.other, | ||
| 1956 | + footer = self.renderFileFooter(file.name, config.width), | ||
| 1957 | + previewOtherTemplate = self.parseFilePreviewIcon(self.getPreviewTemplate('other'), fname); | ||
| 1958 | + if (isDisabled === true) { | ||
| 1959 | + if (!self.isUploadable) { | ||
| 1960 | + footer += '<div class="file-other-error" title="' + self.fileActionSettings.indicatorErrorTitle + | ||
| 1961 | + '">' + self.fileActionSettings.indicatorError + '</div>'; | ||
| 1962 | + } | ||
| 1963 | + } | ||
| 1964 | + self.clearDefaultPreview(); | ||
| 1965 | + self.$preview.append("\n" + previewOtherTemplate | ||
| 1966 | + .replace(/\{previewId}/g, previewId) | ||
| 1967 | + .replace(/\{frameClass}/g, frameClass) | ||
| 1968 | + .replace(/\{fileindex}/g, ind) | ||
| 1969 | + .replace(/\{caption}/g, self.slug(file.name)) | ||
| 1970 | + .replace(/\{width}/g, config.width) | ||
| 1971 | + .replace(/\{height}/g, config.height) | ||
| 1972 | + .replace(/\{type}/g, file.type) | ||
| 1973 | + .replace(/\{data}/g, data) | ||
| 1974 | + .replace(/\{footer}/g, footer)); | ||
| 1975 | + if (isDisabled === true && self.isUploadable) { | ||
| 1976 | + self.setThumbStatus($('#' + previewId), 'Error'); | ||
| 1977 | + } | ||
| 1978 | + }, | ||
| 1979 | + previewFile: function (i, file, theFile, previewId, data) { | ||
| 1980 | + if (!this.showPreview) { | ||
| 1981 | + return; | ||
| 1982 | + } | ||
| 1983 | + var self = this, cat = self.parseFileType(file), fname = file ? file.name : '', caption = self.slug(fname), | ||
| 1984 | + content, strText, types = self.allowedPreviewTypes, mimes = self.allowedPreviewMimeTypes, | ||
| 1985 | + tmplt = self.getPreviewTemplate(cat), chkTypes = types && types.indexOf(cat) >= 0, id, | ||
| 1986 | + config = isSet(cat, self.previewSettings) ? self.previewSettings[cat] : defaultPreviewSettings[cat], | ||
| 1987 | + chkMimes = mimes && mimes.indexOf(file.type) !== -1, | ||
| 1988 | + footer = self.renderFileFooter(caption, config.width), modal = '', | ||
| 1989 | + ind = previewId.slice(previewId.lastIndexOf('-') + 1); | ||
| 1990 | + if (chkTypes || chkMimes) { | ||
| 1991 | + tmplt = self.parseFilePreviewIcon(tmplt, fname.split('.').pop()); | ||
| 1992 | + if (cat === 'text') { | ||
| 1993 | + strText = htmlEncode(theFile.target.result); | ||
| 1994 | + id = 'text-' + uniqId(); | ||
| 1995 | + content = tmplt.replace(/\{zoom}/g, self.getLayoutTemplate('zoom')); | ||
| 1996 | + modal = self.getLayoutTemplate('modal').replace('{id}', id) | ||
| 1997 | + .replace(/\{title}/g, caption) | ||
| 1998 | + .replace(/\{body}/g, strText).replace(/\{heading}/g, self.msgZoomModalHeading); | ||
| 1999 | + content = content.replace(/\{previewId}/g, previewId).replace(/\{caption}/g, caption) | ||
| 2000 | + .replace(/\{width}/g, config.width).replace(/\{height}/g, config.height) | ||
| 2001 | + .replace(/\{frameClass}/g, '').replace(/\{zoomInd}/g, self.zoomIndicator) | ||
| 2002 | + .replace(/\{footer}/g, footer).replace(/\{fileindex}/g, ind) | ||
| 2003 | + .replace(/\{type}/g, file.type).replace(/\{zoomTitle}/g, self.msgZoomTitle) | ||
| 2004 | + .replace(/\{dialog}/g, "$('#" + id + "').modal('show')") | ||
| 2005 | + .replace(/\{data}/g, strText) + modal; | ||
| 2006 | + } else { | ||
| 2007 | + content = tmplt.replace(/\{previewId}/g, previewId).replace(/\{caption}/g, caption) | ||
| 2008 | + .replace(/\{frameClass}/g, '').replace(/\{type}/g, file.type).replace(/\{fileindex}/g, ind) | ||
| 2009 | + .replace(/\{width}/g, config.width).replace(/\{height}/g, config.height) | ||
| 2010 | + .replace(/\{footer}/g, footer).replace(/\{data}/g, data); | ||
| 2011 | + } | ||
| 2012 | + self.clearDefaultPreview(); | ||
| 2013 | + self.$preview.append("\n" + content); | ||
| 2014 | + self.validateImage(i, previewId, caption, file.type); | ||
| 2015 | + } else { | ||
| 2016 | + self.previewDefault(file, previewId); | ||
| 2017 | + } | ||
| 2018 | + }, | ||
| 2019 | + slugDefault: function (text) { | ||
| 2020 | + return isEmpty(text) ? '' : text.split(/(\\|\/)/g).pop().replace(/[^\w\u00C0-\u017F\-.\\\/ ]+/g, ''); | ||
| 2021 | + }, | ||
| 2022 | + readFiles: function (files) { | ||
| 2023 | + this.reader = new FileReader(); | ||
| 2024 | + var self = this, $el = self.$element, $preview = self.$preview, reader = self.reader, | ||
| 2025 | + $container = self.$previewContainer, $status = self.$previewStatus, msgLoading = self.msgLoading, | ||
| 2026 | + msgProgress = self.msgProgress, previewInitId = self.previewInitId, numFiles = files.length, | ||
| 2027 | + settings = self.fileTypeSettings, ctr = self.filestack.length, readFile, | ||
| 2028 | + throwError = function (msg, file, previewId, index) { | ||
| 2029 | + var p1 = $.extend(self.getOutData({}, {}, files), {id: previewId, index: index}), | ||
| 2030 | + p2 = {id: previewId, index: index, file: file, files: files}; | ||
| 2031 | + self.previewDefault(file, previewId, true); | ||
| 2032 | + if (self.isUploadable) { | ||
| 2033 | + self.pushStack(undefined); | ||
| 2034 | + } | ||
| 2035 | + setTimeout(readFile(index + 1), 100); | ||
| 2036 | + self.initFileActions(); | ||
| 2037 | + return self.isUploadable ? self.showUploadError(msg, p1) : self.showError(msg, p2); | ||
| 2038 | + }; | ||
| 2039 | + | ||
| 2040 | + self.loadedImages = []; | ||
| 2041 | + self.totalImagesCount = 0; | ||
| 2042 | + | ||
| 2043 | + $.each(files, function (key, file) { | ||
| 2044 | + var cat = 'image', | ||
| 2045 | + func = isSet(cat, | ||
| 2046 | + self.fileTypeSettings) ? self.fileTypeSettings[cat] : defaultFileTypeSettings[cat]; | ||
| 2047 | + if (func && func(file.type)) { | ||
| 2048 | + self.totalImagesCount++; | ||
| 2049 | + } | ||
| 2050 | + }); | ||
| 2051 | + | ||
| 2052 | + readFile = function (i) { | ||
| 2053 | + if (isEmpty($el.attr('multiple'))) { | ||
| 2054 | + numFiles = 1; | ||
| 2055 | + } | ||
| 2056 | + if (i >= numFiles) { | ||
| 2057 | + if (self.isUploadable && self.filestack.length > 0) { | ||
| 2058 | + self.raise('filebatchselected', [self.getFileStack()]); | ||
| 2059 | + } else { | ||
| 2060 | + self.raise('filebatchselected', [files]); | ||
| 2061 | + } | ||
| 2062 | + $container.removeClass('file-thumb-loading'); | ||
| 2063 | + $status.html(''); | ||
| 2064 | + return; | ||
| 2065 | + } | ||
| 2066 | + var node = ctr + i, previewId = previewInitId + "-" + node, isText, file = files[i], | ||
| 2067 | + caption = self.slug(file.name), fileSize = (file.size || 0) / 1000, checkFile, fileExtExpr = '', | ||
| 2068 | + previewData = objUrl.createObjectURL(file), fileCount = 0, j, msg, typ, chk, | ||
| 2069 | + fileTypes = self.allowedFileTypes, strTypes = isEmpty(fileTypes) ? '' : fileTypes.join(', '), | ||
| 2070 | + fileExt = self.allowedFileExtensions, strExt = isEmpty(fileExt) ? '' : fileExt.join(', '); | ||
| 2071 | + if (!isEmpty(fileExt)) { | ||
| 2072 | + fileExtExpr = new RegExp('\\.(' + fileExt.join('|') + ')$', 'i'); | ||
| 2073 | + } | ||
| 2074 | + fileSize = fileSize.toFixed(2); | ||
| 2075 | + if (self.maxFileSize > 0 && fileSize > self.maxFileSize) { | ||
| 2076 | + msg = self.msgSizeTooLarge.replace('{name}', caption) | ||
| 2077 | + .replace('{size}', fileSize) | ||
| 2078 | + .replace('{maxSize}', self.maxFileSize); | ||
| 2079 | + self.isError = throwError(msg, file, previewId, i); | ||
| 2080 | + return; | ||
| 2081 | + } | ||
| 2082 | + if (!isEmpty(fileTypes) && isArray(fileTypes)) { | ||
| 2083 | + for (j = 0; j < fileTypes.length; j += 1) { | ||
| 2084 | + typ = fileTypes[j]; | ||
| 2085 | + checkFile = settings[typ]; | ||
| 2086 | + chk = (checkFile !== undefined && checkFile(file.type, caption)); | ||
| 2087 | + fileCount += isEmpty(chk) ? 0 : chk.length; | ||
| 2088 | + } | ||
| 2089 | + if (fileCount === 0) { | ||
| 2090 | + msg = self.msgInvalidFileType.replace('{name}', caption).replace('{types}', strTypes); | ||
| 2091 | + self.isError = throwError(msg, file, previewId, i); | ||
| 2092 | + return; | ||
| 2093 | + } | ||
| 2094 | + } | ||
| 2095 | + if (fileCount === 0 && !isEmpty(fileExt) && isArray(fileExt) && !isEmpty(fileExtExpr)) { | ||
| 2096 | + chk = caption.match(fileExtExpr); | ||
| 2097 | + fileCount += isEmpty(chk) ? 0 : chk.length; | ||
| 2098 | + if (fileCount === 0) { | ||
| 2099 | + msg = self.msgInvalidFileExtension.replace('{name}', caption).replace('{extensions}', | ||
| 2100 | + strExt); | ||
| 2101 | + self.isError = throwError(msg, file, previewId, i); | ||
| 2102 | + return; | ||
| 2103 | + } | ||
| 2104 | + } | ||
| 2105 | + if (!self.showPreview) { | ||
| 2106 | + self.pushStack(file); | ||
| 2107 | + setTimeout(readFile(i + 1), 100); | ||
| 2108 | + self.raise('fileloaded', [file, previewId, i, reader]); | ||
| 2109 | + return; | ||
| 2110 | + } | ||
| 2111 | + if ($preview.length > 0 && FileReader !== undefined) { | ||
| 2112 | + $status.html(msgLoading.replace('{index}', i + 1).replace('{files}', numFiles)); | ||
| 2113 | + $container.addClass('file-thumb-loading'); | ||
| 2114 | + reader.onerror = function (evt) { | ||
| 2115 | + self.errorHandler(evt, caption); | ||
| 2116 | + }; | ||
| 2117 | + reader.onload = function (theFile) { | ||
| 2118 | + self.previewFile(i, file, theFile, previewId, previewData); | ||
| 2119 | + self.initFileActions(); | ||
| 2120 | + }; | ||
| 2121 | + reader.onloadend = function () { | ||
| 2122 | + msg = msgProgress | ||
| 2123 | + .replace('{index}', i + 1).replace('{files}', numFiles) | ||
| 2124 | + .replace('{percent}', 50).replace('{name}', caption); | ||
| 2125 | + setTimeout(function () { | ||
| 2126 | + $status.html(msg); | ||
| 2127 | + self.updateFileDetails(numFiles); | ||
| 2128 | + readFile(i + 1); | ||
| 2129 | + }, 100); | ||
| 2130 | + self.raise('fileloaded', [file, previewId, i, reader]); | ||
| 2131 | + }; | ||
| 2132 | + reader.onprogress = function (data) { | ||
| 2133 | + if (data.lengthComputable) { | ||
| 2134 | + var fact = (data.loaded / data.total) * 100, progress = Math.ceil(fact); | ||
| 2135 | + msg = msgProgress.replace('{index}', i + 1).replace('{files}', numFiles) | ||
| 2136 | + .replace('{percent}', progress).replace('{name}', caption); | ||
| 2137 | + setTimeout(function () { | ||
| 2138 | + $status.html(msg); | ||
| 2139 | + }, 100); | ||
| 2140 | + } | ||
| 2141 | + }; | ||
| 2142 | + isText = isSet('text', settings) ? settings.text : defaultFileTypeSettings.text; | ||
| 2143 | + if (isText(file.type, caption)) { | ||
| 2144 | + reader.readAsText(file, self.textEncoding); | ||
| 2145 | + } else { | ||
| 2146 | + reader.readAsArrayBuffer(file); | ||
| 2147 | + } | ||
| 2148 | + } else { | ||
| 2149 | + self.previewDefault(file, previewId); | ||
| 2150 | + setTimeout(function () { | ||
| 2151 | + readFile(i + 1); | ||
| 2152 | + self.updateFileDetails(numFiles); | ||
| 2153 | + }, 100); | ||
| 2154 | + self.raise('fileloaded', [file, previewId, i, reader]); | ||
| 2155 | + } | ||
| 2156 | + self.pushStack(file); | ||
| 2157 | + }; | ||
| 2158 | + | ||
| 2159 | + readFile(0); | ||
| 2160 | + self.updateFileDetails(numFiles, false); | ||
| 2161 | + }, | ||
| 2162 | + updateFileDetails: function (numFiles) { | ||
| 2163 | + var self = this, $el = self.$element, fileStack = self.getFileStack(), | ||
| 2164 | + name = $el.val() || (fileStack.length && fileStack[0].name) || '', label = self.slug(name), | ||
| 2165 | + n = self.isUploadable ? fileStack.length : numFiles, | ||
| 2166 | + nFiles = previewCache.count(self.id) + n, | ||
| 2167 | + log = n > 1 ? self.getMsgSelected(nFiles) : label; | ||
| 2168 | + if (self.isError) { | ||
| 2169 | + self.$previewContainer.removeClass('file-thumb-loading'); | ||
| 2170 | + self.$previewStatus.html(''); | ||
| 2171 | + self.$captionContainer.find('.kv-caption-icon').hide(); | ||
| 2172 | + } else { | ||
| 2173 | + self.showFileIcon(); | ||
| 2174 | + } | ||
| 2175 | + self.setCaption(log, self.isError); | ||
| 2176 | + self.$container.removeClass('file-input-new file-input-ajax-new'); | ||
| 2177 | + if (arguments.length === 1) { | ||
| 2178 | + self.raise('fileselect', [numFiles, label]); | ||
| 2179 | + } | ||
| 2180 | + if (previewCache.count(self.id)) { | ||
| 2181 | + self.initPreviewDeletes(); | ||
| 2182 | + } | ||
| 2183 | + }, | ||
| 2184 | + validateMinCount: function () { | ||
| 2185 | + var self = this, len = self.isUploadable ? self.getFileStack().length : self.$element.get(0).files.length; | ||
| 2186 | + if (self.validateInitialCount && self.minFileCount > 0 && self.getFileCount(len - 1) < self.minFileCount) { | ||
| 2187 | + self.noFilesError({}); | ||
| 2188 | + return false; | ||
| 2189 | + } | ||
| 2190 | + return true; | ||
| 2191 | + }, | ||
| 2192 | + getFileCount: function (fileCount) { | ||
| 2193 | + var self = this, addCount = 0; | ||
| 2194 | + if (self.validateInitialCount && !self.overwriteInitial) { | ||
| 2195 | + addCount = previewCache.count(self.id); | ||
| 2196 | + fileCount += addCount; | ||
| 2197 | + } | ||
| 2198 | + return fileCount; | ||
| 2199 | + }, | ||
| 2200 | + change: function (e) { | ||
| 2201 | + var self = this, $el = self.$element; | ||
| 2202 | + if (!self.isUploadable && isEmpty($el.val()) && self.fileInputCleared) { // IE 11 fix | ||
| 2203 | + self.fileInputCleared = false; | ||
| 2204 | + return; | ||
| 2205 | + } | ||
| 2206 | + self.fileInputCleared = false; | ||
| 2207 | + var tfiles, msg, total, isDragDrop = arguments.length > 1, | ||
| 2208 | + files = isDragDrop ? e.originalEvent.dataTransfer.files : $el.get(0).files, | ||
| 2209 | + isSingleUpload = isEmpty($el.attr('multiple')), i = 0, f, n, folders = 0, | ||
| 2210 | + ctr = self.filestack.length, isAjaxUpload = self.isUploadable, len, | ||
| 2211 | + flagSingle = (isSingleUpload && ctr > 0), | ||
| 2212 | + throwError = function (mesg, file, previewId, index) { | ||
| 2213 | + var p1 = $.extend(self.getOutData({}, {}, files), {id: previewId, index: index}), | ||
| 2214 | + p2 = {id: previewId, index: index, file: file, files: files}; | ||
| 2215 | + return self.isUploadable ? self.showUploadError(mesg, p1) : self.showError(mesg, p2); | ||
| 2216 | + }; | ||
| 2217 | + self.reader = null; | ||
| 2218 | + self.resetUpload(); | ||
| 2219 | + self.hideFileIcon(); | ||
| 2220 | + if (self.isUploadable) { | ||
| 2221 | + self.$container.find('.file-drop-zone .' + self.dropZoneTitleClass).remove(); | ||
| 2222 | + } | ||
| 2223 | + if (isDragDrop) { | ||
| 2224 | + tfiles = []; | ||
| 2225 | + while (files[i]) { | ||
| 2226 | + f = files[i]; | ||
| 2227 | + if (!f.type && f.size % 4096 === 0) { | ||
| 2228 | + folders++; | ||
| 2229 | + } else { | ||
| 2230 | + tfiles.push(f); | ||
| 2231 | + } | ||
| 2232 | + i++; | ||
| 2233 | + } | ||
| 2234 | + } else { | ||
| 2235 | + if (e.target.files === undefined) { | ||
| 2236 | + tfiles = e.target && e.target.value ? [ | ||
| 2237 | + {name: e.target.value.replace(/^.+\\/, '')} | ||
| 2238 | + ] : []; | ||
| 2239 | + } else { | ||
| 2240 | + tfiles = e.target.files; | ||
| 2241 | + } | ||
| 2242 | + } | ||
| 2243 | + if (isEmpty(tfiles) || tfiles.length === 0) { | ||
| 2244 | + if (!isAjaxUpload) { | ||
| 2245 | + self.clear(); | ||
| 2246 | + } | ||
| 2247 | + self.showFolderError(folders); | ||
| 2248 | + self.raise('fileselectnone'); | ||
| 2249 | + return; | ||
| 2250 | + } | ||
| 2251 | + self.resetErrors(); | ||
| 2252 | + len = tfiles.length; | ||
| 2253 | + total = self.isUploadable ? self.getFileStack().length + len : len; | ||
| 2254 | + total = self.getFileCount(total); | ||
| 2255 | + if (self.maxFileCount > 0 && total > self.maxFileCount) { | ||
| 2256 | + if (!self.autoReplace || len > self.maxFileCount) { | ||
| 2257 | + n = (self.autoReplace && len > self.maxFileCount) ? len : total; | ||
| 2258 | + msg = self.msgFilesTooMany.replace('{m}', self.maxFileCount).replace('{n}', n); | ||
| 2259 | + self.isError = throwError(msg, null, null, null); | ||
| 2260 | + self.$captionContainer.find('.kv-caption-icon').hide(); | ||
| 2261 | + self.setCaption('', true); | ||
| 2262 | + self.$container.removeClass('file-input-new file-input-ajax-new'); | ||
| 2263 | + return; | ||
| 2264 | + } | ||
| 2265 | + if (total > self.maxFileCount) { | ||
| 2266 | + self.resetPreviewThumbs(isAjaxUpload); | ||
| 2267 | + } | ||
| 2268 | + } else { | ||
| 2269 | + if (!isAjaxUpload || flagSingle) { | ||
| 2270 | + self.resetPreviewThumbs(false); | ||
| 2271 | + if (flagSingle) { | ||
| 2272 | + self.clearStack(); | ||
| 2273 | + } | ||
| 2274 | + } else { | ||
| 2275 | + if (isAjaxUpload && ctr === 0 && (!previewCache.count(self.id) || self.overwriteInitial)) { | ||
| 2276 | + self.resetPreviewThumbs(true); | ||
| 2277 | + } | ||
| 2278 | + } | ||
| 2279 | + } | ||
| 2280 | + if (self.isPreviewable) { | ||
| 2281 | + self.readFiles(tfiles); | ||
| 2282 | + } else { | ||
| 2283 | + self.updateFileDetails(1); | ||
| 2284 | + } | ||
| 2285 | + self.showFolderError(folders); | ||
| 2286 | + }, | ||
| 2287 | + getFileName: function (file) { | ||
| 2288 | + return file && file.name ? this.slug(file.name) : undefined; | ||
| 2289 | + }, | ||
| 2290 | + getFileNames: function (skipNull) { | ||
| 2291 | + var self = this; | ||
| 2292 | + return self.filenames.filter(function (n) { | ||
| 2293 | + return (skipNull ? n !== undefined : n !== undefined && n !== null); | ||
| 2294 | + }); | ||
| 2295 | + }, | ||
| 2296 | + getFileStack: function (skipNull) { | ||
| 2297 | + var self = this; | ||
| 2298 | + return self.filestack.filter(function (n) { | ||
| 2299 | + return (skipNull ? n !== undefined : n !== undefined && n !== null); | ||
| 2300 | + }); | ||
| 2301 | + }, | ||
| 2302 | + clearStack: function () { | ||
| 2303 | + var self = this; | ||
| 2304 | + self.filestack = []; | ||
| 2305 | + self.filenames = []; | ||
| 2306 | + }, | ||
| 2307 | + updateStack: function (i, file) { | ||
| 2308 | + var self = this; | ||
| 2309 | + self.filestack[i] = file; | ||
| 2310 | + self.filenames[i] = self.getFileName(file); | ||
| 2311 | + }, | ||
| 2312 | + pushStack: function (file) { | ||
| 2313 | + var self = this; | ||
| 2314 | + self.filestack.push(file); | ||
| 2315 | + self.filenames.push(self.getFileName(file)); | ||
| 2316 | + }, | ||
| 2317 | + checkDimensions: function (i, chk, $img, $thumb, fname, type, params) { | ||
| 2318 | + var self = this, msg, dim, tag = chk === 'Small' ? 'min' : 'max', | ||
| 2319 | + limit = self[tag + 'Image' + type], $imgEl, isValid; | ||
| 2320 | + if (isEmpty(limit) || !$img.length) { | ||
| 2321 | + return; | ||
| 2322 | + } | ||
| 2323 | + $imgEl = $img[0]; | ||
| 2324 | + dim = (type === 'Width') ? $imgEl.naturalWidth || $imgEl.width : $imgEl.naturalHeight || $imgEl.height; | ||
| 2325 | + isValid = chk === 'Small' ? dim >= limit : dim <= limit; | ||
| 2326 | + if (isValid) { | ||
| 2327 | + return; | ||
| 2328 | + } | ||
| 2329 | + msg = self['msgImage' + type + chk].replace('{name}', fname).replace('{size}', limit); | ||
| 2330 | + self.showUploadError(msg, params); | ||
| 2331 | + self.setThumbStatus($thumb, 'Error'); | ||
| 2332 | + self.updateStack(i, null); | ||
| 2333 | + }, | ||
| 2334 | + validateImage: function (i, previewId, fname, ftype) { | ||
| 2335 | + var self = this, $preview = self.$preview, params, w1, w2, | ||
| 2336 | + $thumb = $preview.find("#" + previewId), $img = $thumb.find('img'); | ||
| 2337 | + fname = fname || 'Untitled'; | ||
| 2338 | + if (!$img.length) { | ||
| 2339 | + return; | ||
| 2340 | + } | ||
| 2341 | + handler($img, 'load', function () { | ||
| 2342 | + w1 = $thumb.width(); | ||
| 2343 | + w2 = $preview.width(); | ||
| 2344 | + if (w1 > w2) { | ||
| 2345 | + $img.css('width', '100%'); | ||
| 2346 | + $thumb.css('width', '97%'); | ||
| 2347 | + } | ||
| 2348 | + params = {ind: i, id: previewId}; | ||
| 2349 | + self.checkDimensions(i, 'Small', $img, $thumb, fname, 'Width', params); | ||
| 2350 | + self.checkDimensions(i, 'Small', $img, $thumb, fname, 'Height', params); | ||
| 2351 | + if (!self.resizeImage) { | ||
| 2352 | + self.checkDimensions(i, 'Large', $img, $thumb, fname, 'Width', params); | ||
| 2353 | + self.checkDimensions(i, 'Large', $img, $thumb, fname, 'Height', params); | ||
| 2354 | + } | ||
| 2355 | + self.raise('fileimageloaded', [previewId]); | ||
| 2356 | + self.loadedImages.push({ind: i, img: $img, thumb: $thumb, pid: previewId, typ: ftype}); | ||
| 2357 | + self.validateAllImages(); | ||
| 2358 | + objUrl.revokeObjectURL($img.attr('src')); | ||
| 2359 | + }); | ||
| 2360 | + }, | ||
| 2361 | + validateAllImages: function () { | ||
| 2362 | + var self = this, i, config, $img, $thumb, pid, ind, params = {}, errFunc; | ||
| 2363 | + if (self.loadedImages.length !== self.totalImagesCount) { | ||
| 2364 | + return; | ||
| 2365 | + } | ||
| 2366 | + self.raise('fileimagesloaded'); | ||
| 2367 | + if (!self.resizeImage) { | ||
| 2368 | + return; | ||
| 2369 | + } | ||
| 2370 | + errFunc = self.isUploadable ? self.showUploadError : self.showError; | ||
| 2371 | + for (i = 0; i < self.loadedImages.length; i++) { | ||
| 2372 | + config = self.loadedImages[i]; | ||
| 2373 | + $img = config.img; | ||
| 2374 | + $thumb = config.thumb; | ||
| 2375 | + pid = config.pid; | ||
| 2376 | + ind = config.ind; | ||
| 2377 | + params = {id: pid, 'index': ind}; | ||
| 2378 | + if (!self.getResizedImage($img[0], config.typ, pid, ind)) { | ||
| 2379 | + errFunc(self.msgImageResizeError, params, 'fileimageresizeerror'); | ||
| 2380 | + self.setThumbStatus($thumb, 'Error'); | ||
| 2381 | + self.updateStack(ind, undefined); | ||
| 2382 | + } | ||
| 2383 | + } | ||
| 2384 | + self.raise('fileimagesresized'); | ||
| 2385 | + }, | ||
| 2386 | + getResizedImage: function (image, type, pid, ind) { | ||
| 2387 | + var self = this, width = image.naturalWidth, height = image.naturalHeight, ratio = 1, | ||
| 2388 | + maxWidth = self.maxImageWidth || width, maxHeight = self.maxImageHeight || height, | ||
| 2389 | + isValidImage = (width && height), chkWidth, chkHeight, | ||
| 2390 | + canvas = self.imageCanvas, context = self.imageCanvasContext; | ||
| 2391 | + if (!isValidImage) { | ||
| 2392 | + return false; | ||
| 2393 | + } | ||
| 2394 | + if (width === maxWidth && height === maxHeight) { | ||
| 2395 | + return true; | ||
| 2396 | + } | ||
| 2397 | + type = type || self.resizeDefaultImageType; | ||
| 2398 | + chkWidth = width > maxWidth; | ||
| 2399 | + chkHeight = height > maxHeight; | ||
| 2400 | + if (self.resizePreference === 'width') { | ||
| 2401 | + ratio = chkWidth ? maxWidth / width : (chkHeight ? maxHeight / height : 1); | ||
| 2402 | + } else { | ||
| 2403 | + ratio = chkHeight ? maxHeight / height : (chkWidth ? maxWidth / width : 1); | ||
| 2404 | + } | ||
| 2405 | + self.resetCanvas(); | ||
| 2406 | + width *= ratio; | ||
| 2407 | + height *= ratio; | ||
| 2408 | + canvas.width = width; | ||
| 2409 | + canvas.height = height; | ||
| 2410 | + try { | ||
| 2411 | + context.drawImage(image, 0, 0, width, height); | ||
| 2412 | + canvas.toBlob(function (blob) { | ||
| 2413 | + self.raise('fileimageresized', [pid, ind]); | ||
| 2414 | + self.filestack[ind] = blob; | ||
| 2415 | + }, type, self.resizeQuality); | ||
| 2416 | + return true; | ||
| 2417 | + } | ||
| 2418 | + catch (err) { | ||
| 2419 | + return false; | ||
| 2420 | + } | ||
| 2421 | + }, | ||
| 2422 | + initCaption: function () { | ||
| 2423 | + var self = this, cap = self.initialCaption || ''; | ||
| 2424 | + if (self.overwriteInitial || isEmpty(cap)) { | ||
| 2425 | + self.$caption.html(''); | ||
| 2426 | + return false; | ||
| 2427 | + } | ||
| 2428 | + self.setCaption(cap); | ||
| 2429 | + return true; | ||
| 2430 | + }, | ||
| 2431 | + setCaption: function (content, isError) { | ||
| 2432 | + var self = this, title, out; | ||
| 2433 | + if (isError) { | ||
| 2434 | + title = $('<div>' + self.msgValidationError + '</div>').text(); | ||
| 2435 | + out = '<span class="' + self.msgValidationErrorClass + '">' + | ||
| 2436 | + self.msgValidationErrorIcon + title + '</span>'; | ||
| 2437 | + } else { | ||
| 2438 | + if (isEmpty(content) || self.$caption.length === 0) { | ||
| 2439 | + return; | ||
| 2440 | + } | ||
| 2441 | + title = $('<div>' + content + '</div>').text(); | ||
| 2442 | + out = self.getLayoutTemplate('icon') + title; | ||
| 2443 | + } | ||
| 2444 | + self.$caption.html(out); | ||
| 2445 | + self.$caption.attr('title', title); | ||
| 2446 | + self.$captionContainer.find('.file-caption-ellipsis').attr('title', title); | ||
| 2447 | + }, | ||
| 2448 | + initBrowse: function ($container) { | ||
| 2449 | + var self = this; | ||
| 2450 | + self.$btnFile = $container.find('.btn-file'); | ||
| 2451 | + self.$btnFile.append(self.$element); | ||
| 2452 | + }, | ||
| 2453 | + createContainer: function () { | ||
| 2454 | + var self = this, | ||
| 2455 | + $container = $(document.createElement("div")) | ||
| 2456 | + .attr({"class": 'file-input file-input-new'}) | ||
| 2457 | + .html(self.renderMain()); | ||
| 2458 | + self.$element.before($container); | ||
| 2459 | + self.initBrowse($container); | ||
| 2460 | + return $container; | ||
| 2461 | + }, | ||
| 2462 | + refreshContainer: function () { | ||
| 2463 | + var self = this, $container = self.$container; | ||
| 2464 | + $container.before(self.$element); | ||
| 2465 | + $container.html(self.renderMain()); | ||
| 2466 | + self.initBrowse($container); | ||
| 2467 | + }, | ||
| 2468 | + renderMain: function () { | ||
| 2469 | + var self = this, dropCss = (self.isUploadable && self.dropZoneEnabled) ? ' file-drop-zone' : 'file-drop-disabled', | ||
| 2470 | + close = !self.showClose ? '' : self.getLayoutTemplate('close'), | ||
| 2471 | + preview = !self.showPreview ? '' : self.getLayoutTemplate('preview') | ||
| 2472 | + .replace(/\{class}/g, self.previewClass) | ||
| 2473 | + .replace(/\{dropClass}/g, dropCss), | ||
| 2474 | + css = self.isDisabled ? self.captionClass + ' file-caption-disabled' : self.captionClass, | ||
| 2475 | + caption = self.captionTemplate.replace(/\{class}/g, css + ' kv-fileinput-caption'); | ||
| 2476 | + return self.mainTemplate.replace(/\{class}/g, self.mainClass) | ||
| 2477 | + .replace(/\{preview}/g, preview) | ||
| 2478 | + .replace(/\{close}/g, close) | ||
| 2479 | + .replace(/\{caption}/g, caption) | ||
| 2480 | + .replace(/\{upload}/g, self.renderButton('upload')) | ||
| 2481 | + .replace(/\{remove}/g, self.renderButton('remove')) | ||
| 2482 | + .replace(/\{cancel}/g, self.renderButton('cancel')) | ||
| 2483 | + .replace(/\{browse}/g, self.renderButton('browse')); | ||
| 2484 | + }, | ||
| 2485 | + renderButton: function (type) { | ||
| 2486 | + var self = this, tmplt = self.getLayoutTemplate('btnDefault'), css = self[type + 'Class'], | ||
| 2487 | + title = self[type + 'Title'], icon = self[type + 'Icon'], label = self[type + 'Label'], | ||
| 2488 | + status = self.isDisabled ? ' disabled' : '', btnType = 'button'; | ||
| 2489 | + switch (type) { | ||
| 2490 | + case 'remove': | ||
| 2491 | + if (!self.showRemove) { | ||
| 2492 | + return ''; | ||
| 2493 | + } | ||
| 2494 | + break; | ||
| 2495 | + case 'cancel': | ||
| 2496 | + if (!self.showCancel) { | ||
| 2497 | + return ''; | ||
| 2498 | + } | ||
| 2499 | + css += ' hide'; | ||
| 2500 | + break; | ||
| 2501 | + case 'upload': | ||
| 2502 | + if (!self.showUpload) { | ||
| 2503 | + return ''; | ||
| 2504 | + } | ||
| 2505 | + if (self.isUploadable && !self.isDisabled) { | ||
| 2506 | + tmplt = self.getLayoutTemplate('btnLink').replace('{href}', self.uploadUrl); | ||
| 2507 | + } else { | ||
| 2508 | + btnType = 'submit'; | ||
| 2509 | + } | ||
| 2510 | + break; | ||
| 2511 | + case 'browse': | ||
| 2512 | + tmplt = self.getLayoutTemplate('btnBrowse'); | ||
| 2513 | + break; | ||
| 2514 | + default: | ||
| 2515 | + return ''; | ||
| 2516 | + } | ||
| 2517 | + css += type === 'browse' ? ' btn-file' : ' fileinput-' + type + ' fileinput-' + type + '-button'; | ||
| 2518 | + if (!isEmpty(label)) { | ||
| 2519 | + label = ' <span class="' + self.buttonLabelClass + '">' + label + '</span>'; | ||
| 2520 | + } | ||
| 2521 | + return tmplt.replace('{type}', btnType) | ||
| 2522 | + .replace('{css}', css) | ||
| 2523 | + .replace('{title}', title) | ||
| 2524 | + .replace('{status}', status) | ||
| 2525 | + .replace('{icon}', icon) | ||
| 2526 | + .replace('{label}', label); | ||
| 2527 | + } | ||
| 2528 | + }; | ||
| 2529 | + | ||
| 2530 | + $.fn.fileinput = function (option) { | ||
| 2531 | + if (!hasFileAPISupport() && !isIE(9)) { | ||
| 2532 | + return; | ||
| 2533 | + } | ||
| 2534 | + var args = Array.apply(null, arguments), retvals = []; | ||
| 2535 | + args.shift(); | ||
| 2536 | + this.each(function () { | ||
| 2537 | + var self = $(this), data = self.data('fileinput'), options = typeof option === 'object' && option, | ||
| 2538 | + lang = options.language || self.data('language') || 'en', config = $.fn.fileinput.defaults; | ||
| 2539 | + | ||
| 2540 | + if (!data) { | ||
| 2541 | + if (lang !== 'en' && !isEmpty($.fn.fileinputLocales[lang])) { | ||
| 2542 | + $.extend(config, $.fn.fileinputLocales[lang]); | ||
| 2543 | + } | ||
| 2544 | + data = new FileInput(this, $.extend(config, options, self.data())); | ||
| 2545 | + self.data('fileinput', data); | ||
| 2546 | + } | ||
| 2547 | + | ||
| 2548 | + if (typeof option === 'string') { | ||
| 2549 | + retvals.push(data[option].apply(data, args)); | ||
| 2550 | + } | ||
| 2551 | + }); | ||
| 2552 | + switch (retvals.length) { | ||
| 2553 | + case 0: | ||
| 2554 | + return this; | ||
| 2555 | + case 1: | ||
| 2556 | + return retvals[0]; | ||
| 2557 | + default: | ||
| 2558 | + return retvals; | ||
| 2559 | + } | ||
| 2560 | + }; | ||
| 2561 | + | ||
| 2562 | + $.fn.fileinput.defaults = { | ||
| 2563 | + language: 'en', | ||
| 2564 | + showCaption: true, | ||
| 2565 | + showPreview: true, | ||
| 2566 | + showRemove: true, | ||
| 2567 | + showUpload: true, | ||
| 2568 | + showCancel: true, | ||
| 2569 | + showClose: true, | ||
| 2570 | + showUploadedThumbs: true, | ||
| 2571 | + autoReplace: false, | ||
| 2572 | + mainClass: '', | ||
| 2573 | + previewClass: '', | ||
| 2574 | + captionClass: '', | ||
| 2575 | + mainTemplate: null, | ||
| 2576 | + initialCaption: '', | ||
| 2577 | + initialPreview: [], | ||
| 2578 | + initialPreviewDelimiter: '*$$*', | ||
| 2579 | + initialPreviewConfig: [], | ||
| 2580 | + initialPreviewThumbTags: [], | ||
| 2581 | + previewThumbTags: {}, | ||
| 2582 | + initialPreviewShowDelete: true, | ||
| 2583 | + deleteUrl: '', | ||
| 2584 | + deleteExtraData: {}, | ||
| 2585 | + overwriteInitial: true, | ||
| 2586 | + layoutTemplates: defaultLayoutTemplates, | ||
| 2587 | + previewTemplates: defaultPreviewTemplates, | ||
| 2588 | + allowedPreviewTypes: defaultPreviewTypes, | ||
| 2589 | + allowedPreviewMimeTypes: null, | ||
| 2590 | + allowedFileTypes: null, | ||
| 2591 | + allowedFileExtensions: null, | ||
| 2592 | + defaultPreviewContent: null, | ||
| 2593 | + customLayoutTags: {}, | ||
| 2594 | + customPreviewTags: {}, | ||
| 2595 | + previewSettings: defaultPreviewSettings, | ||
| 2596 | + fileTypeSettings: defaultFileTypeSettings, | ||
| 2597 | + previewFileIcon: '<i class="glyphicon glyphicon-file"></i>', | ||
| 2598 | + previewFileIconClass: 'file-icon-4x', | ||
| 2599 | + previewFileIconSettings: {}, | ||
| 2600 | + previewFileExtSettings: {}, | ||
| 2601 | + buttonLabelClass: 'hidden-xs', | ||
| 2602 | + browseIcon: '<i class="glyphicon glyphicon-folder-open"></i>', | ||
| 2603 | + browseClass: 'btn btn-primary', | ||
| 2604 | + removeIcon: '<i class="glyphicon glyphicon-trash"></i>', | ||
| 2605 | + removeClass: 'btn btn-default', | ||
| 2606 | + cancelIcon: '<i class="glyphicon glyphicon-ban-circle"></i>', | ||
| 2607 | + cancelClass: 'btn btn-default', | ||
| 2608 | + uploadIcon: '<i class="glyphicon glyphicon-upload"></i>', | ||
| 2609 | + uploadClass: 'btn btn-default', | ||
| 2610 | + uploadUrl: null, | ||
| 2611 | + uploadAsync: true, | ||
| 2612 | + uploadExtraData: {}, | ||
| 2613 | + minImageWidth: null, | ||
| 2614 | + minImageHeight: null, | ||
| 2615 | + maxImageWidth: null, | ||
| 2616 | + maxImageHeight: null, | ||
| 2617 | + resizeImage: false, | ||
| 2618 | + resizePreference: 'width', | ||
| 2619 | + resizeQuality: 0.92, | ||
| 2620 | + resizeDefaultImageType: 'image/jpeg', | ||
| 2621 | + maxFileSize: 0, | ||
| 2622 | + minFileCount: 0, | ||
| 2623 | + maxFileCount: 0, | ||
| 2624 | + validateInitialCount: false, | ||
| 2625 | + msgValidationErrorClass: 'text-danger', | ||
| 2626 | + msgValidationErrorIcon: '<i class="glyphicon glyphicon-exclamation-sign"></i> ', | ||
| 2627 | + msgErrorClass: 'file-error-message', | ||
| 2628 | + progressThumbClass: "progress-bar progress-bar-success progress-bar-striped active", | ||
| 2629 | + progressClass: "progress-bar progress-bar-success progress-bar-striped active", | ||
| 2630 | + progressCompleteClass: "progress-bar progress-bar-success", | ||
| 2631 | + previewFileType: 'image', | ||
| 2632 | + zoomIndicator: '<i class="glyphicon glyphicon-zoom-in"></i>', | ||
| 2633 | + elCaptionContainer: null, | ||
| 2634 | + elCaptionText: null, | ||
| 2635 | + elPreviewContainer: null, | ||
| 2636 | + elPreviewImage: null, | ||
| 2637 | + elPreviewStatus: null, | ||
| 2638 | + elErrorContainer: null, | ||
| 2639 | + errorCloseButton: '<span class="close kv-error-close">×</span>', | ||
| 2640 | + slugCallback: null, | ||
| 2641 | + dropZoneEnabled: true, | ||
| 2642 | + dropZoneTitleClass: 'file-drop-zone-title', | ||
| 2643 | + fileActionSettings: {}, | ||
| 2644 | + otherActionButtons: '', | ||
| 2645 | + textEncoding: 'UTF-8', | ||
| 2646 | + ajaxSettings: {}, | ||
| 2647 | + ajaxDeleteSettings: {}, | ||
| 2648 | + showAjaxErrorDetails: true | ||
| 2649 | + }; | ||
| 2650 | + | ||
| 2651 | + $.fn.fileinputLocales.en = { | ||
| 2652 | + fileSingle: 'file', | ||
| 2653 | + filePlural: 'files', | ||
| 2654 | + browseLabel: 'Browse …', | ||
| 2655 | + removeLabel: 'Remove', | ||
| 2656 | + removeTitle: 'Clear selected files', | ||
| 2657 | + cancelLabel: 'Cancel', | ||
| 2658 | + cancelTitle: 'Abort ongoing upload', | ||
| 2659 | + uploadLabel: 'Upload', | ||
| 2660 | + uploadTitle: 'Upload selected files', | ||
| 2661 | + msgZoomTitle: 'View details', | ||
| 2662 | + msgZoomModalHeading: 'Detailed Preview', | ||
| 2663 | + msgSizeTooLarge: 'File "{name}" (<b>{size} KB</b>) exceeds maximum allowed upload size of <b>{maxSize} KB</b>.', | ||
| 2664 | + msgFilesTooLess: 'You must select at least <b>{n}</b> {files} to upload.', | ||
| 2665 | + msgFilesTooMany: 'Number of files selected for upload <b>({n})</b> exceeds maximum allowed limit of <b>{m}</b>.', | ||
| 2666 | + msgFileNotFound: 'File "{name}" not found!', | ||
| 2667 | + msgFileSecured: 'Security restrictions prevent reading the file "{name}".', | ||
| 2668 | + msgFileNotReadable: 'File "{name}" is not readable.', | ||
| 2669 | + msgFilePreviewAborted: 'File preview aborted for "{name}".', | ||
| 2670 | + msgFilePreviewError: 'An error occurred while reading the file "{name}".', | ||
| 2671 | + msgInvalidFileType: 'Invalid type for file "{name}". Only "{types}" files are supported.', | ||
| 2672 | + msgInvalidFileExtension: 'Invalid extension for file "{name}". Only "{extensions}" files are supported.', | ||
| 2673 | + msgUploadAborted: 'The file upload was aborted', | ||
| 2674 | + msgValidationError: 'File Upload Error', | ||
| 2675 | + msgLoading: 'Loading file {index} of {files} …', | ||
| 2676 | + msgProgress: 'Loading file {index} of {files} - {name} - {percent}% completed.', | ||
| 2677 | + msgSelected: '{n} {files} selected', | ||
| 2678 | + msgFoldersNotAllowed: 'Drag & drop files only! {n} folder(s) dropped were skipped.', | ||
| 2679 | + msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.', | ||
| 2680 | + msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.', | ||
| 2681 | + msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.', | ||
| 2682 | + msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.', | ||
| 2683 | + msgImageResizeError: 'Could not get the image dimensions to resize.', | ||
| 2684 | + msgImageResizeException: 'Error while resizing the image.<pre>{errors}</pre>', | ||
| 2685 | + dropZoneTitle: 'Drag & drop files here …' | ||
| 2686 | + }; | ||
| 2687 | + | ||
| 2688 | + $.extend($.fn.fileinput.defaults, $.fn.fileinputLocales.en); | ||
| 2689 | + | ||
| 2690 | + $.fn.fileinput.Constructor = FileInput; | ||
| 2691 | + | ||
| 2692 | + /** | ||
| 2693 | + * Convert automatically file inputs with class 'file' | ||
| 2694 | + * into a bootstrap fileinput control. | ||
| 2695 | + */ | ||
| 2696 | + $(document).ready(function () { | ||
| 2697 | + var $input = $('input.file[type=file]'); | ||
| 2698 | + if ($input.length) { | ||
| 2699 | + $input.fileinput(); | ||
| 2700 | + } | ||
| 2701 | + }); | ||
| 2702 | +})); | ||
| 0 | \ No newline at end of file | 2703 | \ No newline at end of file |
src/main/webapp/static/assets/plugins/fileinput/fileinput.min.css
0 → 100644
| 1 | +/*! | ||
| 2 | + * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2015 | ||
| 3 | + * @package bootstrap-fileinput | ||
| 4 | + * @version 4.2.9 | ||
| 5 | + * | ||
| 6 | + * File input styling for Bootstrap 3.0 | ||
| 7 | + * Built for Yii Framework 2.0 | ||
| 8 | + * Author: Kartik Visweswaran | ||
| 9 | + * Year: 2015 | ||
| 10 | + * For more Yii related demos visit http://demos.krajee.com | ||
| 11 | + */.file-preview-frame,.file-preview-image,.file-preview-other{height:160px;vertical-align:middle}.file-loading{top:0;right:0;width:25px;height:25px;font-size:999px;text-align:right;color:#fff;background:url(../img/loading.gif)top left no-repeat;border:none}.file-object{margin:0 0 -5px;padding:0}.btn-file{position:relative;overflow:hidden}.btn-file input[type=file]{position:absolute;top:0;right:0;min-width:100%;min-height:100%;text-align:right;opacity:0;background:0 0;cursor:inherit;display:block}.file-caption-name{display:inline-block;overflow:hidden;height:20px;word-break:break-all}.input-group-lg .file-caption-name{height:25px}.file-preview-detail-modal{text-align:left}.file-error-message{color:#a94442;background-color:#f2dede;margin:5px;border:1px solid #ebccd1;border-radius:4px;padding:15px}.file-error-message pre,.file-error-message ul{margin:0;text-align:left}.file-error-message pre{margin:5px 0}.file-caption-disabled{background-color:#EEE;cursor:not-allowed;opacity:1}.file-preview{border-radius:5px;border:1px solid #ddd;padding:5px;width:100%;margin-bottom:5px}.file-preview-frame{display:table;margin:8px;border:1px solid #ddd;box-shadow:1px 1px 5px 0 #a2958a;padding:6px;float:left;text-align:center}.file-preview-frame:not(.file-preview-error):hover{box-shadow:3px 3px 5px 0 #333}.file-preview-text{text-align:left;width:160px;margin-bottom:2px;color:#428bca;background:#fff;overflow-x:hidden}.file-preview-other{display:table-cell;text-align:center;width:160px;border:2px solid #999;border-radius:30px}.file-preview-other:hover{opacity:.8}.file-actions,.file-other-error{text-align:left}.file-icon-lg{font-size:1.2em}.file-icon-2x{font-size:2.4em}.file-icon-4x{font-size:4.8em}.file-input-ajax-new .fileinput-remove-button,.file-input-ajax-new .fileinput-upload-button,.file-input-new .close,.file-input-new .file-preview,.file-input-new .fileinput-remove-button,.file-input-new .fileinput-upload-button,.file-input-new .glyphicon-file{display:none}.file-thumb-loading{background:url(../img/loading.gif)center center no-repeat content-box!important}.file-actions{margin-top:15px}.file-footer-buttons{float:right}.file-upload-indicator{padding-top:2px;cursor:default;opacity:.8;width:60%}.file-upload-indicator:hover{font-weight:700;opacity:1}.file-footer-caption{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:160px;text-align:center;padding-top:4px;font-size:11px;color:#777;margin:5px auto 10px}.file-preview-error{opacity:.65;box-shadow:none}.file-preview-frame:not(.file-preview-error) .file-footer-caption:hover{color:#000}.file-drop-zone{border:1px dashed #aaa;border-radius:4px;height:100%;text-align:center;vertical-align:middle;margin:12px 15px 12px 12px;padding:5px}.file-drop-zone-title{color:#aaa;font-size:40px;padding:85px 10px}.file-highlighted{border:2px dashed #999!important;background-color:#f0f0f0}.file-uploading{background:url(../img/loading-sm.gif)center bottom 10px no-repeat;opacity:.65}.file-thumb-progress .progress,.file-thumb-progress .progress-bar{height:10px;font-size:9px;line-height:10px}.file-thumbnail-footer{position:relative}.file-thumb-progress{position:absolute;top:22px;left:0;right:0}.btn-file ::-ms-browse{width:100%;height:100%} | ||
| 0 | \ No newline at end of file | 12 | \ No newline at end of file |
src/main/webapp/static/assets/plugins/fileinput/fileinput.min.js
0 → 100644
| 1 | +/*! | ||
| 2 | + * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2015 | ||
| 3 | + * @version 4.2.9 | ||
| 4 | + * | ||
| 5 | + * File input styled for Bootstrap 3.0 that utilizes HTML5 File Input's advanced | ||
| 6 | + * features including the FileReader API. | ||
| 7 | + * | ||
| 8 | + * The plugin drastically enhances the HTML file input to preview multiple files on the client before | ||
| 9 | + * upload. In addition it provides the ability to preview content of images, text, videos, audio, html, | ||
| 10 | + * flash and other objects. It also offers the ability to upload and delete files using AJAX, and add | ||
| 11 | + * files in batches (i.e. preview, append, or remove before upload). | ||
| 12 | + * | ||
| 13 | + * Author: Kartik Visweswaran | ||
| 14 | + * Copyright: 2015, Kartik Visweswaran, Krajee.com | ||
| 15 | + * For more JQuery plugins visit http://plugins.krajee.com | ||
| 16 | + * For more Yii related demos visit http://demos.krajee.com | ||
| 17 | + */!function(e){"use strict";"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery")):e(window.jQuery)}(function(e){"use strict";e.fn.fileinputLocales={};var i,t,a,r,n,l,o,s,d,c,p,u,f,v,g,m,h,w,b,C,x,y,T,F,I,E,k,S,$,P,D,U,A,j,L,z,O,R,M,B,N,Z,H,W,q,_,V,K,X,J,Q,Y;i=function(e){if("Microsoft Internet Explorer"!==navigator.appName)return!1;if(10===e)return new RegExp("msie\\s"+e,"i").test(navigator.userAgent);var i,t=document.createElement("div");return t.innerHTML="<!--[if IE "+e+"]> <i></i> <![endif]-->",i=t.getElementsByTagName("i").length,document.body.appendChild(t),t.parentNode.removeChild(t),i},t=function(){return new RegExp("Edge/[0-9]+","i").test(navigator.userAgent)},a=function(e,i,t,a){var r=a?i:i+".fileinput";e.off(r).on(r,t)},r={data:{},init:function(e){var i=e.initialPreview,t=e.id;i.length>0&&!q(i)&&(i=i.split(e.initialPreviewDelimiter)),r.data[t]={content:i,config:e.initialPreviewConfig,tags:e.initialPreviewThumbTags,delimiter:e.initialPreviewDelimiter,template:e.previewGenericTemplate,msg:function(i){return e.getMsgSelected(i)},initId:e.previewInitId,footer:e.getLayoutTemplate("footer").replace(/\{progress}/g,e.renderThumbProgress()),isDelete:e.initialPreviewShowDelete,caption:e.initialCaption,actions:function(i,t,a,r,n){return e.renderFileActions(i,t,a,r,n)}}},fetch:function(e){return r.data[e].content.filter(function(e){return null!==e})},count:function(e,i){return r.data[e]&&r.data[e].content?i?r.data[e].content.length:r.fetch(e).length:0},get:function(i,t,a){var n,l,o="init_"+t,s=r.data[i],d=s.config[t],c=s.initId+"-"+o,p=" file-preview-initial";return a=void 0===a?!0:a,null===s.content[t]?"":(W(d)||W(d.frameClass)||(p+=" "+d.frameClass),n=s.template.replace(/\{previewId}/g,c).replace(/\{frameClass}/g,p).replace(/\{fileindex}/g,o).replace(/\{content}/g,s.content[t]).replace(/\{footer}/g,r.footer(i,t,a)),s.tags.length&&s.tags[t]&&(n=J(n,s.tags[t])),W(d)||W(d.frameAttr)||(l=e(document.createElement("div")).html(n),l.find(".file-preview-initial").attr(d.frameAttr),n=l.html(),l.remove()),n)},add:function(i,t,a,n,l){var o,s=e.extend(!0,{},r.data[i]);return q(t)||(t=t.split(s.delimiter)),l?(o=s.content.push(t)-1,s.config[o]=a,s.tags[o]=n):(o=t.length,s.content=t,s.config=a,s.tags=n),r.data[i]=s,o},set:function(i,t,a,n,l){var o,s,d=e.extend(!0,{},r.data[i]);if(t&&t.length&&(q(t)||(t=t.split(d.delimiter)),s=t.filter(function(e){return null!==e}),s.length)){if(void 0===d.content&&(d.content=[]),void 0===d.config&&(d.config=[]),void 0===d.tags&&(d.tags=[]),l){for(o=0;o<t.length;o++)t[o]&&d.content.push(t[o]);for(o=0;o<a.length;o++)a[o]&&d.config.push(a[o]);for(o=0;o<n.length;o++)n[o]&&d.tags.push(n[o])}else d.content=t,d.config=a,d.tags=n;r.data[i]=d}},unset:function(e,i){var t=r.count(e);if(t){if(1===t)return r.data[e].content=[],void(r.data[e].config=[]);r.data[e].content[i]=null,r.data[e].config[i]=null}},out:function(e){var i,t="",a=r.data[e],n=r.count(e,!0);if(0===n)return{content:"",caption:""};for(var l=0;n>l;l++)t+=r.get(e,l);return i=a.msg(r.count(e)),{content:t,caption:i}},footer:function(e,i,t){var a=r.data[e];if(t=void 0===t?!0:t,0===a.config.length||W(a.config[i]))return"";var n=a.config[i],l=_("caption",n)?n.caption:"",o=_("width",n)?n.width:"auto",s=_("url",n)?n.url:!1,d=_("key",n)?n.key:null,c=s===!1&&t,p=a.isDelete?a.actions(!1,!0,c,s,d):"",u=a.footer.replace(/\{actions}/g,p);return u.replace(/\{caption}/g,l).replace(/\{width}/g,o).replace(/\{indicator}/g,"").replace(/\{indicatorTitle}/g,"")}},n=function(e,i){return i=i||0,"number"==typeof e?e:("string"==typeof e&&(e=parseFloat(e)),isNaN(e)?i:e)},l=function(){return window.File&&window.FileReader},o=function(){var e=document.createElement("div");return!i(9)&&!t()&&(void 0!==e.draggable||void 0!==e.ondragstart&&void 0!==e.ondrop)},s=function(){return l()&&window.FormData},d=function(e,i){e.removeClass(i).addClass(i)},c='style="width:{width};height:{height};"',p=' <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',u='<div class="file-preview-other">\n <span class="{previewFileIconClass}">{previewFileIcon}</span>\n</div>',f={removeIcon:'<i class="glyphicon glyphicon-trash text-danger"></i>',removeClass:"btn btn-xs btn-default",removeTitle:"Remove file",uploadIcon:'<i class="glyphicon glyphicon-upload text-info"></i>',uploadClass:"btn btn-xs btn-default",uploadTitle:"Upload file",indicatorNew:'<i class="glyphicon glyphicon-hand-down text-warning"></i>',indicatorSuccess:'<i class="glyphicon glyphicon-ok-sign text-success"></i>',indicatorError:'<i class="glyphicon glyphicon-exclamation-sign text-danger"></i>',indicatorLoading:'<i class="glyphicon glyphicon-hand-up text-muted"></i>',indicatorNewTitle:"Not uploaded yet",indicatorSuccessTitle:"Uploaded",indicatorErrorTitle:"Upload Error",indicatorLoadingTitle:"Uploading ..."},v='{preview}\n<div class="kv-upload-progress hide"></div>\n<div class="input-group {class}">\n {caption}\n <div class="input-group-btn">\n {remove}\n {cancel}\n {upload}\n {browse}\n </div>\n</div>',g='{preview}\n<div class="kv-upload-progress hide"></div>\n{remove}\n{cancel}\n{upload}\n{browse}\n',m='<div class="file-preview {class}">\n {close} <div class="{dropClass}">\n <div class="file-preview-thumbnails">\n </div>\n <div class="clearfix"></div> <div class="file-preview-status text-center text-success"></div>\n <div class="kv-fileinput-error"></div>\n </div>\n</div>',w='<div class="close fileinput-remove">×</div>\n',h='<span class="glyphicon glyphicon-file kv-caption-icon"></span>',b='<div tabindex="500" class="form-control file-caption {class}">\n <div class="file-caption-name"></div>\n</div>\n',C='<button type="{type}" tabindex="500" title="{title}" class="{css}" {status}>{icon}{label}</button>',x='<a href="{href}" tabindex="500" title="{title}" class="{css}" {status}>{icon}{label}</a>',y='<div tabindex="500" class="{css}" {status}>{icon}{label}</div>',T='<div id="{id}" class="file-preview-detail-modal modal fade" tabindex="-1">\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">×</button>\n <h3 class="modal-title">{heading} <small>{title}</small></h3>\n </div>\n <div class="modal-body">\n <pre>{body}</pre>\n </div>\n </div>\n </div>\n</div>',F='<div class="progress">\n <div class="{class}" role="progressbar" aria-valuenow="{percent}" aria-valuemin="0" aria-valuemax="100" style="width:{percent}%;">\n {percent}%\n </div>\n</div>',I='<div class="file-thumbnail-footer">\n <div class="file-footer-caption" title="{caption}">{caption}</div>\n {progress} {actions}\n</div>',E='<div class="file-actions">\n <div class="file-footer-buttons">\n {upload}{delete}{other} </div>\n <div class="file-upload-indicator" title="{indicatorTitle}">{indicator}</div>\n <div class="clearfix"></div>\n</div>',k='<button type="button" class="kv-file-remove {removeClass}" title="{removeTitle}" {dataUrl}{dataKey}>{removeIcon}</button>\n',S='<button type="button" class="kv-file-upload {uploadClass}" title="{uploadTitle}"> {uploadIcon}\n</button>\n',$='<button type="button" class="btn btn-default btn-xs btn-block" title="{zoomTitle}: {caption}" onclick="{dialog}">\n {zoomInd}\n</button>\n',P='<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}">\n {content}\n {footer}\n</div>\n',D='<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}">\n <object class="file-object" data="{data}" type="{type}" width="{width}" height="{height}">\n '+u+"\n </object>\n {footer}\n</div>",U='<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}">\n <img src="{data}" class="file-preview-image" title="{caption}" alt="{caption}" '+c+">\n {footer}\n</div>\n",A='<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}">\n <pre class="file-preview-text" title="{caption}" '+c+">{data}</pre>\n {zoom}\n {footer}\n</div>",j='<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}" title="{caption}" '+c+'>\n <video width="{width}" height="{height}" controls>\n <source src="{data}" type="{type}">\n '+u+"\n </video>\n {footer}\n</div>\n",L='<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}" title="{caption}" '+c+'>\n <audio controls>\n <source src="{data}" type="{type}">\n '+u+"\n </audio>\n {footer}\n</div>",z='<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}" title="{caption}" '+c+'>\n <object class="file-object" type="application/x-shockwave-flash" width="{width}" height="{height}" data="{data}">\n'+p+" "+u+"\n </object>\n {footer}\n</div>\n",O='<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}" title="{caption}" '+c+'>\n <object class="file-object" data="{data}" type="{type}" width="{width}" height="{height}">\n <param name="movie" value="{caption}" />\n'+p+" "+u+"\n </object>\n {footer}\n</div>",R='<div class="file-preview-frame{frameClass}" id="{previewId}" data-fileindex="{fileindex}" title="{caption}" '+c+'>\n <div class="file-preview-other-frame">\n '+u+'\n </div>\n <div class="file-preview-other-footer">{footer}</div>\n</div>',M={main1:v,main2:g,preview:m,close:w,zoom:$,icon:h,caption:b,modal:T,progress:F,footer:I,actions:E,actionDelete:k,actionUpload:S,btnDefault:C,btnLink:x,btnBrowse:y},B={generic:P,html:D,image:U,text:A,video:j,audio:L,flash:z,object:O,other:R},N=["image","html","text","video","audio","flash","object"],Z={image:{width:"auto",height:"160px"},html:{width:"213px",height:"160px"},text:{width:"160px",height:"136px"},video:{width:"213px",height:"160px"},audio:{width:"213px",height:"80px"},flash:{width:"213px",height:"160px"},object:{width:"160px",height:"160px"},other:{width:"160px",height:"160px"}},H={image:function(e,i){return void 0!==e?e.match("image.*"):i.match(/\.(gif|png|jpe?g)$/i)},html:function(e,i){return void 0!==e?"text/html"===e:i.match(/\.(htm|html)$/i)},text:function(e,i){return void 0!==e&&e.match("text.*")||i.match(/\.(txt|md|csv|nfo|ini|json|php|js|css)$/i)},video:function(e,i){return void 0!==e&&e.match(/\.video\/(ogg|mp4|webm|3gp)$/i)||i.match(/\.(og?|mp4|webm|3gp)$/i)},audio:function(e,i){return void 0!==e&&e.match(/\.audio\/(ogg|mp3|wav)$/i)||i.match(/\.(ogg|mp3|wav)$/i)},flash:function(e,i){return void 0!==e&&"application/x-shockwave-flash"===e||i.match(/\.(swf)$/i)},object:function(){return!0},other:function(){return!0}},W=function(i,t){return void 0===i||null===i||0===i.length||t&&""===e.trim(i)},q=function(e){return Array.isArray(e)||"[object Array]"===Object.prototype.toString.call(e)},_=function(e,i){return"object"==typeof i&&e in i},V=function(i,t,a){return W(i)||W(i[t])?a:e(i[t])},K=function(){return Math.round((new Date).getTime()+100*Math.random())},X=function(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")},J=function(i,t){var a=i;return t?(e.each(t,function(e,i){"function"==typeof i&&(i=i()),a=a.split(e).join(i)}),a):a},Q=window.URL||window.webkitURL,Y=function(t,a){var r=this;r.$element=e(t),r.validate()&&(r.isPreviewable=l(),r.isIE9=i(9),r.isIE10=i(10),r.isPreviewable||r.isIE9?(r.init(a),r.listen()):r.$element.removeClass("file-loading"))},Y.prototype={constructor:Y,validate:function(){var e,i=this;return"file"===i.$element.attr("type")?!0:(e='<div class="help-block alert alert-warning"><h4>Invalid Input Type</h4>You must set an input <code>type = file</code> for <b>bootstrap-fileinput</b> plugin to initialize.</div>',i.$element.after(e),!1)},init:function(i){var t,a=this,l=a.$element;e.each(i,function(e,i){switch(e){case"minFileCount":case"maxFileCount":case"maxFileSize":a[e]=n(i);break;default:a[e]=i}}),a.fileInputCleared=!1,a.fileBatchCompleted=!0,a.isPreviewable||(a.showPreview=!1),a.uploadFileAttr=W(l.attr("name"))?"file_data":l.attr("name"),a.reader=null,a.formdata={},a.clearStack(),a.uploadCount=0,a.uploadStatus={},a.uploadLog=[],a.uploadAsyncCount=0,a.loadedImages=[],a.totalImagesCount=0,a.ajaxRequests=[],a.isError=!1,a.ajaxAborted=!1,a.cancelling=!1,t=a.getLayoutTemplate("progress"),a.progressTemplate=t.replace("{class}",a.progressClass),a.progressCompleteTemplate=t.replace("{class}",a.progressCompleteClass),a.dropZoneEnabled=o()&&a.dropZoneEnabled,a.isDisabled=a.$element.attr("disabled")||a.$element.attr("readonly"),a.isUploadable=s()&&!W(a.uploadUrl),a.slug="function"==typeof i.slugCallback?i.slugCallback:a.slugDefault,a.mainTemplate=a.getLayoutTemplate(a.showCaption?"main1":"main2"),a.captionTemplate=a.getLayoutTemplate("caption"),a.previewGenericTemplate=a.getPreviewTemplate("generic"),a.resizeImage&&(a.maxImageWidth||a.maxImageHeight)&&(a.imageCanvas=document.createElement("canvas"),a.imageCanvasContext=a.imageCanvas.getContext("2d")),W(a.$element.attr("id"))&&a.$element.attr("id",K()),void 0===a.$container?a.$container=a.createContainer():a.refreshContainer(),a.$progress=a.$container.find(".kv-upload-progress"),a.$btnUpload=a.$container.find(".fileinput-upload"),a.$captionContainer=V(i,"elCaptionContainer",a.$container.find(".file-caption")),a.$caption=V(i,"elCaptionText",a.$container.find(".file-caption-name")),a.$previewContainer=V(i,"elPreviewContainer",a.$container.find(".file-preview")),a.$preview=V(i,"elPreviewImage",a.$container.find(".file-preview-thumbnails")),a.$previewStatus=V(i,"elPreviewStatus",a.$container.find(".file-preview-status")),a.$errorContainer=V(i,"elErrorContainer",a.$previewContainer.find(".kv-fileinput-error")),W(a.msgErrorClass)||d(a.$errorContainer,a.msgErrorClass),a.$errorContainer.hide(),a.fileActionSettings=e.extend(f,i.fileActionSettings),a.previewInitId="preview-"+K(),a.id=a.$element.attr("id"),r.init(a),a.initPreview(!0),a.initPreviewDeletes(),a.options=i,a.setFileDropZoneTitle(),a.$element.removeClass("file-loading"),a.$element.attr("disabled")&&a.disable()},parseError:function(i,t,a){var r=this,n=e.trim(t+""),l="."===n.slice(-1)?"":".",o=void 0!==i.responseJSON&&void 0!==i.responseJSON.error?i.responseJSON.error:i.responseText;return r.cancelling&&r.msgUploadAborted&&(n=r.msgUploadAborted),r.showAjaxErrorDetails&&o?(o=e.trim(o.replace(/\n\s*\n/g,"\n")),o=o.length>0?"<pre>"+o+"</pre>":"",n+=l+o):n+=l,r.cancelling=!1,a?"<b>"+a+": </b>"+n:n},raise:function(i,t){var a=this,r=e.Event(i);if(void 0!==t?a.$element.trigger(r,t):a.$element.trigger(r),r.isDefaultPrevented())return!1;if(!r.result)return r.result;switch(i){case"filebatchuploadcomplete":case"filebatchuploadsuccess":case"fileuploaded":case"fileclear":case"filecleared":case"filereset":case"fileerror":case"filefoldererror":case"fileuploaderror":case"filebatchuploaderror":case"filedeleteerror":case"filecustomerror":case"filesuccessremove":break;default:a.ajaxAborted=r.result}return!0},getLayoutTemplate:function(e){var i=this,t=_(e,i.layoutTemplates)?i.layoutTemplates[e]:M[e];return W(i.customLayoutTags)?t:J(t,i.customLayoutTags)},getPreviewTemplate:function(e){var i=this,t=_(e,i.previewTemplates)?i.previewTemplates[e]:B[e];return W(i.customPreviewTags)?t:J(t,i.customPreviewTags)},parseFilePreviewIcon:function(i,t){var a,r=this,n=r.previewFileIcon;return t&&t.indexOf(".")>-1&&(a=t.split(".").pop(),r.previewFileIconSettings&&r.previewFileIconSettings[a]&&(n=r.previewFileIconSettings[a]),r.previewFileExtSettings&&e.each(r.previewFileExtSettings,function(e,i){r.previewFileIconSettings[e]&&i(a)&&(n=r.previewFileIconSettings[e])})),i.indexOf("{previewFileIcon}")>-1?i.replace(/\{previewFileIconClass}/g,r.previewFileIconClass).replace(/\{previewFileIcon}/g,n):i},getOutData:function(e,i,t){var a=this;return e=e||{},i=i||{},t=t||a.filestack.slice(0)||{},{form:a.formdata,files:t,filenames:a.filenames,extra:a.getExtraData(),response:i,reader:a.reader,jqXHR:e}},listen:function(){var i=this,t=i.$element,r=i.$captionContainer,n=i.$btnFile,l=t.closest("form"),o=i.$container;a(t,"change",e.proxy(i.change,i)),a(n,"click",function(){i.raise("filebrowse"),i.isError&&!i.isUploadable&&i.clear(),r.focus()}),a(l,"reset",e.proxy(i.reset,i)),a(o.find(".fileinput-remove:not([disabled])"),"click",e.proxy(i.clear,i)),a(o.find(".fileinput-cancel"),"click",e.proxy(i.cancel,i)),i.isUploadable&&i.dropZoneEnabled&&i.showPreview&&i.initDragDrop(),i.isUploadable||a(l,"submit",e.proxy(i.submitForm,i)),a(i.$container.find(".fileinput-upload"),"click",function(t){var a,r=e(this),n=!r.hasClass("disabled")&&W(r.attr("disabled"));return i.isUploadable?(t.preventDefault(),void(n&&i.upload())):void(n&&"submit"!==r.attr("type")&&(a=r.closest("form"),a.length&&a.trigger("submit"),t.preventDefault()))})},submitForm:function(){var e=this,i=e.$element,t=i.get(0).files;return t&&e.minFileCount>0&&e.getFileCount(t.length)<e.minFileCount?(e.noFilesError({}),!1):!e.abort({})},abort:function(i){var t,a=this;return a.ajaxAborted&&"object"==typeof a.ajaxAborted&&void 0!==a.ajaxAborted.message?(t=e.extend(a.getOutData(),i),t.abortData=a.ajaxAborted.data||{},t.abortMessage=a.ajaxAborted.message,a.cancel(),a.setProgress(100),a.showUploadError(a.ajaxAborted.message,t,"filecustomerror"),!0):!1},noFilesError:function(e){var i=this,t=i.minFileCount>1?i.filePlural:i.fileSingle,a=i.msgFilesTooLess.replace("{n}",i.minFileCount).replace("{files}",t),r=i.$errorContainer;i.addError(a),i.isError=!0,i.updateFileDetails(0),r.fadeIn(800),i.raise("fileerror",[e]),i.clearFileInput(),d(i.$container,"has-error")},setProgress:function(e,i){var t=this,a=Math.min(e,100),r=100>a?t.progressTemplate:t.progressCompleteTemplate;i=i||t.$progress,W(r)||i.html(r.replace(/\{percent}/g,a))},lock:function(){var e=this;e.resetErrors(),e.disable(),e.showRemove&&d(e.$container.find(".fileinput-remove"),"hide"),e.showCancel&&e.$container.find(".fileinput-cancel").removeClass("hide"),e.raise("filelock",[e.filestack,e.getExtraData()])},unlock:function(e){var i=this;void 0===e&&(e=!0),i.enable(),i.showCancel&&d(i.$container.find(".fileinput-cancel"),"hide"),i.showRemove&&i.$container.find(".fileinput-remove").removeClass("hide"),e&&i.resetFileStack(),i.raise("fileunlock",[i.filestack,i.getExtraData()])},resetFileStack:function(){var i=this,t=0,a=[],r=[];i.getThumbs().each(function(){var n=e(this),l=n.attr("data-fileindex"),o=i.filestack[l];-1!==l&&(void 0!==o?(a[t]=o,r[t]=i.getFileName(o),n.attr({id:i.previewInitId+"-"+t,"data-fileindex":t}),t++):n.attr({id:"uploaded-"+K(),"data-fileindex":"-1"}))}),i.filestack=a,i.filenames=r},destroy:function(){var e=this,i=e.$container;i.find(".file-drop-zone").off(),e.$element.insertBefore(i).off(".fileinput").removeData(),i.off().remove()},refresh:function(i){var t=this,a=t.$element;i=i?e.extend(t.options,i):t.options,t.destroy(),a.fileinput(i),a.val()&&a.trigger("change.fileinput")},initDragDrop:function(){var i=this,t=i.$container.find(".file-drop-zone"),r="dragenter.fileinput dragover.fileinput drop.fileinput";a(t,"dragenter.fileinput dragover.fileinput",function(t){var a=e.inArray("Files",t.originalEvent.dataTransfer.types)>-1;return t.stopPropagation(),t.preventDefault(),i.isDisabled||!a?(t.originalEvent.dataTransfer.effectAllowed="none",void(t.originalEvent.dataTransfer.dropEffect="none")):void d(e(this),"file-highlighted")},!0),a(t,"dragleave",function(t){t.stopPropagation(),t.preventDefault(),i.isDisabled||e(this).removeClass("file-highlighted")}),a(t,"drop",function(t){t.preventDefault(),i.isDisabled||W(t.originalEvent.dataTransfer.files)||(i.change(t,"dragdrop"),e(this).removeClass("file-highlighted"))}),a(e(document),r,function(e){e.stopPropagation(),e.preventDefault()},!0)},setFileDropZoneTitle:function(){var e=this,i=e.$container.find(".file-drop-zone");i.find("."+e.dropZoneTitleClass).remove(),e.isUploadable&&e.showPreview&&0!==i.length&&!(e.getFileStack().length>0)&&e.dropZoneEnabled&&(0===i.find(".file-preview-frame").length&&W(e.defaultPreviewContent)&&i.prepend('<div class="'+e.dropZoneTitleClass+'">'+e.dropZoneTitle+"</div>"),e.$container.removeClass("file-input-new"),d(e.$container,"file-input-ajax-new"))},errorsExist:function(){var i,t=this;return t.$errorContainer.find("li").length?!0:(i=e(document.createElement("div")).html(t.$errorContainer.html()),i.find("span.kv-error-close").remove(),i.find("ul").remove(),e.trim(i.text()).length?!0:!1)},getMsgSelected:function(e){var i=this,t=1===e?i.fileSingle:i.filePlural;return i.msgSelected.replace("{n}",e).replace("{files}",t)},renderThumbProgress:function(){return'<div class="file-thumb-progress hide">'+this.progressTemplate.replace(/\{percent}/g,"0")+"</div>"},renderFileFooter:function(e,i){var t,a,r=this,n=r.fileActionSettings,l=r.getLayoutTemplate("footer");return r.isUploadable?(t=l.replace(/\{actions}/g,r.renderFileActions(!0,!0,!1,!1,!1)),a=t.replace(/\{caption}/g,e).replace(/\{width}/g,i).replace(/\{progress}/g,r.renderThumbProgress()).replace(/\{indicator}/g,n.indicatorNew).replace(/\{indicatorTitle}/g,n.indicatorNewTitle)):a=l.replace(/\{actions}/g,"").replace(/\{caption}/g,e).replace(/\{progress}/g,"").replace(/\{width}/g,i).replace(/\{indicator}/g,"").replace(/\{indicatorTitle}/g,""),a=J(a,r.previewThumbTags)},renderFileActions:function(e,i,t,a,r){if(!e&&!i)return"";var n=this,l=a===!1?"":' data-url="'+a+'"',o=r===!1?"":' data-key="'+r+'"',s=n.getLayoutTemplate("actionDelete"),d="",c=n.getLayoutTemplate("actions"),p=n.otherActionButtons.replace(/\{dataKey}/g,o),u=n.fileActionSettings,f=t?u.removeClass+" disabled":u.removeClass;return s=s.replace(/\{removeClass}/g,f).replace(/\{removeIcon}/g,u.removeIcon).replace(/\{removeTitle}/g,u.removeTitle).replace(/\{dataUrl}/g,l).replace(/\{dataKey}/g,o),e&&(d=n.getLayoutTemplate("actionUpload").replace(/\{uploadClass}/g,u.uploadClass).replace(/\{uploadIcon}/g,u.uploadIcon).replace(/\{uploadTitle}/g,u.uploadTitle)),c.replace(/\{delete}/g,s).replace(/\{upload}/g,d).replace(/\{other}/g,p)},setThumbStatus:function(e,i){var t=this;if(t.showPreview){var a="indicator"+i,r=a+"Title",n="file-preview-"+i.toLowerCase(),l=e.find(".file-upload-indicator"),o=t.fileActionSettings;e.removeClass("file-preview-success file-preview-error file-preview-loading"),"Error"===i&&e.find(".kv-file-upload").attr("disabled",!0),l.html(o[a]),l.attr("title",o[r]),e.addClass(n)}},clearPreview:function(){var e=this,i=e.$preview.find(e.showUploadedThumbs?".file-preview-frame:not(.file-preview-success)":".file-preview-frame");i.remove(),e.$preview.find(".file-preview-frame").length&&e.showPreview||e.resetUpload(),e.validateDefaultPreview()},initPreview:function(e){var i,t=this,a=t.initialCaption||"";return r.count(t.id)?(i=r.out(t.id),a=e&&t.initialCaption?t.initialCaption:i.caption,t.$preview.html(i.content),t.setCaption(a),void(W(i.content)||t.$container.removeClass("file-input-new"))):(t.clearPreview(),void(e?t.setCaption(a):t.initCaption()))},initPreviewDeletes:function(){var i=this,t=i.deleteExtraData||{},n=function(){var e=i.isUploadable?r.count(i.id):i.$element.get(0).files.length;0!==i.$preview.find(".kv-file-remove").length||e||(i.reset(),i.initialCaption="")};i.$preview.find(".kv-file-remove").each(function(){var l=e(this),o=l.data("url")||i.deleteUrl,s=l.data("key");if(!W(o)&&void 0!==s){var c,p,u,f,v=l.closest(".file-preview-frame"),g=r.data[i.id],m=v.data("fileindex");m=parseInt(m.replace("init_","")),u=W(g.config)&&W(g.config[m])?null:g.config[m],f=W(u)||W(u.extra)?t:u.extra,"function"==typeof f&&(f=f()),p={id:l.attr("id"),key:s,extra:f},c=e.extend({url:o,type:"POST",dataType:"json",data:e.extend({key:s},f),beforeSend:function(e){i.ajaxAborted=!1,i.raise("filepredelete",[s,e,f]),i.ajaxAborted?e.abort():(d(v,"file-uploading"),d(l,"disabled"))},success:function(e,t,a){var o,d;return W(e)||W(e.error)?(r.unset(i.id,m),o=r.count(i.id),d=o>0?i.getMsgSelected(o):"",i.raise("filedeleted",[s,a,f]),i.setCaption(d),v.removeClass("file-uploading").addClass("file-deleted"),void v.fadeOut("slow",function(){i.clearObjects(v),v.remove(),n(),o||0!==i.getFileStack().length||(i.setCaption(""),i.reset())})):(p.jqXHR=a,p.response=e,i.showError(e.error,p,"filedeleteerror"),v.removeClass("file-uploading"),l.removeClass("disabled"),void n())},error:function(e,t,a){var r=i.parseError(e,a);p.jqXHR=e,p.response={},i.showError(r,p,"filedeleteerror"),v.removeClass("file-uploading"),n()}},i.ajaxDeleteSettings),a(l,"click",function(){return i.validateMinCount()?void e.ajax(c):!1})}})},clearObjects:function(i){i.find("video audio").each(function(){this.pause(),e(this).remove()}),i.find("img object div").each(function(){e(this).remove()})},clearFileInput:function(){var i,t,a,r=this,n=r.$element;W(n.val())||(r.isIE9||r.isIE10?(i=n.closest("form"),t=e(document.createElement("form")),a=e(document.createElement("div")),n.before(a),i.length?i.after(t):a.after(t),t.append(n).trigger("reset"),a.before(n).remove(),t.remove()):n.val(""),r.fileInputCleared=!0)},resetUpload:function(){var e=this;e.uploadCache={content:[],config:[],tags:[],append:!0},e.uploadCount=0,e.uploadStatus={},e.uploadLog=[],e.uploadAsyncCount=0,e.loadedImages=[],e.totalImagesCount=0,e.$btnUpload.removeAttr("disabled"),e.setProgress(0),d(e.$progress,"hide"),e.resetErrors(!1),e.ajaxAborted=!1,e.ajaxRequests=[],e.resetCanvas()},resetCanvas:function(){var e=this;e.canvas&&e.imageCanvasContext&&e.imageCanvasContext.clearRect(0,0,e.canvas.width,e.canvas.height)},cancel:function(){var i,t=this,a=t.ajaxRequests,r=a.length;if(r>0)for(i=0;r>i;i+=1)t.cancelling=!0,a[i].abort();t.getThumbs().each(function(){var i=e(this),a=i.attr("data-fileindex");i.removeClass("file-uploading"),void 0!==t.filestack[a]&&(i.find(".kv-file-upload").removeClass("disabled").removeAttr("disabled"),i.find(".kv-file-remove").removeClass("disabled").removeAttr("disabled")),t.unlock()})},cleanMemory:function(e){var i=e.is("img")?e.attr("src"):e.find("source").attr("src");Q.revokeObjectURL(i)},hasInitialPreview:function(){var e=this;return!e.overwriteInitial&&r.count(e.id)},clear:function(){var i,t=this;t.$btnUpload.removeAttr("disabled"),t.getThumbs().find("video,audio,img").each(function(){t.cleanMemory(e(this))}),t.resetUpload(),t.clearStack(),t.clearFileInput(),t.resetErrors(!0),t.raise("fileclear"),t.hasInitialPreview()?(t.showFileIcon(),t.resetPreview(),t.initPreviewDeletes(),t.$container.removeClass("file-input-new")):(t.getThumbs().each(function(){t.clearObjects(e(this))}),t.isUploadable&&(r.data[t.id]={}),t.$preview.html(""),i=!t.overwriteInitial&&t.initialCaption.length>0?t.initialCaption:"",t.setCaption(i),t.$caption.attr("title",""),d(t.$container,"file-input-new"),t.validateDefaultPreview()),0===t.$container.find(".file-preview-frame").length&&(t.initCaption()||t.$captionContainer.find(".kv-caption-icon").hide()),t.hideFileIcon(),t.raise("filecleared"),t.$captionContainer.focus(),t.setFileDropZoneTitle()},resetPreview:function(){var e,i,t=this;r.count(t.id)?(e=r.out(t.id),t.$preview.html(e.content),i=t.initialCaption?t.initialCaption:e.caption,t.setCaption(i)):(t.clearPreview(),t.initCaption())},clearDefaultPreview:function(){var e=this;e.$preview.find(".file-default-preview").remove()},validateDefaultPreview:function(){var e=this;e.showPreview&&!W(e.defaultPreviewContent)&&(e.$preview.html('<div class="file-default-preview">'+e.defaultPreviewContent+"</div>"),e.$container.removeClass("file-input-new"))},resetPreviewThumbs:function(e){var i,t=this;return e?(t.clearPreview(),void t.clearStack()):void(t.hasInitialPreview()?(i=r.out(t.id),t.$preview.html(i.content),t.setCaption(i.caption),t.initPreviewDeletes()):t.clearPreview())},reset:function(){var e=this;e.resetPreview(),e.$container.find(".fileinput-filename").text(""),e.raise("filereset"),d(e.$container,"file-input-new"),(e.$preview.find(".file-preview-frame").length||e.isUploadable&&e.dropZoneEnabled)&&e.$container.removeClass("file-input-new"),e.setFileDropZoneTitle(),e.clearStack(),e.formdata={}},disable:function(){var e=this;e.isDisabled=!0,e.raise("filedisabled"),e.$element.attr("disabled","disabled"),e.$container.find(".kv-fileinput-caption").addClass("file-caption-disabled"),e.$container.find(".btn-file, .fileinput-remove, .fileinput-upload, .file-preview-frame button").attr("disabled",!0),e.initDragDrop()},enable:function(){var e=this;e.isDisabled=!1,e.raise("fileenabled"),e.$element.removeAttr("disabled"),e.$container.find(".kv-fileinput-caption").removeClass("file-caption-disabled"),e.$container.find(".btn-file, .fileinput-remove, .fileinput-upload, .file-preview-frame button").removeAttr("disabled"),e.initDragDrop()},getThumbs:function(e){return e=e||"",this.$preview.find(".file-preview-frame:not(.file-preview-initial)"+e)},getExtraData:function(e,i){var t=this,a=t.uploadExtraData;return"function"==typeof t.uploadExtraData&&(a=t.uploadExtraData(e,i)),a},uploadExtra:function(i,t){var a=this,r=a.getExtraData(i,t);0!==r.length&&e.each(r,function(e,i){a.formdata.append(e,i)})},setAsyncUploadStatus:function(i,t,a){var r=this,n=0;r.setProgress(t,e("#"+i).find(".file-thumb-progress")),r.uploadStatus[i]=t,e.each(r.uploadStatus,function(e,i){n+=i}),r.setProgress(Math.ceil(n/a))},initXhr:function(e,i,t){var a=this;return e.upload&&e.upload.addEventListener("progress",function(e){var r=0,n=e.loaded||e.position,l=e.total;e.lengthComputable&&(r=Math.ceil(n/l*100)),i?a.setAsyncUploadStatus(i,r,t):a.setProgress(Math.ceil(r))},!1),e},ajaxSubmit:function(i,t,a,r,n,l){var o,s=this;s.raise("filepreajax",[n,l]),s.uploadExtra(n,l),o=e.extend({xhr:function(){var i=e.ajaxSettings.xhr();return s.initXhr(i,n,s.getFileStack().length)},url:s.uploadUrl,type:"POST",dataType:"json",data:s.formdata,cache:!1,processData:!1,contentType:!1,beforeSend:i,success:t,complete:a,error:r},s.ajaxSettings),s.ajaxRequests.push(e.ajax(o))},initUploadSuccess:function(i,t,a){var n,l,o,s,d,c,p,u,f=this;f.showPreview&&"object"==typeof i&&!e.isEmptyObject(i)&&void 0!==i.initialPreview&&i.initialPreview.length>0&&(f.hasInitData=!0,d=i.initialPreview||[],c=i.initialPreviewConfig||[],p=i.initialPreviewThumbTags||[],n=void 0===i.append||i.append?!0:!1,f.overwriteInitial=!1,void 0!==t?a?(u=t.attr("data-fileindex"),f.uploadCache.content[u]=d[0],f.uploadCache.config[u]=c[0],f.uploadCache.tags[u]=p[0],f.uploadCache.append=n):(o=r.add(f.id,d,c[0],p[0],n),l=r.get(f.id,o,!1),s=e(l).hide(),t.after(s).fadeOut("slow",function(){s.fadeIn("slow").css("display:inline-block"),f.initPreviewDeletes(),f.clearFileInput(),t.remove()})):(r.set(f.id,d,c,p,n),f.initPreview(),f.initPreviewDeletes()))},initSuccessThumbs:function(){var i=this;i.showPreview&&i.getThumbs(".file-preview-success").each(function(){var t=e(this),r=t.find(".kv-file-remove");r.removeAttr("disabled"),a(r,"click",function(){var e=i.raise("filesuccessremove",[t.attr("id"),t.data("fileindex")]);i.cleanMemory(t),e!==!1&&t.fadeOut("slow",function(){t.remove(),i.$preview.find(".file-preview-frame").length||i.reset()})})})},checkAsyncComplete:function(){var i,t,a=this;for(t=0;t<a.filestack.length;t++)if(a.filestack[t]&&(i=a.previewInitId+"-"+t,-1===e.inArray(i,a.uploadLog)))return!1;return a.uploadAsyncCount===a.uploadLog.length},uploadSingle:function(i,t,a){var n,l,o,s,c,p,u,f,v,g,m=this,h=m.getFileStack().length,w=new FormData,b=m.previewInitId+"-"+i,C=m.filestack.length>0||!e.isEmptyObject(m.uploadExtraData),x={id:b,index:i};m.formdata=w,m.showPreview&&(l=e("#"+b+":not(.file-preview-initial)"),s=l.find(".kv-file-upload"),c=l.find(".kv-file-remove"),e("#"+b).find(".file-thumb-progress").removeClass("hide")),0===h||!C||s&&s.hasClass("disabled")||m.abort(x)||(g=function(e,i){ | ||
| 18 | +m.updateStack(e,void 0),m.uploadLog.push(i),m.checkAsyncComplete()&&(m.fileBatchCompleted=!0)},o=function(){m.fileBatchCompleted&&setTimeout(function(){m.showPreview&&(r.set(m.id,m.uploadCache.content,m.uploadCache.config,m.uploadCache.tags,m.uploadCache.append),m.hasInitData&&(m.initPreview(),m.initPreviewDeletes())),m.unlock(),m.clearFileInput(),m.raise("filebatchuploadcomplete",[m.filestack,m.getExtraData()]),m.uploadCount=0,m.uploadStatus={},m.uploadLog=[],m.setProgress(100)},100)},p=function(t){n=m.getOutData(t),m.fileBatchCompleted=!1,m.showPreview&&(l.hasClass("file-preview-success")||(m.setThumbStatus(l,"Loading"),d(l,"file-uploading")),s.attr("disabled",!0),c.attr("disabled",!0)),a||m.lock(),m.raise("filepreupload",[n,b,i]),x=e.extend(x,n),m.abort(x)&&(t.abort(),m.setProgress(100))},u=function(t,r,o){n=m.getOutData(o,t),x=e.extend(x,n),setTimeout(function(){W(t)||W(t.error)?(m.showPreview&&(m.setThumbStatus(l,"Success"),s.hide(),m.initUploadSuccess(t,l,a)),m.raise("fileuploaded",[n,b,i]),a?g(i,b):m.updateStack(i,void 0)):(m.setThumbStatus(l,"Error"),m.showUploadError(t.error,x),a&&g(i,b))},100)},f=function(){setTimeout(function(){m.showPreview&&(s.removeAttr("disabled"),c.removeAttr("disabled"),l.removeClass("file-uploading")),a?o():(m.unlock(!1),m.clearFileInput()),m.initSuccessThumbs()},100)},v=function(r,n,o){var s=m.parseError(r,o,a?t[i].name:null);setTimeout(function(){a&&g(i,b),m.uploadStatus[b]=100,m.setThumbStatus(l,"Error"),x=e.extend(x,m.getOutData(r)),m.showUploadError(s,x)},100)},w.append(m.uploadFileAttr,t[i],m.filenames[i]),w.append("file_id",i),m.ajaxSubmit(p,u,f,v,b,i))},uploadBatch:function(){var i,t,a,r,n,l=this,o=l.filestack,s=o.length,c={},p=l.filestack.length>0||!e.isEmptyObject(l.uploadExtraData);l.formdata=new FormData,0!==s&&p&&!l.abort(c)&&(i=function(){e.each(o,function(e){l.updateStack(e,void 0)}),l.clearFileInput()},t=function(i){l.lock();var t=l.getOutData(i);l.showPreview&&l.getThumbs().each(function(){var i=e(this),t=i.find(".kv-file-upload"),a=i.find(".kv-file-remove");i.hasClass("file-preview-success")||(l.setThumbStatus(i,"Loading"),d(i,"file-uploading")),t.attr("disabled",!0),a.attr("disabled",!0)}),l.raise("filebatchpreupload",[t]),l.abort(t)&&(i.abort(),l.setProgress(100))},a=function(t,a,r){var n=l.getOutData(r,t),o=l.getThumbs(),s=0,d=W(t)||W(t.errorkeys)?[]:t.errorkeys;W(t)||W(t.error)?(l.raise("filebatchuploadsuccess",[n]),i(),l.showPreview?(o.each(function(){var i=e(this),t=i.find(".kv-file-upload");i.find(".kv-file-upload").hide(),l.setThumbStatus(i,"Success"),i.removeClass("file-uploading"),t.removeAttr("disabled")}),l.initUploadSuccess(t)):l.reset()):(l.showPreview&&(o.each(function(){var i=e(this),t=i.find(".kv-file-remove"),a=i.find(".kv-file-upload");return i.removeClass("file-uploading"),a.removeAttr("disabled"),t.removeAttr("disabled"),0===d.length?void l.setThumbStatus(i,"Error"):(-1!==e.inArray(s,d)?l.setThumbStatus(i,"Error"):(i.find(".kv-file-upload").hide(),l.setThumbStatus(i,"Success"),l.updateStack(s,void 0)),void s++)}),l.initUploadSuccess(t)),l.showUploadError(t.error,n,"filebatchuploaderror"))},r=function(){l.setProgress(100),l.unlock(),l.initSuccessThumbs(),l.clearFileInput(),l.raise("filebatchuploadcomplete",[l.filestack,l.getExtraData()])},n=function(i,t,a){var r=l.getOutData(i),n=l.parseError(i,a);l.showUploadError(n,r,"filebatchuploaderror"),l.uploadFileCount=s-1,l.showPreview&&(l.getThumbs().each(function(){var i=e(this),t=i.attr("data-fileindex");i.removeClass("file-uploading"),void 0!==l.filestack[t]&&l.setThumbStatus(i,"Error")}),l.getThumbs().removeClass("file-uploading"),l.getThumbs(" .kv-file-upload").removeAttr("disabled"),l.getThumbs(" .kv-file-delete").removeAttr("disabled"))},e.each(o,function(e,i){W(o[e])||l.formdata.append(l.uploadFileAttr,i,l.filenames[e])}),l.ajaxSubmit(t,a,r,n))},uploadExtraOnly:function(){var e,i,t,a,r=this,n={};r.formdata=new FormData,r.abort(n)||(e=function(e){r.lock();var i=r.getOutData(e);r.raise("filebatchpreupload",[i]),r.setProgress(50),n.data=i,n.xhr=e,r.abort(n)&&(e.abort(),r.setProgress(100))},i=function(e,i,t){var a=r.getOutData(t,e);W(e)||W(e.error)?(r.raise("filebatchuploadsuccess",[a]),r.clearFileInput(),r.initUploadSuccess(e)):r.showUploadError(e.error,a,"filebatchuploaderror")},t=function(){r.setProgress(100),r.unlock(),r.clearFileInput(),r.raise("filebatchuploadcomplete",[r.filestack,r.getExtraData()])},a=function(e,i,t){var a=r.getOutData(e),l=r.parseError(e,t);n.data=a,r.showUploadError(l,a,"filebatchuploaderror")},r.ajaxSubmit(e,i,t,a))},upload:function(){var i,t,a,r=this,n=r.getFileStack().length,l={},o=!e.isEmptyObject(r.getExtraData());if(r.minFileCount>0&&r.getFileCount(n)<r.minFileCount)return void r.noFilesError(l);if(r.isUploadable&&!r.isDisabled&&(0!==n||o)){if(r.resetUpload(),r.$progress.removeClass("hide"),r.uploadCount=0,r.uploadStatus={},r.uploadLog=[],r.lock(),r.setProgress(2),0===n&&o)return void r.uploadExtraOnly();if(a=r.filestack.length,r.hasInitData=!1,r.uploadAsync){for(t=r.getOutData(),r.raise("filebatchpreupload",[t]),r.fileBatchCompleted=!1,r.uploadCache={content:[],config:[],tags:[],append:!0},r.uploadAsyncCount=r.getFileStack().length,i=0;a>i;i++)r.uploadCache.content[i]=null,r.uploadCache.config[i]=null,r.uploadCache.tags[i]=null;for(i=0;a>i;i++)void 0!==r.filestack[i]&&r.uploadSingle(i,r.filestack,!0)}else r.uploadBatch()}},initFileActions:function(){var i=this;i.showPreview&&(i.$preview.find(".kv-file-remove").each(function(){var t,n,l,o,s=e(this),d=s.closest(".file-preview-frame"),c=d.attr("id"),p=d.attr("data-fileindex");a(s,"click",function(){return o=i.raise("filepreremove",[c,p]),o!==!1&&i.validateMinCount()?(t=d.hasClass("file-preview-error"),i.cleanMemory(d),void d.fadeOut("slow",function(){i.updateStack(p,void 0),i.clearObjects(d),d.remove(),c&&t&&i.$errorContainer.find('li[data-file-id="'+c+'"]').fadeOut("fast",function(){e(this).remove(),i.errorsExist()||i.resetErrors()});var a=i.getFileStack(!0),o=a.length,s=r.count(i.id),u=i.showPreview&&i.$preview.find(".file-preview-frame").length;i.clearFileInput(),0!==o||0!==s||u?(n=s+o,l=n>1?i.getMsgSelected(n):a[0]?i.getFileNames()[0]:"",i.setCaption(l)):i.reset(),i.raise("fileremoved",[c,p])})):!1})}),i.$preview.find(".kv-file-upload").each(function(){var t=e(this);a(t,"click",function(){var e=t.closest(".file-preview-frame"),a=e.attr("data-fileindex");e.hasClass("file-preview-error")||i.uploadSingle(a,i.filestack,!1)})}))},hideFileIcon:function(){this.overwriteInitial&&this.$captionContainer.find(".kv-caption-icon").hide()},showFileIcon:function(){this.$captionContainer.find(".kv-caption-icon").show()},addError:function(e){var i=this,t=i.$errorContainer;e&&t.length&&(t.html(i.errorCloseButton+e),t.find(".kv-error-close").off("click").on("click",function(){t.fadeOut("slow")}))},resetErrors:function(e){var i=this,t=i.$errorContainer;i.isError=!1,i.$container.removeClass("has-error"),t.html(""),e?t.fadeOut("slow"):t.hide()},showFolderError:function(e){var i=this,t=i.$errorContainer;e&&(i.addError(i.msgFoldersNotAllowed.replace(/\{n}/g,e)),t.fadeIn(800),d(i.$container,"has-error"),i.raise("filefoldererror",[e]))},showUploadError:function(e,i,t){var a=this,r=a.$errorContainer,n=t||"fileuploaderror",l=i&&i.id?'<li data-file-id="'+i.id+'">'+e+"</li>":"<li>"+e+"</li>";return 0===r.find("ul").length?a.addError("<ul>"+l+"</ul>"):r.find("ul").append(l),r.fadeIn(800),a.raise(n,[i]),a.$container.removeClass("file-input-new"),d(a.$container,"has-error"),!0},showError:function(e,i,t){var a=this,r=a.$errorContainer,n=t||"fileerror";return i=i||{},i.reader=a.reader,a.addError(e),r.fadeIn(800),a.raise(n,[i]),a.isUploadable||a.clearFileInput(),a.$container.removeClass("file-input-new"),d(a.$container,"has-error"),a.$btnUpload.attr("disabled",!0),!0},errorHandler:function(e,i){var t=this,a=e.target.error;t.showError(a.code===a.NOT_FOUND_ERR?t.msgFileNotFound.replace("{name}",i):a.code===a.SECURITY_ERR?t.msgFileSecured.replace("{name}",i):a.code===a.NOT_READABLE_ERR?t.msgFileNotReadable.replace("{name}",i):a.code===a.ABORT_ERR?t.msgFilePreviewAborted.replace("{name}",i):t.msgFilePreviewError.replace("{name}",i))},parseFileType:function(e){var i,t,a,r,n=this;for(r=0;r<N.length;r+=1)if(a=N[r],i=_(a,n.fileTypeSettings)?n.fileTypeSettings[a]:H[a],t=i(e.type,e.name)?a:"",!W(t))return t;return"other"},previewDefault:function(i,t,a){if(this.showPreview){var r=this,n="",l=i?i.name:"",o=Q.createObjectURL(i),s=t.slice(t.lastIndexOf("-")+1),d=r.previewSettings.other||Z.other,c=r.renderFileFooter(i.name,d.width),p=r.parseFilePreviewIcon(r.getPreviewTemplate("other"),l);a===!0&&(r.isUploadable||(c+='<div class="file-other-error" title="'+r.fileActionSettings.indicatorErrorTitle+'">'+r.fileActionSettings.indicatorError+"</div>")),r.clearDefaultPreview(),r.$preview.append("\n"+p.replace(/\{previewId}/g,t).replace(/\{frameClass}/g,n).replace(/\{fileindex}/g,s).replace(/\{caption}/g,r.slug(i.name)).replace(/\{width}/g,d.width).replace(/\{height}/g,d.height).replace(/\{type}/g,i.type).replace(/\{data}/g,o).replace(/\{footer}/g,c)),a===!0&&r.isUploadable&&r.setThumbStatus(e("#"+t),"Error")}},previewFile:function(e,i,t,a,r){if(this.showPreview){var n,l,o,s=this,d=s.parseFileType(i),c=i?i.name:"",p=s.slug(c),u=s.allowedPreviewTypes,f=s.allowedPreviewMimeTypes,v=s.getPreviewTemplate(d),g=u&&u.indexOf(d)>=0,m=_(d,s.previewSettings)?s.previewSettings[d]:Z[d],h=f&&-1!==f.indexOf(i.type),w=s.renderFileFooter(p,m.width),b="",C=a.slice(a.lastIndexOf("-")+1);g||h?(v=s.parseFilePreviewIcon(v,c.split(".").pop()),"text"===d?(l=X(t.target.result),o="text-"+K(),n=v.replace(/\{zoom}/g,s.getLayoutTemplate("zoom")),b=s.getLayoutTemplate("modal").replace("{id}",o).replace(/\{title}/g,p).replace(/\{body}/g,l).replace(/\{heading}/g,s.msgZoomModalHeading),n=n.replace(/\{previewId}/g,a).replace(/\{caption}/g,p).replace(/\{width}/g,m.width).replace(/\{height}/g,m.height).replace(/\{frameClass}/g,"").replace(/\{zoomInd}/g,s.zoomIndicator).replace(/\{footer}/g,w).replace(/\{fileindex}/g,C).replace(/\{type}/g,i.type).replace(/\{zoomTitle}/g,s.msgZoomTitle).replace(/\{dialog}/g,"$('#"+o+"').modal('show')").replace(/\{data}/g,l)+b):n=v.replace(/\{previewId}/g,a).replace(/\{caption}/g,p).replace(/\{frameClass}/g,"").replace(/\{type}/g,i.type).replace(/\{fileindex}/g,C).replace(/\{width}/g,m.width).replace(/\{height}/g,m.height).replace(/\{footer}/g,w).replace(/\{data}/g,r),s.clearDefaultPreview(),s.$preview.append("\n"+n),s.validateImage(e,a,p,i.type)):s.previewDefault(i,a)}},slugDefault:function(e){return W(e)?"":e.split(/(\\|\/)/g).pop().replace(/[^\w\u00C0-\u017F\-.\\\/ ]+/g,"")},readFiles:function(i){this.reader=new FileReader;var t,a=this,r=a.$element,n=a.$preview,l=a.reader,o=a.$previewContainer,s=a.$previewStatus,d=a.msgLoading,c=a.msgProgress,p=a.previewInitId,u=i.length,f=a.fileTypeSettings,v=a.filestack.length,g=function(r,n,l,o){var s=e.extend(a.getOutData({},{},i),{id:l,index:o}),d={id:l,index:o,file:n,files:i};return a.previewDefault(n,l,!0),a.isUploadable&&a.pushStack(void 0),setTimeout(t(o+1),100),a.initFileActions(),a.isUploadable?a.showUploadError(r,s):a.showError(r,d)};a.loadedImages=[],a.totalImagesCount=0,e.each(i,function(e,i){var t="image",r=_(t,a.fileTypeSettings)?a.fileTypeSettings[t]:H[t];r&&r(i.type)&&a.totalImagesCount++}),t=function(e){if(W(r.attr("multiple"))&&(u=1),e>=u)return a.isUploadable&&a.filestack.length>0?a.raise("filebatchselected",[a.getFileStack()]):a.raise("filebatchselected",[i]),o.removeClass("file-thumb-loading"),void s.html("");var m,h,w,b,C,x,y=v+e,T=p+"-"+y,F=i[e],I=a.slug(F.name),E=(F.size||0)/1e3,k="",S=Q.createObjectURL(F),$=0,P=a.allowedFileTypes,D=W(P)?"":P.join(", "),U=a.allowedFileExtensions,A=W(U)?"":U.join(", ");if(W(U)||(k=new RegExp("\\.("+U.join("|")+")$","i")),E=E.toFixed(2),a.maxFileSize>0&&E>a.maxFileSize)return b=a.msgSizeTooLarge.replace("{name}",I).replace("{size}",E).replace("{maxSize}",a.maxFileSize),void(a.isError=g(b,F,T,e));if(!W(P)&&q(P)){for(w=0;w<P.length;w+=1)C=P[w],h=f[C],x=void 0!==h&&h(F.type,I),$+=W(x)?0:x.length;if(0===$)return b=a.msgInvalidFileType.replace("{name}",I).replace("{types}",D),void(a.isError=g(b,F,T,e))}return 0!==$||W(U)||!q(U)||W(k)||(x=I.match(k),$+=W(x)?0:x.length,0!==$)?a.showPreview?(n.length>0&&void 0!==FileReader?(s.html(d.replace("{index}",e+1).replace("{files}",u)),o.addClass("file-thumb-loading"),l.onerror=function(e){a.errorHandler(e,I)},l.onload=function(i){a.previewFile(e,F,i,T,S),a.initFileActions()},l.onloadend=function(){b=c.replace("{index}",e+1).replace("{files}",u).replace("{percent}",50).replace("{name}",I),setTimeout(function(){s.html(b),a.updateFileDetails(u),t(e+1)},100),a.raise("fileloaded",[F,T,e,l])},l.onprogress=function(i){if(i.lengthComputable){var t=i.loaded/i.total*100,a=Math.ceil(t);b=c.replace("{index}",e+1).replace("{files}",u).replace("{percent}",a).replace("{name}",I),setTimeout(function(){s.html(b)},100)}},m=_("text",f)?f.text:H.text,m(F.type,I)?l.readAsText(F,a.textEncoding):l.readAsArrayBuffer(F)):(a.previewDefault(F,T),setTimeout(function(){t(e+1),a.updateFileDetails(u)},100),a.raise("fileloaded",[F,T,e,l])),void a.pushStack(F)):(a.pushStack(F),setTimeout(t(e+1),100),void a.raise("fileloaded",[F,T,e,l])):(b=a.msgInvalidFileExtension.replace("{name}",I).replace("{extensions}",A),void(a.isError=g(b,F,T,e)))},t(0),a.updateFileDetails(u,!1)},updateFileDetails:function(e){var i=this,t=i.$element,a=i.getFileStack(),n=t.val()||a.length&&a[0].name||"",l=i.slug(n),o=i.isUploadable?a.length:e,s=r.count(i.id)+o,d=o>1?i.getMsgSelected(s):l;i.isError?(i.$previewContainer.removeClass("file-thumb-loading"),i.$previewStatus.html(""),i.$captionContainer.find(".kv-caption-icon").hide()):i.showFileIcon(),i.setCaption(d,i.isError),i.$container.removeClass("file-input-new file-input-ajax-new"),1===arguments.length&&i.raise("fileselect",[e,l]),r.count(i.id)&&i.initPreviewDeletes()},validateMinCount:function(){var e=this,i=e.isUploadable?e.getFileStack().length:e.$element.get(0).files.length;return e.validateInitialCount&&e.minFileCount>0&&e.getFileCount(i-1)<e.minFileCount?(e.noFilesError({}),!1):!0},getFileCount:function(e){var i=this,t=0;return i.validateInitialCount&&!i.overwriteInitial&&(t=r.count(i.id),e+=t),e},change:function(i){var t=this,a=t.$element;if(!t.isUploadable&&W(a.val())&&t.fileInputCleared)return void(t.fileInputCleared=!1);t.fileInputCleared=!1;var n,l,o,s,d,c,p=arguments.length>1,u=p?i.originalEvent.dataTransfer.files:a.get(0).files,f=W(a.attr("multiple")),v=0,g=0,m=t.filestack.length,h=t.isUploadable,w=f&&m>0,b=function(i,a,r,n){var l=e.extend(t.getOutData({},{},u),{id:r,index:n}),o={id:r,index:n,file:a,files:u};return t.isUploadable?t.showUploadError(i,l):t.showError(i,o)};if(t.reader=null,t.resetUpload(),t.hideFileIcon(),t.isUploadable&&t.$container.find(".file-drop-zone ."+t.dropZoneTitleClass).remove(),p)for(n=[];u[v];)s=u[v],s.type||s.size%4096!==0?n.push(s):g++,v++;else n=void 0===i.target.files?i.target&&i.target.value?[{name:i.target.value.replace(/^.+\\/,"")}]:[]:i.target.files;if(W(n)||0===n.length)return h||t.clear(),t.showFolderError(g),void t.raise("fileselectnone");if(t.resetErrors(),c=n.length,o=t.isUploadable?t.getFileStack().length+c:c,o=t.getFileCount(o),t.maxFileCount>0&&o>t.maxFileCount){if(!t.autoReplace||c>t.maxFileCount)return d=t.autoReplace&&c>t.maxFileCount?c:o,l=t.msgFilesTooMany.replace("{m}",t.maxFileCount).replace("{n}",d),t.isError=b(l,null,null,null),t.$captionContainer.find(".kv-caption-icon").hide(),t.setCaption("",!0),void t.$container.removeClass("file-input-new file-input-ajax-new");o>t.maxFileCount&&t.resetPreviewThumbs(h)}else!h||w?(t.resetPreviewThumbs(!1),w&&t.clearStack()):!h||0!==m||r.count(t.id)&&!t.overwriteInitial||t.resetPreviewThumbs(!0);t.isPreviewable?t.readFiles(n):t.updateFileDetails(1),t.showFolderError(g)},getFileName:function(e){return e&&e.name?this.slug(e.name):void 0},getFileNames:function(e){var i=this;return i.filenames.filter(function(i){return e?void 0!==i:void 0!==i&&null!==i})},getFileStack:function(e){var i=this;return i.filestack.filter(function(i){return e?void 0!==i:void 0!==i&&null!==i})},clearStack:function(){var e=this;e.filestack=[],e.filenames=[]},updateStack:function(e,i){var t=this;t.filestack[e]=i,t.filenames[e]=t.getFileName(i)},pushStack:function(e){var i=this;i.filestack.push(e),i.filenames.push(i.getFileName(e))},checkDimensions:function(e,i,t,a,r,n,l){var o,s,d,c,p=this,u="Small"===i?"min":"max",f=p[u+"Image"+n];!W(f)&&t.length&&(d=t[0],s="Width"===n?d.naturalWidth||d.width:d.naturalHeight||d.height,c="Small"===i?s>=f:f>=s,c||(o=p["msgImage"+n+i].replace("{name}",r).replace("{size}",f),p.showUploadError(o,l),p.setThumbStatus(a,"Error"),p.updateStack(e,null)))},validateImage:function(e,i,t,r){var n,l,o,s=this,d=s.$preview,c=d.find("#"+i),p=c.find("img");t=t||"Untitled",p.length&&a(p,"load",function(){l=c.width(),o=d.width(),l>o&&(p.css("width","100%"),c.css("width","97%")),n={ind:e,id:i},s.checkDimensions(e,"Small",p,c,t,"Width",n),s.checkDimensions(e,"Small",p,c,t,"Height",n),s.resizeImage||(s.checkDimensions(e,"Large",p,c,t,"Width",n),s.checkDimensions(e,"Large",p,c,t,"Height",n)),s.raise("fileimageloaded",[i]),s.loadedImages.push({ind:e,img:p,thumb:c,pid:i,typ:r}),s.validateAllImages(),Q.revokeObjectURL(p.attr("src"))})},validateAllImages:function(){var e,i,t,a,r,n,l,o=this,s={};if(o.loadedImages.length===o.totalImagesCount&&(o.raise("fileimagesloaded"),o.resizeImage)){for(l=o.isUploadable?o.showUploadError:o.showError,e=0;e<o.loadedImages.length;e++)i=o.loadedImages[e],t=i.img,a=i.thumb,r=i.pid,n=i.ind,s={id:r,index:n},o.getResizedImage(t[0],i.typ,r,n)||(l(o.msgImageResizeError,s,"fileimageresizeerror"),o.setThumbStatus(a,"Error"),o.updateStack(n,void 0));o.raise("fileimagesresized")}},getResizedImage:function(e,i,t,a){var r,n,l=this,o=e.naturalWidth,s=e.naturalHeight,d=1,c=l.maxImageWidth||o,p=l.maxImageHeight||s,u=o&&s,f=l.imageCanvas,v=l.imageCanvasContext;if(!u)return!1;if(o===c&&s===p)return!0;i=i||l.resizeDefaultImageType,r=o>c,n=s>p,d="width"===l.resizePreference?r?c/o:n?p/s:1:n?p/s:r?c/o:1,l.resetCanvas(),o*=d,s*=d,f.width=o,f.height=s;try{return v.drawImage(e,0,0,o,s),f.toBlob(function(e){l.raise("fileimageresized",[t,a]),l.filestack[a]=e},i,l.resizeQuality),!0}catch(g){return!1}},initCaption:function(){var e=this,i=e.initialCaption||"";return e.overwriteInitial||W(i)?(e.$caption.html(""),!1):(e.setCaption(i),!0)},setCaption:function(i,t){var a,r,n=this;if(t)a=e("<div>"+n.msgValidationError+"</div>").text(),r='<span class="'+n.msgValidationErrorClass+'">'+n.msgValidationErrorIcon+a+"</span>";else{if(W(i)||0===n.$caption.length)return;a=e("<div>"+i+"</div>").text(),r=n.getLayoutTemplate("icon")+a}n.$caption.html(r),n.$caption.attr("title",a),n.$captionContainer.find(".file-caption-ellipsis").attr("title",a)},initBrowse:function(e){var i=this;i.$btnFile=e.find(".btn-file"),i.$btnFile.append(i.$element)},createContainer:function(){var i=this,t=e(document.createElement("div")).attr({"class":"file-input file-input-new"}).html(i.renderMain());return i.$element.before(t),i.initBrowse(t),t},refreshContainer:function(){var e=this,i=e.$container;i.before(e.$element),i.html(e.renderMain()),e.initBrowse(i)},renderMain:function(){var e=this,i=e.isUploadable&&e.dropZoneEnabled?" file-drop-zone":"file-drop-disabled",t=e.showClose?e.getLayoutTemplate("close"):"",a=e.showPreview?e.getLayoutTemplate("preview").replace(/\{class}/g,e.previewClass).replace(/\{dropClass}/g,i):"",r=e.isDisabled?e.captionClass+" file-caption-disabled":e.captionClass,n=e.captionTemplate.replace(/\{class}/g,r+" kv-fileinput-caption");return e.mainTemplate.replace(/\{class}/g,e.mainClass).replace(/\{preview}/g,a).replace(/\{close}/g,t).replace(/\{caption}/g,n).replace(/\{upload}/g,e.renderButton("upload")).replace(/\{remove}/g,e.renderButton("remove")).replace(/\{cancel}/g,e.renderButton("cancel")).replace(/\{browse}/g,e.renderButton("browse"))},renderButton:function(e){var i=this,t=i.getLayoutTemplate("btnDefault"),a=i[e+"Class"],r=i[e+"Title"],n=i[e+"Icon"],l=i[e+"Label"],o=i.isDisabled?" disabled":"",s="button";switch(e){case"remove":if(!i.showRemove)return"";break;case"cancel":if(!i.showCancel)return"";a+=" hide";break;case"upload":if(!i.showUpload)return"";i.isUploadable&&!i.isDisabled?t=i.getLayoutTemplate("btnLink").replace("{href}",i.uploadUrl):s="submit";break;case"browse":t=i.getLayoutTemplate("btnBrowse");break;default:return""}return a+="browse"===e?" btn-file":" fileinput-"+e+" fileinput-"+e+"-button",W(l)||(l=' <span class="'+i.buttonLabelClass+'">'+l+"</span>"),t.replace("{type}",s).replace("{css}",a).replace("{title}",r).replace("{status}",o).replace("{icon}",n).replace("{label}",l)}},e.fn.fileinput=function(t){if(l()||i(9)){var a=Array.apply(null,arguments),r=[];switch(a.shift(),this.each(function(){var i=e(this),n=i.data("fileinput"),l="object"==typeof t&&t,o=l.language||i.data("language")||"en",s=e.fn.fileinput.defaults;n||("en"===o||W(e.fn.fileinputLocales[o])||e.extend(s,e.fn.fileinputLocales[o]),n=new Y(this,e.extend(s,l,i.data())),i.data("fileinput",n)),"string"==typeof t&&r.push(n[t].apply(n,a))}),r.length){case 0:return this;case 1:return r[0];default:return r}}},e.fn.fileinput.defaults={language:"en",showCaption:!0,showPreview:!0,showRemove:!0,showUpload:!0,showCancel:!0,showClose:!0,showUploadedThumbs:!0,autoReplace:!1,mainClass:"",previewClass:"",captionClass:"",mainTemplate:null,initialCaption:"",initialPreview:[],initialPreviewDelimiter:"*$$*",initialPreviewConfig:[],initialPreviewThumbTags:[],previewThumbTags:{},initialPreviewShowDelete:!0,deleteUrl:"",deleteExtraData:{},overwriteInitial:!0,layoutTemplates:M,previewTemplates:B,allowedPreviewTypes:N,allowedPreviewMimeTypes:null,allowedFileTypes:null,allowedFileExtensions:null,defaultPreviewContent:null,customLayoutTags:{},customPreviewTags:{},previewSettings:Z,fileTypeSettings:H,previewFileIcon:'<i class="glyphicon glyphicon-file"></i>',previewFileIconClass:"file-icon-4x",previewFileIconSettings:{},previewFileExtSettings:{},buttonLabelClass:"hidden-xs",browseIcon:'<i class="glyphicon glyphicon-folder-open"></i>',browseClass:"btn btn-primary",removeIcon:'<i class="glyphicon glyphicon-trash"></i>',removeClass:"btn btn-default",cancelIcon:'<i class="glyphicon glyphicon-ban-circle"></i>',cancelClass:"btn btn-default",uploadIcon:'<i class="glyphicon glyphicon-upload"></i>',uploadClass:"btn btn-default",uploadUrl:null,uploadAsync:!0,uploadExtraData:{},minImageWidth:null,minImageHeight:null,maxImageWidth:null,maxImageHeight:null,resizeImage:!1,resizePreference:"width",resizeQuality:.92,resizeDefaultImageType:"image/jpeg",maxFileSize:0,minFileCount:0,maxFileCount:0,validateInitialCount:!1,msgValidationErrorClass:"text-danger",msgValidationErrorIcon:'<i class="glyphicon glyphicon-exclamation-sign"></i> ',msgErrorClass:"file-error-message",progressThumbClass:"progress-bar progress-bar-success progress-bar-striped active",progressClass:"progress-bar progress-bar-success progress-bar-striped active",progressCompleteClass:"progress-bar progress-bar-success",previewFileType:"image",zoomIndicator:'<i class="glyphicon glyphicon-zoom-in"></i>',elCaptionContainer:null,elCaptionText:null,elPreviewContainer:null,elPreviewImage:null,elPreviewStatus:null,elErrorContainer:null,errorCloseButton:'<span class="close kv-error-close">×</span>',slugCallback:null,dropZoneEnabled:!0,dropZoneTitleClass:"file-drop-zone-title",fileActionSettings:{},otherActionButtons:"",textEncoding:"UTF-8",ajaxSettings:{},ajaxDeleteSettings:{},showAjaxErrorDetails:!0},e.fn.fileinputLocales.en={fileSingle:"file",filePlural:"files",browseLabel:"Browse …",removeLabel:"Remove",removeTitle:"Clear selected files",cancelLabel:"Cancel",cancelTitle:"Abort ongoing upload",uploadLabel:"Upload",uploadTitle:"Upload selected files",msgZoomTitle:"View details",msgZoomModalHeading:"Detailed Preview",msgSizeTooLarge:'File "{name}" (<b>{size} KB</b>) exceeds maximum allowed upload size of <b>{maxSize} KB</b>.',msgFilesTooLess:"You must select at least <b>{n}</b> {files} to upload.",msgFilesTooMany:"Number of files selected for upload <b>({n})</b> exceeds maximum allowed limit of <b>{m}</b>.",msgFileNotFound:'File "{name}" not found!',msgFileSecured:'Security restrictions prevent reading the file "{name}".',msgFileNotReadable:'File "{name}" is not readable.',msgFilePreviewAborted:'File preview aborted for "{name}".',msgFilePreviewError:'An error occurred while reading the file "{name}".',msgInvalidFileType:'Invalid type for file "{name}". Only "{types}" files are supported.',msgInvalidFileExtension:'Invalid extension for file "{name}". Only "{extensions}" files are supported.',msgUploadAborted:"The file upload was aborted",msgValidationError:"File Upload Error",msgLoading:"Loading file {index} of {files} …",msgProgress:"Loading file {index} of {files} - {name} - {percent}% completed.",msgSelected:"{n} {files} selected",msgFoldersNotAllowed:"Drag & drop files only! {n} folder(s) dropped were skipped.",msgImageWidthSmall:'Width of image file "{name}" must be at least {size} px.',msgImageHeightSmall:'Height of image file "{name}" must be at least {size} px.',msgImageWidthLarge:'Width of image file "{name}" cannot exceed {size} px.',msgImageHeightLarge:'Height of image file "{name}" cannot exceed {size} px.',msgImageResizeError:"Could not get the image dimensions to resize.",msgImageResizeException:"Error while resizing the image.<pre>{errors}</pre>",dropZoneTitle:"Drag & drop files here …"},e.extend(e.fn.fileinput.defaults,e.fn.fileinputLocales.en),e.fn.fileinput.Constructor=Y,e(document).ready(function(){var i=e("input.file[type=file]");i.length&&i.fileinput()})}); | ||
| 0 | \ No newline at end of file | 19 | \ No newline at end of file |
src/main/webapp/static/assets/plugins/fileinput/fileinput_locale_zh.js
0 → 100644
| 1 | +/*! | ||
| 2 | + * FileInput Chinese Translations | ||
| 3 | + * | ||
| 4 | + * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or | ||
| 5 | + * any HTML markup tags in the messages must not be converted or translated. | ||
| 6 | + * | ||
| 7 | + * @see http://github.com/kartik-v/bootstrap-fileinput | ||
| 8 | + * @author kangqf <kangqingfei@gmail.com> | ||
| 9 | + * | ||
| 10 | + * NOTE: this file must be saved in UTF-8 encoding. | ||
| 11 | + */ | ||
| 12 | +(function ($) { | ||
| 13 | + "use strict"; | ||
| 14 | + | ||
| 15 | + $.fn.fileinputLocales['zh'] = { | ||
| 16 | + fileSingle: '文件', | ||
| 17 | + filePlural: '多个文件', | ||
| 18 | + browseLabel: '选择 …', | ||
| 19 | + removeLabel: '移除', | ||
| 20 | + removeTitle: '清除选中文件', | ||
| 21 | + cancelLabel: '取消', | ||
| 22 | + cancelTitle: '取消进行中的上传', | ||
| 23 | + uploadLabel: '上传', | ||
| 24 | + uploadTitle: '上传选中文件', | ||
| 25 | + msgZoomTitle: '查看详情', | ||
| 26 | + msgZoomModalHeading: '详细预览', | ||
| 27 | + msgSizeTooLarge: '文件 "{name}" (<b>{size} KB</b>) 超过了允许大小 <b>{maxSize} KB</b>.', | ||
| 28 | + msgFilesTooLess: '你必须选择最少 <b>{n}</b> {files} 来上传. ', | ||
| 29 | + msgFilesTooMany: '选择的上传文件个数 <b>({n})</b> 超出最大文件的限制个数 <b>{m}</b>.', | ||
| 30 | + msgFileNotFound: '文件 "{name}" 未找到!', | ||
| 31 | + msgFileSecured: '安全限制,为了防止读取文件 "{name}".', | ||
| 32 | + msgFileNotReadable: '文件 "{name}" 不可读.', | ||
| 33 | + msgFilePreviewAborted: '取消 "{name}" 的预览.', | ||
| 34 | + msgFilePreviewError: '读取 "{name}" 时出现了一个错误.', | ||
| 35 | + msgInvalidFileType: '不正确的类型 "{name}". 只支持 "{types}" 类型的文件.', | ||
| 36 | + msgInvalidFileExtension: '不正确的文件扩展名 "{name}". 只支持 "{extensions}" 的文件扩展名.', | ||
| 37 | + msgUploadAborted: '该文件上传被中止', | ||
| 38 | + msgValidationError: '文件上传错误', | ||
| 39 | + msgLoading: '加载第 {index} 文件 共 {files} …', | ||
| 40 | + msgProgress: '加载第 {index} 文件 共 {files} - {name} - {percent}% 完成.', | ||
| 41 | + msgSelected: '{n} {files} 选中', | ||
| 42 | + msgFoldersNotAllowed: '只支持拖拽文件! 跳过 {n} 拖拽的文件夹.', | ||
| 43 | + msgImageWidthSmall: '宽度的图像文件的"{name}"的必须是至少{size}像素.', | ||
| 44 | + msgImageHeightSmall: '图像文件的"{name}"的高度必须至少为{size}像素.', | ||
| 45 | + msgImageWidthLarge: '宽度的图像文件"{name}"不能超过{size}像素.', | ||
| 46 | + msgImageHeightLarge: '图像文件"{name}"的高度不能超过{size}像素.', | ||
| 47 | + msgImageResizeError: '无法获取的图像尺寸调整。', | ||
| 48 | + msgImageResizeException: '错误而调整图像大小。<pre>{errors}</pre>', | ||
| 49 | + dropZoneTitle: '拖拽文件到这里 …', | ||
| 50 | + slugCallback: function(text) { | ||
| 51 | + return text ? text.split(/(\\|\/)/g).pop().replace(/[^\w\u4e00-\u9fa5\-.\\\/ ]+/g, '') : ''; | ||
| 52 | + }, | ||
| 53 | + fileActionSettings: { | ||
| 54 | + removeTitle: '删除文件', | ||
| 55 | + uploadTitle: '上传文件', | ||
| 56 | + indicatorNewTitle: '没有上传', | ||
| 57 | + indicatorSuccessTitle: '上传', | ||
| 58 | + indicatorErrorTitle: '上传错误', | ||
| 59 | + indicatorLoadingTitle: '上传 ...' | ||
| 60 | + } | ||
| 61 | + }; | ||
| 62 | +})(window.jQuery); | ||
| 0 | \ No newline at end of file | 63 | \ No newline at end of file |
src/main/webapp/static/assets/ueditor/dialogs/anchor/anchor.html
0 → 100644
| 1 | +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" | ||
| 2 | + "http://www.w3.org/TR/html4/loose.dtd"> | ||
| 3 | +<html> | ||
| 4 | + <head> | ||
| 5 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | ||
| 6 | + <title></title> | ||
| 7 | + <style type="text/css"> | ||
| 8 | + *{color: #838383;margin: 0;padding: 0} | ||
| 9 | + html,body {font-size: 12px;overflow: hidden; } | ||
| 10 | + .content{padding:5px 0 0 15px;} | ||
| 11 | + input{width:210px;height:21px;line-height:21px;margin-left: 4px;} | ||
| 12 | + </style> | ||
| 13 | + </head> | ||
| 14 | + <body> | ||
| 15 | + <div class="content"> | ||
| 16 | + <span><var id="lang_input_anchorName"></var></span><input id="anchorName" value="" /> | ||
| 17 | + </div> | ||
| 18 | + <script type="text/javascript" src="../internal.js"></script> | ||
| 19 | + <script type="text/javascript"> | ||
| 20 | + var anchorInput = $G('anchorName'), | ||
| 21 | + node = editor.selection.getRange().getClosedNode(); | ||
| 22 | + if(node && node.tagName == 'IMG' && (node = node.getAttribute('anchorname'))){ | ||
| 23 | + anchorInput.value = node; | ||
| 24 | + } | ||
| 25 | + anchorInput.onkeydown = function(evt){ | ||
| 26 | + evt = evt || window.event; | ||
| 27 | + if(evt.keyCode == 13){ | ||
| 28 | + editor.execCommand('anchor', anchorInput.value); | ||
| 29 | + dialog.close(); | ||
| 30 | + domUtils.preventDefault(evt) | ||
| 31 | + } | ||
| 32 | + }; | ||
| 33 | + dialog.onok = function (){ | ||
| 34 | + editor.execCommand('anchor', anchorInput.value); | ||
| 35 | + dialog.close(); | ||
| 36 | + }; | ||
| 37 | + $focus(anchorInput); | ||
| 38 | + </script> | ||
| 39 | + </body> | ||
| 40 | +</html> | ||
| 0 | \ No newline at end of file | 41 | \ No newline at end of file |