diff --git a/src/main/java/com/yaoyuan/jiscuss/common/Node.java b/src/main/java/com/yaoyuan/jiscuss/common/Node.java index 034f780..fc5d303 100644 --- a/src/main/java/com/yaoyuan/jiscuss/common/Node.java +++ b/src/main/java/com/yaoyuan/jiscuss/common/Node.java @@ -4,7 +4,6 @@ import com.yaoyuan.jiscuss.entity.custom.PostCustom; import lombok.Data; import org.springframework.beans.BeanUtils; -import javax.persistence.Column; import java.util.ArrayList; import java.util.Date; import java.util.List; diff --git a/src/main/java/com/yaoyuan/jiscuss/common/PostCommonUtil.java b/src/main/java/com/yaoyuan/jiscuss/common/PostCommonUtil.java index bdb51ce..8217dc3 100644 --- a/src/main/java/com/yaoyuan/jiscuss/common/PostCommonUtil.java +++ b/src/main/java/com/yaoyuan/jiscuss/common/PostCommonUtil.java @@ -6,7 +6,11 @@ import org.springframework.beans.BeanUtils; import java.io.BufferedReader; import java.io.Reader; import java.sql.Clob; -import java.util.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; /** * @author yaoyuan2.chu diff --git a/src/main/java/com/yaoyuan/jiscuss/config/SwaggerConfiguration.java b/src/main/java/com/yaoyuan/jiscuss/config/SwaggerConfiguration.java index a2ff6ea..b22e95a 100644 --- a/src/main/java/com/yaoyuan/jiscuss/config/SwaggerConfiguration.java +++ b/src/main/java/com/yaoyuan/jiscuss/config/SwaggerConfiguration.java @@ -2,7 +2,6 @@ package com.yaoyuan.jiscuss.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; - import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; diff --git a/src/main/java/com/yaoyuan/jiscuss/controller/BaseController.java b/src/main/java/com/yaoyuan/jiscuss/controller/BaseController.java index 621f0c0..c77e29d 100644 --- a/src/main/java/com/yaoyuan/jiscuss/controller/BaseController.java +++ b/src/main/java/com/yaoyuan/jiscuss/controller/BaseController.java @@ -3,7 +3,6 @@ package com.yaoyuan.jiscuss.controller; import com.yaoyuan.jiscuss.entity.UserInfo; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.userdetails.User; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; diff --git a/src/main/java/com/yaoyuan/jiscuss/controller/UserPageController.java b/src/main/java/com/yaoyuan/jiscuss/controller/UserPageController.java index 799f38a..b5fab16 100644 --- a/src/main/java/com/yaoyuan/jiscuss/controller/UserPageController.java +++ b/src/main/java/com/yaoyuan/jiscuss/controller/UserPageController.java @@ -1,29 +1,18 @@ package com.yaoyuan.jiscuss.controller; -import com.yaoyuan.jiscuss.entity.Discussion; -import com.yaoyuan.jiscuss.entity.Tag; -import com.yaoyuan.jiscuss.entity.User; import com.yaoyuan.jiscuss.entity.UserInfo; -import com.yaoyuan.jiscuss.entity.custom.DiscussionCustom; -import com.yaoyuan.jiscuss.entity.custom.TagCustom; import com.yaoyuan.jiscuss.service.IDiscussionsService; import com.yaoyuan.jiscuss.service.ITagsService; import com.yaoyuan.jiscuss.service.IUsersService; -import com.yaoyuan.jiscuss.util.DelTagsUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; -import java.util.*; /** * @author yaoyuan2.chu diff --git a/src/main/java/com/yaoyuan/jiscuss/controller/UserPostController.java b/src/main/java/com/yaoyuan/jiscuss/controller/UserPostController.java index 1817c8a..91f4ade 100644 --- a/src/main/java/com/yaoyuan/jiscuss/controller/UserPostController.java +++ b/src/main/java/com/yaoyuan/jiscuss/controller/UserPostController.java @@ -1,12 +1,17 @@ package com.yaoyuan.jiscuss.controller; -import java.util.*; - -import javax.servlet.http.HttpServletRequest; - -import com.yaoyuan.jiscuss.entity.*; +import com.yaoyuan.jiscuss.entity.Discussion; +import com.yaoyuan.jiscuss.entity.DiscussionTag; +import com.yaoyuan.jiscuss.entity.Post; +import com.yaoyuan.jiscuss.entity.Tag; +import com.yaoyuan.jiscuss.entity.User; +import com.yaoyuan.jiscuss.entity.UserInfo; import com.yaoyuan.jiscuss.entity.custom.DiscussionCustom; -import com.yaoyuan.jiscuss.service.*; +import com.yaoyuan.jiscuss.service.IDiscussionsService; +import com.yaoyuan.jiscuss.service.IDiscussionsTagsService; +import com.yaoyuan.jiscuss.service.IPostsService; +import com.yaoyuan.jiscuss.service.ITagsService; +import com.yaoyuan.jiscuss.service.IUsersService; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,6 +27,10 @@ import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; +import javax.servlet.http.HttpServletRequest; +import java.util.Date; +import java.util.List; + /** * 主题帖子评论控制器 */ diff --git a/src/main/java/com/yaoyuan/jiscuss/controller/UserSystemController.java b/src/main/java/com/yaoyuan/jiscuss/controller/UserSystemController.java index 3debb01..caf0001 100644 --- a/src/main/java/com/yaoyuan/jiscuss/controller/UserSystemController.java +++ b/src/main/java/com/yaoyuan/jiscuss/controller/UserSystemController.java @@ -2,8 +2,8 @@ package com.yaoyuan.jiscuss.controller; import com.yaoyuan.jiscuss.entity.Discussion; import com.yaoyuan.jiscuss.entity.Tag; -import com.yaoyuan.jiscuss.entity.UserInfo; import com.yaoyuan.jiscuss.entity.User; +import com.yaoyuan.jiscuss.entity.UserInfo; import com.yaoyuan.jiscuss.entity.custom.DiscussionCustom; import com.yaoyuan.jiscuss.entity.custom.TagCustom; import com.yaoyuan.jiscuss.service.IDiscussionsService; @@ -17,10 +17,17 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; -import java.util.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * 首页页面系统控制器 @@ -78,7 +85,7 @@ public class UserSystemController extends BaseController { List allTags = tagsService.getAllList(); logger.info("全部标签==>:{}", allTags); - if(!tag.equals("all")){ + if (!tag.equals("all")) { //获取是否有子标签 List allChildTags = tagsService.findByParentId(tag); map.put("allChildTags", allChildTags); @@ -152,15 +159,15 @@ public class UserSystemController extends BaseController { newdd.setContent(newCon); if (null != newdd.getStartUserId()) { User startUser = usersService.findOne(newdd.getStartUserId()); - newdd.setAvatar(startUser.getAvatar()); - newdd.setRealname(startUser.getRealname()); - newdd.setUsername(startUser.getUsername()); + newdd.setAvatar(startUser != null && startUser.getAvatar() != null ? startUser.getAvatar() : ""); + newdd.setRealname(startUser != null && startUser.getRealname() != null ? startUser.getRealname() : ""); + newdd.setUsername(startUser != null && startUser.getUsername() != null ? startUser.getUsername() : ""); } if (null != newdd.getLastUserId()) { User lastUser = usersService.findOne(newdd.getLastUserId()); - newdd.setAvatarLast(lastUser.getAvatar()); - newdd.setRealnameLast(lastUser.getRealname()); - newdd.setUsernameLast(lastUser.getUsername()); + newdd.setAvatarLast(lastUser != null && lastUser.getAvatar() != null ? lastUser.getAvatar() : ""); + newdd.setRealnameLast(lastUser != null && lastUser.getRealname() != null ? lastUser.getRealname() : ""); + newdd.setUsernameLast(lastUser != null && lastUser.getUsername() != null ? lastUser.getUsername() : ""); } //组装tag newdd.setTagList(tagMap.get(dd.getId())); diff --git a/src/main/java/com/yaoyuan/jiscuss/controller/api/RestPostController.java b/src/main/java/com/yaoyuan/jiscuss/controller/api/RestPostController.java index 5a9b614..9af6e45 100644 --- a/src/main/java/com/yaoyuan/jiscuss/controller/api/RestPostController.java +++ b/src/main/java/com/yaoyuan/jiscuss/controller/api/RestPostController.java @@ -1,7 +1,11 @@ package com.yaoyuan.jiscuss.controller.api; -import java.util.List; - +import com.yaoyuan.jiscuss.entity.Discussion; +import com.yaoyuan.jiscuss.exception.BaseException; +import com.yaoyuan.jiscuss.response.ResponseCode; +import com.yaoyuan.jiscuss.service.IDiscussionsService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -12,13 +16,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import com.yaoyuan.jiscuss.entity.Discussion; -import com.yaoyuan.jiscuss.exception.BaseException; -import com.yaoyuan.jiscuss.response.ResponseCode; -import com.yaoyuan.jiscuss.service.IDiscussionsService; - -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import java.util.List; @RestController @RequestMapping(path = "/other_api", produces = "application/json;charset=utf-8") diff --git a/src/main/java/com/yaoyuan/jiscuss/controller/api/RestUserController.java b/src/main/java/com/yaoyuan/jiscuss/controller/api/RestUserController.java index ef849d8..3cacfef 100644 --- a/src/main/java/com/yaoyuan/jiscuss/controller/api/RestUserController.java +++ b/src/main/java/com/yaoyuan/jiscuss/controller/api/RestUserController.java @@ -1,7 +1,11 @@ package com.yaoyuan.jiscuss.controller.api; -import java.util.List; - +import com.yaoyuan.jiscuss.entity.User; +import com.yaoyuan.jiscuss.exception.BaseException; +import com.yaoyuan.jiscuss.response.ResponseCode; +import com.yaoyuan.jiscuss.service.IUsersService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -14,13 +18,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import com.yaoyuan.jiscuss.entity.User; -import com.yaoyuan.jiscuss.exception.BaseException; -import com.yaoyuan.jiscuss.response.ResponseCode; -import com.yaoyuan.jiscuss.service.IUsersService; - -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import java.util.List; @RestController @RequestMapping("/user_api") diff --git a/src/main/java/com/yaoyuan/jiscuss/entity/Discussion.java b/src/main/java/com/yaoyuan/jiscuss/entity/Discussion.java index 8aa1208..e29cdbc 100644 --- a/src/main/java/com/yaoyuan/jiscuss/entity/Discussion.java +++ b/src/main/java/com/yaoyuan/jiscuss/entity/Discussion.java @@ -1,7 +1,6 @@ package com.yaoyuan.jiscuss.entity; -import java.io.Serializable; -import java.util.Date; +import lombok.Data; import javax.persistence.Column; import javax.persistence.Entity; @@ -9,8 +8,8 @@ import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; - -import lombok.Data; +import java.io.Serializable; +import java.util.Date; @Data @Entity diff --git a/src/main/java/com/yaoyuan/jiscuss/entity/DiscussionTag.java b/src/main/java/com/yaoyuan/jiscuss/entity/DiscussionTag.java index 963c869..b272be9 100644 --- a/src/main/java/com/yaoyuan/jiscuss/entity/DiscussionTag.java +++ b/src/main/java/com/yaoyuan/jiscuss/entity/DiscussionTag.java @@ -1,11 +1,15 @@ package com.yaoyuan.jiscuss.entity; -import java.io.Serializable; - -import javax.persistence.*; - import lombok.Data; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import java.io.Serializable; + @Data @Entity @Table(name = "discussiontag") diff --git a/src/main/java/com/yaoyuan/jiscuss/entity/LikeCollect.java b/src/main/java/com/yaoyuan/jiscuss/entity/LikeCollect.java index 80aee45..b7bce26 100644 --- a/src/main/java/com/yaoyuan/jiscuss/entity/LikeCollect.java +++ b/src/main/java/com/yaoyuan/jiscuss/entity/LikeCollect.java @@ -2,7 +2,12 @@ package com.yaoyuan.jiscuss.entity; import lombok.Data; -import javax.persistence.*; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; import java.io.Serializable; import java.util.Date; diff --git a/src/main/java/com/yaoyuan/jiscuss/entity/Post.java b/src/main/java/com/yaoyuan/jiscuss/entity/Post.java index 162d37a..8dda459 100644 --- a/src/main/java/com/yaoyuan/jiscuss/entity/Post.java +++ b/src/main/java/com/yaoyuan/jiscuss/entity/Post.java @@ -1,7 +1,6 @@ package com.yaoyuan.jiscuss.entity; -import java.io.Serializable; -import java.util.Date; +import lombok.Data; import javax.persistence.Column; import javax.persistence.Entity; @@ -9,8 +8,8 @@ import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; - -import lombok.Data; +import java.io.Serializable; +import java.util.Date; @Data @Entity diff --git a/src/main/java/com/yaoyuan/jiscuss/entity/Setting.java b/src/main/java/com/yaoyuan/jiscuss/entity/Setting.java index bc57ef4..b280ed4 100644 --- a/src/main/java/com/yaoyuan/jiscuss/entity/Setting.java +++ b/src/main/java/com/yaoyuan/jiscuss/entity/Setting.java @@ -1,11 +1,15 @@ package com.yaoyuan.jiscuss.entity; -import java.io.Serializable; - -import javax.persistence.*; - import lombok.Data; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import java.io.Serializable; + @Data @Entity @Table(name = "setting") diff --git a/src/main/java/com/yaoyuan/jiscuss/entity/Tag.java b/src/main/java/com/yaoyuan/jiscuss/entity/Tag.java index 0e7ae98..1606c25 100644 --- a/src/main/java/com/yaoyuan/jiscuss/entity/Tag.java +++ b/src/main/java/com/yaoyuan/jiscuss/entity/Tag.java @@ -1,7 +1,6 @@ package com.yaoyuan.jiscuss.entity; -import java.io.Serializable; -import java.util.Date; +import lombok.Data; import javax.persistence.Column; import javax.persistence.Entity; @@ -9,8 +8,8 @@ import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; - -import lombok.Data; +import java.io.Serializable; +import java.util.Date; @Data @Entity diff --git a/src/main/java/com/yaoyuan/jiscuss/entity/User.java b/src/main/java/com/yaoyuan/jiscuss/entity/User.java index d26b5ad..86914ed 100644 --- a/src/main/java/com/yaoyuan/jiscuss/entity/User.java +++ b/src/main/java/com/yaoyuan/jiscuss/entity/User.java @@ -1,11 +1,7 @@ package com.yaoyuan.jiscuss.entity; -import java.io.Serializable; - -import java.util.Collection; -import java.util.Date; -import java.util.List; +import lombok.Data; import javax.persistence.Column; import javax.persistence.Entity; @@ -13,11 +9,8 @@ import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; - - -import lombok.Data; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; +import java.io.Serializable; +import java.util.Date; @Data @Entity diff --git a/src/main/java/com/yaoyuan/jiscuss/entity/UserInfo.java b/src/main/java/com/yaoyuan/jiscuss/entity/UserInfo.java index 759ecf9..631ad31 100644 --- a/src/main/java/com/yaoyuan/jiscuss/entity/UserInfo.java +++ b/src/main/java/com/yaoyuan/jiscuss/entity/UserInfo.java @@ -5,7 +5,6 @@ import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import java.util.Collection; -import java.util.Set; /** * @author yaoyuan2.chu diff --git a/src/main/java/com/yaoyuan/jiscuss/entity/custom/DiscussionCustom.java b/src/main/java/com/yaoyuan/jiscuss/entity/custom/DiscussionCustom.java index 697cad4..5a586d7 100644 --- a/src/main/java/com/yaoyuan/jiscuss/entity/custom/DiscussionCustom.java +++ b/src/main/java/com/yaoyuan/jiscuss/entity/custom/DiscussionCustom.java @@ -1,12 +1,10 @@ package com.yaoyuan.jiscuss.entity.custom; import com.yaoyuan.jiscuss.entity.Discussion; -import com.yaoyuan.jiscuss.entity.Tag; import lombok.Data; import lombok.Getter; import lombok.Setter; -import javax.persistence.Entity; import java.util.List; /** diff --git a/src/main/java/com/yaoyuan/jiscuss/entity/custom/PostCustom.java b/src/main/java/com/yaoyuan/jiscuss/entity/custom/PostCustom.java index 06bc3e3..4fac8eb 100644 --- a/src/main/java/com/yaoyuan/jiscuss/entity/custom/PostCustom.java +++ b/src/main/java/com/yaoyuan/jiscuss/entity/custom/PostCustom.java @@ -5,8 +5,6 @@ import lombok.Data; import lombok.Getter; import lombok.Setter; -import javax.persistence.Column; -import javax.persistence.Entity; import java.util.List; /** diff --git a/src/main/java/com/yaoyuan/jiscuss/entity/custom/TagCustom.java b/src/main/java/com/yaoyuan/jiscuss/entity/custom/TagCustom.java index a76fd95..54ed72a 100644 --- a/src/main/java/com/yaoyuan/jiscuss/entity/custom/TagCustom.java +++ b/src/main/java/com/yaoyuan/jiscuss/entity/custom/TagCustom.java @@ -1,14 +1,10 @@ package com.yaoyuan.jiscuss.entity.custom; -import com.yaoyuan.jiscuss.entity.Post; -import com.yaoyuan.jiscuss.entity.Tag; import lombok.Data; import lombok.Getter; import lombok.Setter; import javax.persistence.Column; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; /** * @author yaoyuan2.chu diff --git a/src/main/java/com/yaoyuan/jiscuss/exception/BaseException.java b/src/main/java/com/yaoyuan/jiscuss/exception/BaseException.java index d741a78..8f07e17 100644 --- a/src/main/java/com/yaoyuan/jiscuss/exception/BaseException.java +++ b/src/main/java/com/yaoyuan/jiscuss/exception/BaseException.java @@ -1,7 +1,6 @@ package com.yaoyuan.jiscuss.exception; import com.yaoyuan.jiscuss.response.ResponseCode; - import lombok.Data; import lombok.EqualsAndHashCode; diff --git a/src/main/java/com/yaoyuan/jiscuss/handler/RbacPermission.java b/src/main/java/com/yaoyuan/jiscuss/handler/RbacPermission.java index c3ff81c..6bd5aa1 100644 --- a/src/main/java/com/yaoyuan/jiscuss/handler/RbacPermission.java +++ b/src/main/java/com/yaoyuan/jiscuss/handler/RbacPermission.java @@ -5,7 +5,6 @@ import org.springframework.stereotype.Component; import org.springframework.util.AntPathMatcher; import javax.servlet.http.HttpServletRequest; -import java.util.List; /** * RBAC数据模型控制权限 diff --git a/src/main/java/com/yaoyuan/jiscuss/repository/DiscussionsRepository.java b/src/main/java/com/yaoyuan/jiscuss/repository/DiscussionsRepository.java index 04d1d2e..c1df9d7 100644 --- a/src/main/java/com/yaoyuan/jiscuss/repository/DiscussionsRepository.java +++ b/src/main/java/com/yaoyuan/jiscuss/repository/DiscussionsRepository.java @@ -1,17 +1,12 @@ package com.yaoyuan.jiscuss.repository; import com.yaoyuan.jiscuss.entity.Discussion; -import com.yaoyuan.jiscuss.entity.User; -import org.springframework.data.domain.Example; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import java.util.List; - @Repository public interface DiscussionsRepository extends JpaRepository { diff --git a/src/main/java/com/yaoyuan/jiscuss/repository/PostsRepository.java b/src/main/java/com/yaoyuan/jiscuss/repository/PostsRepository.java index 11876f9..fcbead1 100644 --- a/src/main/java/com/yaoyuan/jiscuss/repository/PostsRepository.java +++ b/src/main/java/com/yaoyuan/jiscuss/repository/PostsRepository.java @@ -1,7 +1,6 @@ package com.yaoyuan.jiscuss.repository; import com.yaoyuan.jiscuss.entity.Post; -import com.yaoyuan.jiscuss.entity.custom.PostCustom; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; diff --git a/src/main/java/com/yaoyuan/jiscuss/repository/UsersRepository.java b/src/main/java/com/yaoyuan/jiscuss/repository/UsersRepository.java index d4a4060..dcd5e45 100644 --- a/src/main/java/com/yaoyuan/jiscuss/repository/UsersRepository.java +++ b/src/main/java/com/yaoyuan/jiscuss/repository/UsersRepository.java @@ -1,13 +1,12 @@ package com.yaoyuan.jiscuss.repository; -import java.util.List; - +import com.yaoyuan.jiscuss.entity.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import com.yaoyuan.jiscuss.entity.User; +import java.util.List; @Repository diff --git a/src/main/java/com/yaoyuan/jiscuss/response/ResponseResult.java b/src/main/java/com/yaoyuan/jiscuss/response/ResponseResult.java index 0bb377b..5e1b868 100644 --- a/src/main/java/com/yaoyuan/jiscuss/response/ResponseResult.java +++ b/src/main/java/com/yaoyuan/jiscuss/response/ResponseResult.java @@ -1,10 +1,10 @@ package com.yaoyuan.jiscuss.response; -import java.io.Serializable; - import lombok.AllArgsConstructor; import lombok.Data; +import java.io.Serializable; + /** * 统一的公共响应体 * diff --git a/src/main/java/com/yaoyuan/jiscuss/service/IDiscussionsService.java b/src/main/java/com/yaoyuan/jiscuss/service/IDiscussionsService.java index a96b9d7..04459dd 100644 --- a/src/main/java/com/yaoyuan/jiscuss/service/IDiscussionsService.java +++ b/src/main/java/com/yaoyuan/jiscuss/service/IDiscussionsService.java @@ -1,10 +1,9 @@ package com.yaoyuan.jiscuss.service; -import java.util.List; - +import com.yaoyuan.jiscuss.entity.Discussion; import org.springframework.data.domain.Page; -import com.yaoyuan.jiscuss.entity.Discussion; +import java.util.List; public interface IDiscussionsService { diff --git a/src/main/java/com/yaoyuan/jiscuss/service/IDiscussionsTagsService.java b/src/main/java/com/yaoyuan/jiscuss/service/IDiscussionsTagsService.java index 8f4130d..9dc3f3b 100644 --- a/src/main/java/com/yaoyuan/jiscuss/service/IDiscussionsTagsService.java +++ b/src/main/java/com/yaoyuan/jiscuss/service/IDiscussionsTagsService.java @@ -1,9 +1,9 @@ package com.yaoyuan.jiscuss.service; -import java.util.List; - import com.yaoyuan.jiscuss.entity.DiscussionTag; +import java.util.List; + public interface IDiscussionsTagsService { List getAllList(); diff --git a/src/main/java/com/yaoyuan/jiscuss/service/IPostsService.java b/src/main/java/com/yaoyuan/jiscuss/service/IPostsService.java index 473cc7b..b58772c 100644 --- a/src/main/java/com/yaoyuan/jiscuss/service/IPostsService.java +++ b/src/main/java/com/yaoyuan/jiscuss/service/IPostsService.java @@ -1,11 +1,10 @@ package com.yaoyuan.jiscuss.service; -import java.util.List; -import java.util.Map; - import com.yaoyuan.jiscuss.entity.Post; import com.yaoyuan.jiscuss.entity.custom.PostCustom; +import java.util.List; + public interface IPostsService { List getAllList(); diff --git a/src/main/java/com/yaoyuan/jiscuss/service/ISettingsService.java b/src/main/java/com/yaoyuan/jiscuss/service/ISettingsService.java index 342121c..9f453d7 100644 --- a/src/main/java/com/yaoyuan/jiscuss/service/ISettingsService.java +++ b/src/main/java/com/yaoyuan/jiscuss/service/ISettingsService.java @@ -1,9 +1,9 @@ package com.yaoyuan.jiscuss.service; -import java.util.List; - import com.yaoyuan.jiscuss.entity.Setting; +import java.util.List; + public interface ISettingsService { List getAllList(); diff --git a/src/main/java/com/yaoyuan/jiscuss/service/ITagsService.java b/src/main/java/com/yaoyuan/jiscuss/service/ITagsService.java index 279399a..732400e 100644 --- a/src/main/java/com/yaoyuan/jiscuss/service/ITagsService.java +++ b/src/main/java/com/yaoyuan/jiscuss/service/ITagsService.java @@ -1,10 +1,10 @@ package com.yaoyuan.jiscuss.service; -import java.util.List; - import com.yaoyuan.jiscuss.entity.Tag; import com.yaoyuan.jiscuss.entity.custom.TagCustom; +import java.util.List; + public interface ITagsService { List getAllList(); diff --git a/src/main/java/com/yaoyuan/jiscuss/service/IUsersService.java b/src/main/java/com/yaoyuan/jiscuss/service/IUsersService.java index 23152e6..8a6deb3 100644 --- a/src/main/java/com/yaoyuan/jiscuss/service/IUsersService.java +++ b/src/main/java/com/yaoyuan/jiscuss/service/IUsersService.java @@ -1,10 +1,9 @@ package com.yaoyuan.jiscuss.service; -import java.util.List; - +import com.yaoyuan.jiscuss.entity.User; import org.springframework.data.domain.Page; -import com.yaoyuan.jiscuss.entity.User; +import java.util.List; public interface IUsersService { diff --git a/src/main/java/com/yaoyuan/jiscuss/service/impl/DiscussionsServiceImpl.java b/src/main/java/com/yaoyuan/jiscuss/service/impl/DiscussionsServiceImpl.java index 9037ad0..6f5adcf 100644 --- a/src/main/java/com/yaoyuan/jiscuss/service/impl/DiscussionsServiceImpl.java +++ b/src/main/java/com/yaoyuan/jiscuss/service/impl/DiscussionsServiceImpl.java @@ -1,16 +1,18 @@ package com.yaoyuan.jiscuss.service.impl; -import java.util.List; - -import javax.transaction.Transactional; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.*; -import org.springframework.stereotype.Service; - import com.yaoyuan.jiscuss.entity.Discussion; import com.yaoyuan.jiscuss.repository.DiscussionsRepository; import com.yaoyuan.jiscuss.service.IDiscussionsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Example; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; + +import javax.transaction.Transactional; +import java.util.List; @Service @Transactional diff --git a/src/main/java/com/yaoyuan/jiscuss/service/impl/DiscussionsTagsServiceImpl.java b/src/main/java/com/yaoyuan/jiscuss/service/impl/DiscussionsTagsServiceImpl.java index 04e887a..0a7fd75 100644 --- a/src/main/java/com/yaoyuan/jiscuss/service/impl/DiscussionsTagsServiceImpl.java +++ b/src/main/java/com/yaoyuan/jiscuss/service/impl/DiscussionsTagsServiceImpl.java @@ -1,15 +1,13 @@ package com.yaoyuan.jiscuss.service.impl; -import java.util.List; - -import javax.transaction.Transactional; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - import com.yaoyuan.jiscuss.entity.DiscussionTag; import com.yaoyuan.jiscuss.repository.DiscussionsTagsRepository; import com.yaoyuan.jiscuss.service.IDiscussionsTagsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.transaction.Transactional; +import java.util.List; @Service @Transactional diff --git a/src/main/java/com/yaoyuan/jiscuss/service/impl/PostsServiceImpl.java b/src/main/java/com/yaoyuan/jiscuss/service/impl/PostsServiceImpl.java index 95a3595..dcd4672 100644 --- a/src/main/java/com/yaoyuan/jiscuss/service/impl/PostsServiceImpl.java +++ b/src/main/java/com/yaoyuan/jiscuss/service/impl/PostsServiceImpl.java @@ -1,25 +1,21 @@ package com.yaoyuan.jiscuss.service.impl; -import java.io.BufferedReader; -import java.io.Reader; -import java.sql.Clob; -import java.util.*; - import com.yaoyuan.jiscuss.common.Node; import com.yaoyuan.jiscuss.common.PostCommonUtil; -import com.yaoyuan.jiscuss.entity.Discussion; -import com.yaoyuan.jiscuss.entity.custom.DiscussionCustom; -import com.yaoyuan.jiscuss.entity.custom.PostCustom; -import org.springframework.beans.BeanUtils; -import org.springframework.beans.factory.annotation.Autowired; - import com.yaoyuan.jiscuss.entity.Post; +import com.yaoyuan.jiscuss.entity.custom.PostCustom; import com.yaoyuan.jiscuss.repository.PostsRepository; import com.yaoyuan.jiscuss.service.IPostsService; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Example; import org.springframework.stereotype.Service; import javax.transaction.Transactional; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; @Service diff --git a/src/main/java/com/yaoyuan/jiscuss/service/impl/SettingsServiceImpl.java b/src/main/java/com/yaoyuan/jiscuss/service/impl/SettingsServiceImpl.java index 677a96c..eb67906 100644 --- a/src/main/java/com/yaoyuan/jiscuss/service/impl/SettingsServiceImpl.java +++ b/src/main/java/com/yaoyuan/jiscuss/service/impl/SettingsServiceImpl.java @@ -1,15 +1,13 @@ package com.yaoyuan.jiscuss.service.impl; -import java.util.List; - -import javax.transaction.Transactional; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - import com.yaoyuan.jiscuss.entity.Setting; import com.yaoyuan.jiscuss.repository.SettingsRepository; import com.yaoyuan.jiscuss.service.ISettingsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.transaction.Transactional; +import java.util.List; @Service @Transactional diff --git a/src/main/java/com/yaoyuan/jiscuss/service/impl/TagsServiceImpl.java b/src/main/java/com/yaoyuan/jiscuss/service/impl/TagsServiceImpl.java index 3e52d8d..c340f79 100644 --- a/src/main/java/com/yaoyuan/jiscuss/service/impl/TagsServiceImpl.java +++ b/src/main/java/com/yaoyuan/jiscuss/service/impl/TagsServiceImpl.java @@ -1,16 +1,14 @@ package com.yaoyuan.jiscuss.service.impl; -import java.util.List; - -import javax.transaction.Transactional; - +import com.yaoyuan.jiscuss.entity.Tag; import com.yaoyuan.jiscuss.entity.custom.TagCustom; +import com.yaoyuan.jiscuss.repository.TagsRepository; +import com.yaoyuan.jiscuss.service.ITagsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import com.yaoyuan.jiscuss.entity.Tag; -import com.yaoyuan.jiscuss.repository.TagsRepository; -import com.yaoyuan.jiscuss.service.ITagsService; +import javax.transaction.Transactional; +import java.util.List; @Service @Transactional @@ -44,7 +42,7 @@ public class TagsServiceImpl implements ITagsService { } @Override - public List findByParentId(String tag){ + public List findByParentId(String tag) { int tagId = Integer.parseInt(tag); return tagsRepository.findByParentId(tagId); } diff --git a/src/main/java/com/yaoyuan/jiscuss/service/impl/UserDetailServiceImpl.java b/src/main/java/com/yaoyuan/jiscuss/service/impl/UserDetailServiceImpl.java index 00c8939..c5cc22a 100644 --- a/src/main/java/com/yaoyuan/jiscuss/service/impl/UserDetailServiceImpl.java +++ b/src/main/java/com/yaoyuan/jiscuss/service/impl/UserDetailServiceImpl.java @@ -1,7 +1,7 @@ package com.yaoyuan.jiscuss.service.impl; -import com.yaoyuan.jiscuss.entity.UserInfo; import com.yaoyuan.jiscuss.entity.User; +import com.yaoyuan.jiscuss.entity.UserInfo; import com.yaoyuan.jiscuss.service.IUsersService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.GrantedAuthority; diff --git a/src/main/java/com/yaoyuan/jiscuss/service/impl/UsersServiceImpl.java b/src/main/java/com/yaoyuan/jiscuss/service/impl/UsersServiceImpl.java index a886ae8..652ca97 100644 --- a/src/main/java/com/yaoyuan/jiscuss/service/impl/UsersServiceImpl.java +++ b/src/main/java/com/yaoyuan/jiscuss/service/impl/UsersServiceImpl.java @@ -1,23 +1,21 @@ package com.yaoyuan.jiscuss.service.impl; -import java.util.List; - -import javax.transaction.Transactional; - +import com.yaoyuan.jiscuss.entity.User; +import com.yaoyuan.jiscuss.repository.UsersRepository; +import com.yaoyuan.jiscuss.service.IUsersService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; +import org.springframework.cache.annotation.Cacheable; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; -import org.springframework.cache.annotation.Cacheable; -import com.yaoyuan.jiscuss.entity.User; -import com.yaoyuan.jiscuss.repository.UsersRepository; -import com.yaoyuan.jiscuss.service.IUsersService; +import javax.transaction.Transactional; +import java.util.List; @Service @Transactional diff --git a/src/main/resources/application-h2.yml b/src/main/resources/application-h2.yml index e8381b0..7ddbf18 100644 --- a/src/main/resources/application-h2.yml +++ b/src/main/resources/application-h2.yml @@ -52,9 +52,9 @@ spring: stat-view-servlet: enabled: true url-pattern: /druid/* -# reset-enable: false -# login-username: root -# login-password: root + # reset-enable: false + # login-username: root + # login-password: root freemarker: # 设置模板后缀名 suffix: .ftl diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 12edfbf..e627583 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -10,9 +10,9 @@ spring: hibernate: ddl-auto: update datasource: - url: jdbc:mysql://101.200.164.179:3306/jiscuss?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&useSSL=false - username: jiscuss - password: jiscusscyy + url: jdbc:mysql://localhost:3306/jiscuss?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&useSSL=false + username: root + password: 123456 driver-class-name: com.mysql.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource tomcat: diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 610185a..cc1e06b 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -1,71 +1,77 @@ - +insert into user +values (1, 'admin', '管理员', 'as_2583698@sina.com', '123', '2019-09-09 00:00:00', 31, '', '男', '13804250293', 0, 0, + '2019-09-09 00:00:00', 1, 1); insert into user -values (1, 'admin', '管理员', 'as_2583698@sina.com','123','2019-09-09 00:00:00',31,'','男','13804250293',0,0,'2019-09-09 00:00:00',1,1); +values (2, 'test', '测试用户1', 'as_2583698@sina.com', '123', '2019-09-09 00:00:00', 31, '', '男', '13804250293', 0, 0, + '2019-09-09 00:00:00', 1, 0); -insert into user -values (2, 'test', '测试用户1', 'as_2583698@sina.com','123','2019-09-09 00:00:00',31,'','男','13804250293',0,0,'2019-09-09 00:00:00',1,0); - - -insert into discussion -values (1, '测试主题1', '测试内容1',null,null,null,'2020-09-19 00:00:00',1,null,'2020-09-29 00:00:00',2,null,null,null,null,null,1,'2020-09-09 00:00:00'); - - -insert into discussion -values (2, '测试主题2', '测试内容2',null,null,null,null,null,null,null,1,null,null,null,null,null,null,null); insert into discussion -values (3, '测试主题3', '测试内容3',null,null,null,null,null,null,null,1,null,null,null,null,null,null,null); +values (1, '测试主题1', '测试内容1', null, null, null, '2020-09-19 00:00:00', 1, null, '2020-09-29 00:00:00', 2, null, null, + null, null, null, 1, '2020-09-09 00:00:00'); -insert into discussion -values (4, '测试主题4', '测试内容4',null,null,null,null,null,null,null,1,null,null,null,null,null,null,null); - - -insert into discussion -values (5, '测试主题5', '测试内容2测试内容2测试内容2测试内容2测试内容2测试内容2',null,null,null,null,null,null,null,1,null,null,null,null,null,null,null); - insert into discussion -values (6, '测试主题6', '测试内容3测试测试测试测试测试测试测试测试测试测试测试测试测试',null,null,null,null,null,null,null,1,null,null,null,null,null,null,null); - -insert into discussion -values (7, '测试主题7', '测试内容7',null,null,null,null,null,null,null,1,null,null,null,null,null,null,null); - - -insert into discussion -values (8, '测试主题8', '测试内容8',null,null,null,null,null,null,null,1,null,null,null,null,null,null,null); +values (2, '测试主题2', '测试内容2', null, null, null, null, null, null, null, 1, null, null, null, null, null, null, null); insert into discussion -values (9, '测试主题9', '测试内容9',null,null,null,null,null,null,null,1,null,null,null,null,null,null,null); +values (3, '测试主题3', '测试内容3', null, null, null, null, null, null, null, 1, null, null, null, null, null, null, null); + insert into discussion -values (10, '测试主题10', '测试内容113',null,null,null,null,null,null,null,1,null,null,null,null,null,null,null); +values (4, '测试主题4', '测试内容4', null, null, null, null, null, null, null, 1, null, null, null, null, null, null, null); + insert into discussion -values (11, '测试主题11', '测试内容3测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试',null,null,null,null,null,null,null,1,null,null,null,null,null,null,null); +values (5, '测试主题5', '测试内容2测试内容2测试内容2测试内容2测试内容2测试内容2', null, null, null, null, null, null, null, 1, null, null, null, + null, null, null, null); + +insert into discussion +values (6, '测试主题6', '测试内容3测试测试测试测试测试测试测试测试测试测试测试测试测试', null, null, null, null, null, null, null, 1, null, null, null, + null, null, null, null); + +insert into discussion +values (7, '测试主题7', '测试内容7', null, null, null, null, null, null, null, 1, null, null, null, null, null, null, null); + + +insert into discussion +values (8, '测试主题8', '测试内容8', null, null, null, null, null, null, null, 1, null, null, null, null, null, null, null); + +insert into discussion +values (9, '测试主题9', '测试内容9', null, null, null, null, null, null, null, 1, null, null, null, null, null, null, null); + +insert into discussion +values (10, '测试主题10', '测试内容113', null, null, null, null, null, null, null, 1, null, null, null, null, null, null, null); + +insert into discussion +values (11, '测试主题11', '测试内容3测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试', null, null, null, null, null, null, null, 1, + null, null, null, null, null, null, null); insert into tag -values (1, '测试标签1',null,null,'edit',null,null,null,null,null,null,null); +values (1, '测试标签1', null, null, 'edit', null, null, null, null, null, null, null); insert into post -values (1, 1, 1,'2020-02-09 00:00:00',1,null,'评论内容222',null,null,null,null,null,null,1,'2020-08-09 00:00:00'); +values (1, 1, 1, '2020-02-09 00:00:00', 1, null, '评论内容222', null, null, null, null, null, null, 1, + '2020-08-09 00:00:00'); insert into post -values (2, 1, 2,'2020-01-09 00:00:00',2,null,'评论内容333',null,null,1,null,null,null,2,'2020-07-09 00:00:00'); +values (2, 1, 2, '2020-01-09 00:00:00', 2, null, '评论内容333', null, null, 1, null, null, null, 2, '2020-07-09 00:00:00'); insert into post -values (7, 1, 7,'2020-01-09 00:00:00',1,null,'评论内容3331111',null,null,1,null,null,null,1,'2020-03-09 00:00:00'); +values (7, 1, 7, '2020-01-09 00:00:00', 1, null, '评论内容3331111', null, null, 1, null, null, null, 1, + '2020-03-09 00:00:00'); insert into post -values (3, 1, 3,'2020-01-09 00:00:00',1,1,'评论内容444',null,null,1,null,null,null,1,'2020-02-09 00:00:00'); +values (3, 1, 3, '2020-01-09 00:00:00', 1, 1, '评论内容444', null, null, 1, null, null, null, 1, '2020-02-09 00:00:00'); insert into post -values (4, 1, 4,'2020-01-09 00:00:00',2,1,'评论内容555',null,null,null,null,null,null,2,'2020-03-09 00:00:00'); +values (4, 1, 4, '2020-01-09 00:00:00', 2, 1, '评论内容555', null, null, null, null, null, null, 2, '2020-03-09 00:00:00'); insert into post -values (5, 1, 5,'2020-01-09 00:00:00',2,null,'评论内容666',null,null,1,null,null,null,2,'2020-09-09 00:00:00'); +values (5, 1, 5, '2020-01-09 00:00:00', 2, null, '评论内容666', null, null, 1, null, null, null, 2, '2020-09-09 00:00:00'); insert into post -values (6, 1, 6,'2020-01-09 00:00:00',1,null,'评论内容777',null,null,5,null,null,null,1,'2020-09-09 00:00:00'); +values (6, 1, 6, '2020-01-09 00:00:00', 1, null, '评论内容777', null, null, 5, null, null, null, 1, '2020-09-09 00:00:00'); diff --git a/src/main/resources/rebel.xml b/src/main/resources/rebel.xml index aa37822..a903885 100644 --- a/src/main/resources/rebel.xml +++ b/src/main/resources/rebel.xml @@ -4,11 +4,13 @@ This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project. Refer to https://manuals.zeroturnaround.com/jrebel/standalone/config.html for more information. --> - + - - - - + + + + diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index ff00b53..2232f76 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -1,108 +1,115 @@ -- 用户表1 drop table if exists user; -CREATE TABLE user( -id INTEGER not null primary key auto_increment, -username varchar(20), -realname varchar(20), -email varchar(20), -password varchar(20), -join_time datetime, -age INTEGER, -avatar text, -gender char(20), -phone char(20), -discussions_count INTEGER, -comments_count INTEGER, -last_seen_time datetime, -flag INTEGER, -level INTEGER +CREATE TABLE user +( + id INTEGER not null primary key auto_increment, + username varchar(20), + realname varchar(20), + email varchar(20), + password varchar(20), + join_time datetime, + age INTEGER, + avatar text, + gender char(20), + phone char(20), + discussions_count INTEGER, + comments_count INTEGER, + last_seen_time datetime, + flag INTEGER, + level INTEGER ); -- 主题表2 drop table if exists discussion; -CREATE TABLE discussion( -id INTEGER not null primary key auto_increment, -title varchar(200), -content text, -comments_count INTEGER, -participants_count INTEGER, -number_index INTEGER, -start_time datetime, -start_user_id INTEGER, -start_post_id INTEGER, -last_time datetime, -last_user_id INTEGER, -last_post_id INTEGER, -last_post_number INTEGER, -is_approved INTEGER, -like_count INTEGER, -ip_address varchar(200), -create_id INTEGER, -create_time datetime +CREATE TABLE discussion +( + id INTEGER not null primary key auto_increment, + title varchar(200), + content text, + comments_count INTEGER, + participants_count INTEGER, + number_index INTEGER, + start_time datetime, + start_user_id INTEGER, + start_post_id INTEGER, + last_time datetime, + last_user_id INTEGER, + last_post_id INTEGER, + last_post_number INTEGER, + is_approved INTEGER, + like_count INTEGER, + ip_address varchar(200), + create_id INTEGER, + create_time datetime ); -- 主题标签关联表3 drop table if exists discussiontag; -CREATE TABLE discussiontag( -id INTEGER not null primary key auto_increment, -discussion_id INTEGER not null , -tag_id INTEGER +CREATE TABLE discussiontag +( + id INTEGER not null primary key auto_increment, + discussion_id INTEGER not null, + tag_id INTEGER ); -- 评论表4 drop table if exists post; -CREATE TABLE post( -id INTEGER not null primary key auto_increment , -discussion_id INTEGER, -number INTEGER, -time datetime, -user_id INTEGER, -type varchar(20), -content text, -edit_time datetime, -edit_user_id INTEGER, -parent_id INTEGER, -ip_address varchar(200), -copyright varchar(200), -is_approved INTEGER, -create_id INTEGER, -create_time datetime +CREATE TABLE post +( + id INTEGER not null primary key auto_increment, + discussion_id INTEGER, + number INTEGER, + time datetime, + user_id INTEGER, + type varchar(20), + content text, + edit_time datetime, + edit_user_id INTEGER, + parent_id INTEGER, + ip_address varchar(200), + copyright varchar(200), + is_approved INTEGER, + create_id INTEGER, + create_time datetime ); -- 设置表5 drop table if exists setting; -CREATE TABLE setting( -id INTEGER not null primary key auto_increment , -setting_key varchar(20) , -setting_value text +CREATE TABLE setting +( + id INTEGER not null primary key auto_increment, + setting_key varchar(20), + setting_value text ); -- 标签表6 drop table if exists tag; -CREATE TABLE tag( -id INTEGER not null primary key auto_increment, -name varchar(200), -description varchar(200), -color varchar(200), -icon varchar(200), -position INTEGER, -parent_id INTEGER, -discussions_count text, -last_time datetime, -last_discussion_id INTEGER, -create_id INTEGER, -create_time datetime +CREATE TABLE tag +( + id INTEGER not null primary key auto_increment, + name varchar(200), + description varchar(200), + color varchar(200), + icon varchar(200), + position INTEGER, + parent_id INTEGER, + discussions_count text, + last_time datetime, + last_discussion_id INTEGER, + create_id INTEGER, + create_time datetime ); -- 喜欢收藏表7 drop table if exists likecollect; -CREATE TABLE likecollect( -id INTEGER not null primary key auto_increment, -discussion_id INTEGER , -discussion_name varchar(200), -tag_id INTEGER , -post_id INTEGER , -post_content text, -user_id INTEGER , -user_name varchar(200), -type varchar(20), -like_type varchar(20), -collect_type varchar(20), -create_id INTEGER, -create_time datetime +CREATE TABLE likecollect +( + id INTEGER not null primary key auto_increment, + discussion_id INTEGER, + discussion_name varchar(200), + tag_id INTEGER, + post_id INTEGER, + post_content text, + user_id INTEGER, + user_name varchar(200), + type varchar(20), + like_type varchar(20), + collect_type varchar(20), + create_id INTEGER, + create_time datetime ); diff --git a/src/main/resources/static/js/comm/util.js b/src/main/resources/static/js/comm/util.js index 74229dc..dbb3f3f 100644 --- a/src/main/resources/static/js/comm/util.js +++ b/src/main/resources/static/js/comm/util.js @@ -1,3 +1,3 @@ -function massage(msg,type,title){ - layx.msg(msg,{dialogIcon:type}); +function massage(msg, type, title) { + layx.msg(msg, {dialogIcon: type}); } \ No newline at end of file diff --git a/src/main/resources/static/js/user/discussions.js b/src/main/resources/static/js/user/discussions.js index c95924d..2766a0d 100644 --- a/src/main/resources/static/js/user/discussions.js +++ b/src/main/resources/static/js/user/discussions.js @@ -1,17 +1,17 @@ - let discussionsId = null; function setDiscussionsId(id) { - console.log('setDiscussionsId:'+id); + console.log('setDiscussionsId:' + id); discussionsId = id; // id } + $("#addPost").click(function () { console.log("点击 addPost"); console.log(username); console.log(discussionsId); let postId = $("#postId").val(); console.log(postId); - if(username && username!=null){ + if (username && username != null) { var token = $("meta[name='_csrf']").attr("content"); var header = $("meta[name='_csrf_header']").attr("content"); console.warn(header) @@ -27,24 +27,24 @@ $("#addPost").click(function () { parentId: postId }), contentType: 'application/json', - beforeSend: function(request) { + beforeSend: function (request) { request.setRequestHeader(header, token); // 添加 CSRF Token }, dataType: "JSON", success: function (data) { console.log(data); - if(data.flag){ - massage(content+',添加成功!','success',''); + if (data.flag) { + massage(content + ',添加成功!', 'success', ''); location.reload(); - massage('评论添加成功!','success',''); - }else{ - massage(data.msg,'error',''); + massage('评论添加成功!', 'success', ''); + } else { + massage(data.msg, 'error', ''); return false; } } }); - }else{ - massage('您未登录,请先登录!','error',''); + } else { + massage('您未登录,请先登录!', 'error', ''); } }); diff --git a/src/main/resources/static/js/user/header.js b/src/main/resources/static/js/user/header.js index bbea222..b619da1 100644 --- a/src/main/resources/static/js/user/header.js +++ b/src/main/resources/static/js/user/header.js @@ -1,6 +1,6 @@ let username = null; function setusername(name) { - console.log('已经登陆:'+name); - username = name; // name + console.log('已经登陆:' + name); + username = name; // name } \ No newline at end of file diff --git a/src/main/resources/static/js/user/user.js b/src/main/resources/static/js/user/user.js index 8f8d3d3..487286e 100644 --- a/src/main/resources/static/js/user/user.js +++ b/src/main/resources/static/js/user/user.js @@ -2,7 +2,7 @@ $("#userButton").click(function () { console.log("点击 userButton"); $('#userButtonsidebar') .sidebar({ - transition:'scale down' //默认uncover,可以取值push\overlay\slide along\slide out\scale down + transition: 'scale down' //默认uncover,可以取值push\overlay\slide along\slide out\scale down }) .sidebar('toggle') ; diff --git a/src/main/resources/static/layx/layx.css b/src/main/resources/static/layx/layx.css new file mode 100644 index 0000000..d7dd905 --- /dev/null +++ b/src/main/resources/static/layx/layx.css @@ -0,0 +1,1070 @@ +/*! + * file : layx.css + * gitee : https://gitee.com/monksoul/LayX + * github : https://github.com/MonkSoul/Layx/ + * author : 百小僧/MonkSoul + * version : v2.5.4 + * create time : 2018.05.11 + * update time : 2018.11.03 + */ + +*[class^="layx-"] { + box-sizing: border-box; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + margin: 0; + padding: 0; + outline: none; + border: none; + background-color: transparent; +} + +.layx-flexbox { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + display: -webkit-flex; +} + +.layx-flex-vertical { + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-align-items: center; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + -webkit-justify-content: flex-start; +} + +.layx-flex-center { + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-justify-content: center; +} + +.layx-flexauto { + flex: 1; + -webkit-box-flex: 1; + -moz-box-flex: 1; + -webkit-flex: 1; + -ms-flex: 1; +} + +.layx-shade, +#layx-window-move { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + background-color: transparent; +} + +body.ilayx-body { + overflow: hidden !important; +} + +.layx-window { + position: fixed; + overflow: visible !important; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + color: #000; + -webkit-tap-highlight-color: rgba(0,0,0,0); + visibility: visible; + border: none; +} + +.layx-window.layx-flicker { + animation-name: layx-flicker; + -webkit-animation-name: layx-flicker; + -moz-animation-name: layx-flicker; + animation-duration: 0.12s; + -webkit-animation-duration: 0.12s; + -moz-animation-duration: 0.12s; + animation-iteration-count: 8; + -webkit-animation-iteration-count: 8; + -moz-animation-iteration-count: 8; +} + +.layx-window.layx-max-statu, .layx-window.layx-max-statu .layx-control-bar, .layx-window.layx-max-statu .layx-main, .layx-window.layx-max-statu .layx-statu-bar { + border-radius: 0px !important; + -webkit-border-radius: 0px !important; + -moz-border-radius: 0px !important; +} + +.layx-window.layx-min-statu { + min-height: 0 !important; + overflow: hidden !important; + min-width: 0 !important; +} + +.layx-window.layx-min-statu .layx-title { + overflow: hidden !important; +} + +.layx-window.layx-min-statu .layx-inlay-menus .layx-stick-menu, +.layx-window.layx-min-statu .layx-inlay-menus .layx-debug-menu { + display: none; +} + +.layx-window.layx-bubble-type { + overflow: visible !important; + position: absolute !important; +} + +.layx-window.layx-hide-statu { + display: none !important; +} + +.layx-control-bar { + min-height: 30px; + overflow: hidden; + width: 100%; + padding-left: 5px; +} + +.layx-iconfont { + width: 1em; + height: 1em; + vertical-align: -0.15em; + fill: currentColor; + overflow: hidden; + font-size: 14px; + line-height: normal; + display: block; + line-height: normal; +} + +.layx-icon { + text-align: center; +} + +.layx-icon * { + pointer-events: none; +} + +.layx-left-bar { + margin-right: 5px; +} + +.layx-window-icon { + -webkit-tap-highlight-color: rgba(0,0,0,0); +} + +.layx-window-icon .layx-iconfont { + font-size: 16px; +} + +.layx-title, +.layx-group-tab { + -webkit-touch-callout: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + margin-right: 5px; + min-width: 0; + -ms-touch-action: none; + touch-action: none; + -webkit-tap-highlight-color: rgba(0,0,0,0); +} + +.layx-title { + -webkit-app-region: drag; +} + +.layx-group-tab { + -webkit-app-region: no-drag; +} + +.layx-title .layx-label, +.layx-group-title .layx-label { + line-height: normal; + font-size: 14px; + max-width: 100%; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; + word-wrap: break-word; + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + white-space: nowrap; + display: inline-block; + pointer-events: none; + visibility: visible; + position: relative; + top: -1px; + top: 0px\0; +} + +.layx-group-tab .layx-label { + line-height: 28px; +} + +.layx-group-tab.layx-type-group { + overflow: visible; + margin-right: 0; + border-bottom: 1px solid #dddddd; +} + +.layx-control-bar.layx-type-group { + overflow: visible; + border-bottom: 1px solid #dddddd; +} + +.layx-group-title { + height: 27px; + line-height: 25px; + max-width: 150px; + width: 150px; + padding: 0 8px; + background-color: #f5f5f5; + border: 1px solid #dddddd; + border-width: 1px 1px 0 0; + position: relative; + color: #666; + white-space: nowrap; + min-width: 0; + -webkit-tap-highlight-color: rgba(0,0,0,0); +} + +.layx-title.layx-type-group .layx-group-title { + height: 30px; + line-height: 34px; +} + +.layx-title.layx-type-group { + overflow: visible; +} + +.layx-title.layx-type-group .layx-group-title:first-child { + border-left: 1px solid #dddddd; +} + +.layx-group-title[data-enable="1"] { + background-color: #fff; + color: #000; +} + +.layx-group-title[data-enable="1"]::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + height: 100%; + width: 100%; + content: ''; + border-bottom: 1px solid #fff; +} + +.layx-inlay-menus { + height: 100%; + height: 30px; + line-height: 30px; + position: relative; + max-height: 30px; + z-index: 2; +} + +.layx-inlay-menus .layx-icon { + width: 45px; + -webkit-tap-highlight-color: rgba(0,0,0,0); +} + +.layx-inlay-menus .layx-icon:hover { + background-color: #e5e5e5; +} + +.layx-inlay-menus .layx-icon.layx-destroy-menu:hover { + background-color: #e81123 !important; + color: #fff !important; +} + +.layx-inlay-menus .layx-icon.layx-stick-menu[data-enable='1'] { + color: #f00; +} + +.layx-main { + overflow: auto; + position: relative; + clear: both; + -webkit-overflow-scrolling: touch; + -webkit-transform: translate3d(0, 0, 0); + -webkit-app-region: no-drag; +} + +.layx-readonly { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + background: transparent; + z-index: 199205270356; +} + +.layx-group-main { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + height: 100%; + width: 100%; + z-index: 0; + visibility: hidden; + overflow: auto; + -webkit-overflow-scrolling: touch; + -webkit-transform: translate3d(0, 0, 0); +} + +.layx-group-main[data-enable="1"] { + z-index: 1; + visibility: visible; +} + +.layx-mouse-preventDefault { + position: absolute; + z-index: 3; + height: 100%; + width: 100%; + left: 0; + top: 0; + right: 0; + bottom: 0; + overflow: hidden; + background-color: transparent; +} + +.layx-content-shade { + position: absolute; + z-index: 2; + width: 100%; + height: 100%; + left: 0; + right: 0; + bottom: 0; + top: 0; + overflow: hidden; + background-color: #fff; +} + +.layx-html { + width: 100%; + height: 100%; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1; + -webkit-overflow-scrolling: touch; + -webkit-transform: translate3d(0, 0, 0); + overflow: auto; +} + +.layx-dialog-icon { + margin-right: 10px; + position: relative; + top: -5px; +} + +.layx-dialog-icon .layx-iconfont { + font-size: 40px !important; +} + +.layx-dialog-msg .layx-dialog-icon .layx-iconfont, .layx-dialog-tip .layx-dialog-icon .layx-iconfont { + font-size: 25px !important; +} + +.layx-dialog-msg .layx-dialog-icon, .layx-dialog-tip .layx-dialog-icon { + top: 0; +} + +.layx-dialog-icon-success { + color: #01AAED; +} + +.layx-dialog-icon-warn { + color: #FFB800; +} + +.layx-dialog-icon-error { + color: #f00; +} + +.layx-dialog-icon-help { + color: #009688; +} + +.layx-dialog-msg, +.layx-dialog-tip, +.layx-dialog-load { + color: #000; + padding: 10px; +} + +.layx-dialog-alert, +.layx-dialog-confirm, +.layx-dialog-prompt { + padding: 10px; + color: #039; +} + +.layx-dialog-prompt { + width: 100%; +} + +.layx-dialog-msg, .layx-dialog-tip { + height: 100%; +} + +.layx-dialog-content { + font-size: 14px; +} + +.layx-textarea { + display: block; + border: 1px solid #dddddd; + width: 100%; + resize: none; + height: 60px; + margin-top: 8px; + padding: 8px; + font-size: 15px; + color: #000; + line-height: 1.5; +} + +.layx-textarea:focus { + border: 1px solid #3baced; +} + +.layx-buttons { + padding: 8px 10px; + text-align: right; +} + +.layx-button-item { + padding: 0 16px; + height: 24px; + line-height: normal; + color: #000; + font-size: 14px; + border: 1px solid #adadad; + outline: none; + margin-left: 8px; + display: inline-block; + background-color: #e1e1e1; + -webkit-tap-highlight-color: rgba(0,0,0,0); + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.layx-buttons .layx-button-item:hover { + background-color: #e5f1fb; + border: 1px solid #0078d7; +} + +.layx-buttons .layx-button-item[disabled] { + color: #999; + cursor: not-allowed; +} + +.layx-buttons .layx-button-item[disabled]:hover { + background-color: #e1e1e1; + border: 1px solid #adadad; +} + +.layx-iframe { + width: 1px; + min-width: 100%; + *width: 100%; + height: 100%; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1; +} + +.layx-statu-bar { + border-top: 1px solid #dddddd; + min-height: 25px; + background-color: #eeeef2; +} + +.layx-resizes[data-enable='0'] { + visibility: hidden; +} + +.layx-resizes > div { + position: absolute; + z-index: 3; + -ms-touch-action: none; + touch-action: none; +} + +.layx-resize-top, +.layx-resize-bottom { + height: 3px; + left: 3px; + right: 3px; +} + +.layx-resize-top { + top: 0; + cursor: n-resize; +} + +.layx-resize-bottom { + bottom: 0; + cursor: s-resize; +} + +.layx-resize-left, +.layx-resize-right { + width: 3px; + top: 3px; + bottom: 3px; +} + +.layx-resize-left { + left: 0; + cursor: w-resize; +} + +.layx-resize-right { + right: 0; + cursor: e-resize; +} + +.layx-resize-left-top, +.layx-resize-right-top, +.layx-resize-left-bottom, +.layx-resize-right-bottom { + width: 3px; + height: 3px; +} + +.layx-resize-left-top { + left: 0; + top: 0; + cursor: nw-resize; +} + +.layx-resize-right-top { + right: 0; + top: 0; + cursor: ne-resize; +} + +.layx-resize-left-bottom { + left: 0; + bottom: 0; + cursor: sw-resize; +} + +.layx-resize-right-bottom { + right: 0; + bottom: 0; + cursor: se-resize; +} + +.layx-resize-top.layx-reisize-touch, +.layx-resize-bottom.layx-reisize-touch { + height: 16px; + left: 16px; + right: 16px; +} + +.layx-resize-left.layx-reisize-touch, +.layx-resize-right.layx-reisize-touch { + width: 16px; + top: 16px; + bottom: 16px; +} + +.layx-resize-left-top.layx-reisize-touch, +.layx-resize-right-top.layx-reisize-touch, +.layx-resize-left-bottom.layx-reisize-touch, +.layx-resize-right-bottom.layx-reisize-touch { + width: 16px; + height: 16px; +} + +.layx-resize-top.layx-reisize-touch { + top: -8px; +} + +.layx-resize-bottom.layx-reisize-touch { + bottom: -8px; +} + +.layx-resize-left.layx-reisize-touch { + left: -8px; +} + +.layx-resize-right.layx-reisize-touch { + right: -8px; +} + +.layx-resize-left-top.layx-reisize-touch { + left: -8px; + top: -8px; +} + +.layx-resize-right-top.layx-reisize-touch { + right: -8px; + top: -8px; +} + +.layx-resize-left-bottom.layx-reisize-touch { + left: -8px; + bottom: -8px; +} + +.layx-resize-right-bottom.layx-reisize-touch { + right: -8px; + bottom: -8px; +} + +.layx-resize-left[data-enable='0'], +.layx-resize-top[data-enable='0'], +.layx-resize-right[data-enable='0'], +.layx-resize-bottom[data-enable='0'], +.layx-resize-left-top[data-enable='0'], +.layx-resize-left-bottom[data-enable='0'], +.layx-resize-right-top[data-enable='0'], +.layx-resize-right-bottom[data-enable='0'] { + visibility: hidden; +} + +.layx-auto-destroy-tip { + position: absolute; + bottom: 3px; + right: 3px; + height: 25px; + line-height: 25px; + z-index: 5; + color: #444; + background-color: #f1f1f1; + padding: 0 8px; + font-size: 13px; +} + +.layx-code { + border: 1px solid #dedede; + border-radius: 3px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + padding: 10px; + width: 100%; + height: 100%; + -webkit-overflow-scrolling: touch; + -webkit-transform: translate3d(0, 0, 0); + background: #f5f5f5; + overflow: auto; +} + +.layx-bubble, +.layx-bubble-inlay { + position: absolute; + width: 0; + height: 0; +} + +.layx-bubble-bottom { + top: -11px; + left: 2px; + border-left: 10px solid transparent; + border-right: 10px solid transparent; + border-bottom: 11px solid transparent; +} + +.layx-bubble-inlay-bottom { + top: 2px; + left: -9px; + border-left: 9px solid transparent; + border-right: 9px solid transparent; + border-bottom: 9px solid transparent; +} + +.layx-bubble-top { + bottom: -11px; + left: 2px; + border-left: 10px solid transparent; + border-right: 10px solid transparent; + border-top: 11px solid transparent; +} + +.layx-bubble-inlay-top { + bottom: 2px; + left: -9px; + border-left: 9px solid transparent; + border-right: 9px solid transparent; + border-top: 9px solid transparent; +} + +.layx-bubble-right { + top: 2px; + left: -11px; + border-top: 10px solid transparent; + border-bottom: 10px solid transparent; + border-right: 11px solid transparent; +} + +.layx-bubble-inlay-right { + top: -9px; + left: 2px; + border-top: 9px solid transparent; + border-bottom: 9px solid transparent; + border-right: 9px solid transparent; +} + +.layx-bubble-left { + top: 2px; + right: -11px; + border-top: 10px solid transparent; + border-bottom: 10px solid transparent; + border-left: 11px solid transparent; +} + +.layx-bubble-inlay-left { + top: -9px; + right: 2px; + border-top: 9px solid transparent; + border-bottom: 9px solid transparent; + border-left: 9px solid transparent; +} + +.layx-pre { + height: auto; + width: 100%; + font-size: 14px; + font-family: Arial; + border-radius: 3px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + display: block; + font-family: Arial; +} + +.layx-dot { + display: inline-block; + width: 25px; +} + +.layx-load-animate { + width: 32px; + height: 32px; + position: relative; + margin-right: 10px; +} + +.layx-load-inner, .layx-load-inner2 { + position: absolute; + width: 100%; + height: 100%; + border-radius: 40px; + -webkit-border-radius: 40px; + -moz-border-radius: 40px; + overflow: hidden; + left: 0; + top: 0; +} + +.layx-load-inner { + opacity: 1; + background-color: #89abdd; + -webkit-animation: layx-second-half-hide 1.6s steps(1, end) infinite; + animation: layx-second-half-hide 1.6s steps(1, end) infinite; + -moz-animation: layx-second-half-hide 1.6s steps(1, end) infinite; +} + +.layx-load-inner2 { + opacity: 0; + background-color: #4b86db; + -webkit-animation: layx-second-half-show 1.6s steps(1, end) infinite; + animation: layx-second-half-show 1.6s steps(1, end) infinite; + -moz-animation: layx-second-half-show 1.6s steps(1, end) infinite; +} + +.layx-load-spiner, .layx-load-filler, .layx-load-masker { + position: absolute; + width: 50%; + height: 100%; +} + +.layx-load-spiner { + border-radius: 40px 0 0 40px; + -webkit-border-radius: 40px 0 0 40px; + -moz-border-radius: 40px 0 0 40px; + background-color: #4b86db; + -webkit-transform-origin: right center; + -ms-transform-origin: right center; + transform-origin: right center; + -moz-transform-origin: right center; + -webkit-animation: layx-spin 800ms infinite linear; + animation: layx-spin 800ms infinite linear; + -moz-animation: layx-spin 800ms infinite linear; + left: 0; + top: 0; +} + +.layx-load-filler { + border-radius: 0 40px 40px 0; + -webkit-border-radius: 0 40px 40px 0; + -moz-border-radius: 0 40px 40px 0; + background-color: #4b86db; + -webkit-animation: layx-second-half-hide 800ms steps(1, end) infinite; + animation: layx-second-half-hide 800ms steps(1, end) infinite; + -moz-animation: layx-second-half-hide 800ms steps(1, end) infinite; + left: 50%; + top: 0; + opacity: 1; +} + +.layx-load-masker { + border-radius: 40px 0 0 40px; + -moz-border-radius: 40px 0 0 40px; + -webkit-border-radius: 40px 0 0 40px; + background-color: #89abdd; + -webkit-animation: layx-second-half-show 800ms steps(1, end) infinite; + animation: layx-second-half-show 800ms steps(1, end) infinite; + -moz-animation: layx-second-half-show 800ms steps(1, end) infinite; + left: 0; + top: 0; + opacity: 0; +} + +.layx-load-inner2 .layx-load-spiner, .layx-load-inner2 .layx-load-filler { + background-color: #89abdd; +} + +.layx-load-inner2 .layx-load-masker { + background-color: #4b86db; +} +/*default 皮肤*/ +.layx-window.layx-skin-default { + border: 1px solid #3baced; +} + +.layx-window.layx-skin-default .layx-control-bar { + background-color: #fff; +} + +.layx-window.layx-skin-default .layx-inlay-menus .layx-icon:hover { +} + +.layx-window.layx-skin-default .layx-button-item { +} + +.layx-window.layx-skin-default .layx-button-item:hover { +} +/*cloud 皮肤*/ +.layx-window.layx-skin-cloud { +} + +.layx-window.layx-skin-cloud .layx-control-bar { + background-color: #ecf0f1; +} + +.layx-window.layx-skin-cloud .layx-inlay-menus .layx-icon:hover { + background-color: #bdc3c7; +} + +.layx-window.layx-skin-cloud .layx-button-item { + background-color: #ecf0f1; + border: 1px solid #ccc; +} + +.layx-window.layx-skin-cloud .layx-button-item:hover { + background-color: #bdc3c7; + color: #fff; + border: 1px solid #ecf0f1; +} + +/*turquoise 皮肤*/ +.layx-window.layx-skin-turquoise { +} + +.layx-window.layx-skin-turquoise .layx-control-bar { + background-color: #1abc9c; + color: #fff; +} + +.layx-window.layx-skin-turquoise .layx-inlay-menus .layx-icon:hover { + background-color: #16a085; +} + +.layx-window.layx-skin-turquoise .layx-button-item { + background-color: #1abc9c; + color: #fff; + border: 1px solid#1abc9c; +} + +.layx-window.layx-skin-turquoise .layx-button-item:hover { + background-color: #16a085; + border: 1px solid #1abc9c; +} +/*river 皮肤*/ +.layx-window.layx-skin-river { +} + +.layx-window.layx-skin-river .layx-control-bar { + background-color: #3498db; + color: #fff; +} + +.layx-window.layx-skin-river .layx-inlay-menus .layx-icon:hover { + background-color: #2980b9; +} + +.layx-window.layx-skin-river .layx-button-item { + background-color: #3498db; + color: #fff; + border: 1px solid #3498db; +} + +.layx-window.layx-skin-river .layx-button-item:hover { + background-color: #2980b9; + border: 1px solid #3498db; +} + +/*asphalt 皮肤*/ +.layx-window.layx-asphalt-river { +} + +.layx-window.layx-skin-asphalt .layx-control-bar { + background-color: #34495e; + color: #fff; +} + +.layx-window.layx-skin-asphalt .layx-inlay-menus .layx-icon:hover { + background-color: #2c3e50; +} + +.layx-window.layx-skin-asphalt .layx-button-item { + background-color: #34495e; + color: #fff; + border: 1px solid #34495e; +} + +.layx-window.layx-skin-asphalt .layx-button-item:hover { + background-color: #2c3e50; + border: 1px solid #34495e; +} + +@keyframes layx-flicker { + from { + -webkit-box-shadow: 1px 1px 24px rgba(0, 0, 0, .3); + box-shadow: 1px 1px 24px rgba(0, 0, 0, .3); + -moz-box-shadow: 1px 1px 24px rgba(0, 0, 0, .3); + } + + to { + -webkit-box-shadow: 1px 1px 12px rgba(0, 0, 0, .3); + box-shadow: 1px 1px 12px rgba(0, 0, 0, .3); + -moz-box-shadow: 1px 1px 12px rgba(0, 0, 0, .3); + } +} + +@-webkit-keyframes layx-flicker { + from { + -webkit-box-shadow: 1px 1px 24px rgba(0, 0, 0, .3); + box-shadow: 1px 1px 24px rgba(0, 0, 0, .3); + -moz-box-shadow: 1px 1px 24px rgba(0, 0, 0, .3); + } + + to { + -webkit-box-shadow: 1px 1px 12px rgba(0, 0, 0, .3); + box-shadow: 1px 1px 12px rgba(0, 0, 0, .3); + -moz-box-shadow: 1px 1px 12px rgba(0, 0, 0, .3); + } +} + +@-webkit-keyframes layx-spin { + 0% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + -moz-transform: rotate(360deg); + } + + 100% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + -moz-transform: rotate(0deg); + } +} + +@keyframes layx-spin { + 0% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + -moz-transform: rotate(360deg); + } + + 100% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + -moz-transform: rotate(0deg); + } +} + +@-webkit-keyframes layx-second-half-hide { + 0% { + opacity: 1; + } + + 50%, 100% { + opacity: 0; + } +} + +@keyframes layx-second-half-hide { + 0% { + opacity: 1; + } + + 50%, 100% { + opacity: 0; + } +} + +@-webkit-keyframes layx-second-half-show { + 0% { + opacity: 0; + } + + 50%, 100% { + opacity: 1; + } +} + +@keyframes layx-second-half-show { + 0% { + opacity: 0; + } + + 50%, 100% { + opacity: 1; + } +} diff --git a/src/main/resources/static/layx/layx.js b/src/main/resources/static/layx/layx.js new file mode 100644 index 0000000..30a8c02 --- /dev/null +++ b/src/main/resources/static/layx/layx.js @@ -0,0 +1,3638 @@ +/*! + * file : layx.js + * gitee : https://gitee.com/monksoul/LayX + * github : https://github.com/MonkSoul/Layx/ + * author : 百小僧/MonkSoul + * version : v2.5.4 + * create time : 2018.05.11 + * update time : 2018.11.03 + */ +; +!(function (over, win, slf) { + var Layx = { + version: '2.5.4', + defaults: { + id: '', + icon: true, + title: '', + width: 800, + height: 600, + minWidth: 200, + minHeight: 200, + position: 'ct', + storeStatus: true, + control: true, + style: '', + controlStyle: '', + existFlicker: true, + bgColor: "#fff", + shadow: true, + border: true, + borderRadius: '3px', + skin: 'default', + type: 'html', + focusToReveal: true, + enableDomainFocus: true, + dialogType: '', + frames: [], + frameIndex: 0, + preload: 1, + mergeTitle: true, + content: '', + dialogIcon: false, + cloneElementContent: true, + url: '', + useFrameTitle: false, + opacity: 1, + escKey: true, + floatTarget: false, + floatDirection: 'bottom', + shadable: false, + shadeDestroy: false, + readonly: false, + loadingText: '内容正在加载中,请稍后', + dragInTopToMax: true, + isOverToMax: true, + stickMenu: false, + stickable: true, + minMenu: true, + minable: true, + maxMenu: true, + maxable: true, + closeMenu: true, + closable: true, + debugMenu: false, + restorable: true, + resizable: true, + autodestroy: false, + autodestroyText: '此窗口将在 {second} 秒内自动关闭.', + resizeLimit: { + t: false, + r: false, + b: false, + l: false, + lt: false, + rt: false, + lb: false, + rb: false + }, + buttonKey: 'enter', + buttons: [], + movable: true, + moveLimit: { + vertical: false, + horizontal: false, + leftOut: true, + rightOut: true, + topOut: true, + bottomOut: true + }, + focusable: true, + alwaysOnTop: false, + allowControlDbclick: true, + statusBar: false, + statusBarStyle: '', + event: { + onload: { + before: function (layxWindow, winform) { }, + after: function (layxWindow, winform) { } + }, + onmin: { + before: function (layxWindow, winform) { }, + after: function (layxWindow, winform) { } + }, + onmax: { + before: function (layxWindow, winform) { }, + after: function (layxWindow, winform) { } + }, + onrestore: { + before: function (layxWindow, winform) { }, + after: function (layxWindow, winform) { } + }, + ondestroy: { + before: function (layxWindow, winform, params, inside, escKey) { }, + after: function () { } + }, + onvisual: { + before: function (layxWindow, winform, params, inside, status) { }, + after: function (layxWindow, winform, status) { } + }, + onmove: { + before: function (layxWindow, winform) { }, + progress: function (layxWindow, winform) { }, + after: function (layxWindow, winform) { } + }, + onresize: { + before: function (layxWindow, winform) { }, + progress: function (layxWindow, winform) { }, + after: function (layxWindow, winform) { } + }, + onfocus: function (layxWindow, winform) { }, + onexist: function (layxWindow, winform) { }, + onswitch: { + before: function (layxWindow, winform, frameId) { }, + after: function (layxWindow, winform, frameId) { } + }, + onstick: { + before: function (layxWindow, winform) { }, + after: function (layxWindow, winform) { } + } + } + }, + defaultButtons: { + label: '确定', + callback: function (id, button, event) { }, + id: '', + classes: [], + style: '' + }, + defaultFrames: { + id: '', + title: '', + type: 'html', + url: '', + content: '', + useFrameTitle: false, + cloneElementContent: true, + bgColor: "#fff" + }, + zIndex: 10000000, + windows: {}, + stickZIndex: 20000000, + prevFocusId: null, + focusId: null, + create: function (options) { + var that = this, + config = layxDeepClone({}, that.defaults, options || {}), + winform = {}; + if (!config.id) { + console.error("窗口id不能为空且唯一"); + return; + } + Layx.prevFocusId = Layx.focusId; + Layx.focusId = config.id; + var _winform = that.windows[config.id]; + if (_winform) { + if (_winform.status === "min") { + that.restore(_winform.id); + } + if (_winform.existFlicker === true) { + that.flicker(config.id); + } + if (Utils.isFunction(config.event.onexist)) { + config.event.onexist(_winform.layxWindow, _winform); + } + var fixFocus = setInterval(function () { + if (config.id !== Layx.focusId) { + that.updateZIndex(config.id); + } else { + clearInterval(fixFocus); + } + }, 0); + return _winform; + } + if (Utils.isArray(config.frames)) { + for (var i = 0; i < config.frames.length; i++) { + config.frames[i] = layxDeepClone({}, that.defaultFrames, config.frames[i]); + if (!config.frames[i].id) { + console.error("窗口组窗口id不能为空且窗口组内唯一"); + return; + } + } + } + if (Utils.isArray(config.buttons)) { + for (var i = 0; i < config.buttons.length; i++) { + config.buttons[i] = layxDeepClone({}, that.defaultButtons, config.buttons[i]); + } + } + if (config.shadable === true || /^(0(\.[0-9])?$)|(1)$/.test(config.shadable)) { + var layxShade = document.createElement("div"); + layxShade.setAttribute("id", "layx-" + config.id + "-shade"); + layxShade.classList.add("layx-shade"); + layxShade.style.zIndex = config.alwaysOnTop === true ? (++that.stickZIndex) : (++that.zIndex); + if (/^(0(\.[0-9])?$)|(1)$/.test(config.shadable)) { + layxShade.style.backgroundColor = "rgba(0,0,0," + config.shadable + ")"; + } + layxShade.oncontextmenu = function (e) { + e = e || window.event; + e.returnValue = false; + return false; + }; + layxShade.onclick = function (e) { + e = e || window.event; + if (config.shadeDestroy === true) { + that.destroy(config.id, null, true); + } else { + if (config.existFlicker === true) { + that.flicker(config.id); + } + } + e.stopPropagation(); + }; + document.body.appendChild(layxShade); + } + if (config.style) { + var style = document.getElementById("layx-style"); + if (style) { + style.innerHTML += config.style; + } else { + style = document.createElement("style"); + style.setAttribute("id", "layx-style"); + style.type = "text/css"; + style.innerHTML = config.style; + document.getElementsByTagName("HEAD").item(0).appendChild(style); + } + } + var layxWindow = document.createElement("div"); + layxWindow.setAttribute("id", "layx-" + config.id); + layxWindow.classList.add("layx-window"); + layxWindow.classList.add("layx-flexbox"); + layxWindow.classList.add("layx-skin-" + config.skin); + if (config.shadow === true) { + layxWindow.style.setProperty("box-shadow", "1px 1px 24px rgba(0, 0, 0, .3)"); + layxWindow.style.setProperty("-moz-box-shadow", "1px 1px 24px rgba(0, 0, 0, .3)"); + layxWindow.style.setProperty("-webkit-box-shadow", "1px 1px 24px rgba(0, 0, 0, .3)"); + } + var _minWidth, + _minHeight, + _width, + _height, + _top, + _left; + _minWidth = Utils.compileLayxWidthOrHeight("width", config.minWidth, that.defaults.minWidth); + _minHeight = Utils.compileLayxWidthOrHeight("height", config.minHeight, that.defaults.minHeight); + _width = Utils.compileLayxWidthOrHeight("width", config.width, that.defaults.width); + _height = Utils.compileLayxWidthOrHeight("height", config.height, that.defaults.height); + _width = Math.max(_width, _minWidth); + _height = Math.max(_height, _minHeight); + var _position = Utils.compileLayxPosition(_width, _height, config.position); + _top = _position.top; + _left = _position.left; + _top = Math.max(_top, 0); + _top = Math.min(win.innerHeight - 15, _top); + _left = Math.max(_left, -(_width - 15)); + _left = Math.min(_left, win.innerWidth - 15); + if (config.storeStatus === true && config.floatTarget === false) { + var _areaInfo = that.getStoreWindowAreaInfo(config.id); + if (_areaInfo) { + _width = _areaInfo.width; + _height = _areaInfo.height; + _top = _areaInfo.top; + _left = _areaInfo.left; + } else { + that.storeWindowAreaInfo(config.id, { + width: _width, + height: _height, + top: _top, + left: _left + }); + } + } else { + that.removeStoreWindowAreaInfo(config.id); + } + if (Utils.isDom(config.floatTarget)) { + layxWindow.classList.add("layx-bubble-type"); + var bubble = document.createElement("div"); + bubble.classList.add("layx-bubble"); + bubble.classList.add("layx-bubble-" + config.floatDirection); + layxWindow.appendChild(bubble); + var bubbleInlay = document.createElement("div"); + bubbleInlay.classList.add("layx-bubble-inlay"); + bubbleInlay.classList.add("layx-bubble-inlay-" + config.floatDirection); + bubble.appendChild(bubbleInlay); + } + layxWindow.style.zIndex = config.alwaysOnTop === true ? (++that.stickZIndex) : (++that.zIndex); + layxWindow.style.width = _width + "px"; + layxWindow.style.height = _height + "px"; + layxWindow.style.minWidth = _minWidth + "px"; + layxWindow.style.minHeight = _minHeight + "px"; + layxWindow.style.top = _top + "px"; + layxWindow.style.left = _left + "px"; + layxWindow.style.setProperty("border", Utils.isBoolean(config.border) ? (config.skin === "default" && config.border === true ? "" : "none") : config.border); + layxWindow.style.backgroundColor = config.bgColor; + layxWindow.style.setProperty("border-radius", config.borderRadius); + layxWindow.style.setProperty("-moz-border-radius", config.borderRadius); + layxWindow.style.setProperty("-webkit-border-radius", config.borderRadius); + layxWindow.style.opacity = /^(0(\.[0-9])?$)|(1)$/.test(config.opacity) ? config.opacity : 1; + if (config.focusable === true) { + layxWindow.onclick = function (e) { + e = e || window.event; + if (Utils.isFunction(config.event.onfocus)) { + var revel = Utils.isFunction(config.event.onfocus); + if (revel === false) { + return; + } + config.event.onfocus(layxWindow, winform); + } + that.updateZIndex(config.id); + }; + } + document.body.appendChild(layxWindow); + var layxWindowStyle = layxWindow.currentStyle ? layxWindow.currentStyle : win.getComputedStyle(layxWindow, null); + winform.id = config.id; + winform.title = config.title; + winform.layxWindowId = layxWindow.getAttribute("id"); + winform.layxWindow = layxWindow; + winform.createDate = new Date(); + winform.status = "normal"; + winform.type = config.type; + winform.buttons = config.buttons; + winform.frames = config.frames; + winform.useFrameTitle = config.useFrameTitle; + winform.cloneElementContent = config.cloneElementContent; + winform.storeStatus = config.storeStatus; + winform.url = config.url; + winform.content = config.content; + winform.escKey = config.escKey; + winform.focusToReveal = config.focusToReveal; + winform.dialogType = config.dialogType; + winform.enableDomainFocus = config.enableDomainFocus; + winform.buttonKey = config.buttonKey; + winform.existFlicker = config.existFlicker; + winform.groupCurrentId = (Utils.isArray(config.frames) && config.frames.length > 0 && config.frames[config.frameIndex]) ? config.frames[config.frameIndex].id : null; + winform.area = { + width: _width, + height: _height, + minWidth: _minWidth, + minHeight: _minHeight, + top: _top, + left: _left + }; + winform.border = config.border; + winform.control = config.control; + winform.isFloatTarget = Utils.isDom(config.floatTarget); + winform.floatTarget = config.floatTarget; + winform.floatDirection = config.floatDirection; + winform.loadingText = config.loadingText; + winform.focusable = config.focusable; + winform.isStick = config.alwaysOnTop === true; + winform.zIndex = config.alwaysOnTop === true ? that.stickZIndex : that.zIndex; + winform.movable = config.movable; + winform.moveLimit = config.moveLimit; + winform.resizable = config.resizable; + winform.resizeLimit = config.resizeLimit; + winform.stickable = config.stickable; + winform.minable = config.minable; + winform.maxable = config.maxable; + winform.restorable = config.restorable; + winform.closable = config.closable; + winform.skin = config.skin; + winform.event = config.event; + winform.dragInTopToMax = config.dragInTopToMax; + that.windows[config.id] = winform; + if (config.control === true) { + var controlBar = document.createElement("div"); + controlBar.classList.add("layx-control-bar"); + controlBar.classList.add("layx-flexbox"); + controlBar.style.setProperty("border-radius", layxWindowStyle.borderRadius + " " + layxWindowStyle.borderRadius + " " + "0 0"); + controlBar.style.setProperty("-moz-border-radius", layxWindowStyle.borderRadius + " " + layxWindowStyle.borderRadius + " " + "0 0"); + controlBar.style.setProperty("-webkit-border-radius", layxWindowStyle.borderRadius + " " + layxWindowStyle.borderRadius + " " + "0 0"); + config.controlStyle && controlBar.setAttribute("style", config.controlStyle); + if (config.type === "group" && config.mergeTitle === true) { + controlBar.classList.add("layx-type-group"); + } + layxWindow.appendChild(controlBar); + if (config.icon !== false) { + var leftBar = document.createElement("div"); + leftBar.classList.add("layx-left-bar"); + leftBar.classList.add("layx-flexbox"); + leftBar.classList.add("layx-flex-vertical"); + controlBar.appendChild(leftBar); + var windowIcon = document.createElement("div"); + windowIcon.classList.add("layx-icon"); + windowIcon.classList.add("layx-window-icon"); + windowIcon.innerHTML = config.icon === true ? '' : config.icon; + if (config.icon === true) { + windowIcon.ondblclick = function (e) { + e = e || window.event; + that.destroy(config.id, null, true); + e.stopPropagation(); + }; + } + leftBar.appendChild(windowIcon); + } + var title = document.createElement("div"); + title.classList.add("layx-title"); + title.classList.add("layx-flexauto"); + title.classList.add("layx-flexbox"); + title.classList.add("layx-flex-vertical"); + if (config.type === "group" && config.mergeTitle === true) { + title.classList.add("layx-type-group"); + } + if (config.allowControlDbclick === true) { + title.ondblclick = function (e) { + e = e || window.event; + if (config.restorable === true) { + that.restore(config.id); + } + e.stopPropagation(); + }; + } + if (config.movable === true && Utils.isDom(config.floatTarget) == false) { + new LayxDrag(title); + } + controlBar.appendChild(title); + if (config.type !== "group") { + var label = document.createElement("label"); + label.classList.add("layx-label"); + label.innerHTML = config.useFrameTitle === true ? "" : config.title; + title.setAttribute("title", label.innerText); + title.appendChild(label); + } else { + if (Utils.isArray(config.frames)) { + if (config.mergeTitle === false) { + var groupTab = document.createElement("div"); + groupTab.classList.add("layx-group-tab"); + groupTab.classList.add("layx-flexbox"); + groupTab.classList.add("layx-type-group"); + layxWindow.appendChild(groupTab); + var label = document.createElement("label"); + label.classList.add("layx-label"); + label.innerHTML = config.useFrameTitle === true ? "" : config.title; + title.setAttribute("title", label.innerText); + title.appendChild(label); + } + for (var i = 0; i < config.frames.length; i++) { + var frameConfig = layxDeepClone({}, that.defaultFrames, config.frames[i]); + var frameTitle = document.createElement("div"); + frameTitle.setAttribute("data-frameId", frameConfig.id); + frameTitle.classList.add("layx-group-title"); + frameTitle.classList.add("layx-flexauto"); + frameTitle.classList.add("layx-flex-vertical"); + if (i === config.frameIndex) { + frameTitle.setAttribute("data-enable", "1"); + } + if (Utils.isSupportTouch) { + frameTitle.ontouchstart = function (e) { + e = e || window.event; + that._setGroupIndex(config.id, this); + }; + if (Utils.IsPC()) { + frameTitle.onclick = function (e) { + e = e || window.event; + that._setGroupIndex(config.id, this); + e.stopPropagation(); + }; + } + } else { + frameTitle.onclick = function (e) { + e = e || window.event; + that._setGroupIndex(config.id, this); + e.stopPropagation(); + }; + } + if (config.mergeTitle === false) { + groupTab.appendChild(frameTitle); + } else { + title.appendChild(frameTitle); + } + var groupLabel = document.createElement("label"); + groupLabel.classList.add("layx-label"); + groupLabel.innerHTML = frameConfig.title; + frameTitle.setAttribute("title", groupLabel.innerText); + frameTitle.appendChild(groupLabel); + } + } + } + var rightBar = document.createElement("div"); + rightBar.classList.add("layx-right-bar"); + rightBar.classList.add("layx-flexbox"); + controlBar.appendChild(rightBar); + var customMenu = document.createElement("div"); + customMenu.classList.add("layx-custom-menus"); + customMenu.classList.add("layx-flexbox"); + rightBar.appendChild(customMenu); + if (config.stickMenu === true || config.minMenu === true || config.maxMenu === true || config.closeMenu === true || config.debugMenu === true) { + var inlayMenu = document.createElement("div"); + inlayMenu.classList.add("layx-inlay-menus"); + inlayMenu.classList.add("layx-flexbox"); + rightBar.appendChild(inlayMenu); + if (!Utils.isDom(config.floatTarget)) { + if (config.debugMenu === true) { + var debugMenu = document.createElement("div"); + debugMenu.classList.add("layx-icon"); + debugMenu.classList.add("layx-flexbox"); + debugMenu.classList.add("layx-flex-center"); + debugMenu.classList.add("layx-debug-menu"); + debugMenu.setAttribute("title", "调试信息"); + debugMenu.innerHTML = ''; + debugMenu.onclick = function (e) { + e = e || window.event; + var jsonStr = JSON.stringify(winform, null, 4).replace(//g, ">"); + that.create({ + id: 'layx-' + config.id + '-debug', + title: "窗口调试信息", + width: 300, + height: 300, + content: '
' + jsonStr + '
', + shadable: true, + debugMenu: false, + minMenu: false, + minable: false, + position: [layxWindow.offsetTop + 10, layxWindow.offsetLeft + 10], + storeStatus: false + }); + }; + inlayMenu.appendChild(debugMenu); + } + if (config.stickMenu === true || (config.alwaysOnTop === true && config.stickMenu)) { + var stickMenu = document.createElement("div"); + stickMenu.classList.add("layx-icon"); + stickMenu.classList.add("layx-flexbox"); + stickMenu.classList.add("layx-flex-center"); + stickMenu.classList.add("layx-stick-menu"); + config.alwaysOnTop === true ? stickMenu.setAttribute("title", "取消置顶") : stickMenu.setAttribute("title", "置顶"); + config.alwaysOnTop === true && stickMenu.setAttribute("data-enable", "1"); + stickMenu.innerHTML = ''; + if (config.stickable === true) { + stickMenu.onclick = function (e) { + e = e || window.event; + that.stickToggle(config.id); + }; + } + inlayMenu.appendChild(stickMenu); + } + if (config.minMenu === true) { + var minMenu = document.createElement("div"); + minMenu.classList.add("layx-icon"); + minMenu.classList.add("layx-flexbox"); + minMenu.classList.add("layx-flex-center"); + minMenu.classList.add("layx-min-menu"); + minMenu.setAttribute("title", "最小化"); + minMenu.setAttribute("data-menu", "min"); + minMenu.innerHTML = ''; + minMenu.onclick = function (e) { + e = e || window.event; + if (!this.classList.contains("layx-restore-menu")) { + if (config.minable === true) { + that.min(config.id); + } + } else { + if (config.restorable === true) { + that.restore(config.id); + } + } + }; + inlayMenu.appendChild(minMenu); + } + if (config.maxMenu === true) { + var maxMenu = document.createElement("div"); + maxMenu.classList.add("layx-icon"); + maxMenu.classList.add("layx-flexbox"); + maxMenu.classList.add("layx-flex-center"); + maxMenu.classList.add("layx-max-menu"); + maxMenu.setAttribute("title", "最大化"); + maxMenu.setAttribute("data-menu", "max"); + maxMenu.innerHTML = ''; + maxMenu.onclick = function (e) { + e = e || window.event; + if (!this.classList.contains("layx-restore-menu")) { + if (config.maxable === true) { + that.max(config.id); + } + } else { + if (config.restorable === true) { + that.restore(config.id); + } + } + }; + inlayMenu.appendChild(maxMenu); + } + } + if (config.closeMenu === true) { + var destroyMenu = document.createElement("div"); + destroyMenu.classList.add("layx-icon"); + destroyMenu.classList.add("layx-flexbox"); + destroyMenu.classList.add("layx-flex-center"); + destroyMenu.classList.add("layx-destroy-menu"); + destroyMenu.setAttribute("title", "关闭"); + destroyMenu.innerHTML = ''; + destroyMenu.onclick = function (e) { + e = e || window.event; + if (config.closable === true) { + that.destroy(config.id, null, true); + } + }; + inlayMenu.appendChild(destroyMenu); + } + } + } + var main = document.createElement("div"); + main.classList.add("layx-main"); + main.classList.add("layx-flexauto"); + if (!config.statusBar) { + main.style.setProperty("border-radius", "0 0 " + layxWindowStyle.borderRadius + " " + layxWindowStyle.borderRadius); + main.style.setProperty("-moz-border-radius", "0 0 " + layxWindowStyle.borderRadius + " " + layxWindowStyle.borderRadius); + main.style.setProperty("-webkit-border-radius", "0 0 " + layxWindowStyle.borderRadius + " " + layxWindowStyle.borderRadius); + } + layxWindow.appendChild(main); + if (config.readonly === true) { + var readonlyPanel = document.createElement("div"); + readonlyPanel.classList.add("layx-readonly"); + readonlyPanel.oncontextmenu = function (e) { + e = e || window.event; + e.returnValue = false; + return false; + }; + if (config.focusable === true) { + readonlyPanel.onclick = function (e) { + e = e || window.event; + if (Utils.isFunction(config.event.onfocus)) { + var revel = Utils.isFunction(config.event.onfocus); + if (revel === false) { + return; + } + config.event.onfocus(layxWindow, winform); + } + that.updateZIndex(config.id); + e.stopPropagation(); + }; + } + main.appendChild(readonlyPanel); + } + switch (config.type) { + case "html": + default: + if (Utils.isFunction(config.event.onload.before)) { + var revel = config.event.onload.before(layxWindow, winform); + if (revel === false) { + return; + } + } + var contentShade = that.createContenLoadAnimate(main, config.loadingText, winform); + that.createHtmlBody(main, config, config.content); + contentShade && main.removeChild(contentShade); + if (winform.loadingTextTimer) { + clearInterval(winform.loadingTextTimer); + delete winform.loadingTextTimer; + } + if (Utils.isFunction(config.event.onload.after)) { + config.event.onload.after(layxWindow, winform); + } + break; + case "url": + if (Utils.isFunction(config.event.onload.before)) { + var revel = config.event.onload.before(layxWindow, winform); + if (revel === false) { + return; + } + } + var contentShade = that.createContenLoadAnimate(main, config.loadingText, winform); + that.createFrameBody(main, config, layxWindow, winform); + break; + case "group": + if (Utils.isArray(config.frames)) { + if (Utils.isFunction(config.event.onload.before)) { + var revel = config.event.onload.before(layxWindow, winform); + if (revel === false) { + return; + } + } + var contentShade = that.createContenLoadAnimate(main, config.loadingText, winform); + config.preload = (/(^[1-9]\d*$)/.test(config.preload) === false) ? true : Math.min(config.preload, config.frames.length); + var groupLoadCompleteListener = setInterval(function () { + var loadComplteMains = layxWindow.querySelectorAll(".layx-group-main[data-complete='1']"); + if (loadComplteMains.length === Utils.isBoolean(config.preload) ? config.frames.length : config.preload) { + clearInterval(groupLoadCompleteListener); + if (winform.loadingTextTimer) { + clearInterval(winform.loadingTextTimer); + delete winform.loadingTextTimer; + } + layxWindow.setAttribute("data-group-init", "1"); + contentShade && main.removeChild(contentShade); + if (Utils.isFunction(config.event.onload.after)) { + config.event.onload.after(layxWindow, winform); + } + } + }, 100); + for (var i = 0; i < config.frames.length; i++) { + var frameConfig = layxDeepClone({}, that.defaultFrames, config.frames[i]); + var frameBody = document.createElement("div"); + frameBody.classList.add("layx-group-main"); + frameBody.style.backgroundColor = frameConfig.bgColor; + frameBody.setAttribute("data-frameId", frameConfig.id); + if (i === config.frameIndex) { + frameBody.setAttribute("data-enable", "1"); + } + main.appendChild(frameBody); + var isNeedLoad = (i === config.frameIndex) ? true : (Utils.isBoolean(config.preload) ? true : (i + 1 <= config.preload)); + if (frameConfig.type === "html") { + that.createHtmlBody(frameBody, config, frameConfig.content, "group", frameConfig, isNeedLoad); + if (isNeedLoad) { + frameBody.setAttribute("data-complete", "1"); + } + } else if (frameConfig.type === "url") { + that.createFrameBody(frameBody, config, layxWindow, winform, "group", frameConfig, isNeedLoad); + } + } + } + break; + } + if (/(^[1-9]\d*$)/.test(config.autodestroy)) { + var second = config.autodestroy / 1000; + if (config.autodestroyText !== false) { + var autodestroyTip = document.createElement("div"); + autodestroyTip.classList.add("layx-auto-destroy-tip"); + autodestroyTip.innerHTML = config.autodestroyText.replace("{second}", second); + layxWindow.appendChild(autodestroyTip); + } + winform.destroyTimer = setInterval(function () { + --second; + if (config.autodestroyText !== false) { + autodestroyTip.innerHTML = config.autodestroyText.replace("{second}", second); + } + if (second <= 0) { + clearInterval(winform.destroyTimer); + that.destroy(config.id, null, true); + } + }, 1000); + } + var resize = document.createElement("div"); + resize.classList.add("layx-resizes"); + if (config.resizable === false) { + resize.setAttribute("data-enable", "0"); + } + layxWindow.appendChild(resize); + var resizeTop = document.createElement("div"); + resizeTop.classList.add("layx-resize-top"); + if (Utils.isSupportTouch) { + resizeTop.classList.add("layx-reisize-touch"); + } + if (config.resizeLimit.t === true) { + resizeTop.setAttribute("data-enable", "0"); + } + new LayxResize(resizeTop, true, false, true, false); + resize.appendChild(resizeTop); + var resizeLeft = document.createElement("div"); + resizeLeft.classList.add("layx-resize-left"); + if (Utils.isSupportTouch) { + resizeLeft.classList.add("layx-reisize-touch"); + } + if (config.resizeLimit.l === true) { + resizeLeft.setAttribute("data-enable", "0"); + } + new LayxResize(resizeLeft, false, true, false, true); + resize.appendChild(resizeLeft); + var resizeLeftTop = document.createElement("div"); + resizeLeftTop.classList.add("layx-resize-left-top"); + if (Utils.isSupportTouch) { + resizeLeftTop.classList.add("layx-reisize-touch"); + } + if (config.resizeLimit.lt === true) { + resizeLeftTop.setAttribute("data-enable", "0"); + } + new LayxResize(resizeLeftTop, true, true, false, false); + resize.appendChild(resizeLeftTop); + var resizeRightTop = document.createElement("div"); + resizeRightTop.classList.add("layx-resize-right-top"); + if (Utils.isSupportTouch) { + resizeRightTop.classList.add("layx-reisize-touch"); + } + if (config.resizeLimit.rt === true) { + resizeRightTop.setAttribute("data-enable", "0"); + } + new LayxResize(resizeRightTop, true, false, false, false); + resize.appendChild(resizeRightTop); + var resizeLeftBottom = document.createElement("div"); + resizeLeftBottom.classList.add("layx-resize-left-bottom"); + if (Utils.isSupportTouch) { + resizeLeftBottom.classList.add("layx-reisize-touch"); + } + if (config.resizeLimit.lb === true) { + resizeLeftBottom.setAttribute("data-enable", "0"); + } + new LayxResize(resizeLeftBottom, false, true, false, false); + resize.appendChild(resizeLeftBottom); + var resizeRight = document.createElement("div"); + resizeRight.classList.add("layx-resize-right"); + if (Utils.isSupportTouch) { + resizeRight.classList.add("layx-reisize-touch"); + } + if (config.resizeLimit.r === true) { + resizeRight.setAttribute("data-enable", "0"); + } + new LayxResize(resizeRight, false, false, false, true); + resize.appendChild(resizeRight); + var resizeBottom = document.createElement("div"); + resizeBottom.classList.add("layx-resize-bottom"); + if (Utils.isSupportTouch) { + resizeBottom.classList.add("layx-reisize-touch"); + } + if (config.resizeLimit.b === true) { + resizeBottom.setAttribute("data-enable", "0"); + } + new LayxResize(resizeBottom, false, false, true, false); + resize.appendChild(resizeBottom); + var resizeRightBottom = document.createElement("div"); + resizeRightBottom.classList.add("layx-resize-right-bottom"); + if (Utils.isSupportTouch) { + resizeRightBottom.classList.add("layx-reisize-touch"); + } + if (config.resizeLimit.rb === true) { + resizeRightBottom.setAttribute("data-enable", "0"); + } + new LayxResize(resizeRightBottom, false, false, false, false); + resize.appendChild(resizeRightBottom); + if (config.statusBar) { + var statusBar = document.createElement("div"); + statusBar.classList.add("layx-statu-bar"); + statusBar.style.setProperty("border-radius", "0 0 " + layxWindowStyle.borderRadius + " " + layxWindowStyle.borderRadius); + statusBar.style.setProperty("-moz-border-radius", "0 0 " + layxWindowStyle.borderRadius + " " + layxWindowStyle.borderRadius); + statusBar.style.setProperty("-webkit-border-radius", "0 0 " + layxWindowStyle.borderRadius + " " + layxWindowStyle.borderRadius); + config.statusBarStyle && statusBar.setAttribute("style", config.statusBarStyle); + if (config.statusBar === true && Utils.isArray(config.buttons)) { + var btnElement = that.createLayxButtons(config.buttons, config.id, config.dialogType === "prompt" ? true : false); + btnElement && statusBar.appendChild(btnElement); + } else { + if (Utils.isDom(config.statusBar)) { + statusBar.appendChild(config.statusBar); + } else { + statusBar.innerHTML = config.statusBar; + } + } + layxWindow.appendChild(statusBar); + } + if (Utils.isDom(config.floatTarget)) { + that.updateFloatWinPosition(config.id, config.floatDirection); + } + if (config.isOverToMax === true && (Utils.isDom(config.floatTarget) === false)) { + if (_width > window.innerWidth || _height > window.innerHeight) { + that.max(config.id); + } + } + var fixFocus = setInterval(function () { + if (config.id !== Layx.focusId) { + that.updateZIndex(config.id); + } else { + clearInterval(fixFocus); + } + }, 0); + return winform; + }, + updateFloatWinPosition: function (id, direction) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id], + bubbleDirectionOptions = ['top', 'bottom', 'left', 'right']; + if (layxWindow && winform && winform.isFloatTarget === true) { + direction = bubbleDirectionOptions.indexOf(direction) > -1 ? direction : winform.floatDirection; + var bubble = layxWindow.querySelector(".layx-bubble"); + var bubbleInlay = layxWindow.querySelector(".layx-bubble-inlay"); + if (bubble && bubbleInlay) { + bubble.classList.remove("layx-bubble-" + winform.floatDirection); + bubble.style["border" + winform.floatDirection.toFirstUpperCase() + "Color"] = "transparent"; + bubbleInlay.classList.remove("layx-bubble-inlay-" + winform.floatDirection); + bubbleInlay.style["border" + winform.floatDirection.toFirstUpperCase() + "Color"] = "transparent"; + bubble.classList.add("layx-bubble-" + direction); + bubbleInlay.classList.add("layx-bubble-inlay-" + direction); + var layxWindowStyle = layxWindow.currentStyle ? layxWindow.currentStyle : win.getComputedStyle(layxWindow, null); + var _controlBar = layxWindow.querySelector(".layx-control-bar"); + var controlStyle = _controlBar && (_controlBar.currentStyle ? _controlBar.currentStyle : win.getComputedStyle(_controlBar, null)); + if (winform.control === true && _controlBar && controlStyle) { + bubble.style["border" + direction.toFirstUpperCase() + "Color"] = (layxWindowStyle.borderColor === "rgba(0, 0, 0, 0)" || layxWindowStyle.borderColor === "transparent" || (!layxWindowStyle.borderColor) || (Utils.isBoolean(winform.border))) ? ((winform.skin === "default") ? "#3baced" : controlStyle.backgroundColor) : layxWindowStyle.borderColor; + bubbleInlay.style["border" + direction.toFirstUpperCase() + "Color"] = controlStyle.backgroundColor; + } else { + bubble.style["border" + direction.toFirstUpperCase() + "Color"] = (layxWindowStyle.borderColor === "rgba(0, 0, 0, 0)" || layxWindowStyle.borderColor === "transparent" || (!layxWindowStyle.borderColor) || (Utils.isBoolean(winform.border))) ? ((winform.skin === "default") ? "#3baced" : "#fff") : layxWindowStyle.borderColor; + bubbleInlay.style["border" + direction.toFirstUpperCase() + "Color"] = layxWindowStyle.backgroundColor; + } + var bubblePosition = Utils.compilebubbleDirection(direction, winform.floatTarget, winform.area.width, winform.area.height); + that.setPosition(id, { + top: bubblePosition.top, + left: bubblePosition.left + }, true); + var floatPos = Utils.getElementPos(winform.floatTarget); + if (direction === "top" || direction === "bottom") { + bubble.style.left = Math.abs(floatPos.x + winform.floatTarget.offsetWidth / 2 - winform.layxWindow.offsetLeft - 9) + "px"; + } + if (direction === "left" || direction === "right") { + bubble.style.top = Math.abs(floatPos.y + winform.floatTarget.offsetHeight / 2 - winform.layxWindow.offsetTop - 9) + "px"; + } + if ((direction === "top") || ((direction === "right" || direction === "left") && (winform.control === true && _controlBar && controlStyle && bubble.offsetTop > _controlBar.offsetHeight))) { + bubble.style["border" + direction.toFirstUpperCase() + "Color"] = (layxWindowStyle.borderColor === "rgba(0, 0, 0, 0)" || layxWindowStyle.borderColor === "transparent" || (!layxWindowStyle.borderColor) || (Utils.isBoolean(winform.border))) ? ((winform.skin === "default") ? "#3baced" : "#fff") : layxWindowStyle.borderColor; + bubbleInlay.style["border" + direction.toFirstUpperCase() + "Color"] = layxWindowStyle.backgroundColor; + } + winform.floatDirection = direction; + that.updateFloatWinResize(id, direction); + } + } + }, + updateFloatWinResize: function (id, direction) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id], + bubbleDirectionOptions = ['top', 'bottom', 'left', 'right']; + if (layxWindow && winform && winform.isFloatTarget === true) { + direction = bubbleDirectionOptions.indexOf(direction) > -1 ? direction : winform.floatDirection; + switch (direction) { + case "bottom": + layxWindow.querySelector(".layx-resize-left").setAttribute("data-enable", "0"); + layxWindow.querySelector(".layx-resize-top").setAttribute("data-enable", "0"); + layxWindow.querySelector(".layx-resize-left-top").setAttribute("data-enable", "0"); + layxWindow.querySelector(".layx-resize-left-bottom").setAttribute("data-enable", "0"); + layxWindow.querySelector(".layx-resize-right-top").setAttribute("data-enable", "0"); + if (winform.resizeLimit.r === false) { + layxWindow.querySelector(".layx-resize-right").removeAttribute("data-enable"); + } + if (winform.resizeLimit.b === false) { + layxWindow.querySelector(".layx-resize-bottom").removeAttribute("data-enable"); + } + if (winform.resizeLimit.rb === false) { + layxWindow.querySelector(".layx-resize-right-bottom").removeAttribute("data-enable"); + } + break; + case "top": + layxWindow.querySelector(".layx-resize-left").setAttribute("data-enable", "0"); + layxWindow.querySelector(".layx-resize-left-top").setAttribute("data-enable", "0"); + layxWindow.querySelector(".layx-resize-bottom").setAttribute("data-enable", "0"); + layxWindow.querySelector(".layx-resize-left-bottom").setAttribute("data-enable", "0"); + layxWindow.querySelector(".layx-resize-right-bottom").setAttribute("data-enable", "0"); + if (winform.resizeLimit.r === false) { + layxWindow.querySelector(".layx-resize-right").removeAttribute("data-enable"); + } + if (winform.resizeLimit.t === false) { + layxWindow.querySelector(".layx-resize-top").removeAttribute("data-enable"); + } + if (winform.resizeLimit.rt === false) { + layxWindow.querySelector(".layx-resize-right-top").removeAttribute("data-enable"); + } + break; + case "right": + layxWindow.querySelector(".layx-resize-left").setAttribute("data-enable", "0"); + layxWindow.querySelector(".layx-resize-top").setAttribute("data-enable", "0"); + layxWindow.querySelector(".layx-resize-left-top").setAttribute("data-enable", "0"); + layxWindow.querySelector(".layx-resize-left-bottom").setAttribute("data-enable", "0"); + layxWindow.querySelector(".layx-resize-right-top").setAttribute("data-enable", "0"); + if (winform.resizeLimit.r === false) { + layxWindow.querySelector(".layx-resize-right").removeAttribute("data-enable"); + } + if (winform.resizeLimit.b === false) { + layxWindow.querySelector(".layx-resize-bottom").removeAttribute("data-enable"); + } + if (winform.resizeLimit.rb === false) { + layxWindow.querySelector(".layx-resize-right-bottom").removeAttribute("data-enable"); + } + break; + case "left": + layxWindow.querySelector(".layx-resize-top").setAttribute("data-enable", "0"); + layxWindow.querySelector(".layx-resize-right").setAttribute("data-enable", "0"); + layxWindow.querySelector(".layx-resize-left-top").setAttribute("data-enable", "0"); + layxWindow.querySelector(".layx-resize-right-top").setAttribute("data-enable", "0"); + layxWindow.querySelector(".layx-resize-right-bottom").setAttribute("data-enable", "0"); + if (winform.resizeLimit.l === false) { + layxWindow.querySelector(".layx-resize-left").removeAttribute("data-enable"); + } + if (winform.resizeLimit.b === false) { + layxWindow.querySelector(".layx-resize-bottom").removeAttribute("data-enable"); + } + if (winform.resizeLimit.lb === false) { + layxWindow.querySelector(".layx-resize-left-bottom").removeAttribute("data-enable"); + } + break; + } + } + }, + removeStoreWindowAreaInfo: function (id) { + var that = this, + windowId = "layx-" + id, + storeAreaInfo = (typeof (Storage) !== "undefined") && !(win.location.protocol.indexOf("file:") > -1) && localStorage.getItem(windowId); + if (storeAreaInfo) { + localStorage.removeItem(windowId); + } + }, + storeWindowAreaInfo: function (id, area) { + var that = this, + windowId = "layx-" + id; + (typeof (Storage) !== "undefined") && !(win.location.protocol.indexOf("file:") > -1) && localStorage.setItem(windowId, JSON.stringify(area)); + }, + getStoreWindowAreaInfo: function (id) { + var that = this, + windowId = "layx-" + id, + storeAreaInfo = (typeof (Storage) !== "undefined") && !(win.location.protocol.indexOf("file:") > -1) && localStorage.getItem(windowId); + if (storeAreaInfo) { + return JSON.parse(storeAreaInfo); + } + return null; + }, + _setGroupIndex: function (id, target) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform && winform.type === "group") { + var prevSelectTitle = layxWindow.querySelector(".layx-group-title[data-enable='1']"); + if (prevSelectTitle !== target) { + if (Utils.isFunction(winform.event.onswitch.before)) { + var revel = winform.event.onswitch.before(layxWindow, winform, prevSelectTitle.getAttribute("data-frameId")); + if (revel === false) { + return; + } + } + prevSelectTitle.removeAttribute("data-enable"); + target.setAttribute("data-enable", "1"); + var frameId = target.getAttribute("data-frameId"); + var prevGroupMain = layxWindow.querySelector(".layx-group-main[data-enable='1']"); + var currentGroupMain = layxWindow.querySelector(".layx-group-main[data-frameId='" + frameId + "']"); + if (currentGroupMain !== prevGroupMain) { + prevGroupMain.removeAttribute("data-enable"); + currentGroupMain.setAttribute("data-enable", "1"); + winform.groupCurrentId = frameId; + if (currentGroupMain.getAttribute("data-preload") === "1") { + var frameform = that.getGroupFrame(winform.frames, frameId); + if (frameform.type === "url") { + that.setGroupUrl(id, frameId, frameform.url); + currentGroupMain.removeAttribute("data-preload"); + } + if (frameform.type === "html") { + that.setGroupContent(id, frameId, frameform.content, frameform.cloneElementContent); + currentGroupMain.removeAttribute("data-preload"); + } + } + } + if (Utils.isFunction(winform.event.onswitch.after)) { + winform.event.onswitch.after(layxWindow, winform, target.getAttribute("data-frameId")); + } + } + } + }, + setGroupIndex: function (id, frameId) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform) { + var title = layxWindow.querySelector(".layx-group-title[data-frameId='" + frameId + "']"); + title.click(); + } + }, + cloneStore: {}, + createHtmlBody: function (main, config, content, type, frameConfig, isLoad) { + var that = this; + var html = document.createElement("div"); + html.classList.add("layx-html"); + html.setAttribute("id", "layx-" + config.id + (type === "group" ? "-" + frameConfig.id + "-" : "-") + "html"); + var newContent; + if (isLoad !== false) { + if (Utils.isDom(content)) { + var _ctStyle = content.currentStyle ? content.currentStyle : win.getComputedStyle(content, null); + if (type !== "group" && config.cloneElementContent === false) { + Layx.cloneStore[config.id] = { + prev: content.previousSibling, + parent: content.parentNode, + next: content.nextSibling, + display: _ctStyle.display + }; + } + if (type === "group" && frameConfig.cloneElementContent === false) { + if (!Layx.cloneStore[config.id]) { + Layx.cloneStore[config.id] = { frames: {} }; + } + Layx.cloneStore[config.id].frames[frameConfig.id] = { + prev: content.previousSibling, + parent: content.parentNode, + next: content.nextSibling, + display: _ctStyle.display + }; + } + newContent = html.appendChild((type === "group" ? frameConfig : config).cloneElementContent === true ? content.cloneNode(true) : content); + } else { + html.innerHTML = content; + } + } else { + main.setAttribute("data-preload", "1"); + } + main.appendChild(html); + if (Utils.isDom(newContent)) { + var contentStyle = newContent.currentStyle ? newContent.currentStyle : win.getComputedStyle(newContent, null); + if (contentStyle.display === "none") { + newContent.style.display = ""; + } + } + }, + frameLoadHandle: function (iframe, main, config, layxWindow, winform, type, frameConfig, isLoad) { + var that = this; + var contentShade = (type === "group" ? iframe.parentNode.parentNode : iframe.parentNode).querySelector(".layx-content-shade"); + try { + if (config.focusable === true && config.enableDomainFocus === true) { + if (!iframe.getAttribute("data-focus")) { + IframeOnClick.track(iframe, function () { + if (Utils.isFunction(config.event.onfocus)) { + var revel = Utils.isFunction(config.event.onfocus); + if (revel === false) { + return; + } + config.event.onfocus(layxWindow, winform); + } + that.updateZIndex(config.id); + }); + iframe.setAttribute("data-focus", "true"); + } + } + var iframeTitle = config.title; + if (type === "group") { + if (frameConfig.useFrameTitle === true) { + iframeTitle = iframe.contentWindow.document.querySelector("title").innerText; + that.setGroupTitle(config.id, frameConfig.id, iframeTitle); + } + } else { + if (config.useFrameTitle === true) { + iframeTitle = iframe.contentWindow.document.querySelector("title").innerText; + that.setTitle(config.id, iframeTitle); + } + } + iframe.contentWindow.document.addEventListener("click", function (event) { + var e = event || window.event || arguments.callee.caller.arguments[0]; + if (config.focusable === true) { + if (Utils.isFunction(config.event.onfocus)) { + var revel = Utils.isFunction(config.event.onfocus); + if (revel === false) { + return; + } + config.event.onfocus(layxWindow, winform); + } + that.updateZIndex(config.id); + } + }, false); + iframe.contentWindow.document.addEventListener("keydown", function (event) { + var e = event || window.event || arguments.callee.caller.arguments[0]; + var focusWindow = Layx.windows[Layx.focusId]; + if (e && e.keyCode == 27) { + if (focusWindow) { + Layx.destroy(Layx.focusId, {}, false, true); + } + } + if (e && e.keyCode === 13) { + if (focusWindow && focusWindow.buttons.length > 0) { + if (focusWindow.buttonKey.toLowerCase() === "enter" && !e.ctrlKey) { + if (focusWindow.dialogType !== "prompt") { + focusWindow.buttons[0].callback(focusWindow.id, Layx.getButton(focusWindow.id, focusWindow.buttons[0].id, e)); + } else { + var textarea = Layx.getPromptTextArea(focusWindow.id); + focusWindow.buttons[0].callback(focusWindow.id, (textarea ? textarea.value : "").replace(/(^\s*)|(\s*$)/g, ""), textarea, Layx.getButton(focusWindow.id, focusWindow.buttons[0].id, e)); + } + } else if (focusWindow.buttonKey.toLowerCase() === "ctrl+enter" && e.ctrlKey) { + if (focusWindow.dialogType !== "prompt") { + focusWindow.buttons[0].callback(focusWindow.id, Layx.getButton(focusWindow.id, focusWindow.buttons[0].id, e)); + } else { + var textarea = Layx.getPromptTextArea(focusWindow.id); + focusWindow.buttons[0].callback(focusWindow.id, (textarea ? textarea.value : "").replace(/(^\s*)|(\s*$)/g, ""), textarea, Layx.getButton(focusWindow.id, focusWindow.buttons[0].id, e)); + } + } + } + } + }, false); + } catch (e) { + if (type === "group") { + contentShade && contentShade.parentNode.removeChild(contentShade); + } + console.warn(e); + } finally { + if (type === "group") { + if (isLoad) { + main.setAttribute("data-complete", "1"); + } + if (layxWindow.getAttribute("data-group-init") === "1") { + if (winform.loadingTextTimer) { + clearInterval(winform.loadingTextTimer); + delete winform.loadingTextTimer; + } + contentShade && contentShade.parentNode.removeChild(contentShade); + if (Utils.isFunction(config.event.onload.after)) { + config.event.onload.after(layxWindow, winform); + } + } + } else { + contentShade && contentShade.parentNode.removeChild(contentShade); + if (winform.loadingTextTimer) { + clearInterval(winform.loadingTextTimer); + delete winform.loadingTextTimer; + } + if (Utils.isFunction(config.event.onload.after)) { + config.event.onload.after(layxWindow, winform); + } + } + } + }, + createFrameBody: function (main, config, layxWindow, winform, type, frameConfig, isLoad) { + var that = this; + var iframe = document.createElement("iframe"); + iframe.setAttribute("id", "layx-" + config.id + (type === "group" ? "-" + frameConfig.id + "-" : "-") + "iframe"); + iframe.classList.add("layx-iframe"); + iframe.classList.add("layx-flexbox"); + iframe.setAttribute("allowtransparency", "true"); + iframe.setAttribute("frameborder", "0"); + if (win.navigator.userAgent.toLowerCase().indexOf('iphone') > -1 || (!!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/))) { + iframe.setAttribute("scrolling", "no"); + } else { + iframe.setAttribute("scrolling", "auto"); + } + iframe.setAttribute("allowfullscreen", ""); + iframe.setAttribute("mozallowfullscreen", ""); + iframe.setAttribute("webkitallowfullscreen", ""); + iframe.src = isLoad !== false ? ((type === "group" ? frameConfig.url : config.url) || 'about:blank') : 'about:blank'; + if (iframe.attachEvent) { + iframe.attachEvent("onreadystatechange", function () { + if (iframe.readyState === "complete" || iframe.readyState == "loaded") { + iframe.detachEvent("onreadystatechange", arguments.callee); + that.frameLoadHandle(iframe, main, config, layxWindow, winform, type, frameConfig, isLoad); + } + }); + } else { + iframe.addEventListener("load", function () { + this.removeEventListener("load", arguments.call, false); + that.frameLoadHandle(iframe, main, config, layxWindow, winform, type, frameConfig, isLoad); + }, false); + } + if (isLoad === false) { + main.setAttribute("data-preload", "1"); + } + main.appendChild(iframe); + }, + setContent: function (id, content, cloneElementContent) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform) { + if (winform.type === "html") { + var html = layxWindow.querySelector("#layx-" + id + "-html"); + if (html) { + if (Utils.isFunction(winform.event.onload.before)) { + var revel = winform.event.onload.before(layxWindow, winform); + if (revel === false) { + return; + } + } + try { + var contentShade = that.createContenLoadAnimate(html.parentNode, winform.loadingText, winform); + cloneElementContent = Utils.isBoolean(cloneElementContent) ? cloneElementContent : winform.cloneElementContent; + var newContent; + if (Utils.isDom(content)) { + var _ctStyle = content.currentStyle ? content.currentStyle : win.getComputedStyle(content, null); + if (cloneElementContent === false) { + Layx.cloneStore[id] = { + prev: content.previousSibling, + parent: content.parentNode, + next: content.nextSibling, + display: _ctStyle.display + }; + } + html.innerHTML = ""; + newContent = html.appendChild(cloneElementContent === true ? content.cloneNode(true) : content); + } else { + html.innerHTML = content; + } + if (Utils.isDom(newContent)) { + var contentStyle = newContent.currentStyle ? newContent.currentStyle : window.getComputedStyle(newContent, null); + if (contentStyle.display === "none") { + newContent.style.display = ""; + } + } + winform.content = content; + } finally { + contentShade && html.parentNode.removeChild(contentShade); + if (winform.loadingTextTimer) { + clearInterval(winform.loadingTextTimer); + delete winform.loadingTextTimer; + } + if (Utils.isFunction(winform.event.onload.after)) { + winform.event.onload.after(layxWindow, winform); + } + } + } + } + } + }, + getGroupFrame: function (frames, frameId) { + var frm = {}; + for (var i = 0; i < frames.length; i++) { + if (frames[i].id === frameId) { + frm = frames[i]; + break; + } + } + return frm; + }, + reloadGroupFrame: function (id, frameId) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform && winform.type === "group") { + var frameform = that.getGroupFrame(winform.frames, frameId); + if (frameform.type === "url") { + var iframe = layxWindow.querySelector("#layx-" + id + "-" + frameId + "-" + "iframe"); + if (iframe) { + var url = iframe.getAttribute("src"); + that.setGroupUrl(id, frameId, url); + } + } + } + }, + setGroupContent: function (id, frameId, content, cloneElementContent) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform && winform.type === "group") { + var frameform = that.getGroupFrame(winform.frames, frameId); + if (frameform.type === "html") { + var html = layxWindow.querySelector("#layx-" + id + "-" + frameId + "-" + "html"); + if (html) { + if (Utils.isFunction(winform.event.onload.before)) { + var revel = winform.event.onload.before(layxWindow, winform); + if (revel === false) { + return; + } + } + try { + var contentShade = that.createContenLoadAnimate(html.parentNode.parentNode, winform.loadingText, winform); + cloneElementContent = Utils.isBoolean(cloneElementContent) ? cloneElementContent : frameform.cloneElementContent; + var newContent; + if (Utils.isDom(content)) { + var _ctStyle = content.currentStyle ? content.currentStyle : win.getComputedStyle(content, null); + if (cloneElementContent === false) { + if (!Layx.cloneStore[id]) { + Layx.cloneStore[id] = { frames: {} }; + } + Layx.cloneStore[id].frames[frameId] = { + prev: content.previousSibling, + parent: content.parentNode, + next: content.nextSibling, + display: _ctStyle.display + }; + } + html.innerHTML = ""; + newContent = html.appendChild(cloneElementContent === true ? content.cloneNode(true) : content); + } else { + html.innerHTML = content; + } + if (Utils.isDom(newContent)) { + var contentStyle = newContent.currentStyle ? newContent.currentStyle : window.getComputedStyle(newContent, null); + if (contentStyle.display === "none") { + newContent.style.display = ""; + } + } + frameform.content = content; + } finally { + contentShade && html.parentNode.parentNode.removeChild(contentShade); + if (winform.loadingTextTimer) { + clearInterval(winform.loadingTextTimer); + delete winform.loadingTextTimer; + } + if (Utils.isFunction(winform.event.onload.after)) { + winform.event.onload.after(layxWindow, winform); + } + } + } + } + } + }, + createContenLoadAnimate: function (pEle, loadingText, winform, isCreateLoadAnimate) { + var that = this; + if (loadingText !== false) { + if (Utils.isArray(loadingText) && loadingText.length === 2 && loadingText[0] === true) { + return that.createContenLoadAnimate(pEle, loadingText[1], winform, false); + } + var contentShade = document.createElement("div"); + contentShade.classList.add("layx-content-shade"); + contentShade.classList.add("layx-flexbox"); + contentShade.classList.add("layx-flex-center"); + if (Utils.isDom(loadingText)) { + contentShade.appendChild(loadingText); + } else { + if (isCreateLoadAnimate !== false) { + contentShade.appendChild(that.createLoadAnimate()); + } + var msgContent = document.createElement("div"); + msgContent.classList.add("layx-load-content-msg"); + msgContent.innerHTML = loadingText; + contentShade.appendChild(msgContent); + var span = document.createElement("span"); + span.classList.add("layx-dot"); + msgContent.appendChild(span); + var dotCount = 0; + winform.loadingTextTimer = setInterval(function () { + if (dotCount === 5) { + dotCount = 0; + } + ++dotCount; + var dotHtml = ""; + for (var i = 0; i < dotCount; i++) { + dotHtml += "."; + } + span.innerHTML = dotHtml; + }, 200); + } + return pEle.appendChild(contentShade); + } + }, + setUrl: function (id, url) { + url = url || 'about:blank'; + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform) { + if (winform.type === "url") { + var iframe = layxWindow.querySelector("#layx-" + id + "-iframe"); + if (iframe) { + if (Utils.isFunction(winform.event.onload.before)) { + var revel = winform.event.onload.before(layxWindow, winform); + if (revel === false) { + return; + } + } + var contentShade = that.createContenLoadAnimate(iframe.parentNode, winform.loadingText, winform); + iframe.setAttribute("src", url); + } + } + } + }, + setGroupUrl: function (id, frameId, url) { + url = url || 'about:blank'; + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform && winform.type === "group") { + var frameform = that.getGroupFrame(winform.frames, frameId); + if (frameform.type === "url") { + var iframe = layxWindow.querySelector("#layx-" + id + "-" + frameId + "-" + "iframe"); + if (iframe) { + if (Utils.isFunction(winform.event.onload.before)) { + var revel = winform.event.onload.before(layxWindow, winform); + if (revel === false) { + return; + } + } + iframe.parentNode.removeAttribute("data-complete"); + var contentShade = that.createContenLoadAnimate(iframe.parentNode.parentNode, winform.loadingText, winform); + iframe.setAttribute("src", url); + } + } + } + }, + setGroupTitle: function (id, frameId, content, useFrameTitle) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform && winform.type === "group") { + var title = layxWindow.querySelector(".layx-group-title[data-frameId='" + frameId + "']"); + if (title) { + var frameform = that.getGroupFrame(winform.frames, frameId); + if (useFrameTitle === true && frameform.type === "url") { + var iframe = layxWindow.querySelector("#layx-" + id + "-" + frameId + "-" + "iframe"); + try { + content = iframe.contentDocument.querySelector("title").innerText; + } catch (e) { } + } + var label = title.querySelector(".layx-label"); + if (label) { + label.innerHTML = content; + title.setAttribute("title", label.innerHTML); + frameform.title = content; + } + } + } + }, + setTitle: function (id, content, useFrameTitle) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform) { + var title = layxWindow.querySelector(".layx-title"); + if (title) { + if (useFrameTitle === true && winform.type === "url") { + var iframe = layxWindow.querySelector("#layx-" + id + "-iframe"); + try { + content = iframe.contentDocument.querySelector("title").innerText; + } catch (e) { } + } + var label = title.querySelector(".layx-label"); + if (label) { + label.innerHTML = content; + title.setAttribute("title", label.innerHTML); + winform.title = content; + } + } + } + }, + stickToggle: function (id) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform) { + that.updateZIndex(id); + if (Utils.isFunction(winform.event.onstick.before)) { + var revel = winform.event.onstick.before(layxWindow, winform); + if (revel === false) { + return; + } + } + winform.isStick = !winform.isStick; + var stickMenu = layxWindow.querySelector(".layx-stick-menu"); + if (stickMenu) { + stickMenu.setAttribute("data-enable", winform.isStick ? "1" : "0"); + winform.isStick ? stickMenu.setAttribute("title", "取消置顶") : stickMenu.setAttribute("title", "置顶"); + } + that.updateZIndex(id); + if (Utils.isFunction(winform.event.onstick.after)) { + winform.event.onstick.after(layxWindow, winform); + } + } + }, + reloadFrame: function (id) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform) { + if (winform.type === "url") { + var iframe = layxWindow.querySelector("#layx-" + id + "-iframe"); + if (iframe) { + var url = iframe.getAttribute("src"); + that.setUrl(id, url); + } + } + } + }, + restore: function (id) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform) { + if (winform.restorable !== true) + return; + that.updateZIndex(id); + if (Utils.isFunction(winform.event.onrestore.before)) { + var revel = winform.event.onrestore.before(layxWindow, winform); + if (revel === false) { + return; + } + } + var area = winform.area; + if (winform.status === "normal") { + that.max(id); + } else if (winform.status === "max") { + if (document.body.classList.contains("ilayx-body")) { + document.body.classList.remove('ilayx-body'); + } + layxWindow.style.top = area.top + "px"; + layxWindow.style.left = area.left + "px"; + layxWindow.style.width = area.width + "px"; + layxWindow.style.height = area.height + "px"; + layxWindow.classList.remove("layx-max-statu"); + winform.status = "normal"; + var restoreMenu = layxWindow.querySelector(".layx-restore-menu[data-menu='max']"); + if (restoreMenu) { + restoreMenu.classList.remove("layx-restore-menu"); + restoreMenu.classList.add("layx-max-menu"); + restoreMenu.setAttribute("title", "最大化"); + restoreMenu.innerHTML = ''; + } + var resizePanel = layxWindow.querySelector(".layx-resizes"); + if (resizePanel) { + resizePanel.removeAttribute("data-enable"); + } + } + if (winform.status === "min") { + if (winform.minBefore === "normal") { + layxWindow.style.top = area.top + "px"; + layxWindow.style.left = area.left + "px"; + layxWindow.style.width = area.width + "px"; + layxWindow.style.height = area.height + "px"; + winform.status = "normal"; + var restoreMenu = layxWindow.querySelector(".layx-restore-menu[data-menu='min']"); + if (restoreMenu) { + restoreMenu.classList.remove("layx-restore-menu"); + restoreMenu.classList.add("layx-min-menu"); + restoreMenu.setAttribute("title", "最小化"); + restoreMenu.innerHTML = ''; + } + var resizePanel = layxWindow.querySelector(".layx-resizes"); + if (resizePanel) { + resizePanel.removeAttribute("data-enable"); + } + } else if (winform.minBefore === "max") { + that.max(id); + } + that.updateMinLayout(); + } + var _winform = layxDeepClone({}, {}, winform); + delete that.windows[id]; + that.windows[id] = _winform; + that.updateMinLayout(); + if (layxWindow.classList.contains("layx-min-statu")) { + layxWindow.classList.remove("layx-min-statu"); + } + if (Utils.isFunction(_winform.event.onrestore.after)) { + _winform.event.onrestore.after(layxWindow, _winform); + } + } + }, + min: function (id) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform && winform.isFloatTarget === false) { + if (winform.minable !== true || winform.status === "min") + return; + that.updateZIndex(id); + if (Utils.isFunction(winform.event.onmin.before)) { + var revel = winform.event.onmin.before(layxWindow, winform); + if (revel === false) { + return; + } + } + var innertArea = Utils.innerArea(); + winform.minBefore = winform.status; + winform.status = "min"; + var minMenu = layxWindow.querySelector(".layx-min-menu"); + if (minMenu) { + minMenu.classList.remove("layx-max-menu"); + minMenu.classList.add("layx-restore-menu"); + minMenu.setAttribute("title", "还原"); + minMenu.innerHTML = ''; + } + var resizePanel = layxWindow.querySelector(".layx-resizes"); + if (resizePanel) { + resizePanel.setAttribute("data-enable", "0"); + } + var restoreMenu = layxWindow.querySelector(".layx-restore-menu[data-menu='max']"); + if (restoreMenu) { + restoreMenu.classList.remove("layx-restore-menu"); + restoreMenu.classList.add("layx-max-menu"); + restoreMenu.setAttribute("title", "最大化"); + restoreMenu.innerHTML = ''; + } + if (layxWindow.classList.contains("layx-max-statu")) { + layxWindow.classList.remove("layx-max-statu"); + } + var _winform = layxDeepClone({}, winform); + delete that.windows[id]; + that.windows[id] = _winform; + that.updateMinLayout(); + if (document.body.classList.contains("ilayx-body")) { + document.body.classList.remove('ilayx-body'); + } + if (Utils.isFunction(winform.event.onmin.after)) { + winform.event.onmin.after(layxWindow, winform); + } + } + }, + updateZIndex: function (id) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform) { + if (winform.dialogType !== "load" && winform.dialogType !== "msg") { + Layx.focusId = id; + } + if (winform.focusToReveal === true) { + var layxShade = document.getElementById("layx-" + id + "-shade"); + if (layxShade) { + layxShade.style.zIndex = (winform.isStick === true ? (++that.stickZIndex) : (++that.zIndex)); + } + if (winform.isStick === true) { + winform.zIndex = (++that.stickZIndex) + 1; + } else { + winform.zIndex = (++that.zIndex) + 1; + } + layxWindow.style.zIndex = winform.zIndex; + } + } + }, + updateMinLayout: function () { + var that = this, + windows = that.windows, + innertArea = Utils.innerArea(), + paddingLeft = 10, + paddingBottom = 10, + widthByMinStatu = 240, + stepIndex = 0, + lineMaxCount = Math.floor(innertArea.width / (widthByMinStatu + paddingLeft)); + for (var id in windows) { + var winform = windows[id], + layxWindow = document.getElementById("layx-" + id); + if (layxWindow && winform.status === "min") { + var control = layxWindow.querySelector(".layx-control-bar"); + if (control) { + var heightByMinStatus = control.offsetHeight; + layxWindow.classList.add("layx-min-statu"); + layxWindow.style.width = widthByMinStatu + 'px'; + layxWindow.style.height = heightByMinStatus + 'px'; + layxWindow.style.top = innertArea.height - (Math.floor(stepIndex / lineMaxCount) + 1) * (heightByMinStatus + paddingBottom) + 'px'; + layxWindow.style.left = stepIndex % lineMaxCount * (widthByMinStatu + paddingLeft) + paddingLeft + 'px'; + stepIndex++; + } + } + } + }, + max: function (id) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id], + innertArea = Utils.innerArea(); + if (layxWindow && winform && winform.isFloatTarget === false) { + if (winform.maxable !== true) + return; + if (winform.status === "max") { + layxWindow.style.top = 0; + layxWindow.style.left = 0; + layxWindow.style.width = innertArea.width + "px"; + layxWindow.style.height = innertArea.height + "px"; + } else { + that.updateZIndex(id); + if (Utils.isFunction(winform.event.onmax.before)) { + var revel = winform.event.onmax.before(layxWindow, winform); + if (revel === false) { + return; + } + } + document.body.classList.add('ilayx-body'); + layxWindow.style.top = 0; + layxWindow.style.left = 0; + layxWindow.style.width = innertArea.width + "px"; + layxWindow.style.height = innertArea.height + "px"; + layxWindow.classList.add("layx-max-statu"); + winform.status = "max"; + var maxMenu = layxWindow.querySelector(".layx-max-menu"); + if (maxMenu) { + maxMenu.classList.remove("layx-max-menu"); + maxMenu.classList.add("layx-restore-menu"); + maxMenu.setAttribute("title", "还原"); + maxMenu.innerHTML = ''; + } + var resizePanel = layxWindow.querySelector(".layx-resizes"); + if (resizePanel) { + resizePanel.setAttribute("data-enable", "0"); + } + var restoreMenu = layxWindow.querySelector(".layx-restore-menu[data-menu='min']"); + if (restoreMenu) { + restoreMenu.classList.remove("layx-restore-menu"); + restoreMenu.classList.add("layx-min-menu"); + restoreMenu.setAttribute("title", "最小化"); + restoreMenu.innerHTML = ''; + } + var _winform = layxDeepClone({}, winform); + delete that.windows[id]; + that.windows[id] = _winform; + that.updateMinLayout(); + if (layxWindow.classList.contains("layx-min-statu")) { + layxWindow.classList.remove("layx-min-statu"); + } + if (Utils.isFunction(winform.event.onmax.after)) { + winform.event.onmax.after(layxWindow, winform); + } + } + } + }, + visual: function (id, status, params, inside) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + layxShade = document.getElementById(windowId + '-shade'), + winform = that.windows[id]; + if (layxWindow && winform) { + if (Utils.isFunction(winform.event.onvisual.before)) { + var revel = winform.event.onvisual.before(layxWindow, winform, params || {}, inside === true, status !== false); + if (revel === false) { + return; + } + } + if (status !== false) { + layxWindow.classList.remove("layx-hide-statu"); + } else { + layxWindow.classList.add("layx-hide-statu"); + } + that.updateMinLayout(); + if (Utils.isFunction(winform.event.onvisual.after)) { + winform.event.onvisual.after(layxWindow, winform, status !== false); + } + } + }, + destroyInlay: function (id) { + var that = this; + that.destroy(id, null, true); + }, + destroy: function (id, params, inside, escKey, force) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + layxShade = document.getElementById(windowId + '-shade'), + winform = that.windows[id]; + if (layxWindow && winform) { + if (winform.escKey === false && escKey === true) + return; + that.updateZIndex(id); + if (Utils.isFunction(winform.event.ondestroy.before)) { + var revel = winform.event.ondestroy.before(layxWindow, winform, params || {}, inside === true, escKey === true); + if (force === true) { } else { + if (revel === false) { + return; + } + } + } + if (winform.closable !== true) + return; + var oldNodeInfo = that.cloneStore[id]; + if (winform.type === "html" && oldNodeInfo) { + var html = layxWindow.querySelector("#layx-" + id + "-html"); + if (html) { + var child = html.children[0]; + if (child && child.style) { + child.style.display = oldNodeInfo.display; + } + if (oldNodeInfo.prev) { + setTimeout(function () { + Utils.insertAfter(child, oldNodeInfo.prev); + }, 0); + } else { + setTimeout(function () { + oldNodeInfo.parent && oldNodeInfo.parent.insertBefore(child, oldNodeInfo.next); + }, 0); + } + } + } + if (winform.type === "group" && oldNodeInfo) { + if (oldNodeInfo && oldNodeInfo.frames) { + for (var frameId in oldNodeInfo.frames) { + var frameInfo = oldNodeInfo.frames[frameId]; + var html = layxWindow.querySelector("#layx-" + id + "-" + frameId + "-html"); + if (html) { + var child = html.children[0]; + if (child && child.style) { + child.style.display = frameInfo.display; + } + if (frameInfo.prev) { + setTimeout(function () { + Utils.insertAfter(child, frameInfo.prev); + }, 0); + } else { + setTimeout(function () { + frameInfo.parent && frameInfo.parent.insertBefore(child, frameInfo.next); + }, 0); + } + } + } + } + } + Layx.focusId = Layx.prevFocusId; + delete that.cloneStore[id]; + delete that.windows[id]; + if (document.body.classList.contains("ilayx-body")) { + document.body.classList.remove('ilayx-body'); + } + layxWindow.parentNode.removeChild(layxWindow); + if (layxShade) { + layxShade.parentNode.removeChild(layxShade); + } + that.updateMinLayout(); + if (Utils.isFunction(winform.event.ondestroy.after)) { + winform.event.ondestroy.after(); + } + if (winform.destroyTimer) + clearInterval(winform.destroyTimer); + if (winform.loadTimer) + clearInterval(winform.loadTimer); + if (winform.loadingTextTimer) + clearInterval(winform.loadingTextTimer); + for (var key in winform) { + delete winform[key]; + } + winform = undefined; + } + }, + destroyAll: function () { + var that = this; + for (var id in Layx.windows) { + that.destroy(id); + } + }, + flicker: function (id) { + var that = this, + flickerTimer, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform) { + that.updateZIndex(id); + if (layxWindow.classList.contains('layx-flicker')) { + layxWindow.classList.remove('layx-flicker'); + } + layxWindow.classList.add('layx-flicker'); + flickerTimer = setTimeout(function () { + layxWindow.classList.remove('layx-flicker'); + clearTimeout(flickerTimer); + }, 120 * 8); + } + }, + setPosition: function (id, position, isFloatTarget) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform) { + var _position = isFloatTarget === true ? position : Utils.compileLayxPosition(winform.area.width, winform.area.height, position); + winform.area.left = _position.left; + winform.area.top = _position.top; + if (winform.storeStatus === true) { + that.storeWindowAreaInfo(id, winform.area); + } + layxWindow.style.left = _position.left + "px"; + layxWindow.style.top = _position.top + "px"; + } + }, + setSize: function (id, area) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform) { + if (area) { + if (area["width"]) { + var _width = Utils.compileLayxWidthOrHeight("width", area["width"], that.defaults.width); + winform.area.width = _width; + layxWindow.style.width = _width + "px"; + } + if (area["height"]) { + var _height = Utils.compileLayxWidthOrHeight("height", area["height"], that.defaults.height); + winform.area.height = _height; + layxWindow.style.height = _height + "px"; + } + if (winform.storeStatus === true) { + that.storeWindowAreaInfo(id, winform.area); + } + } + } + }, + getFrameContext: function (id) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id], + iframeWindow = null; + if (layxWindow && winform && winform.type === "url") { + var iframe = layxWindow.querySelector(".layx-iframe"); + if (iframe) { + try { + iframeWindow = iframe.contentWindow; + } catch (e) { } + } + } + return iframeWindow; + }, + getParentContext: function (id) { + var that = this; + var iframeWindow = that.getFrameContext(id); + if (iframeWindow) { + return iframeWindow.parent; + } else { + return null; + } + }, + getGroupFrameContext: function (id, frameId) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id], + iframeWindow = null; + if (layxWindow && winform && winform.type === "group") { + var frameform = that.getGroupFrame(winform.frames, frameId); + if (frameform.type === "url") { + var iframe = layxWindow.querySelector("#layx-" + id + "-" + frameId + "-" + "iframe"); + if (iframe) { + try { + iframeWindow = iframe.contentWindow; + } catch (e) { } + } + } + } + return iframeWindow; + }, + createLayxButtons: function (buttons, id, isPrompt) { + var that = this; + var buttonPanel = document.createElement("div"); + buttonPanel.classList.add("layx-buttons"); + for (var i = 0; i < buttons.length; i++) { + var buttonItem = document.createElement("button"); + var buttonConfig = layxDeepClone({}, that.defaultButtons, buttons[i]); + buttonItem.classList.add("layx-button-item"); + buttonItem.setAttribute("title", buttonConfig.label); + buttonItem.innerText = buttonConfig.label; + buttonConfig.id && buttonItem.setAttribute("id", "layx-" + id + "-button-" + buttonConfig.id); + if (Utils.isArray(buttonConfig.classes)) { + for (var n = 0; n < buttonConfig.classes.length; n++) { + buttonItem.classList.add(buttonConfig.classes[n]); + } + } else { + buttonConfig.classes && buttonItem.classList.add(buttonConfig.classes.toString()); + } + buttonConfig.style && buttonItem.setAttribute("style", buttonConfig.style); + buttonItem.callback = buttons[i].callback; + buttonItem.onclick = function (e) { + e = e || window.event || arguments.callee.caller.arguments[0]; + if (Utils.isFunction(this.callback)) { + if (isPrompt === true) { + var textarea = that.getPromptTextArea(id); + that.updateZIndex(id); + this.callback(id, (textarea ? textarea.value : "").replace(/(^\s*)|(\s*$)/g, ""), textarea, this, e); + } else { + that.updateZIndex(id); + this.callback(id, this, e); + } + } + }; + buttonPanel.appendChild(buttonItem); + } + return buttonPanel; + }, + setButtonStatus: function (id, buttonId, isEnable) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform) { + var button = layxWindow.querySelector("#layx-" + id + "-button-" + buttonId); + if (button) { + if (isEnable === false) { + button.setAttribute("disabled", "disabled"); + } else { + button.removeAttribute("disabled"); + } + } + } + }, + getStrSizeRange: function (str, minWidth, minHeight, maxWidth, maxHeight, dialogIcon) { + var width = 0, + height = 0, + span = document.createElement("span"); + span.innerHTML = str; + span.classList.add("layx-calc-text"); + span.style.visibility = 'hidden'; + span.style.display = 'inline-block'; + span.style.minWidth = minWidth + "px"; + span.style.minHeight = minHeight + "px"; + span.style.maxWidth = maxWidth + "px"; + span.style.maxHeight = maxHeight + "px"; + span.style.paddingLeft = 10 + 'px'; + span.style.paddingRight = 10 + 'px'; + span.style.paddingTop = 10 + 'px'; + span.style.paddingBottom = 10 + 'px'; + span.style.margin = "0"; + span.style.border = "none"; + span.style.lineHeight = 1.5; + document.body.appendChild(span); + width = span.offsetWidth; + height = span.offsetHeight + 1; + document.body.removeChild(span); + return { + width: width + (dialogIcon === true ? 45 : 0), + height: height + }; + }, + getButton: function (id, buttonId) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform) { + return layxWindow.querySelector("#layx-" + id + "-button" + (buttonId ? "-" + buttonId : "")); + } + return null; + }, + tip: function (msg, target, direction, options) { + var that = this; + if (Utils.isDom(target)) { + var _id = (options && options.id) ? options.id : 'layx-dialog-tip-' + Utils.rndNum(8); + target.addEventListener("mouseover", function (e) { + var msgSizeRange = that.getStrSizeRange(msg, 20, 20, 320, 90, ((options && options.dialogIcon) ? true : false)); + that.create(layxDeepClone({}, { + id: _id, + type: 'html', + control: false, + content: that.createDialogContent("tip", msg, ((options && options.dialogIcon) ? options.dialogIcon : false)), + width: msgSizeRange.width, + height: msgSizeRange.height, + minHeight: msgSizeRange.height, + minWidth: msgSizeRange.width, + stickMenu: false, + minMenu: false, + floatTarget: target, + floatDirection: direction || 'bottom', + maxMenu: false, + closeMenu: false, + alwaysOnTop: true, + resizable: false, + movable: false, + allowControlDbclick: false, + autodestroyText: false, + loadingText: false, + storeStatus: false + }, options)); + }, false); + target.addEventListener("mouseout", function (e) { + that.destroy(_id, null, true); + }, false); + } + }, + msg: function (msg, options) { + var that = this; + var msgSizeRange = that.getStrSizeRange(msg, 120, 20, 320, 90, ((options && options.dialogIcon) ? true : false)); + var winform = that.create(layxDeepClone({}, { + id: (options && options.id) ? options.id : 'layx-dialog-msg-' + Utils.rndNum(8), + type: 'html', + control: false, + content: that.createDialogContent("msg", msg, ((options && options.dialogIcon) ? options.dialogIcon : false)), + autodestroy: 5000, + width: msgSizeRange.width, + height: msgSizeRange.height, + minHeight: msgSizeRange.height, + stickMenu: false, + minMenu: false, + maxMenu: false, + closeMenu: false, + alwaysOnTop: true, + resizable: false, + movable: false, + allowControlDbclick: false, + position: [10, 'tc'], + autodestroyText: false, + loadingText: false, + storeStatus: false, + dialogType: 'msg' + }, options)); + that.flicker(winform.id); + return winform; + }, + createDialogContent: function (type, content, iconType) { + var that = this; + var dialog = document.createElement("div"); + dialog.classList.add("layx-dialog-" + type); + dialog.classList.add("layx-flexbox"); + if (iconType) { + var dialogIcon = document.createElement("div"); + dialogIcon.classList.add("layx-dialog-icon"); + var iconWrap = document.createElement("div"); + iconWrap.classList.add("layx-icon"); + iconWrap.classList.add("layx-dialog-icon-" + iconType); + switch (iconType) { + case "success": + iconWrap.innerHTML = ''; + break; + case "warn": + iconWrap.innerHTML = ''; + break; + case "error": + iconWrap.innerHTML = ''; + break; + case "help": + iconWrap.innerHTML = ''; + break; + } + dialogIcon.appendChild(iconWrap); + dialog.appendChild(dialogIcon); + } + var dialogContent = document.createElement("div"); + dialogContent.classList.add("layx-dialog-content"); + dialogContent.classList.add("layx-flexauto"); + dialogContent.innerHTML = content; + dialog.appendChild(dialogContent); + return dialog; + }, + alert: function (title, msg, yes, options) { + var that = this; + var msgSizeRange = that.getStrSizeRange(msg, 137, 66, 352, 157, ((options && options.dialogIcon) ? true : false)); + var winform = that.create(layxDeepClone({}, { + id: (options && options.id) ? options.id : 'layx-dialog-alert-' + Utils.rndNum(8), + title: title || "提示消息", + icon: false, + type: 'html', + content: that.createDialogContent("alert", msg, ((options && options.dialogIcon) ? options.dialogIcon : false)), + width: msgSizeRange.width + 20, + height: msgSizeRange.height + 73, + minHeight: msgSizeRange.height + 73, + stickMenu: false, + dialogType: "alert", + minMenu: false, + minable: false, + maxMenu: false, + maxable: false, + alwaysOnTop: true, + resizable: false, + allowControlDbclick: false, + shadable: true, + statusBar: true, + buttons: [{ + label: '确定', + callback: function (id, button, event) { + event = event || window.event || arguments.callee.caller.arguments[0]; + event.stopPropagation(); + if (Utils.isFunction(yes)) { + var reval = yes(id, button, event); + if (reval !== false) { + Layx.destroy(id); + } + } else { + Layx.destroy(id); + } + } + }], + position: 'ct', + loadingText: false, + storeStatus: false + }, options)); + return winform; + }, + confirm: function (title, msg, yes, options) { + var that = this; + var msgSizeRange = that.getStrSizeRange(msg, 180, 137, 352, 180, ((options && options.dialogIcon) ? true : false)); + var winform = that.create(layxDeepClone({}, { + id: (options && options.id) ? options.id : 'layx-dialog-confirm-' + Utils.rndNum(8), + title: title || "询问消息", + icon: false, + type: 'html', + content: that.createDialogContent("confirm", msg, ((options && options.dialogIcon) ? options.dialogIcon : false)), + width: msgSizeRange.width + 20, + height: msgSizeRange.height, + minHeight: msgSizeRange.height, + stickMenu: false, + dialogType: "confirm", + minMenu: false, + minable: false, + maxMenu: false, + maxable: false, + alwaysOnTop: true, + resizable: false, + allowControlDbclick: false, + shadable: true, + buttons: [{ + label: '确定', + callback: function (id, button, event) { + event = event || window.event || arguments.callee.caller.arguments[0]; + event.stopPropagation(); + if (Utils.isFunction(yes)) { + var reval = yes(id, button); + if (reval !== false) { + Layx.destroy(id); + } + } + } + }, { + label: '取消', + callback: function (id, button, event) { + event = event || window.event; + event.stopPropagation(); + Layx.destroy(id); + } + }], + statusBar: true, + position: 'ct', + loadingText: false, + storeStatus: false + }, options)); + return winform; + }, + getPromptTextArea: function (id) { + var that = this, + windowId = "layx-" + id, + layxWindow = document.getElementById(windowId), + winform = that.windows[id]; + if (layxWindow && winform && winform.type === "html") { + var promptPanel = layxWindow.querySelector(".layx-dialog-prompt"); + if (promptPanel) { + var textarea = promptPanel.querySelector(".layx-textarea"); + if (textarea) { + return textarea; + } + } + } + return null; + }, + prompt: function (title, msg, yes, defaultValue, options) { + var that = this; + var msgSizeRange = that.getStrSizeRange(msg, 200, 184, 352, 200); + var winform = that.create(layxDeepClone({}, { + id: (options && options.id) ? options.id : 'layx-dialog-prompt-' + Utils.rndNum(8), + title: title || "请输入信息", + icon: false, + type: 'html', + content: that.createDialogContent("prompt", ""), + width: msgSizeRange.width + 20, + height: msgSizeRange.height, + minHeight: msgSizeRange.height, + stickMenu: false, + dialogType: "prompt", + minMenu: false, + minable: false, + maxMenu: false, + maxable: false, + alwaysOnTop: true, + resizable: false, + allowControlDbclick: false, + shadable: true, + statusBar: true, + buttonKey: 'ctrl+enter', + buttons: [{ + label: '确定', + callback: function (id, value, textarea, button, event) { + event = event || window.event || arguments.callee.caller.arguments[0]; + event.stopPropagation(); + if (textarea && value.length === 0) { + textarea.focus(); + } else { + if (Utils.isFunction(yes)) { + var reval = yes(id, value, textarea, button, event); + if (reval !== false) { + Layx.destroy(id); + } + } + } + } + }, { + label: '取消', + callback: function (id, value, textarea, button, event) { + event = event || window.event; + event.stopPropagation(); + Layx.destroy(id); + } + }], + position: 'ct', + loadingText: false, + storeStatus: false + }, options)); + return winform; + }, + createLoadAnimate: function () { + var animate = document.createElement("div"); + animate.classList.add("layx-load-animate"); + var inner = document.createElement("div"); + inner.classList.add("layx-load-inner"); + var spiner = document.createElement("div"); + spiner.classList.add("layx-load-spiner"); + inner.appendChild(spiner); + var filler = document.createElement("div"); + filler.classList.add("layx-load-filler"); + inner.appendChild(filler); + var masker = document.createElement("div"); + masker.classList.add("layx-load-masker"); + inner.appendChild(masker); + animate.appendChild(inner); + var inner2 = inner.cloneNode(true); + inner2.classList.remove("layx-load-inner"); + inner2.classList.add("layx-load-inner2"); + animate.appendChild(inner2); + return animate; + }, + load: function (id, msg, options) { + var that = this; + var msgSizeRange = that.getStrSizeRange(msg, 120, 53, 320, 90); + var loadElement = document.createElement("div"); + loadElement.classList.add("layx-dialog-load"); + loadElement.classList.add("layx-flexbox"); + loadElement.classList.add("layx-flex-center"); + loadElement.appendChild(that.createLoadAnimate()); + var msgContent = document.createElement("div"); + msgContent.classList.add("layx-load-msg"); + msgContent.innerHTML = msg; + loadElement.appendChild(msgContent); + var span = document.createElement("span"); + span.classList.add("layx-dot"); + msgContent.appendChild(span); + var dotCount = 0; + var loadTimer = setInterval(function () { + if (dotCount === 5) { + dotCount = 0; + } + ++dotCount; + var dotHtml = ""; + for (var i = 0; i < dotCount; i++) { + dotHtml += "."; + } + span.innerHTML = dotHtml; + }, 200); + var winform = that.create(layxDeepClone({}, { + id: id ? id : 'layx-dialog-load-' + Utils.rndNum(8), + type: 'html', + control: false, + shadable: true, + content: loadElement, + cloneElementContent: false, + width: msgSizeRange.width + 70, + height: msgSizeRange.height, + minHeight: msgSizeRange.height, + stickMenu: false, + minMenu: false, + maxMenu: false, + closeMenu: false, + escKey: false, + alwaysOnTop: true, + resizable: false, + movable: false, + allowControlDbclick: false, + position: 'ct', + loadingText: false, + storeStatus: false, + dialogType: 'load' + }, options)); + winform.loadTimer = loadTimer; + return winform; + } + }; + String.prototype.toFirstUpperCase = function () { + return this.replace(/^\S/, function (s) { + return s.toUpperCase(); + }); + }; + if (!("classList" in document.documentElement)) { + Object.defineProperty(HTMLElement.prototype, 'classList', { + get: function () { + var self = this; + function update(fn) { + return function (value) { + var classes = self.className.split(/\s+/g), + index = classes.indexOf(value); + fn(classes, index, value); + self.className = classes.join(" "); + }; + } + return { + add: update(function (classes, index, value) { + if (!~index) + classes.push(value); + }), + remove: update(function (classes, index) { + if (~index) + classes.splice(index, 1); + }), + toggle: update(function (classes, index, value) { + if (~index) + classes.splice(index, 1); + else + classes.push(value); + }), + contains: function (value) { + return !!~self.className.split(/\s+/g).indexOf(value); + }, + item: function (i) { + return self.className.split(/\s+/g)[i] || null; + } + }; + } + }); + } + var IframeOnClick = { + resolution: 0, + iframes: [], + interval: null, + Iframe: function () { + this.element = arguments[0]; + this.cb = arguments[1]; + this.hasTracked = false; + }, + track: function (element, cb) { + this.iframes.push(new this.Iframe(element, cb)); + if (!this.interval) { + var _this = this; + this.interval = setInterval(function () { + _this.checkClick(); + }, this.resolution); + } + }, + checkClick: function () { + if (document.activeElement) { + var activeElement = document.activeElement; + for (var i in this.iframes) { + if (activeElement === this.iframes[i].element) { + if (this.iframes[i].hasTracked == false) { + this.iframes[i].cb.apply(win, []); + this.iframes[i].hasTracked = true; + } + } else { + this.iframes[i].hasTracked = false; + } + } + } + } + }; + var Utils = { + isSupportTouch: "ontouchstart" in document ? true : false, + isSupportMouse: "onmouseup" in document ? true : false, + IsPC: function () { + var userAgentInfo = navigator.userAgent; + var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"]; + var flag = true; + for (var v = 0; v < Agents.length; v++) { + if (userAgentInfo.indexOf(Agents[v]) > 0) { + flag = false; + break; + } + } + return flag; + }, + isBoolean: function (obj) { + return typeof obj === "boolean"; + }, + isString: function (obj) { + return typeof obj === "string"; + }, + isNumber: function (obj) { + return typeof obj === "number"; + }, + isArray: function (o) { + return Object.prototype.toString.call(o) == '[object Array]'; + }, + isFunction: function (func) { + return func && Object.prototype.toString.call(func) === '[object Function]'; + }, + isDom: function (obj) { + return !!(obj && typeof window !== 'undefined' && (obj === window || obj.nodeType)); + }, + insertAfter: function (newEl, targetEl) { + var parentEl = targetEl.parentNode; + if (newEl) { + if (parentEl.lastChild == targetEl) { + parentEl.appendChild(newEl); + } else { + parentEl.insertBefore(newEl, targetEl.nextSibling); + } + } + }, + innerArea: function () { + return { + width: win.innerWidth, + height: win.innerHeight + }; + }, + getCross: function (p1, p2, p) { + return (p2.x - p1.x) * (p.y - p1.y) - (p.x - p1.x) * (p2.y - p1.y); + }, + IsPointInMatrix: function (area, p) { + var that = this; + var p1 = area.p1; + var p2 = area.p2; + var p3 = area.p3; + var p4 = area.p4; + return that.getCross(p1, p2, p) * that.getCross(p3, p4, p) >= 0 && that.getCross(p2, p3, p) * that.getCross(p4, p1, p) >= 0; + }, + checkElementIsVisual: function (pEle, ele, allContain) { + var that = this; + var innerArea = that.innerArea(); + var pEleStartPos = that.getElementPos(pEle); + var pEleEndPos = { + x: pEleStartPos.x + pEle.offsetWidth, + y: pEleStartPos.y + pEle.offsetHeight + }; + var eleStartPos = that.getElementPos(ele); + var eleEndPos = { + x: eleStartPos.x + ele.offsetWidth, + y: eleStartPos.y + ele.offsetHeight + }; + if (allContain === false) { + var pleArea = { + p1: { + x: pEleStartPos.x, + y: pEleEndPos.y + }, + p2: { + x: pEleStartPos.x, + y: pEleStartPos.y + }, + p3: { + x: pEleEndPos.x, + y: pEleStartPos.y + }, + p4: { + x: pEleEndPos.x, + y: pEleEndPos.y + } + }; + var winArea = { + p1: { + x: 0, + y: innerArea.height + }, + p2: { + x: 0, + y: 0 + }, + p3: { + x: innerArea.width, + y: 0 + }, + p4: { + x: innerArea.width, + y: innerArea.height + } + }; + var ltPoint = that.IsPointInMatrix(pleArea, { + x: eleStartPos.x, + y: eleStartPos.y + }); + var rtPoint = that.IsPointInMatrix(pleArea, { + x: eleEndPos.x, + y: eleStartPos.y + }); + var lbPoint = that.IsPointInMatrix(pleArea, { + x: eleStartPos.x, + y: eleEndPos.y + }); + var rbPoint = that.IsPointInMatrix(pleArea, { + x: eleEndPos.x, + y: eleEndPos.y + }); + var wltPoint = that.IsPointInMatrix(winArea, { + x: eleStartPos.x, + y: eleStartPos.y + }); + var wrtPoint = that.IsPointInMatrix(winArea, { + x: eleEndPos.x, + y: eleStartPos.y + }); + var wlbPoint = that.IsPointInMatrix(winArea, { + x: eleStartPos.x, + y: eleEndPos.y + }); + var wrbPoint = that.IsPointInMatrix(winArea, { + x: eleEndPos.x, + y: eleEndPos.y + }); + return (ltPoint || rtPoint || lbPoint || rbPoint) && (wltPoint || wrtPoint || wlbPoint || wrbPoint); + } + return (eleStartPos.x >= pEleStartPos.x) && (eleEndPos.x <= pEleEndPos.x) && (eleStartPos.y >= pEleStartPos.y) && (eleEndPos.y <= pEleEndPos.y) && (eleStartPos.x >= 0) && (eleEndPos.x <= innerArea.width) && (eleStartPos.y >= 0) && (eleEndPos.y <= innerArea.height); + }, + compilebubbleDirection: function (direction, target, width, height) { + var that = this, + bubbleDirectionOptions = ['top', 'bottom', 'left', 'right'], + targetPos = that.getElementPos(target), + innerArea = that.innerArea(), + bubbleSize = 11, + pos = { + top: 0, + left: 0 + }; + direction = bubbleDirectionOptions.indexOf(direction) > -1 ? direction : 'bottom'; + switch (direction) { + case "bottom": + pos.top = targetPos.y + target.offsetHeight + bubbleSize; + pos.left = targetPos.x; + if (targetPos.x + width >= innerArea.width) { + pos.left = innerArea.width - width; + } + break; + case "top": + pos.top = targetPos.y - (height + bubbleSize); + pos.left = targetPos.x; + if (targetPos.x + width >= innerArea.width) { + pos.left = innerArea.width - width; + } + break; + case "right": + pos.top = targetPos.y; + pos.left = targetPos.x + target.offsetWidth + bubbleSize; + if (targetPos.y + height >= innerArea.height) { + pos.top = innerArea.height - height; + } + break; + case "left": + pos.top = targetPos.y; + pos.left = targetPos.x - (width + bubbleSize); + if (targetPos.y + height >= innerArea.height) { + pos.top = innerArea.height - height; + } + break; + } + return pos; + }, + compileLayxPosition: function (width, height, position) { + var that = this, + postionOptions = ['ct', 'lt', 'rt', 'lb', 'rb', 'lc', 'tc', 'rc', 'bc'], + innerArea = that.innerArea(); + var pos = { + top: 0, + left: 0 + }; + if (that.isArray(position) && position.length === 2) { + pos.top = that.isNumber(position[0]) ? position[0] : that.compileLayxPosition(width, height, position[0]).top; + pos.left = that.isNumber(position[1]) ? position[1] : that.compileLayxPosition(width, height, position[1]).left; + } else { + position = postionOptions.indexOf(position.toString()) > -1 ? position.toString() : 'ct'; + switch (position) { + case 'ct': + pos.top = (innerArea.height - height) / 2; + pos.left = (innerArea.width - width) / 2; + break; + case 'lt': + pos.top = 0; + pos.left = 0; + break; + case 'rt': + pos.top = 0; + pos.left = innerArea.width - width; + break; + case 'lb': + pos.top = innerArea.height - height; + pos.left = 0; + break; + case 'rb': + pos.top = innerArea.height - height; + pos.left = innerArea.width - width; + break; + case 'lc': + pos.left = 0; + pos.top = (innerArea.height - height) / 2; + break; + case 'tc': + pos.top = 0; + pos.left = (innerArea.width - width) / 2; + break; + case 'rc': + pos.left = innerArea.width - width; + pos.top = (innerArea.height - height) / 2; + break; + case 'bc': + pos.top = innerArea.height - height; + pos.left = (innerArea.width - width) / 2; + break; + } + } + return pos; + }, + rndNum: function (n) { + var rnd = ""; + for (var i = 0; i < n; i++) + rnd += Math.floor(Math.random() * 10); + return rnd; + }, + compileLayxWidthOrHeight: function (type, widthOrHeight, errorValue) { + var that = this, + innerArea = that.innerArea(); + if (/(^[1-9]\d*$)/.test(widthOrHeight)) { + return Number(widthOrHeight); + } + if (/^(100|[1-9]?\d(\.\d\d?)?)%$/.test(widthOrHeight)) { + var value = Number(widthOrHeight.toString().replace('%', '')); + if (type === "width") { + return innerArea.width * (value / 100); + } + if (type === "height") { + return innerArea.height * (value / 100); + } + } + if (/^[1-9]\d*v[hw]$/.test(widthOrHeight)) { + if (type === "width") { + return innerArea.width * parseFloat(widthOrHeight) / 100; + } + if (type === "height") { + return innerArea.height * parseFloat(widthOrHeight) / 100; + } + } + return errorValue; + }, + getNodeByClassName: function (node, className, parentWindow) { + parentWindow = parentWindow || win; + var that = this; + if (node === parentWindow.document.body) { + return null; + } + var cls = node.classList; + if (cls.contains(className)) { + return node; + } else { + return that.getNodeByClassName(node.parentNode, className); + } + }, + getMousePosition: function (e) { + e = e || window.event; + if (e.touches) { + if (Utils.IsPC()) { + var button = e.button || e.which; + if (button == 1 && e.shiftKey == false) { + var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; + var scrollY = document.documentElement.scrollTop || document.body.scrollTop; + var x = e.pageX || e.clientX + scrollX; + var y = e.pageY || e.clientY + scrollY; + return { + x: x, + y: y + }; + } + } + return { + x: e.touches[0].clientX, + y: e.touches[0].clientY + }; + } else { + var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; + var scrollY = document.documentElement.scrollTop || document.body.scrollTop; + var x = e.pageX || e.clientX + scrollX; + var y = e.pageY || e.clientY + scrollY; + return { + x: x, + y: y + }; + } + }, + getElementPos: function (el) { + var ua = navigator.userAgent.toLowerCase(); + var isOpera = (ua.indexOf('opera') != -1); + var isIE = (ua.indexOf('msie') != -1 && !isOpera); + if (el.parentNode === null || el.style.display == 'none') { + return false; + } + var parent = null; + var pos = []; + var box; + if (el.getBoundingClientRect) { + box = el.getBoundingClientRect(); + var scrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop); + var scrollLeft = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft); + return { + x: box.left + scrollLeft, + y: box.top + scrollTop + }; + } else if (document.getBoxObjectFor) { + box = document.getBoxObjectFor(el); + var borderLeft = (el.style.borderLeftWidth) ? parseInt(el.style.borderLeftWidth) : 0; + var borderTop = (el.style.borderTopWidth) ? parseInt(el.style.borderTopWidth) : 0; + pos = [box.x - borderLeft, box.y - borderTop]; + } else { + pos = [el.offsetLeft, el.offsetTop]; + parent = el.offsetParent; + if (parent != el) { + while (parent) { + pos[0] += parent.offsetLeft; + pos[1] += parent.offsetTop; + parent = parent.offsetParent; + } + } + if (ua.indexOf('opera') != -1 || (ua.indexOf('safari') != -1 && el.style.position == 'absolute')) { + pos[0] -= document.body.offsetLeft; + pos[1] -= document.body.offsetTop; + } + } + if (el.parentNode) { + parent = el.parentNode; + } else { + parent = null; + } + while (parent && parent.tagName != 'BODY' && parent.tagName != 'HTML') { + pos[0] -= parent.scrollLeft; + pos[1] -= parent.scrollTop; + if (parent.parentNode) { + parent = parent.parentNode; + } else { + parent = null; + } + } + return { + x: pos[0], + y: pos[1] + }; + } + }; + var LayxResize = function (handle, isTop, isLeft, lockX, lockY) { + LayxResize.isResizing = false; + LayxResize.isFirstResizing = true; + var drag = function (e) { + e = e || window.event; + var moveMouseCoord = Utils.getMousePosition(e), + distX = moveMouseCoord.x - handle.mouseStartCoord.x, + distY = moveMouseCoord.y - handle.mouseStartCoord.y; + if (Utils.isSupportTouch) { + if (e.cancelable) { + if (!e.defaultPrevented) { + e.preventDefault(); + } + } + if (((distX !== 0 || distY !== 0) && (new Date() - handle.touchDate > 100)) === false) + return; + if (Utils.IsPC()) { + var button = e.button || e.which; + if ((button == 1 && e.shiftKey == false) === false) + return; + if (!e.defaultPrevented) { + e.preventDefault(); + } + if ((distX !== 0 || distY !== 0) === false) + return; + } + } else { + var button = e.button || e.which; + if ((button == 1 && e.shiftKey == false) === false) + return; + if (!e.defaultPrevented) { + e.preventDefault(); + } + if ((distX !== 0 || distY !== 0) === false) + return; + } + var _top = handle.winform.area.top + distY, + _left = handle.winform.area.left + distX, + _height = isTop ? handle.winform.area.height - distY : handle.winform.area.height + distY, + _width = isLeft ? handle.winform.area.width - distX : handle.winform.area.width + distX; + LayxResize.isResizing = true; + if (LayxResize.isFirstResizing === true) { + LayxResize.isFirstResizing = false; + if (Utils.isFunction(handle.winform.event.onresize.before)) { + var reval = handle.winform.event.onresize.before(handle.layxWindow, handle.winform); + if (reval === false) { + LayxResize.isResizing = false; + LayxResize.isFirstResizing = true; + if (Utils.isSupportTouch) { + document.ontouchend = null; + document.ontouchmove = null; + if (Utils.IsPC()) { + document.onmouseup = null; + document.onmousemove = null; + } + } else { + document.onmouseup = null; + document.onmousemove = null; + } + return; + } + } + } + _width = Math.max(_width, handle.winform.area.minWidth); + if (isLeft) { + _left = Math.min(_left, handle.winform.area.left + handle.winform.area.width - handle.winform.area.minWidth); + _left = Math.max(0, _left); + _width = Math.min(_width, handle.winform.area.left + handle.winform.area.width); + } else { + _left = Math.min(_left, handle.winform.area.left); + _left = Math.max(handle.winform.area.left, _left); + _width = Math.min(_width, handle.innerArea.width - handle.winform.area.left); + } + _height = Math.max(_height, handle.winform.area.minHeight); + if (isTop) { + _top = Math.min(_top, handle.winform.area.top + handle.winform.area.height - handle.winform.area.minHeight); + _top = Math.max(0, _top); + _height = Math.min(_height, handle.winform.area.top + handle.winform.area.height); + } else { + _top = Math.min(_top, handle.winform.area.top); + _top = Math.max(handle.winform.area.top, _top); + _height = Math.min(_height, handle.innerArea.height - handle.winform.area.top); + } + if (lockY) { + handle.layxWindow.style.width = _width + 'px'; + handle.layxWindow.style.left = _left + 'px'; + } + if (lockX) { + handle.layxWindow.style.top = _top + 'px'; + handle.layxWindow.style.height = _height + 'px'; + } + if (lockY === false && lockX === false) { + handle.layxWindow.style.width = _width + 'px'; + handle.layxWindow.style.left = _left + 'px'; + handle.layxWindow.style.top = _top + 'px'; + handle.layxWindow.style.height = _height + 'px'; + } + if (Utils.isFunction(handle.winform.event.onresize.progress)) { + handle.winform.event.onresize.progress(handle.layxWindow, handle.winform); + } + }; + var dragend = function (e) { + e = e || window.event; + if (Utils.isSupportTouch) { + document.ontouchend = null; + document.ontouchmove = null; + if (Utils.IsPC()) { + var button = e.button || e.which; + if (button == 1 && e.shiftKey == false) { + var resizeList = handle.layxWindow.querySelectorAll(".layx-resizes > div"); + for (var i = 0; i < resizeList.length; i++) { + resizeList[i].classList.add("layx-reisize-touch"); + } + } + document.onmouseup = null; + document.onmousemove = null; + } + } else { + document.onmouseup = null; + document.onmousemove = null; + } + var mousePreventDefault = handle.layxWindow.querySelector(".layx-mouse-preventDefault"); + if (mousePreventDefault) { + mousePreventDefault.parentNode.removeChild(mousePreventDefault); + } + var layxMove = document.getElementById("layx-window-move"); + if (layxMove) { + layxMove.parentNode.removeChild(layxMove); + } + if (LayxResize.isResizing === true) { + LayxResize.isResizing = false; + LayxResize.isFirstResizing = true; + handle.winform.area.top = handle.layxWindow.offsetTop; + handle.winform.area.left = handle.layxWindow.offsetLeft; + handle.winform.area.width = handle.layxWindow.offsetWidth; + handle.winform.area.height = handle.layxWindow.offsetHeight; + if (handle.winform.storeStatus === true) { + Layx.storeWindowAreaInfo(handle.winform.id, { + top: handle.winform.area.top, + left: handle.winform.area.left, + width: handle.winform.area.width, + height: handle.winform.area.height + }); + } + if (Utils.isFunction(handle.winform.event.onresize.after)) { + handle.winform.event.onresize.after(handle.layxWindow, handle.winform); + } + } + }; + var dragstart = function (e) { + e = e || window.event; + var layxWindow = Utils.getNodeByClassName(handle, 'layx-window', win); + if (layxWindow) { + var id = layxWindow.getAttribute("id").substr(5), + winform = Layx.windows[id]; + if (winform) { + if (winform.status !== "min" && winform.resizable === true) { + var layxMove = document.getElementById("layx-window-move"); + if (!layxMove) { + layxMove = document.createElement("div"); + layxMove.setAttribute("id", "layx-window-move"); + document.body.appendChild(layxMove); + } + Layx.updateZIndex(id); + layxMove.style.zIndex = winform.zIndex - 1; + var mouseCoord = Utils.getMousePosition(e); + handle.mouseStartCoord = mouseCoord; + handle.layxWindow = layxWindow; + handle.winform = winform; + handle.innerArea = Utils.innerArea(); + handle.touchDate = new Date(); + var mousePreventDefault = layxWindow.querySelector(".layx-mouse-preventDefault"); + if (!mousePreventDefault) { + mousePreventDefault = document.createElement("div"); + mousePreventDefault.classList.add("layx-mouse-preventDefault"); + var main = layxWindow.querySelector(".layx-main"); + if (main) { + main.appendChild(mousePreventDefault); + } + } + if (Utils.isSupportTouch) { + document.ontouchend = dragend; + document.ontouchmove = drag; + if (Utils.IsPC()) { + var button = e.button || e.which; + if (button == 1 && e.shiftKey == false) { + var resizeList = layxWindow.querySelectorAll(".layx-resizes > div"); + for (var i = 0; i < resizeList.length; i++) { + resizeList[i].classList.remove("layx-reisize-touch"); + } + } + document.onmouseup = dragend; + document.onmousemove = drag; + } + } else { + document.onmouseup = dragend; + document.onmousemove = drag; + } + } else { + Layx.restore(id); + } + } + } + return false; + }; + if (Utils.isSupportTouch) { + handle.ontouchstart = dragstart; + if (Utils.IsPC()) { + handle.onmousedown = dragstart; + } + } else { + handle.onmousedown = dragstart; + } + }; + var LayxDrag = function (handle) { + LayxDrag.isMoveing = false; + LayxDrag.isFirstMoveing = true; + var drag = function (e) { + e = e || window.event; + var moveMouseCoord = Utils.getMousePosition(e), + distX = moveMouseCoord.x - handle.mouseStartCoord.x, + distY = moveMouseCoord.y - handle.mouseStartCoord.y; + if (Utils.isSupportTouch) { + if (e.cancelable) { + if (!e.defaultPrevented) { + e.preventDefault(); + } + } + if (((distX !== 0 || distY !== 0) && (new Date() - handle.touchDate > 100)) === false) + return; + if (Utils.IsPC()) { + var button = e.button || e.which; + if ((button == 1 && e.shiftKey == false) === false) + return; + if (!e.defaultPrevented) { + e.preventDefault(); + } + if ((distX !== 0 || distY !== 0) === false) + return; + } + } else { + var button = e.button || e.which; + if ((button == 1 && e.shiftKey == false) === false) + return; + if (!e.defaultPrevented) { + e.preventDefault(); + } + if ((distX !== 0 || distY !== 0) === false) + return; + } + LayxDrag.isMoveing = true; + if (LayxDrag.isFirstMoveing === true) { + LayxDrag.isFirstMoveing = false; + if (Utils.isFunction(handle.winform.event.onmove.before)) { + var reval = handle.winform.event.onmove.before(handle.layxWindow, handle.winform); + if (reval === false) { + LayxDrag.isMoveing = false; + LayxDrag.isFirstMoveing = true; + if (Utils.isSupportTouch) { + document.ontouchend = null; + document.ontouchmove = null; + } else { + document.onmouseup = null; + document.onmousemove = null; + } + return; + } + } + } + var _left = handle.winform.area.left + distX; + var _top = handle.winform.area.top + distY; + if (handle.winform.status === "max" && handle.winform.resizable === true) { + if (moveMouseCoord.x < handle.winform.area.width / 2) { + _left = 0; + } else if (moveMouseCoord.x > handle.winform.area.width / 2 && moveMouseCoord.x < handle.innerArea.width - handle.winform.area.width) { + _left = moveMouseCoord.x - handle.winform.area.width / 2; + } else if (handle.innerArea.width - moveMouseCoord.x < handle.winform.area.width / 2) { + _left = handle.innerArea.width - handle.winform.area.width; + } else if (handle.innerArea.width - moveMouseCoord.x > handle.winform.area.width / 2 && moveMouseCoord.x >= handle.innerArea.width - handle.winform.area.width) { + _left = moveMouseCoord.x - handle.winform.area.width / 2; + } + _top = 0; + handle.winform.area.top = 0; + handle.winform.area.left = _left; + Layx.restore(handle.winform.id); + } + handle.winform.moveLimit.horizontal === true && (_left = handle.winform.area.left); + handle.winform.moveLimit.vertical === true && (_top = handle.winform.area.top); + handle.winform.moveLimit.leftOut === false && (_left = Math.max(_left, 0)); + handle.winform.moveLimit.rightOut === false && (_left = Math.min(_left, handle.innerArea.width - handle.winform.area.width)); + handle.winform.moveLimit.bottomOut === false && (_top = Math.min(_top, handle.innerArea.height - handle.winform.area.height)); + _top = Math.max(_top, 0); + _top = Math.min(handle.innerArea.height - 15, _top); + _left = Math.max(_left, -(handle.winform.area.width - 15)); + _left = Math.min(_left, handle.innerArea.width - 15); + handle.layxWindow.style.left = _left + "px"; + handle.layxWindow.style.top = _top + "px"; + if (Utils.isFunction(handle.winform.event.onmove.progress)) { + handle.winform.event.onmove.progress(handle.layxWindow, handle.winform); + } + }; + var dragend = function (e) { + e = e || window.event; + if (Utils.isSupportTouch) { + document.ontouchend = null; + document.ontouchmove = null; + if (Utils.IsPC()) { + var button = e.button || e.which; + if (button == 1 && e.shiftKey == false) { + var resizeList = handle.layxWindow.querySelectorAll(".layx-resizes > div"); + for (var i = 0; i < resizeList.length; i++) { + resizeList[i].classList.add("layx-reisize-touch"); + } + } + document.onmouseup = null; + document.onmousemove = null; + } + } else { + document.onmouseup = null; + document.onmousemove = null; + } + var mousePreventDefault = handle.layxWindow.querySelector(".layx-mouse-preventDefault"); + if (mousePreventDefault) { + mousePreventDefault.parentNode.removeChild(mousePreventDefault); + } + var layxMove = document.getElementById("layx-window-move"); + if (layxMove) { + layxMove.parentNode.removeChild(layxMove); + } + if (LayxDrag.isMoveing === true) { + LayxDrag.isMoveing = false; + LayxDrag.isFirstMoveing = true; + handle.winform.area.top = handle.layxWindow.offsetTop; + handle.winform.area.left = handle.layxWindow.offsetLeft; + if (handle.winform.storeStatus === true) { + Layx.storeWindowAreaInfo(handle.winform.id, { + top: handle.winform.area.top, + left: handle.winform.area.left, + width: handle.winform.area.width, + height: handle.winform.area.height + }); + } + if (handle.winform.area.top === 0 && handle.winform.status === "normal" && handle.winform.maxable === true && handle.winform.resizable === true && handle.winform.dragInTopToMax === true) { + handle.winform.area.top = handle.defaultArea.top; + handle.winform.area.left = handle.defaultArea.left; + if (handle.winform.storeStatus === true) { + Layx.storeWindowAreaInfo(handle.winform.id, { + top: handle.winform.area.top, + left: handle.winform.area.left, + width: handle.winform.area.width, + height: handle.winform.area.height + }); + } + Layx.max(handle.winform.id); + } + if (Utils.isFunction(handle.winform.event.onmove.after)) { + handle.winform.event.onmove.after(handle.layxWindow, handle.winform); + } + } + }; + var dragstart = function (e) { + e = e || window.event; + var layxWindow = Utils.getNodeByClassName(handle, 'layx-window', win); + if (layxWindow) { + var id = layxWindow.getAttribute("id").substr(5), + winform = Layx.windows[id]; + if (winform) { + if (winform.status !== "min" && winform.movable === true) { + var layxMove = document.getElementById("layx-window-move"); + if (!layxMove) { + layxMove = document.createElement("div"); + layxMove.setAttribute("id", "layx-window-move"); + document.body.appendChild(layxMove); + } + Layx.updateZIndex(id); + layxMove.style.zIndex = winform.zIndex - 1; + var mouseCoord = Utils.getMousePosition(e); + handle.mouseStartCoord = mouseCoord; + handle.layxWindow = layxWindow; + handle.winform = winform; + handle.innerArea = Utils.innerArea(); + handle.defaultArea = layxDeepClone({}, winform.area); + handle.touchDate = new Date(); + var mousePreventDefault = layxWindow.querySelector(".layx-mouse-preventDefault"); + if (!mousePreventDefault) { + mousePreventDefault = document.createElement("div"); + mousePreventDefault.classList.add("layx-mouse-preventDefault"); + var main = layxWindow.querySelector(".layx-main"); + if (main) { + main.appendChild(mousePreventDefault); + } + } + if (Utils.isSupportTouch) { + document.ontouchend = dragend; + document.ontouchmove = drag; + if (Utils.IsPC()) { + var button = e.button || e.which; + if (button == 1 && e.shiftKey == false) { + var resizeList = layxWindow.querySelectorAll(".layx-resizes > div"); + for (var i = 0; i < resizeList.length; i++) { + resizeList[i].classList.remove("layx-reisize-touch"); + } + } + document.onmouseup = dragend; + document.onmousemove = drag; + } + } else { + document.onmouseup = dragend; + document.onmousemove = drag; + } + } else { + Layx.restore(id); + } + } + } + return false; + }; + if (Utils.isSupportTouch) { + handle.ontouchstart = dragstart; + if (Utils.IsPC()) { + handle.onmousedown = dragstart; + } + } else { + handle.onmousedown = dragstart; + } + }; + win.layx = { + v: (function () { + return Layx.version; + })(), + open: function (options) { + var winform = Layx.create(options); + return winform; + }, + html: function (id, title, content, options) { + var winform = Layx.create(layxDeepClone({}, { + id: id, + title: title, + type: 'html', + content: content + }, options || {})); + return winform; + }, + iframe: function (id, title, url, options) { + var winform = Layx.create(layxDeepClone({}, { + id: id, + title: title, + type: 'url', + url: url, + useFrameTitle: title === true ? true : false + }, options || {})); + return winform; + }, + group: function (id, frames, frameIndex, options) { + var winform = Layx.create(layxDeepClone({}, { + id: id, + type: 'group', + frames: frames, + frameIndex: typeof frameIndex === "number" ? (frameIndex > frames.length ? 0 : frameIndex) : 0 + }, options || {})); + return winform; + }, + windows: function () { + return Layx.windows; + }, + getWindow: function (id) { + return Layx.windows[id]; + }, + destroy: function (id, params, force) { + Layx.destroy(id, params, false, false, force); + }, + visual: function (id, status, params) { + Layx.visual(id, status, params); + }, + min: function (id) { + Layx.min(id); + }, + max: function (id) { + Layx.max(id); + }, + setTitle: function (id, title, useFrameTitle) { + Layx.setTitle(id, title, useFrameTitle); + }, + flicker: function (id) { + Layx.flicker(id); + }, + restore: function (id) { + Layx.restore(id); + }, + updateZIndex: function (id) { + Layx.updateZIndex(id); + }, + updateMinLayout: function () { + Layx.updateMinLayout(); + }, + stickToggle: function (id) { + Layx.stickToggle(id); + }, + setPosition: function (id, position) { + Layx.setPosition(id, position); + }, + getFrameContext: function (id) { + return Layx.getFrameContext(id); + }, + getParentContext: function (id) { + return Layx.getParentContext(id); + }, + setContent: function (id, content, cloneElementContent) { + Layx.setContent(id, content, cloneElementContent); + }, + setUrl: function (id, url) { + Layx.setUrl(id, url); + }, + setGroupContent: function (id, frameId, content, cloneElementContent) { + Layx.setGroupContent(id, frameId, content, cloneElementContent); + }, + setGroupTitle: function (id, frameId, title, useFrameTitle) { + Layx.setGroupTitle(id, frameId, title, useFrameTitle); + }, + setGroupUrl: function (id, frameId, url) { + Layx.setGroupUrl(id, frameId, url); + }, + setGroupIndex: function (id, frameId) { + Layx.setGroupIndex(id, frameId); + }, + getGroupFrameContext: function (id, frameId) { + return Layx.getGroupFrameContext(id, frameId); + }, + destroyAll: function () { + Layx.destroyAll(); + }, + tip: function (msg, target, direction, options) { + Layx.tip(msg, target, direction, options); + }, + msg: function (msg, options) { + return Layx.msg(msg, options); + }, + alert: function (title, msg, yes, options) { + return Layx.alert(title, msg, yes, options); + }, + confirm: function (title, msg, yes, options) { + return Layx.confirm(title, msg, yes, options); + }, + getPromptTextArea: function (id) { + return Layx.getPromptTextArea(id); + }, + prompt: function (title, msg, yes, defaultValue, options) { + return Layx.prompt(title, msg, yes, defaultValue, options); + }, + load: function (id, msg, options) { + return Layx.load(id, msg, options); + }, + multiLine: function (f) { + return f.toString().replace(/^[^\/]+\/\*!?\s?/, '').replace(/\*\/[^\/]+$/, ''); + }, + reloadFrame: function (id) { + Layx.reloadFrame(id); + }, + reloadGroupFrame: function (id, frameId) { + Layx.reloadGroupFrame(id, frameId); + }, + setButtonStatus: function (id, buttonId, isEnable) { + Layx.setButtonStatus(id, buttonId, isEnable); + }, + updateFloatWinPosition: function (id, direction) { + Layx.updateFloatWinPosition(id, direction); + }, + getElementPos: function (ele) { + return Utils.getElementPos(ele); + }, + destroyInlay: function (id) { + Layx.destroyInlay(id); + }, + checkVisual: function (pEle, ele, allContain) { + return Utils.checkElementIsVisual(pEle, ele, allContain); + }, + getButton: function (id, buttonId) { + return Layx.getButton(id, buttonId); + }, + setSize: function (id, area) { + Layx.setSize(id, area); + } + }; + win.document.addEventListener("keydown", function (event) { + var e = event || window.event || arguments.callee.caller.arguments[0]; + var focusWindow = Layx.windows[Layx.focusId]; + if (e && e.keyCode == 27) { + if (focusWindow) { + Layx.destroy(Layx.focusId, {}, false, true); + } + } + if (e && e.keyCode === 13) { + if (focusWindow && focusWindow.buttons.length > 0) { + if (focusWindow.buttonKey.toLowerCase() === "enter" && !e.ctrlKey) { + if (focusWindow.dialogType !== "prompt") { + focusWindow.buttons[0].callback(focusWindow.id, Layx.getButton(focusWindow.id, focusWindow.buttons[0].id, e)); + } else { + var textarea = Layx.getPromptTextArea(focusWindow.id); + focusWindow.buttons[0].callback(focusWindow.id, (textarea ? textarea.value : "").replace(/(^\s*)|(\s*$)/g, ""), textarea, Layx.getButton(focusWindow.id, focusWindow.buttons[0].id, e)); + } + } else if (focusWindow.buttonKey.toLowerCase() === "ctrl+enter" && e.ctrlKey) { + if (focusWindow.dialogType !== "prompt") { + focusWindow.buttons[0].callback(focusWindow.id, Layx.getButton(focusWindow.id, focusWindow.buttons[0].id, e)); + } else { + var textarea = Layx.getPromptTextArea(focusWindow.id); + focusWindow.buttons[0].callback(focusWindow.id, (textarea ? textarea.value : "").replace(/(^\s*)|(\s*$)/g, ""), textarea, Layx.getButton(focusWindow.id, focusWindow.buttons[0].id, e)); + } + } + } + } + }, false); +})(top, window, self); +; +!(function (global) { + var extend, + _extend, + _isObject; + _isObject = function (o) { + return Object.prototype.toString.call(o) === '[object Object]'; + }; + _extend = function self(destination, source) { + var property; + for (property in destination) { + if (destination.hasOwnProperty(property)) { + if (_isObject(destination[property]) && _isObject(source[property])) { + self(destination[property], source[property]); + } + if (source.hasOwnProperty(property)) { + continue; + } else { + source[property] = destination[property]; + } + } + } + }; + extend = function () { + var arr = arguments, + result = {}, + i; + if (!arr.length) + return {}; + for (i = arr.length - 1; i >= 0; i--) { + if (_isObject(arr[i])) { + _extend(arr[i], result); + } + } + arr[0] = result; + return result; + }; + global.layxDeepClone = extend; +})(window); +; +!(function (window) { + var svgSprite = ''; + var script = function () { + var scripts = document.getElementsByTagName("script"); + return scripts[scripts.length - 1]; + }(); + var shouldInjectCss = script.getAttribute("data-injectcss"); + var ready = function (fn) { + if (document.addEventListener) { + if (~["complete", "loaded", "interactive"].indexOf(document.readyState)) { + setTimeout(fn, 0); + } else { + var loadFn = function () { + document.removeEventListener("DOMContentLoaded", loadFn, false); + fn(); + }; + document.addEventListener("DOMContentLoaded", loadFn, false); + } + } else if (document.attachEvent) { + IEContentLoaded(window, fn); + } + function IEContentLoaded(w, fn) { + var d = w.document, + done = false, + init = function () { + if (!done) { + done = true; + fn(); + } + }; + var polling = function () { + try { + d.documentElement.doScroll("left"); + } catch (e) { + setTimeout(polling, 50); + return; + } + init(); + }; + polling(); + d.onreadystatechange = function () { + if (d.readyState == "complete") { + d.onreadystatechange = null; + init(); + } + }; + } + }; + var before = function (el, target) { + target.parentNode.insertBefore(el, target); + }; + var prepend = function (el, target) { + if (target.firstChild) { + before(el, target.firstChild); + } else { + target.appendChild(el); + } + }; + function appendSvg() { + var div, + svg; + div = document.createElement("div"); + div.innerHTML = svgSprite; + svgSprite = null; + svg = div.getElementsByTagName("svg")[0]; + if (svg) { + svg.setAttribute("aria-hidden", "true"); + svg.style.position = "absolute"; + svg.style.width = 0; + svg.style.height = 0; + svg.style.overflow = "hidden"; + prepend(svg, document.body); + } + } + if (shouldInjectCss && !window.__iconfont__svg__cssinject__) { + window.__iconfont__svg__cssinject__ = true; + try { + document.write(""); + } catch (e) { + console && console.log(e); + } + } + ready(appendSvg); +})(window); \ No newline at end of file diff --git a/src/main/resources/static/semanticui/my.css b/src/main/resources/static/semanticui/my.css index 6c3ff72..9731253 100644 --- a/src/main/resources/static/semanticui/my.css +++ b/src/main/resources/static/semanticui/my.css @@ -1,3 +1,3 @@ .nullright { - float: right; + float: right; } \ No newline at end of file diff --git a/src/main/resources/static/semanticui/semantic.js b/src/main/resources/static/semanticui/semantic.js index 28b6c3f..e715863 100644 --- a/src/main/resources/static/semanticui/semantic.js +++ b/src/main/resources/static/semanticui/semantic.js @@ -1,4 +1,4 @@ - /* +/* * # Semantic UI - 2.4.2 * https://github.com/Semantic-Org/Semantic-UI * http://www.semantic-ui.com/ @@ -20,481 +20,481 @@ ;(function ($, window, document, undefined) { -$.site = $.fn.site = function(parameters) { - var - time = new Date().getTime(), - performance = [], - - query = arguments[0], - methodInvoked = (typeof query == 'string'), - queryArguments = [].slice.call(arguments, 1), - - settings = ( $.isPlainObject(parameters) ) - ? $.extend(true, {}, $.site.settings, parameters) - : $.extend({}, $.site.settings), - - namespace = settings.namespace, - error = settings.error, - - eventNamespace = '.' + namespace, - moduleNamespace = 'module-' + namespace, - - $document = $(document), - $module = $document, - element = this, - instance = $module.data(moduleNamespace), - - module, - returnedValue - ; - module = { - - initialize: function() { - module.instantiate(); - }, - - instantiate: function() { - module.verbose('Storing instance of site', module); - instance = module; - $module - .data(moduleNamespace, module) - ; - }, - - normalize: function() { - module.fix.console(); - module.fix.requestAnimationFrame(); - }, - - fix: { - console: function() { - module.debug('Normalizing window.console'); - if (console === undefined || console.log === undefined) { - module.verbose('Console not available, normalizing events'); - module.disable.console(); - } - if (typeof console.group == 'undefined' || typeof console.groupEnd == 'undefined' || typeof console.groupCollapsed == 'undefined') { - module.verbose('Console group not available, normalizing events'); - window.console.group = function() {}; - window.console.groupEnd = function() {}; - window.console.groupCollapsed = function() {}; - } - if (typeof console.markTimeline == 'undefined') { - module.verbose('Mark timeline not available, normalizing events'); - window.console.markTimeline = function() {}; - } - }, - consoleClear: function() { - module.debug('Disabling programmatic console clearing'); - window.console.clear = function() {}; - }, - requestAnimationFrame: function() { - module.debug('Normalizing requestAnimationFrame'); - if(window.requestAnimationFrame === undefined) { - module.debug('RequestAnimationFrame not available, normalizing event'); - window.requestAnimationFrame = window.requestAnimationFrame - || window.mozRequestAnimationFrame - || window.webkitRequestAnimationFrame - || window.msRequestAnimationFrame - || function(callback) { setTimeout(callback, 0); } - ; - } - } - }, - - moduleExists: function(name) { - return ($.fn[name] !== undefined && $.fn[name].settings !== undefined); - }, - - enabled: { - modules: function(modules) { + $.site = $.fn.site = function (parameters) { var - enabledModules = [] - ; - modules = modules || settings.modules; - $.each(modules, function(index, name) { - if(module.moduleExists(name)) { - enabledModules.push(name); - } - }); - return enabledModules; - } - }, + time = new Date().getTime(), + performance = [], - disabled: { - modules: function(modules) { - var - disabledModules = [] - ; - modules = modules || settings.modules; - $.each(modules, function(index, name) { - if(!module.moduleExists(name)) { - disabledModules.push(name); - } - }); - return disabledModules; - } - }, + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), - change: { - setting: function(setting, value, modules, modifyExisting) { - modules = (typeof modules === 'string') - ? (modules === 'all') - ? settings.modules - : [modules] - : modules || settings.modules + settings = ($.isPlainObject(parameters)) + ? $.extend(true, {}, $.site.settings, parameters) + : $.extend({}, $.site.settings), + + namespace = settings.namespace, + error = settings.error, + + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + $document = $(document), + $module = $document, + element = this, + instance = $module.data(moduleNamespace), + + module, + returnedValue ; - modifyExisting = (modifyExisting !== undefined) - ? modifyExisting - : true - ; - $.each(modules, function(index, name) { - var - namespace = (module.moduleExists(name)) - ? $.fn[name].settings.namespace || false - : true, - $existingModules - ; - if(module.moduleExists(name)) { - module.verbose('Changing default setting', setting, value, name); - $.fn[name].settings[setting] = value; - if(modifyExisting && namespace) { - $existingModules = $(':data(module-' + namespace + ')'); - if($existingModules.length > 0) { - module.verbose('Modifying existing settings', $existingModules); - $existingModules[name]('setting', setting, value); - } + module = { + + initialize: function () { + module.instantiate(); + }, + + instantiate: function () { + module.verbose('Storing instance of site', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + + normalize: function () { + module.fix.console(); + module.fix.requestAnimationFrame(); + }, + + fix: { + console: function () { + module.debug('Normalizing window.console'); + if (console === undefined || console.log === undefined) { + module.verbose('Console not available, normalizing events'); + module.disable.console(); + } + if (typeof console.group == 'undefined' || typeof console.groupEnd == 'undefined' || typeof console.groupCollapsed == 'undefined') { + module.verbose('Console group not available, normalizing events'); + window.console.group = function () { + }; + window.console.groupEnd = function () { + }; + window.console.groupCollapsed = function () { + }; + } + if (typeof console.markTimeline == 'undefined') { + module.verbose('Mark timeline not available, normalizing events'); + window.console.markTimeline = function () { + }; + } + }, + consoleClear: function () { + module.debug('Disabling programmatic console clearing'); + window.console.clear = function () { + }; + }, + requestAnimationFrame: function () { + module.debug('Normalizing requestAnimationFrame'); + if (window.requestAnimationFrame === undefined) { + module.debug('RequestAnimationFrame not available, normalizing event'); + window.requestAnimationFrame = window.requestAnimationFrame + || window.mozRequestAnimationFrame + || window.webkitRequestAnimationFrame + || window.msRequestAnimationFrame + || function (callback) { + setTimeout(callback, 0); + } + ; + } + } + }, + + moduleExists: function (name) { + return ($.fn[name] !== undefined && $.fn[name].settings !== undefined); + }, + + enabled: { + modules: function (modules) { + var + enabledModules = [] + ; + modules = modules || settings.modules; + $.each(modules, function (index, name) { + if (module.moduleExists(name)) { + enabledModules.push(name); + } + }); + return enabledModules; + } + }, + + disabled: { + modules: function (modules) { + var + disabledModules = [] + ; + modules = modules || settings.modules; + $.each(modules, function (index, name) { + if (!module.moduleExists(name)) { + disabledModules.push(name); + } + }); + return disabledModules; + } + }, + + change: { + setting: function (setting, value, modules, modifyExisting) { + modules = (typeof modules === 'string') + ? (modules === 'all') + ? settings.modules + : [modules] + : modules || settings.modules + ; + modifyExisting = (modifyExisting !== undefined) + ? modifyExisting + : true + ; + $.each(modules, function (index, name) { + var + namespace = (module.moduleExists(name)) + ? $.fn[name].settings.namespace || false + : true, + $existingModules + ; + if (module.moduleExists(name)) { + module.verbose('Changing default setting', setting, value, name); + $.fn[name].settings[setting] = value; + if (modifyExisting && namespace) { + $existingModules = $(':data(module-' + namespace + ')'); + if ($existingModules.length > 0) { + module.verbose('Modifying existing settings', $existingModules); + $existingModules[name]('setting', setting, value); + } + } + } + }); + }, + settings: function (newSettings, modules, modifyExisting) { + modules = (typeof modules === 'string') + ? [modules] + : modules || settings.modules + ; + modifyExisting = (modifyExisting !== undefined) + ? modifyExisting + : true + ; + $.each(modules, function (index, name) { + var + $existingModules + ; + if (module.moduleExists(name)) { + module.verbose('Changing default setting', newSettings, name); + $.extend(true, $.fn[name].settings, newSettings); + if (modifyExisting && namespace) { + $existingModules = $(':data(module-' + namespace + ')'); + if ($existingModules.length > 0) { + module.verbose('Modifying existing settings', $existingModules); + $existingModules[name]('setting', newSettings); + } + } + } + }); + } + }, + + enable: { + console: function () { + module.console(true); + }, + debug: function (modules, modifyExisting) { + modules = modules || settings.modules; + module.debug('Enabling debug for modules', modules); + module.change.setting('debug', true, modules, modifyExisting); + }, + verbose: function (modules, modifyExisting) { + modules = modules || settings.modules; + module.debug('Enabling verbose debug for modules', modules); + module.change.setting('verbose', true, modules, modifyExisting); + } + }, + disable: { + console: function () { + module.console(false); + }, + debug: function (modules, modifyExisting) { + modules = modules || settings.modules; + module.debug('Disabling debug for modules', modules); + module.change.setting('debug', false, modules, modifyExisting); + }, + verbose: function (modules, modifyExisting) { + modules = modules || settings.modules; + module.debug('Disabling verbose debug for modules', modules); + module.change.setting('verbose', false, modules, modifyExisting); + } + }, + + console: function (enable) { + if (enable) { + if (instance.cache.console === undefined) { + module.error(error.console); + return; + } + module.debug('Restoring console function'); + window.console = instance.cache.console; + } else { + module.debug('Disabling console function'); + instance.cache.console = window.console; + window.console = { + clear: function () { + }, + error: function () { + }, + group: function () { + }, + groupCollapsed: function () { + }, + groupEnd: function () { + }, + info: function () { + }, + log: function () { + }, + markTimeline: function () { + }, + warn: function () { + } + }; + } + }, + + destroy: function () { + module.verbose('Destroying previous site for', $module); + $module + .removeData(moduleNamespace) + ; + }, + + cache: {}, + + setting: function (name, value) { + if ($.isPlainObject(name)) { + $.extend(true, settings, name); + } else if (value !== undefined) { + settings[name] = value; + } else { + return settings[name]; + } + }, + internal: function (name, value) { + if ($.isPlainObject(name)) { + $.extend(true, module, name); + } else if (value !== undefined) { + module[name] = value; + } else { + return module[name]; + } + }, + debug: function () { + if (settings.debug) { + if (settings.performance) { + module.performance.log(arguments); + } else { + module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.debug.apply(console, arguments); + } + } + }, + verbose: function () { + if (settings.verbose && settings.debug) { + if (settings.performance) { + module.performance.log(arguments); + } else { + module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.verbose.apply(console, arguments); + } + } + }, + error: function () { + module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); + module.error.apply(console, arguments); + }, + performance: { + log: function (message) { + var + currentTime, + executionTime, + previousTime + ; + if (settings.performance) { + currentTime = new Date().getTime(); + previousTime = time || currentTime; + executionTime = currentTime - previousTime; + time = currentTime; + performance.push({ + 'Element': element, + 'Name': message[0], + 'Arguments': [].slice.call(message, 1) || '', + 'Execution Time': executionTime + }); + } + clearTimeout(module.performance.timer); + module.performance.timer = setTimeout(module.performance.display, 500); + }, + display: function () { + var + title = settings.name + ':', + totalTime = 0 + ; + time = false; + clearTimeout(module.performance.timer); + $.each(performance, function (index, data) { + totalTime += data['Execution Time']; + }); + title += ' ' + totalTime + 'ms'; + if ((console.group !== undefined || console.table !== undefined) && performance.length > 0) { + console.groupCollapsed(title); + if (console.table) { + console.table(performance); + } else { + $.each(performance, function (index, data) { + console.log(data['Name'] + ': ' + data['Execution Time'] + 'ms'); + }); + } + console.groupEnd(); + } + performance = []; + } + }, + invoke: function (query, passedArguments, context) { + var + object = instance, + maxDepth, + found, + response + ; + passedArguments = passedArguments || queryArguments; + context = element || context; + if (typeof query == 'string' && object !== undefined) { + query = query.split(/[\. ]/); + maxDepth = query.length - 1; + $.each(query, function (depth, value) { + var camelCaseValue = (depth != maxDepth) + ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) + : query + ; + if ($.isPlainObject(object[camelCaseValue]) && (depth != maxDepth)) { + object = object[camelCaseValue]; + } else if (object[camelCaseValue] !== undefined) { + found = object[camelCaseValue]; + return false; + } else if ($.isPlainObject(object[value]) && (depth != maxDepth)) { + object = object[value]; + } else if (object[value] !== undefined) { + found = object[value]; + return false; + } else { + module.error(error.method, query); + return false; + } + }); + } + if ($.isFunction(found)) { + response = found.apply(context, passedArguments); + } else if (found !== undefined) { + response = found; + } + if ($.isArray(returnedValue)) { + returnedValue.push(response); + } else if (returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } else if (response !== undefined) { + returnedValue = response; + } + return found; } - } - }); - }, - settings: function(newSettings, modules, modifyExisting) { - modules = (typeof modules === 'string') - ? [modules] - : modules || settings.modules - ; - modifyExisting = (modifyExisting !== undefined) - ? modifyExisting - : true - ; - $.each(modules, function(index, name) { - var - $existingModules - ; - if(module.moduleExists(name)) { - module.verbose('Changing default setting', newSettings, name); - $.extend(true, $.fn[name].settings, newSettings); - if(modifyExisting && namespace) { - $existingModules = $(':data(module-' + namespace + ')'); - if($existingModules.length > 0) { - module.verbose('Modifying existing settings', $existingModules); - $existingModules[name]('setting', newSettings); - } - } - } - }); - } - }, - - enable: { - console: function() { - module.console(true); - }, - debug: function(modules, modifyExisting) { - modules = modules || settings.modules; - module.debug('Enabling debug for modules', modules); - module.change.setting('debug', true, modules, modifyExisting); - }, - verbose: function(modules, modifyExisting) { - modules = modules || settings.modules; - module.debug('Enabling verbose debug for modules', modules); - module.change.setting('verbose', true, modules, modifyExisting); - } - }, - disable: { - console: function() { - module.console(false); - }, - debug: function(modules, modifyExisting) { - modules = modules || settings.modules; - module.debug('Disabling debug for modules', modules); - module.change.setting('debug', false, modules, modifyExisting); - }, - verbose: function(modules, modifyExisting) { - modules = modules || settings.modules; - module.debug('Disabling verbose debug for modules', modules); - module.change.setting('verbose', false, modules, modifyExisting); - } - }, - - console: function(enable) { - if(enable) { - if(instance.cache.console === undefined) { - module.error(error.console); - return; - } - module.debug('Restoring console function'); - window.console = instance.cache.console; - } - else { - module.debug('Disabling console function'); - instance.cache.console = window.console; - window.console = { - clear : function(){}, - error : function(){}, - group : function(){}, - groupCollapsed : function(){}, - groupEnd : function(){}, - info : function(){}, - log : function(){}, - markTimeline : function(){}, - warn : function(){} }; - } - }, - destroy: function() { - module.verbose('Destroying previous site for', $module); - $module - .removeData(moduleNamespace) - ; - }, - - cache: {}, - - setting: function(name, value) { - if( $.isPlainObject(name) ) { - $.extend(true, settings, name); - } - else if(value !== undefined) { - settings[name] = value; - } - else { - return settings[name]; - } - }, - internal: function(name, value) { - if( $.isPlainObject(name) ) { - $.extend(true, module, name); - } - else if(value !== undefined) { - module[name] = value; - } - else { - return module[name]; - } - }, - debug: function() { - if(settings.debug) { - if(settings.performance) { - module.performance.log(arguments); + if (methodInvoked) { + if (instance === undefined) { + module.initialize(); + } + module.invoke(query); + } else { + if (instance !== undefined) { + module.destroy(); + } + module.initialize(); } - else { - module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); - module.debug.apply(console, arguments); + return (returnedValue !== undefined) + ? returnedValue + : this + ; + }; + + $.site.settings = { + + name: 'Site', + namespace: 'site', + + error: { + console: 'Console cannot be restored, most likely it was overwritten outside of module', + method: 'The method you called is not defined.' + }, + + debug: false, + verbose: false, + performance: true, + + modules: [ + 'accordion', + 'api', + 'checkbox', + 'dimmer', + 'dropdown', + 'embed', + 'form', + 'modal', + 'nag', + 'popup', + 'rating', + 'shape', + 'sidebar', + 'state', + 'sticky', + 'tab', + 'transition', + 'visit', + 'visibility' + ], + + siteNamespace: 'site', + namespaceStub: { + cache: {}, + config: {}, + sections: {}, + section: {}, + utilities: {} } - } - }, - verbose: function() { - if(settings.verbose && settings.debug) { - if(settings.performance) { - module.performance.log(arguments); - } - else { - module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); - module.verbose.apply(console, arguments); - } - } - }, - error: function() { - module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); - module.error.apply(console, arguments); - }, - performance: { - log: function(message) { - var - currentTime, - executionTime, - previousTime - ; - if(settings.performance) { - currentTime = new Date().getTime(); - previousTime = time || currentTime; - executionTime = currentTime - previousTime; - time = currentTime; - performance.push({ - 'Element' : element, - 'Name' : message[0], - 'Arguments' : [].slice.call(message, 1) || '', - 'Execution Time' : executionTime - }); - } - clearTimeout(module.performance.timer); - module.performance.timer = setTimeout(module.performance.display, 500); - }, - display: function() { - var - title = settings.name + ':', - totalTime = 0 - ; - time = false; - clearTimeout(module.performance.timer); - $.each(performance, function(index, data) { - totalTime += data['Execution Time']; - }); - title += ' ' + totalTime + 'ms'; - if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { - console.groupCollapsed(title); - if(console.table) { - console.table(performance); - } - else { - $.each(performance, function(index, data) { - console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); - }); - } - console.groupEnd(); - } - performance = []; - } - }, - invoke: function(query, passedArguments, context) { - var - object = instance, - maxDepth, - found, - response - ; - passedArguments = passedArguments || queryArguments; - context = element || context; - if(typeof query == 'string' && object !== undefined) { - query = query.split(/[\. ]/); - maxDepth = query.length - 1; - $.each(query, function(depth, value) { - var camelCaseValue = (depth != maxDepth) - ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) - : query - ; - if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { - object = object[camelCaseValue]; - } - else if( object[camelCaseValue] !== undefined ) { - found = object[camelCaseValue]; - return false; - } - else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { - object = object[value]; - } - else if( object[value] !== undefined ) { - found = object[value]; - return false; - } - else { - module.error(error.method, query); - return false; - } - }); - } - if ( $.isFunction( found ) ) { - response = found.apply(context, passedArguments); - } - else if(found !== undefined) { - response = found; - } - if($.isArray(returnedValue)) { - returnedValue.push(response); - } - else if(returnedValue !== undefined) { - returnedValue = [returnedValue, response]; - } - else if(response !== undefined) { - returnedValue = response; - } - return found; - } - }; - if(methodInvoked) { - if(instance === undefined) { - module.initialize(); - } - module.invoke(query); - } - else { - if(instance !== undefined) { - module.destroy(); - } - module.initialize(); - } - return (returnedValue !== undefined) - ? returnedValue - : this - ; -}; - -$.site.settings = { - - name : 'Site', - namespace : 'site', - - error : { - console : 'Console cannot be restored, most likely it was overwritten outside of module', - method : 'The method you called is not defined.' - }, - - debug : false, - verbose : false, - performance : true, - - modules: [ - 'accordion', - 'api', - 'checkbox', - 'dimmer', - 'dropdown', - 'embed', - 'form', - 'modal', - 'nag', - 'popup', - 'rating', - 'shape', - 'sidebar', - 'state', - 'sticky', - 'tab', - 'transition', - 'visit', - 'visibility' - ], - - siteNamespace : 'site', - namespaceStub : { - cache : {}, - config : {}, - sections : {}, - section : {}, - utilities : {} - } - -}; + }; // allows for selection of elements with data attributes -$.extend($.expr[ ":" ], { - data: ($.expr.createPseudo) - ? $.expr.createPseudo(function(dataName) { - return function(elem) { - return !!$.data(elem, dataName); - }; - }) - : function(elem, i, match) { - // support: jQuery < 1.8 - return !!$.data(elem, match[ 3 ]); - } -}); + $.extend($.expr[":"], { + data: ($.expr.createPseudo) + ? $.expr.createPseudo(function (dataName) { + return function (elem) { + return !!$.data(elem, dataName); + }; + }) + : function (elem, i, match) { + // support: jQuery < 1.8 + return !!$.data(elem, match[3]); + } + }); -})( jQuery, window, document ); +})(jQuery, window, document); /*! * # Semantic UI 2.4.2 - Form Validation @@ -508,1700 +508,1645 @@ $.extend($.expr[ ":" ], { ;(function ($, window, document, undefined) { -'use strict'; + 'use strict'; -window = (typeof window != 'undefined' && window.Math == Math) - ? window - : (typeof self != 'undefined' && self.Math == Math) - ? self - : Function('return this')() -; + window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() + ; -$.fn.form = function(parameters) { - var - $allModules = $(this), - moduleSelector = $allModules.selector || '', + $.fn.form = function (parameters) { + var + $allModules = $(this), + moduleSelector = $allModules.selector || '', - time = new Date().getTime(), - performance = [], + time = new Date().getTime(), + performance = [], - query = arguments[0], - legacyParameters = arguments[1], - methodInvoked = (typeof query == 'string'), - queryArguments = [].slice.call(arguments, 1), - returnedValue - ; - $allModules - .each(function() { - var - $module = $(this), - element = this, - - formErrors = [], - keyHeldDown = false, - - // set at run-time - $field, - $group, - $message, - $prompt, - $submit, - $clear, - $reset, - - settings, - validation, - - metadata, - selector, - className, - regExp, - error, - - namespace, - moduleNamespace, - eventNamespace, - - instance, - module - ; - - module = { - - initialize: function() { - - // settings grabbed at run time - module.get.settings(); - if(methodInvoked) { - if(instance === undefined) { - module.instantiate(); - } - module.invoke(query); - } - else { - if(instance !== undefined) { - instance.invoke('destroy'); - } - module.verbose('Initializing form validation', $module, settings); - module.bindEvents(); - module.set.defaults(); - module.instantiate(); - } - }, - - instantiate: function() { - module.verbose('Storing instance of module', module); - instance = module; - $module - .data(moduleNamespace, module) - ; - }, - - destroy: function() { - module.verbose('Destroying previous module', instance); - module.removeEvents(); - $module - .removeData(moduleNamespace) - ; - }, - - refresh: function() { - module.verbose('Refreshing selector cache'); - $field = $module.find(selector.field); - $group = $module.find(selector.group); - $message = $module.find(selector.message); - $prompt = $module.find(selector.prompt); - - $submit = $module.find(selector.submit); - $clear = $module.find(selector.clear); - $reset = $module.find(selector.reset); - }, - - submit: function() { - module.verbose('Submitting form', $module); - $module - .submit() - ; - }, - - attachEvents: function(selector, action) { - action = action || 'submit'; - $(selector) - .on('click' + eventNamespace, function(event) { - module[action](); - event.preventDefault(); - }) - ; - }, - - bindEvents: function() { - module.verbose('Attaching form events'); - $module - .on('submit' + eventNamespace, module.validate.form) - .on('blur' + eventNamespace, selector.field, module.event.field.blur) - .on('click' + eventNamespace, selector.submit, module.submit) - .on('click' + eventNamespace, selector.reset, module.reset) - .on('click' + eventNamespace, selector.clear, module.clear) - ; - if(settings.keyboardShortcuts) { - $module - .on('keydown' + eventNamespace, selector.field, module.event.field.keydown) - ; - } - $field - .each(function() { - var - $input = $(this), - type = $input.prop('type'), - inputEvent = module.get.changeEvent(type, $input) - ; - $(this) - .on(inputEvent + eventNamespace, module.event.field.change) - ; - }) - ; - }, - - clear: function() { - $field + query = arguments[0], + legacyParameters = arguments[1], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + returnedValue + ; + $allModules .each(function () { - var - $field = $(this), - $element = $field.parent(), - $fieldGroup = $field.closest($group), - $prompt = $fieldGroup.find(selector.prompt), - defaultValue = $field.data(metadata.defaultValue) || '', - isCheckbox = $element.is(selector.uiCheckbox), - isDropdown = $element.is(selector.uiDropdown), - isErrored = $fieldGroup.hasClass(className.error) - ; - if(isErrored) { - module.verbose('Resetting error on field', $fieldGroup); - $fieldGroup.removeClass(className.error); - $prompt.remove(); - } - if(isDropdown) { - module.verbose('Resetting dropdown value', $element, defaultValue); - $element.dropdown('clear'); - } - else if(isCheckbox) { - $field.prop('checked', false); - } - else { - module.verbose('Resetting field value', $field, defaultValue); - $field.val(''); - } - }) - ; - }, - - reset: function() { - $field - .each(function () { - var - $field = $(this), - $element = $field.parent(), - $fieldGroup = $field.closest($group), - $prompt = $fieldGroup.find(selector.prompt), - defaultValue = $field.data(metadata.defaultValue), - isCheckbox = $element.is(selector.uiCheckbox), - isDropdown = $element.is(selector.uiDropdown), - isErrored = $fieldGroup.hasClass(className.error) - ; - if(defaultValue === undefined) { - return; - } - if(isErrored) { - module.verbose('Resetting error on field', $fieldGroup); - $fieldGroup.removeClass(className.error); - $prompt.remove(); - } - if(isDropdown) { - module.verbose('Resetting dropdown value', $element, defaultValue); - $element.dropdown('restore defaults'); - } - else if(isCheckbox) { - module.verbose('Resetting checkbox value', $element, defaultValue); - $field.prop('checked', defaultValue); - } - else { - module.verbose('Resetting field value', $field, defaultValue); - $field.val(defaultValue); - } - }) - ; - }, - - determine: { - isValid: function() { - var - allValid = true - ; - $.each(validation, function(fieldName, field) { - if( !( module.validate.field(field, fieldName, true) ) ) { - allValid = false; - } - }); - return allValid; - } - }, - - is: { - bracketedRule: function(rule) { - return (rule.type && rule.type.match(settings.regExp.bracket)); - }, - shorthandFields: function(fields) { - var - fieldKeys = Object.keys(fields), - firstRule = fields[fieldKeys[0]] - ; - return module.is.shorthandRules(firstRule); - }, - // duck type rule test - shorthandRules: function(rules) { - return (typeof rules == 'string' || $.isArray(rules)); - }, - empty: function($field) { - if(!$field || $field.length === 0) { - return true; - } - else if($field.is('input[type="checkbox"]')) { - return !$field.is(':checked'); - } - else { - return module.is.blank($field); - } - }, - blank: function($field) { - return $.trim($field.val()) === ''; - }, - valid: function(field) { - var - allValid = true - ; - if(field) { - module.verbose('Checking if field is valid', field); - return module.validate.field(validation[field], field, false); - } - else { - module.verbose('Checking if form is valid'); - $.each(validation, function(fieldName, field) { - if( !module.is.valid(fieldName) ) { - allValid = false; - } - }); - return allValid; - } - } - }, - - removeEvents: function() { - $module - .off(eventNamespace) - ; - $field - .off(eventNamespace) - ; - $submit - .off(eventNamespace) - ; - $field - .off(eventNamespace) - ; - }, - - event: { - field: { - keydown: function(event) { - var - $field = $(this), - key = event.which, - isInput = $field.is(selector.input), - isCheckbox = $field.is(selector.checkbox), - isInDropdown = ($field.closest(selector.uiDropdown).length > 0), - keyCode = { - enter : 13, - escape : 27 - } - ; - if( key == keyCode.escape) { - module.verbose('Escape key pressed blurring field'); - $field - .blur() - ; - } - if(!event.ctrlKey && key == keyCode.enter && isInput && !isInDropdown && !isCheckbox) { - if(!keyHeldDown) { - $field - .one('keyup' + eventNamespace, module.event.field.keyup) - ; - module.submit(); - module.debug('Enter pressed on input submitting form'); - } - keyHeldDown = true; - } - }, - keyup: function() { - keyHeldDown = false; - }, - blur: function(event) { - var - $field = $(this), - $fieldGroup = $field.closest($group), - validationRules = module.get.validation($field) - ; - if( $fieldGroup.hasClass(className.error) ) { - module.debug('Revalidating field', $field, validationRules); - if(validationRules) { - module.validate.field( validationRules ); - } - } - else if(settings.on == 'blur') { - if(validationRules) { - module.validate.field( validationRules ); - } - } - }, - change: function(event) { - var - $field = $(this), - $fieldGroup = $field.closest($group), - validationRules = module.get.validation($field) - ; - if(validationRules && (settings.on == 'change' || ( $fieldGroup.hasClass(className.error) && settings.revalidate) )) { - clearTimeout(module.timer); - module.timer = setTimeout(function() { - module.debug('Revalidating field', $field, module.get.validation($field)); - module.validate.field( validationRules ); - }, settings.delay); - } - } - } - - }, - - get: { - ancillaryValue: function(rule) { - if(!rule.type || (!rule.value && !module.is.bracketedRule(rule))) { - return false; - } - return (rule.value !== undefined) - ? rule.value - : rule.type.match(settings.regExp.bracket)[1] + '' - ; - }, - ruleName: function(rule) { - if( module.is.bracketedRule(rule) ) { - return rule.type.replace(rule.type.match(settings.regExp.bracket)[0], ''); - } - return rule.type; - }, - changeEvent: function(type, $input) { - if(type == 'checkbox' || type == 'radio' || type == 'hidden' || $input.is('select')) { - return 'change'; - } - else { - return module.get.inputEvent(); - } - }, - inputEvent: function() { - return (document.createElement('input').oninput !== undefined) - ? 'input' - : (document.createElement('input').onpropertychange !== undefined) - ? 'propertychange' - : 'keyup' - ; - }, - fieldsFromShorthand: function(fields) { - var - fullFields = {} - ; - $.each(fields, function(name, rules) { - if(typeof rules == 'string') { - rules = [rules]; - } - fullFields[name] = { - rules: [] - }; - $.each(rules, function(index, rule) { - fullFields[name].rules.push({ type: rule }); - }); - }); - return fullFields; - }, - prompt: function(rule, field) { - var - ruleName = module.get.ruleName(rule), - ancillary = module.get.ancillaryValue(rule), - $field = module.get.field(field.identifier), - value = $field.val(), - prompt = $.isFunction(rule.prompt) - ? rule.prompt(value) - : rule.prompt || settings.prompt[ruleName] || settings.text.unspecifiedRule, - requiresValue = (prompt.search('{value}') !== -1), - requiresName = (prompt.search('{name}') !== -1), - $label, - name - ; - if(requiresValue) { - prompt = prompt.replace('{value}', $field.val()); - } - if(requiresName) { - $label = $field.closest(selector.group).find('label').eq(0); - name = ($label.length == 1) - ? $label.text() - : $field.prop('placeholder') || settings.text.unspecifiedField - ; - prompt = prompt.replace('{name}', name); - } - prompt = prompt.replace('{identifier}', field.identifier); - prompt = prompt.replace('{ruleValue}', ancillary); - if(!rule.prompt) { - module.verbose('Using default validation prompt for type', prompt, ruleName); - } - return prompt; - }, - settings: function() { - if($.isPlainObject(parameters)) { - var - keys = Object.keys(parameters), - isLegacySettings = (keys.length > 0) - ? (parameters[keys[0]].identifier !== undefined && parameters[keys[0]].rules !== undefined) - : false, - ruleKeys - ; - if(isLegacySettings) { - // 1.x (ducktyped) - settings = $.extend(true, {}, $.fn.form.settings, legacyParameters); - validation = $.extend({}, $.fn.form.settings.defaults, parameters); - module.error(settings.error.oldSyntax, element); - module.verbose('Extending settings from legacy parameters', validation, settings); - } - else { - // 2.x - if(parameters.fields && module.is.shorthandFields(parameters.fields)) { - parameters.fields = module.get.fieldsFromShorthand(parameters.fields); - } - settings = $.extend(true, {}, $.fn.form.settings, parameters); - validation = $.extend({}, $.fn.form.settings.defaults, settings.fields); - module.verbose('Extending settings', validation, settings); - } - } - else { - settings = $.fn.form.settings; - validation = $.fn.form.settings.defaults; - module.verbose('Using default form validation', validation, settings); - } - - // shorthand - namespace = settings.namespace; - metadata = settings.metadata; - selector = settings.selector; - className = settings.className; - regExp = settings.regExp; - error = settings.error; - moduleNamespace = 'module-' + namespace; - eventNamespace = '.' + namespace; - - // grab instance - instance = $module.data(moduleNamespace); - - // refresh selector cache - module.refresh(); - }, - field: function(identifier) { - module.verbose('Finding field with identifier', identifier); - identifier = module.escape.string(identifier); - if($field.filter('#' + identifier).length > 0 ) { - return $field.filter('#' + identifier); - } - else if( $field.filter('[name="' + identifier +'"]').length > 0 ) { - return $field.filter('[name="' + identifier +'"]'); - } - else if( $field.filter('[name="' + identifier +'[]"]').length > 0 ) { - return $field.filter('[name="' + identifier +'[]"]'); - } - else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) { - return $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]'); - } - return $(''); - }, - fields: function(fields) { - var - $fields = $() - ; - $.each(fields, function(index, name) { - $fields = $fields.add( module.get.field(name) ); - }); - return $fields; - }, - validation: function($field) { - var - fieldValidation, - identifier - ; - if(!validation) { - return false; - } - $.each(validation, function(fieldName, field) { - identifier = field.identifier || fieldName; - if( module.get.field(identifier)[0] == $field[0] ) { - field.identifier = identifier; - fieldValidation = field; - } - }); - return fieldValidation || false; - }, - value: function (field) { - var - fields = [], - results - ; - fields.push(field); - results = module.get.values.call(element, fields); - return results[field]; - }, - values: function (fields) { - var - $fields = $.isArray(fields) - ? module.get.fields(fields) - : $field, - values = {} - ; - $fields.each(function(index, field) { - var - $field = $(field), - type = $field.prop('type'), - name = $field.prop('name'), - value = $field.val(), - isCheckbox = $field.is(selector.checkbox), - isRadio = $field.is(selector.radio), - isMultiple = (name.indexOf('[]') !== -1), - isChecked = (isCheckbox) - ? $field.is(':checked') - : false - ; - if(name) { - if(isMultiple) { - name = name.replace('[]', ''); - if(!values[name]) { - values[name] = []; - } - if(isCheckbox) { - if(isChecked) { - values[name].push(value || true); - } - else { - values[name].push(false); - } - } - else { - values[name].push(value); - } - } - else { - if(isRadio) { - if(values[name] === undefined || values[name] == false) { - values[name] = (isChecked) - ? value || true - : false - ; - } - } - else if(isCheckbox) { - if(isChecked) { - values[name] = value || true; - } - else { - values[name] = false; - } - } - else { - values[name] = value; - } - } - } - }); - return values; - } - }, - - has: { - - field: function(identifier) { - module.verbose('Checking for existence of a field with identifier', identifier); - identifier = module.escape.string(identifier); - if(typeof identifier !== 'string') { - module.error(error.identifier, identifier); - } - if($field.filter('#' + identifier).length > 0 ) { - return true; - } - else if( $field.filter('[name="' + identifier +'"]').length > 0 ) { - return true; - } - else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) { - return true; - } - return false; - } - - }, - - escape: { - string: function(text) { - text = String(text); - return text.replace(regExp.escape, '\\$&'); - } - }, - - add: { - // alias - rule: function(name, rules) { - module.add.field(name, rules); - }, - field: function(name, rules) { - var - newValidation = {} - ; - if(module.is.shorthandRules(rules)) { - rules = $.isArray(rules) - ? rules - : [rules] - ; - newValidation[name] = { - rules: [] - }; - $.each(rules, function(index, rule) { - newValidation[name].rules.push({ type: rule }); - }); - } - else { - newValidation[name] = rules; - } - validation = $.extend({}, validation, newValidation); - module.debug('Adding rules', newValidation, validation); - }, - fields: function(fields) { - var - newValidation - ; - if(fields && module.is.shorthandFields(fields)) { - newValidation = module.get.fieldsFromShorthand(fields); - } - else { - newValidation = fields; - } - validation = $.extend({}, validation, newValidation); - }, - prompt: function(identifier, errors) { - var - $field = module.get.field(identifier), - $fieldGroup = $field.closest($group), - $prompt = $fieldGroup.children(selector.prompt), - promptExists = ($prompt.length !== 0) - ; - errors = (typeof errors == 'string') - ? [errors] - : errors - ; - module.verbose('Adding field error state', identifier); - $fieldGroup - .addClass(className.error) - ; - if(settings.inline) { - if(!promptExists) { - $prompt = settings.templates.prompt(errors); - $prompt - .appendTo($fieldGroup) - ; - } - $prompt - .html(errors[0]) - ; - if(!promptExists) { - if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { - module.verbose('Displaying error with css transition', settings.transition); - $prompt.transition(settings.transition + ' in', settings.duration); - } - else { - module.verbose('Displaying error with fallback javascript animation'); - $prompt - .fadeIn(settings.duration) - ; - } - } - else { - module.verbose('Inline errors are disabled, no inline error added', identifier); - } - } - }, - errors: function(errors) { - module.debug('Adding form error messages', errors); - module.set.error(); - $message - .html( settings.templates.error(errors) ) - ; - } - }, - - remove: { - rule: function(field, rule) { - var - rules = $.isArray(rule) - ? rule - : [rule] - ; - if(rule == undefined) { - module.debug('Removed all rules'); - validation[field].rules = []; - return; - } - if(validation[field] == undefined || !$.isArray(validation[field].rules)) { - return; - } - $.each(validation[field].rules, function(index, rule) { - if(rules.indexOf(rule.type) !== -1) { - module.debug('Removed rule', rule.type); - validation[field].rules.splice(index, 1); - } - }); - }, - field: function(field) { - var - fields = $.isArray(field) - ? field - : [field] - ; - $.each(fields, function(index, field) { - module.remove.rule(field); - }); - }, - // alias - rules: function(field, rules) { - if($.isArray(field)) { - $.each(fields, function(index, field) { - module.remove.rule(field, rules); - }); - } - else { - module.remove.rule(field, rules); - } - }, - fields: function(fields) { - module.remove.field(fields); - }, - prompt: function(identifier) { - var - $field = module.get.field(identifier), - $fieldGroup = $field.closest($group), - $prompt = $fieldGroup.children(selector.prompt) - ; - $fieldGroup - .removeClass(className.error) - ; - if(settings.inline && $prompt.is(':visible')) { - module.verbose('Removing prompt for field', identifier); - if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { - $prompt.transition(settings.transition + ' out', settings.duration, function() { - $prompt.remove(); - }); - } - else { - $prompt - .fadeOut(settings.duration, function(){ - $prompt.remove(); - }) - ; - } - } - } - }, - - set: { - success: function() { - $module - .removeClass(className.error) - .addClass(className.success) - ; - }, - defaults: function () { - $field - .each(function () { var - $field = $(this), - isCheckbox = ($field.filter(selector.checkbox).length > 0), - value = (isCheckbox) - ? $field.is(':checked') - : $field.val() + $module = $(this), + element = this, + + formErrors = [], + keyHeldDown = false, + + // set at run-time + $field, + $group, + $message, + $prompt, + $submit, + $clear, + $reset, + + settings, + validation, + + metadata, + selector, + className, + regExp, + error, + + namespace, + moduleNamespace, + eventNamespace, + + instance, + module ; - $field.data(metadata.defaultValue, value); - }) - ; - }, - error: function() { - $module - .removeClass(className.success) - .addClass(className.error) - ; - }, - value: function (field, value) { - var - fields = {} - ; - fields[field] = value; - return module.set.values.call(element, fields); - }, - values: function (fields) { - if($.isEmptyObject(fields)) { - return; - } - $.each(fields, function(key, value) { - var - $field = module.get.field(key), - $element = $field.parent(), - isMultiple = $.isArray(value), - isCheckbox = $element.is(selector.uiCheckbox), - isDropdown = $element.is(selector.uiDropdown), - isRadio = ($field.is(selector.radio) && isCheckbox), - fieldExists = ($field.length > 0), - $multipleField - ; - if(fieldExists) { - if(isMultiple && isCheckbox) { - module.verbose('Selecting multiple', value, $field); - $element.checkbox('uncheck'); - $.each(value, function(index, value) { - $multipleField = $field.filter('[value="' + value + '"]'); - $element = $multipleField.parent(); - if($multipleField.length > 0) { - $element.checkbox('check'); + + module = { + + initialize: function () { + + // settings grabbed at run time + module.get.settings(); + if (methodInvoked) { + if (instance === undefined) { + module.instantiate(); + } + module.invoke(query); + } else { + if (instance !== undefined) { + instance.invoke('destroy'); + } + module.verbose('Initializing form validation', $module, settings); + module.bindEvents(); + module.set.defaults(); + module.instantiate(); + } + }, + + instantiate: function () { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + + destroy: function () { + module.verbose('Destroying previous module', instance); + module.removeEvents(); + $module + .removeData(moduleNamespace) + ; + }, + + refresh: function () { + module.verbose('Refreshing selector cache'); + $field = $module.find(selector.field); + $group = $module.find(selector.group); + $message = $module.find(selector.message); + $prompt = $module.find(selector.prompt); + + $submit = $module.find(selector.submit); + $clear = $module.find(selector.clear); + $reset = $module.find(selector.reset); + }, + + submit: function () { + module.verbose('Submitting form', $module); + $module + .submit() + ; + }, + + attachEvents: function (selector, action) { + action = action || 'submit'; + $(selector) + .on('click' + eventNamespace, function (event) { + module[action](); + event.preventDefault(); + }) + ; + }, + + bindEvents: function () { + module.verbose('Attaching form events'); + $module + .on('submit' + eventNamespace, module.validate.form) + .on('blur' + eventNamespace, selector.field, module.event.field.blur) + .on('click' + eventNamespace, selector.submit, module.submit) + .on('click' + eventNamespace, selector.reset, module.reset) + .on('click' + eventNamespace, selector.clear, module.clear) + ; + if (settings.keyboardShortcuts) { + $module + .on('keydown' + eventNamespace, selector.field, module.event.field.keydown) + ; + } + $field + .each(function () { + var + $input = $(this), + type = $input.prop('type'), + inputEvent = module.get.changeEvent(type, $input) + ; + $(this) + .on(inputEvent + eventNamespace, module.event.field.change) + ; + }) + ; + }, + + clear: function () { + $field + .each(function () { + var + $field = $(this), + $element = $field.parent(), + $fieldGroup = $field.closest($group), + $prompt = $fieldGroup.find(selector.prompt), + defaultValue = $field.data(metadata.defaultValue) || '', + isCheckbox = $element.is(selector.uiCheckbox), + isDropdown = $element.is(selector.uiDropdown), + isErrored = $fieldGroup.hasClass(className.error) + ; + if (isErrored) { + module.verbose('Resetting error on field', $fieldGroup); + $fieldGroup.removeClass(className.error); + $prompt.remove(); + } + if (isDropdown) { + module.verbose('Resetting dropdown value', $element, defaultValue); + $element.dropdown('clear'); + } else if (isCheckbox) { + $field.prop('checked', false); + } else { + module.verbose('Resetting field value', $field, defaultValue); + $field.val(''); + } + }) + ; + }, + + reset: function () { + $field + .each(function () { + var + $field = $(this), + $element = $field.parent(), + $fieldGroup = $field.closest($group), + $prompt = $fieldGroup.find(selector.prompt), + defaultValue = $field.data(metadata.defaultValue), + isCheckbox = $element.is(selector.uiCheckbox), + isDropdown = $element.is(selector.uiDropdown), + isErrored = $fieldGroup.hasClass(className.error) + ; + if (defaultValue === undefined) { + return; + } + if (isErrored) { + module.verbose('Resetting error on field', $fieldGroup); + $fieldGroup.removeClass(className.error); + $prompt.remove(); + } + if (isDropdown) { + module.verbose('Resetting dropdown value', $element, defaultValue); + $element.dropdown('restore defaults'); + } else if (isCheckbox) { + module.verbose('Resetting checkbox value', $element, defaultValue); + $field.prop('checked', defaultValue); + } else { + module.verbose('Resetting field value', $field, defaultValue); + $field.val(defaultValue); + } + }) + ; + }, + + determine: { + isValid: function () { + var + allValid = true + ; + $.each(validation, function (fieldName, field) { + if (!(module.validate.field(field, fieldName, true))) { + allValid = false; + } + }); + return allValid; + } + }, + + is: { + bracketedRule: function (rule) { + return (rule.type && rule.type.match(settings.regExp.bracket)); + }, + shorthandFields: function (fields) { + var + fieldKeys = Object.keys(fields), + firstRule = fields[fieldKeys[0]] + ; + return module.is.shorthandRules(firstRule); + }, + // duck type rule test + shorthandRules: function (rules) { + return (typeof rules == 'string' || $.isArray(rules)); + }, + empty: function ($field) { + if (!$field || $field.length === 0) { + return true; + } else if ($field.is('input[type="checkbox"]')) { + return !$field.is(':checked'); + } else { + return module.is.blank($field); + } + }, + blank: function ($field) { + return $.trim($field.val()) === ''; + }, + valid: function (field) { + var + allValid = true + ; + if (field) { + module.verbose('Checking if field is valid', field); + return module.validate.field(validation[field], field, false); + } else { + module.verbose('Checking if form is valid'); + $.each(validation, function (fieldName, field) { + if (!module.is.valid(fieldName)) { + allValid = false; + } + }); + return allValid; + } + } + }, + + removeEvents: function () { + $module + .off(eventNamespace) + ; + $field + .off(eventNamespace) + ; + $submit + .off(eventNamespace) + ; + $field + .off(eventNamespace) + ; + }, + + event: { + field: { + keydown: function (event) { + var + $field = $(this), + key = event.which, + isInput = $field.is(selector.input), + isCheckbox = $field.is(selector.checkbox), + isInDropdown = ($field.closest(selector.uiDropdown).length > 0), + keyCode = { + enter: 13, + escape: 27 + } + ; + if (key == keyCode.escape) { + module.verbose('Escape key pressed blurring field'); + $field + .blur() + ; + } + if (!event.ctrlKey && key == keyCode.enter && isInput && !isInDropdown && !isCheckbox) { + if (!keyHeldDown) { + $field + .one('keyup' + eventNamespace, module.event.field.keyup) + ; + module.submit(); + module.debug('Enter pressed on input submitting form'); + } + keyHeldDown = true; + } + }, + keyup: function () { + keyHeldDown = false; + }, + blur: function (event) { + var + $field = $(this), + $fieldGroup = $field.closest($group), + validationRules = module.get.validation($field) + ; + if ($fieldGroup.hasClass(className.error)) { + module.debug('Revalidating field', $field, validationRules); + if (validationRules) { + module.validate.field(validationRules); + } + } else if (settings.on == 'blur') { + if (validationRules) { + module.validate.field(validationRules); + } + } + }, + change: function (event) { + var + $field = $(this), + $fieldGroup = $field.closest($group), + validationRules = module.get.validation($field) + ; + if (validationRules && (settings.on == 'change' || ($fieldGroup.hasClass(className.error) && settings.revalidate))) { + clearTimeout(module.timer); + module.timer = setTimeout(function () { + module.debug('Revalidating field', $field, module.get.validation($field)); + module.validate.field(validationRules); + }, settings.delay); + } + } + } + + }, + + get: { + ancillaryValue: function (rule) { + if (!rule.type || (!rule.value && !module.is.bracketedRule(rule))) { + return false; + } + return (rule.value !== undefined) + ? rule.value + : rule.type.match(settings.regExp.bracket)[1] + '' + ; + }, + ruleName: function (rule) { + if (module.is.bracketedRule(rule)) { + return rule.type.replace(rule.type.match(settings.regExp.bracket)[0], ''); + } + return rule.type; + }, + changeEvent: function (type, $input) { + if (type == 'checkbox' || type == 'radio' || type == 'hidden' || $input.is('select')) { + return 'change'; + } else { + return module.get.inputEvent(); + } + }, + inputEvent: function () { + return (document.createElement('input').oninput !== undefined) + ? 'input' + : (document.createElement('input').onpropertychange !== undefined) + ? 'propertychange' + : 'keyup' + ; + }, + fieldsFromShorthand: function (fields) { + var + fullFields = {} + ; + $.each(fields, function (name, rules) { + if (typeof rules == 'string') { + rules = [rules]; + } + fullFields[name] = { + rules: [] + }; + $.each(rules, function (index, rule) { + fullFields[name].rules.push({type: rule}); + }); + }); + return fullFields; + }, + prompt: function (rule, field) { + var + ruleName = module.get.ruleName(rule), + ancillary = module.get.ancillaryValue(rule), + $field = module.get.field(field.identifier), + value = $field.val(), + prompt = $.isFunction(rule.prompt) + ? rule.prompt(value) + : rule.prompt || settings.prompt[ruleName] || settings.text.unspecifiedRule, + requiresValue = (prompt.search('{value}') !== -1), + requiresName = (prompt.search('{name}') !== -1), + $label, + name + ; + if (requiresValue) { + prompt = prompt.replace('{value}', $field.val()); + } + if (requiresName) { + $label = $field.closest(selector.group).find('label').eq(0); + name = ($label.length == 1) + ? $label.text() + : $field.prop('placeholder') || settings.text.unspecifiedField + ; + prompt = prompt.replace('{name}', name); + } + prompt = prompt.replace('{identifier}', field.identifier); + prompt = prompt.replace('{ruleValue}', ancillary); + if (!rule.prompt) { + module.verbose('Using default validation prompt for type', prompt, ruleName); + } + return prompt; + }, + settings: function () { + if ($.isPlainObject(parameters)) { + var + keys = Object.keys(parameters), + isLegacySettings = (keys.length > 0) + ? (parameters[keys[0]].identifier !== undefined && parameters[keys[0]].rules !== undefined) + : false, + ruleKeys + ; + if (isLegacySettings) { + // 1.x (ducktyped) + settings = $.extend(true, {}, $.fn.form.settings, legacyParameters); + validation = $.extend({}, $.fn.form.settings.defaults, parameters); + module.error(settings.error.oldSyntax, element); + module.verbose('Extending settings from legacy parameters', validation, settings); + } else { + // 2.x + if (parameters.fields && module.is.shorthandFields(parameters.fields)) { + parameters.fields = module.get.fieldsFromShorthand(parameters.fields); + } + settings = $.extend(true, {}, $.fn.form.settings, parameters); + validation = $.extend({}, $.fn.form.settings.defaults, settings.fields); + module.verbose('Extending settings', validation, settings); + } + } else { + settings = $.fn.form.settings; + validation = $.fn.form.settings.defaults; + module.verbose('Using default form validation', validation, settings); + } + + // shorthand + namespace = settings.namespace; + metadata = settings.metadata; + selector = settings.selector; + className = settings.className; + regExp = settings.regExp; + error = settings.error; + moduleNamespace = 'module-' + namespace; + eventNamespace = '.' + namespace; + + // grab instance + instance = $module.data(moduleNamespace); + + // refresh selector cache + module.refresh(); + }, + field: function (identifier) { + module.verbose('Finding field with identifier', identifier); + identifier = module.escape.string(identifier); + if ($field.filter('#' + identifier).length > 0) { + return $field.filter('#' + identifier); + } else if ($field.filter('[name="' + identifier + '"]').length > 0) { + return $field.filter('[name="' + identifier + '"]'); + } else if ($field.filter('[name="' + identifier + '[]"]').length > 0) { + return $field.filter('[name="' + identifier + '[]"]'); + } else if ($field.filter('[data-' + metadata.validate + '="' + identifier + '"]').length > 0) { + return $field.filter('[data-' + metadata.validate + '="' + identifier + '"]'); + } + return $(''); + }, + fields: function (fields) { + var + $fields = $() + ; + $.each(fields, function (index, name) { + $fields = $fields.add(module.get.field(name)); + }); + return $fields; + }, + validation: function ($field) { + var + fieldValidation, + identifier + ; + if (!validation) { + return false; + } + $.each(validation, function (fieldName, field) { + identifier = field.identifier || fieldName; + if (module.get.field(identifier)[0] == $field[0]) { + field.identifier = identifier; + fieldValidation = field; + } + }); + return fieldValidation || false; + }, + value: function (field) { + var + fields = [], + results + ; + fields.push(field); + results = module.get.values.call(element, fields); + return results[field]; + }, + values: function (fields) { + var + $fields = $.isArray(fields) + ? module.get.fields(fields) + : $field, + values = {} + ; + $fields.each(function (index, field) { + var + $field = $(field), + type = $field.prop('type'), + name = $field.prop('name'), + value = $field.val(), + isCheckbox = $field.is(selector.checkbox), + isRadio = $field.is(selector.radio), + isMultiple = (name.indexOf('[]') !== -1), + isChecked = (isCheckbox) + ? $field.is(':checked') + : false + ; + if (name) { + if (isMultiple) { + name = name.replace('[]', ''); + if (!values[name]) { + values[name] = []; + } + if (isCheckbox) { + if (isChecked) { + values[name].push(value || true); + } else { + values[name].push(false); + } + } else { + values[name].push(value); + } + } else { + if (isRadio) { + if (values[name] === undefined || values[name] == false) { + values[name] = (isChecked) + ? value || true + : false + ; + } + } else if (isCheckbox) { + if (isChecked) { + values[name] = value || true; + } else { + values[name] = false; + } + } else { + values[name] = value; + } + } + } + }); + return values; + } + }, + + has: { + + field: function (identifier) { + module.verbose('Checking for existence of a field with identifier', identifier); + identifier = module.escape.string(identifier); + if (typeof identifier !== 'string') { + module.error(error.identifier, identifier); + } + if ($field.filter('#' + identifier).length > 0) { + return true; + } else if ($field.filter('[name="' + identifier + '"]').length > 0) { + return true; + } else if ($field.filter('[data-' + metadata.validate + '="' + identifier + '"]').length > 0) { + return true; + } + return false; + } + + }, + + escape: { + string: function (text) { + text = String(text); + return text.replace(regExp.escape, '\\$&'); + } + }, + + add: { + // alias + rule: function (name, rules) { + module.add.field(name, rules); + }, + field: function (name, rules) { + var + newValidation = {} + ; + if (module.is.shorthandRules(rules)) { + rules = $.isArray(rules) + ? rules + : [rules] + ; + newValidation[name] = { + rules: [] + }; + $.each(rules, function (index, rule) { + newValidation[name].rules.push({type: rule}); + }); + } else { + newValidation[name] = rules; + } + validation = $.extend({}, validation, newValidation); + module.debug('Adding rules', newValidation, validation); + }, + fields: function (fields) { + var + newValidation + ; + if (fields && module.is.shorthandFields(fields)) { + newValidation = module.get.fieldsFromShorthand(fields); + } else { + newValidation = fields; + } + validation = $.extend({}, validation, newValidation); + }, + prompt: function (identifier, errors) { + var + $field = module.get.field(identifier), + $fieldGroup = $field.closest($group), + $prompt = $fieldGroup.children(selector.prompt), + promptExists = ($prompt.length !== 0) + ; + errors = (typeof errors == 'string') + ? [errors] + : errors + ; + module.verbose('Adding field error state', identifier); + $fieldGroup + .addClass(className.error) + ; + if (settings.inline) { + if (!promptExists) { + $prompt = settings.templates.prompt(errors); + $prompt + .appendTo($fieldGroup) + ; + } + $prompt + .html(errors[0]) + ; + if (!promptExists) { + if (settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { + module.verbose('Displaying error with css transition', settings.transition); + $prompt.transition(settings.transition + ' in', settings.duration); + } else { + module.verbose('Displaying error with fallback javascript animation'); + $prompt + .fadeIn(settings.duration) + ; + } + } else { + module.verbose('Inline errors are disabled, no inline error added', identifier); + } + } + }, + errors: function (errors) { + module.debug('Adding form error messages', errors); + module.set.error(); + $message + .html(settings.templates.error(errors)) + ; + } + }, + + remove: { + rule: function (field, rule) { + var + rules = $.isArray(rule) + ? rule + : [rule] + ; + if (rule == undefined) { + module.debug('Removed all rules'); + validation[field].rules = []; + return; + } + if (validation[field] == undefined || !$.isArray(validation[field].rules)) { + return; + } + $.each(validation[field].rules, function (index, rule) { + if (rules.indexOf(rule.type) !== -1) { + module.debug('Removed rule', rule.type); + validation[field].rules.splice(index, 1); + } + }); + }, + field: function (field) { + var + fields = $.isArray(field) + ? field + : [field] + ; + $.each(fields, function (index, field) { + module.remove.rule(field); + }); + }, + // alias + rules: function (field, rules) { + if ($.isArray(field)) { + $.each(fields, function (index, field) { + module.remove.rule(field, rules); + }); + } else { + module.remove.rule(field, rules); + } + }, + fields: function (fields) { + module.remove.field(fields); + }, + prompt: function (identifier) { + var + $field = module.get.field(identifier), + $fieldGroup = $field.closest($group), + $prompt = $fieldGroup.children(selector.prompt) + ; + $fieldGroup + .removeClass(className.error) + ; + if (settings.inline && $prompt.is(':visible')) { + module.verbose('Removing prompt for field', identifier); + if (settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { + $prompt.transition(settings.transition + ' out', settings.duration, function () { + $prompt.remove(); + }); + } else { + $prompt + .fadeOut(settings.duration, function () { + $prompt.remove(); + }) + ; + } + } + } + }, + + set: { + success: function () { + $module + .removeClass(className.error) + .addClass(className.success) + ; + }, + defaults: function () { + $field + .each(function () { + var + $field = $(this), + isCheckbox = ($field.filter(selector.checkbox).length > 0), + value = (isCheckbox) + ? $field.is(':checked') + : $field.val() + ; + $field.data(metadata.defaultValue, value); + }) + ; + }, + error: function () { + $module + .removeClass(className.success) + .addClass(className.error) + ; + }, + value: function (field, value) { + var + fields = {} + ; + fields[field] = value; + return module.set.values.call(element, fields); + }, + values: function (fields) { + if ($.isEmptyObject(fields)) { + return; + } + $.each(fields, function (key, value) { + var + $field = module.get.field(key), + $element = $field.parent(), + isMultiple = $.isArray(value), + isCheckbox = $element.is(selector.uiCheckbox), + isDropdown = $element.is(selector.uiDropdown), + isRadio = ($field.is(selector.radio) && isCheckbox), + fieldExists = ($field.length > 0), + $multipleField + ; + if (fieldExists) { + if (isMultiple && isCheckbox) { + module.verbose('Selecting multiple', value, $field); + $element.checkbox('uncheck'); + $.each(value, function (index, value) { + $multipleField = $field.filter('[value="' + value + '"]'); + $element = $multipleField.parent(); + if ($multipleField.length > 0) { + $element.checkbox('check'); + } + }); + } else if (isRadio) { + module.verbose('Selecting radio value', value, $field); + $field.filter('[value="' + value + '"]') + .parent(selector.uiCheckbox) + .checkbox('check') + ; + } else if (isCheckbox) { + module.verbose('Setting checkbox value', value, $element); + if (value === true) { + $element.checkbox('check'); + } else { + $element.checkbox('uncheck'); + } + } else if (isDropdown) { + module.verbose('Setting dropdown value', value, $element); + $element.dropdown('set selected', value); + } else { + module.verbose('Setting field value', value, $field); + $field.val(value); + } + } + }); + } + }, + + validate: { + + form: function (event, ignoreCallbacks) { + var + values = module.get.values(), + apiRequest + ; + + // input keydown event will fire submit repeatedly by browser default + if (keyHeldDown) { + return false; + } + + // reset errors + formErrors = []; + if (module.determine.isValid()) { + module.debug('Form has no validation errors, submitting'); + module.set.success(); + if (ignoreCallbacks !== true) { + return settings.onSuccess.call(element, event, values); + } + } else { + module.debug('Form has errors'); + module.set.error(); + if (!settings.inline) { + module.add.errors(formErrors); + } + // prevent ajax submit + if ($module.data('moduleApi') !== undefined) { + event.stopImmediatePropagation(); + } + if (ignoreCallbacks !== true) { + return settings.onFailure.call(element, formErrors, values); + } + } + }, + + // takes a validation object and returns whether field passes validation + field: function (field, fieldName, showErrors) { + showErrors = (showErrors !== undefined) + ? showErrors + : true + ; + if (typeof field == 'string') { + module.verbose('Validating field', field); + fieldName = field; + field = validation[field]; + } + var + identifier = field.identifier || fieldName, + $field = module.get.field(identifier), + $dependsField = (field.depends) + ? module.get.field(field.depends) + : false, + fieldValid = true, + fieldErrors = [] + ; + if (!field.identifier) { + module.debug('Using field name as identifier', identifier); + field.identifier = identifier; + } + if ($field.prop('disabled')) { + module.debug('Field is disabled. Skipping', identifier); + fieldValid = true; + } else if (field.optional && module.is.blank($field)) { + module.debug('Field is optional and blank. Skipping', identifier); + fieldValid = true; + } else if (field.depends && module.is.empty($dependsField)) { + module.debug('Field depends on another value that is not present or empty. Skipping', $dependsField); + fieldValid = true; + } else if (field.rules !== undefined) { + $.each(field.rules, function (index, rule) { + if (module.has.field(identifier) && !(module.validate.rule(field, rule))) { + module.debug('Field is invalid', identifier, rule.type); + fieldErrors.push(module.get.prompt(rule, field)); + fieldValid = false; + } + }); + } + if (fieldValid) { + if (showErrors) { + module.remove.prompt(identifier, fieldErrors); + settings.onValid.call($field); + } + } else { + if (showErrors) { + formErrors = formErrors.concat(fieldErrors); + module.add.prompt(identifier, fieldErrors); + settings.onInvalid.call($field, fieldErrors); + } + return false; + } + return true; + }, + + // takes validation rule and returns whether field passes rule + rule: function (field, rule) { + var + $field = module.get.field(field.identifier), + type = rule.type, + value = $field.val(), + isValid = true, + ancillary = module.get.ancillaryValue(rule), + ruleName = module.get.ruleName(rule), + ruleFunction = settings.rules[ruleName] + ; + if (!$.isFunction(ruleFunction)) { + module.error(error.noRule, ruleName); + return; + } + // cast to string avoiding encoding special values + value = (value === undefined || value === '' || value === null) + ? '' + : $.trim(value + '') + ; + return ruleFunction.call($field, value, ancillary); + } + }, + + setting: function (name, value) { + if ($.isPlainObject(name)) { + $.extend(true, settings, name); + } else if (value !== undefined) { + settings[name] = value; + } else { + return settings[name]; + } + }, + internal: function (name, value) { + if ($.isPlainObject(name)) { + $.extend(true, module, name); + } else if (value !== undefined) { + module[name] = value; + } else { + return module[name]; + } + }, + debug: function () { + if (!settings.silent && settings.debug) { + if (settings.performance) { + module.performance.log(arguments); + } else { + module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.debug.apply(console, arguments); + } + } + }, + verbose: function () { + if (!settings.silent && settings.verbose && settings.debug) { + if (settings.performance) { + module.performance.log(arguments); + } else { + module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.verbose.apply(console, arguments); + } + } + }, + error: function () { + if (!settings.silent) { + module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); + module.error.apply(console, arguments); + } + }, + performance: { + log: function (message) { + var + currentTime, + executionTime, + previousTime + ; + if (settings.performance) { + currentTime = new Date().getTime(); + previousTime = time || currentTime; + executionTime = currentTime - previousTime; + time = currentTime; + performance.push({ + 'Name': message[0], + 'Arguments': [].slice.call(message, 1) || '', + 'Element': element, + 'Execution Time': executionTime + }); + } + clearTimeout(module.performance.timer); + module.performance.timer = setTimeout(module.performance.display, 500); + }, + display: function () { + var + title = settings.name + ':', + totalTime = 0 + ; + time = false; + clearTimeout(module.performance.timer); + $.each(performance, function (index, data) { + totalTime += data['Execution Time']; + }); + title += ' ' + totalTime + 'ms'; + if (moduleSelector) { + title += ' \'' + moduleSelector + '\''; + } + if ($allModules.length > 1) { + title += ' ' + '(' + $allModules.length + ')'; + } + if ((console.group !== undefined || console.table !== undefined) && performance.length > 0) { + console.groupCollapsed(title); + if (console.table) { + console.table(performance); + } else { + $.each(performance, function (index, data) { + console.log(data['Name'] + ': ' + data['Execution Time'] + 'ms'); + }); + } + console.groupEnd(); + } + performance = []; + } + }, + invoke: function (query, passedArguments, context) { + var + object = instance, + maxDepth, + found, + response + ; + passedArguments = passedArguments || queryArguments; + context = element || context; + if (typeof query == 'string' && object !== undefined) { + query = query.split(/[\. ]/); + maxDepth = query.length - 1; + $.each(query, function (depth, value) { + var camelCaseValue = (depth != maxDepth) + ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) + : query + ; + if ($.isPlainObject(object[camelCaseValue]) && (depth != maxDepth)) { + object = object[camelCaseValue]; + } else if (object[camelCaseValue] !== undefined) { + found = object[camelCaseValue]; + return false; + } else if ($.isPlainObject(object[value]) && (depth != maxDepth)) { + object = object[value]; + } else if (object[value] !== undefined) { + found = object[value]; + return false; + } else { + return false; + } + }); + } + if ($.isFunction(found)) { + response = found.apply(context, passedArguments); + } else if (found !== undefined) { + response = found; + } + if ($.isArray(returnedValue)) { + returnedValue.push(response); + } else if (returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } else if (response !== undefined) { + returnedValue = response; + } + return found; } - }); - } - else if(isRadio) { - module.verbose('Selecting radio value', value, $field); - $field.filter('[value="' + value + '"]') - .parent(selector.uiCheckbox) - .checkbox('check') - ; - } - else if(isCheckbox) { - module.verbose('Setting checkbox value', value, $element); - if(value === true) { - $element.checkbox('check'); - } - else { - $element.checkbox('uncheck'); - } - } - else if(isDropdown) { - module.verbose('Setting dropdown value', value, $element); - $element.dropdown('set selected', value); - } - else { - module.verbose('Setting field value', value, $field); - $field.val(value); - } - } - }); - } + }; + module.initialize(); + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; + }; + + $.fn.form.settings = { + + name: 'Form', + namespace: 'form', + + debug: false, + verbose: false, + performance: true, + + fields: false, + + keyboardShortcuts: true, + on: 'submit', + inline: false, + + delay: 200, + revalidate: true, + + transition: 'scale', + duration: 200, + + onValid: function () { }, - - validate: { - - form: function(event, ignoreCallbacks) { - var - values = module.get.values(), - apiRequest - ; - - // input keydown event will fire submit repeatedly by browser default - if(keyHeldDown) { - return false; - } - - // reset errors - formErrors = []; - if( module.determine.isValid() ) { - module.debug('Form has no validation errors, submitting'); - module.set.success(); - if(ignoreCallbacks !== true) { - return settings.onSuccess.call(element, event, values); - } - } - else { - module.debug('Form has errors'); - module.set.error(); - if(!settings.inline) { - module.add.errors(formErrors); - } - // prevent ajax submit - if($module.data('moduleApi') !== undefined) { - event.stopImmediatePropagation(); - } - if(ignoreCallbacks !== true) { - return settings.onFailure.call(element, formErrors, values); - } - } - }, - - // takes a validation object and returns whether field passes validation - field: function(field, fieldName, showErrors) { - showErrors = (showErrors !== undefined) - ? showErrors - : true - ; - if(typeof field == 'string') { - module.verbose('Validating field', field); - fieldName = field; - field = validation[field]; - } - var - identifier = field.identifier || fieldName, - $field = module.get.field(identifier), - $dependsField = (field.depends) - ? module.get.field(field.depends) - : false, - fieldValid = true, - fieldErrors = [] - ; - if(!field.identifier) { - module.debug('Using field name as identifier', identifier); - field.identifier = identifier; - } - if($field.prop('disabled')) { - module.debug('Field is disabled. Skipping', identifier); - fieldValid = true; - } - else if(field.optional && module.is.blank($field)){ - module.debug('Field is optional and blank. Skipping', identifier); - fieldValid = true; - } - else if(field.depends && module.is.empty($dependsField)) { - module.debug('Field depends on another value that is not present or empty. Skipping', $dependsField); - fieldValid = true; - } - else if(field.rules !== undefined) { - $.each(field.rules, function(index, rule) { - if( module.has.field(identifier) && !( module.validate.rule(field, rule) ) ) { - module.debug('Field is invalid', identifier, rule.type); - fieldErrors.push(module.get.prompt(rule, field)); - fieldValid = false; - } - }); - } - if(fieldValid) { - if(showErrors) { - module.remove.prompt(identifier, fieldErrors); - settings.onValid.call($field); - } - } - else { - if(showErrors) { - formErrors = formErrors.concat(fieldErrors); - module.add.prompt(identifier, fieldErrors); - settings.onInvalid.call($field, fieldErrors); - } - return false; - } + onInvalid: function () { + }, + onSuccess: function () { return true; - }, - - // takes validation rule and returns whether field passes rule - rule: function(field, rule) { - var - $field = module.get.field(field.identifier), - type = rule.type, - value = $field.val(), - isValid = true, - ancillary = module.get.ancillaryValue(rule), - ruleName = module.get.ruleName(rule), - ruleFunction = settings.rules[ruleName] - ; - if( !$.isFunction(ruleFunction) ) { - module.error(error.noRule, ruleName); - return; - } - // cast to string avoiding encoding special values - value = (value === undefined || value === '' || value === null) - ? '' - : $.trim(value + '') - ; - return ruleFunction.call($field, value, ancillary); - } + }, + onFailure: function () { + return false; }, - setting: function(name, value) { - if( $.isPlainObject(name) ) { - $.extend(true, settings, name); - } - else if(value !== undefined) { - settings[name] = value; - } - else { - return settings[name]; - } + metadata: { + defaultValue: 'default', + validate: 'validate' }, - internal: function(name, value) { - if( $.isPlainObject(name) ) { - $.extend(true, module, name); - } - else if(value !== undefined) { - module[name] = value; - } - else { - return module[name]; - } + + regExp: { + htmlID: /^[a-zA-Z][\w:.-]*$/g, + bracket: /\[(.*)\]/i, + decimal: /^\d+\.?\d*$/, + email: /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i, + escape: /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, + flags: /^\/(.*)\/(.*)?/, + integer: /^\-?\d+$/, + number: /^\-?\d*(\.\d+)?$/, + url: /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/i }, - debug: function() { - if(!settings.silent && settings.debug) { - if(settings.performance) { - module.performance.log(arguments); - } - else { - module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); - module.debug.apply(console, arguments); - } - } + + text: { + unspecifiedRule: 'Please enter a valid value', + unspecifiedField: 'This field' }, - verbose: function() { - if(!settings.silent && settings.verbose && settings.debug) { - if(settings.performance) { - module.performance.log(arguments); - } - else { - module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); - module.verbose.apply(console, arguments); - } - } + + prompt: { + empty: '{name} must have a value', + checked: '{name} must be checked', + email: '{name} must be a valid e-mail', + url: '{name} must be a valid url', + regExp: '{name} is not formatted correctly', + integer: '{name} must be an integer', + decimal: '{name} must be a decimal number', + number: '{name} must be set to a number', + is: '{name} must be "{ruleValue}"', + isExactly: '{name} must be exactly "{ruleValue}"', + not: '{name} cannot be set to "{ruleValue}"', + notExactly: '{name} cannot be set to exactly "{ruleValue}"', + contain: '{name} must contain "{ruleValue}"', + containExactly: '{name} must contain exactly "{ruleValue}"', + doesntContain: '{name} cannot contain "{ruleValue}"', + doesntContainExactly: '{name} cannot contain exactly "{ruleValue}"', + minLength: '{name} must be at least {ruleValue} characters', + length: '{name} must be at least {ruleValue} characters', + exactLength: '{name} must be exactly {ruleValue} characters', + maxLength: '{name} cannot be longer than {ruleValue} characters', + match: '{name} must match {ruleValue} field', + different: '{name} must have a different value than {ruleValue} field', + creditCard: '{name} must be a valid credit card number', + minCount: '{name} must have at least {ruleValue} choices', + exactCount: '{name} must have exactly {ruleValue} choices', + maxCount: '{name} must have {ruleValue} or less choices' }, - error: function() { - if(!settings.silent) { - module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); - module.error.apply(console, arguments); - } + + selector: { + checkbox: 'input[type="checkbox"], input[type="radio"]', + clear: '.clear', + field: 'input, textarea, select', + group: '.field', + input: 'input', + message: '.error.message', + prompt: '.prompt.label', + radio: 'input[type="radio"]', + reset: '.reset:not([type="reset"])', + submit: '.submit:not([type="submit"])', + uiCheckbox: '.ui.checkbox', + uiDropdown: '.ui.dropdown' }, - performance: { - log: function(message) { - var - currentTime, - executionTime, - previousTime - ; - if(settings.performance) { - currentTime = new Date().getTime(); - previousTime = time || currentTime; - executionTime = currentTime - previousTime; - time = currentTime; - performance.push({ - 'Name' : message[0], - 'Arguments' : [].slice.call(message, 1) || '', - 'Element' : element, - 'Execution Time' : executionTime - }); - } - clearTimeout(module.performance.timer); - module.performance.timer = setTimeout(module.performance.display, 500); - }, - display: function() { - var - title = settings.name + ':', - totalTime = 0 - ; - time = false; - clearTimeout(module.performance.timer); - $.each(performance, function(index, data) { - totalTime += data['Execution Time']; - }); - title += ' ' + totalTime + 'ms'; - if(moduleSelector) { - title += ' \'' + moduleSelector + '\''; - } - if($allModules.length > 1) { - title += ' ' + '(' + $allModules.length + ')'; - } - if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { - console.groupCollapsed(title); - if(console.table) { - console.table(performance); - } - else { - $.each(performance, function(index, data) { - console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); + + className: { + error: 'error', + label: 'ui prompt label', + pressed: 'down', + success: 'success' + }, + + error: { + identifier: 'You must specify a string identifier for each field', + method: 'The method you called is not defined.', + noRule: 'There is no rule matching the one you specified', + oldSyntax: 'Starting in 2.0 forms now only take a single settings object. Validation settings converted to new syntax automatically.' + }, + + templates: { + + // template that produces error message + error: function (errors) { + var + html = '
    ' + ; + $.each(errors, function (index, value) { + html += '
  • ' + value + '
  • '; }); - } - console.groupEnd(); + html += '
'; + return $(html); + }, + + // template that produces label + prompt: function (errors) { + return $('
') + .addClass('ui basic red pointing prompt label') + .html(errors[0]) + ; } - performance = []; - } }, - invoke: function(query, passedArguments, context) { - var - object = instance, - maxDepth, - found, - response - ; - passedArguments = passedArguments || queryArguments; - context = element || context; - if(typeof query == 'string' && object !== undefined) { - query = query.split(/[\. ]/); - maxDepth = query.length - 1; - $.each(query, function(depth, value) { - var camelCaseValue = (depth != maxDepth) - ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) - : query - ; - if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { - object = object[camelCaseValue]; - } - else if( object[camelCaseValue] !== undefined ) { - found = object[camelCaseValue]; - return false; - } - else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { - object = object[value]; - } - else if( object[value] !== undefined ) { - found = object[value]; - return false; - } - else { - return false; - } - }); - } - if( $.isFunction( found ) ) { - response = found.apply(context, passedArguments); - } - else if(found !== undefined) { - response = found; - } - if($.isArray(returnedValue)) { - returnedValue.push(response); - } - else if(returnedValue !== undefined) { - returnedValue = [returnedValue, response]; - } - else if(response !== undefined) { - returnedValue = response; - } - return found; - } - }; - module.initialize(); - }) - ; - return (returnedValue !== undefined) - ? returnedValue - : this - ; -}; + rules: { -$.fn.form.settings = { + // is not empty or blank string + empty: function (value) { + return !(value === undefined || '' === value || $.isArray(value) && value.length === 0); + }, - name : 'Form', - namespace : 'form', + // checkbox checked + checked: function () { + return ($(this).filter(':checked').length > 0); + }, - debug : false, - verbose : false, - performance : true, + // is most likely an email + email: function (value) { + return $.fn.form.settings.regExp.email.test(value); + }, - fields : false, + // value is most likely url + url: function (value) { + return $.fn.form.settings.regExp.url.test(value); + }, - keyboardShortcuts : true, - on : 'submit', - inline : false, + // matches specified regExp + regExp: function (value, regExp) { + if (regExp instanceof RegExp) { + return value.match(regExp); + } + var + regExpParts = regExp.match($.fn.form.settings.regExp.flags), + flags + ; + // regular expression specified as /baz/gi (flags) + if (regExpParts) { + regExp = (regExpParts.length >= 2) + ? regExpParts[1] + : regExp + ; + flags = (regExpParts.length >= 3) + ? regExpParts[2] + : '' + ; + } + return value.match(new RegExp(regExp, flags)); + }, - delay : 200, - revalidate : true, + // is valid integer or matches range + integer: function (value, range) { + var + intRegExp = $.fn.form.settings.regExp.integer, + min, + max, + parts + ; + if (!range || ['', '..'].indexOf(range) !== -1) { + // do nothing + } else if (range.indexOf('..') == -1) { + if (intRegExp.test(range)) { + min = max = range - 0; + } + } else { + parts = range.split('..', 2); + if (intRegExp.test(parts[0])) { + min = parts[0] - 0; + } + if (intRegExp.test(parts[1])) { + max = parts[1] - 0; + } + } + return ( + intRegExp.test(value) && + (min === undefined || value >= min) && + (max === undefined || value <= max) + ); + }, - transition : 'scale', - duration : 200, + // is valid number (with decimal) + decimal: function (value) { + return $.fn.form.settings.regExp.decimal.test(value); + }, - onValid : function() {}, - onInvalid : function() {}, - onSuccess : function() { return true; }, - onFailure : function() { return false; }, + // is valid number + number: function (value) { + return $.fn.form.settings.regExp.number.test(value); + }, - metadata : { - defaultValue : 'default', - validate : 'validate' - }, + // is value (case insensitive) + is: function (value, text) { + text = (typeof text == 'string') + ? text.toLowerCase() + : text + ; + value = (typeof value == 'string') + ? value.toLowerCase() + : value + ; + return (value == text); + }, - regExp: { - htmlID : /^[a-zA-Z][\w:.-]*$/g, - bracket : /\[(.*)\]/i, - decimal : /^\d+\.?\d*$/, - email : /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i, - escape : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, - flags : /^\/(.*)\/(.*)?/, - integer : /^\-?\d+$/, - number : /^\-?\d*(\.\d+)?$/, - url : /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/i - }, + // is value + isExactly: function (value, text) { + return (value == text); + }, - text: { - unspecifiedRule : 'Please enter a valid value', - unspecifiedField : 'This field' - }, + // value is not another value (case insensitive) + not: function (value, notValue) { + value = (typeof value == 'string') + ? value.toLowerCase() + : value + ; + notValue = (typeof notValue == 'string') + ? notValue.toLowerCase() + : notValue + ; + return (value != notValue); + }, - prompt: { - empty : '{name} must have a value', - checked : '{name} must be checked', - email : '{name} must be a valid e-mail', - url : '{name} must be a valid url', - regExp : '{name} is not formatted correctly', - integer : '{name} must be an integer', - decimal : '{name} must be a decimal number', - number : '{name} must be set to a number', - is : '{name} must be "{ruleValue}"', - isExactly : '{name} must be exactly "{ruleValue}"', - not : '{name} cannot be set to "{ruleValue}"', - notExactly : '{name} cannot be set to exactly "{ruleValue}"', - contain : '{name} must contain "{ruleValue}"', - containExactly : '{name} must contain exactly "{ruleValue}"', - doesntContain : '{name} cannot contain "{ruleValue}"', - doesntContainExactly : '{name} cannot contain exactly "{ruleValue}"', - minLength : '{name} must be at least {ruleValue} characters', - length : '{name} must be at least {ruleValue} characters', - exactLength : '{name} must be exactly {ruleValue} characters', - maxLength : '{name} cannot be longer than {ruleValue} characters', - match : '{name} must match {ruleValue} field', - different : '{name} must have a different value than {ruleValue} field', - creditCard : '{name} must be a valid credit card number', - minCount : '{name} must have at least {ruleValue} choices', - exactCount : '{name} must have exactly {ruleValue} choices', - maxCount : '{name} must have {ruleValue} or less choices' - }, + // value is not another value (case sensitive) + notExactly: function (value, notValue) { + return (value != notValue); + }, - selector : { - checkbox : 'input[type="checkbox"], input[type="radio"]', - clear : '.clear', - field : 'input, textarea, select', - group : '.field', - input : 'input', - message : '.error.message', - prompt : '.prompt.label', - radio : 'input[type="radio"]', - reset : '.reset:not([type="reset"])', - submit : '.submit:not([type="submit"])', - uiCheckbox : '.ui.checkbox', - uiDropdown : '.ui.dropdown' - }, + // value contains text (insensitive) + contains: function (value, text) { + // escape regex characters + text = text.replace($.fn.form.settings.regExp.escape, "\\$&"); + return (value.search(new RegExp(text, 'i')) !== -1); + }, - className : { - error : 'error', - label : 'ui prompt label', - pressed : 'down', - success : 'success' - }, + // value contains text (case sensitive) + containsExactly: function (value, text) { + // escape regex characters + text = text.replace($.fn.form.settings.regExp.escape, "\\$&"); + return (value.search(new RegExp(text)) !== -1); + }, - error: { - identifier : 'You must specify a string identifier for each field', - method : 'The method you called is not defined.', - noRule : 'There is no rule matching the one you specified', - oldSyntax : 'Starting in 2.0 forms now only take a single settings object. Validation settings converted to new syntax automatically.' - }, + // value contains text (insensitive) + doesntContain: function (value, text) { + // escape regex characters + text = text.replace($.fn.form.settings.regExp.escape, "\\$&"); + return (value.search(new RegExp(text, 'i')) === -1); + }, - templates: { + // value contains text (case sensitive) + doesntContainExactly: function (value, text) { + // escape regex characters + text = text.replace($.fn.form.settings.regExp.escape, "\\$&"); + return (value.search(new RegExp(text)) === -1); + }, - // template that produces error message - error: function(errors) { - var - html = '
    ' - ; - $.each(errors, function(index, value) { - html += '
  • ' + value + '
  • '; - }); - html += '
'; - return $(html); - }, + // is at least string length + minLength: function (value, requiredLength) { + return (value !== undefined) + ? (value.length >= requiredLength) + : false + ; + }, - // template that produces label - prompt: function(errors) { - return $('
') - .addClass('ui basic red pointing prompt label') - .html(errors[0]) - ; - } - }, + // see rls notes for 2.0.6 (this is a duplicate of minLength) + length: function (value, requiredLength) { + return (value !== undefined) + ? (value.length >= requiredLength) + : false + ; + }, - rules: { + // is exactly length + exactLength: function (value, requiredLength) { + return (value !== undefined) + ? (value.length == requiredLength) + : false + ; + }, - // is not empty or blank string - empty: function(value) { - return !(value === undefined || '' === value || $.isArray(value) && value.length === 0); - }, + // is less than length + maxLength: function (value, maxLength) { + return (value !== undefined) + ? (value.length <= maxLength) + : false + ; + }, - // checkbox checked - checked: function() { - return ($(this).filter(':checked').length > 0); - }, + // matches another field + match: function (value, identifier) { + var + $form = $(this), + matchingValue + ; + if ($('[data-validate="' + identifier + '"]').length > 0) { + matchingValue = $('[data-validate="' + identifier + '"]').val(); + } else if ($('#' + identifier).length > 0) { + matchingValue = $('#' + identifier).val(); + } else if ($('[name="' + identifier + '"]').length > 0) { + matchingValue = $('[name="' + identifier + '"]').val(); + } else if ($('[name="' + identifier + '[]"]').length > 0) { + matchingValue = $('[name="' + identifier + '[]"]'); + } + return (matchingValue !== undefined) + ? (value.toString() == matchingValue.toString()) + : false + ; + }, - // is most likely an email - email: function(value){ - return $.fn.form.settings.regExp.email.test(value); - }, + // different than another field + different: function (value, identifier) { + // use either id or name of field + var + $form = $(this), + matchingValue + ; + if ($('[data-validate="' + identifier + '"]').length > 0) { + matchingValue = $('[data-validate="' + identifier + '"]').val(); + } else if ($('#' + identifier).length > 0) { + matchingValue = $('#' + identifier).val(); + } else if ($('[name="' + identifier + '"]').length > 0) { + matchingValue = $('[name="' + identifier + '"]').val(); + } else if ($('[name="' + identifier + '[]"]').length > 0) { + matchingValue = $('[name="' + identifier + '[]"]'); + } + return (matchingValue !== undefined) + ? (value.toString() !== matchingValue.toString()) + : false + ; + }, - // value is most likely url - url: function(value) { - return $.fn.form.settings.regExp.url.test(value); - }, + creditCard: function (cardNumber, cardTypes) { + var + cards = { + visa: { + pattern: /^4/, + length: [16] + }, + amex: { + pattern: /^3[47]/, + length: [15] + }, + mastercard: { + pattern: /^5[1-5]/, + length: [16] + }, + discover: { + pattern: /^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)/, + length: [16] + }, + unionPay: { + pattern: /^(62|88)/, + length: [16, 17, 18, 19] + }, + jcb: { + pattern: /^35(2[89]|[3-8][0-9])/, + length: [16] + }, + maestro: { + pattern: /^(5018|5020|5038|6304|6759|676[1-3])/, + length: [12, 13, 14, 15, 16, 17, 18, 19] + }, + dinersClub: { + pattern: /^(30[0-5]|^36)/, + length: [14] + }, + laser: { + pattern: /^(6304|670[69]|6771)/, + length: [16, 17, 18, 19] + }, + visaElectron: { + pattern: /^(4026|417500|4508|4844|491(3|7))/, + length: [16] + } + }, + valid = {}, + validCard = false, + requiredTypes = (typeof cardTypes == 'string') + ? cardTypes.split(',') + : false, + unionPay, + validation + ; - // matches specified regExp - regExp: function(value, regExp) { - if(regExp instanceof RegExp) { - return value.match(regExp); - } - var - regExpParts = regExp.match($.fn.form.settings.regExp.flags), - flags - ; - // regular expression specified as /baz/gi (flags) - if(regExpParts) { - regExp = (regExpParts.length >= 2) - ? regExpParts[1] - : regExp - ; - flags = (regExpParts.length >= 3) - ? regExpParts[2] - : '' - ; - } - return value.match( new RegExp(regExp, flags) ); - }, + if (typeof cardNumber !== 'string' || cardNumber.length === 0) { + return; + } - // is valid integer or matches range - integer: function(value, range) { - var - intRegExp = $.fn.form.settings.regExp.integer, - min, - max, - parts - ; - if( !range || ['', '..'].indexOf(range) !== -1) { - // do nothing - } - else if(range.indexOf('..') == -1) { - if(intRegExp.test(range)) { - min = max = range - 0; - } - } - else { - parts = range.split('..', 2); - if(intRegExp.test(parts[0])) { - min = parts[0] - 0; - } - if(intRegExp.test(parts[1])) { - max = parts[1] - 0; - } - } - return ( - intRegExp.test(value) && - (min === undefined || value >= min) && - (max === undefined || value <= max) - ); - }, + // allow dashes in card + cardNumber = cardNumber.replace(/[\-]/g, ''); - // is valid number (with decimal) - decimal: function(value) { - return $.fn.form.settings.regExp.decimal.test(value); - }, + // verify card types + if (requiredTypes) { + $.each(requiredTypes, function (index, type) { + // verify each card type + validation = cards[type]; + if (validation) { + valid = { + length: ($.inArray(cardNumber.length, validation.length) !== -1), + pattern: (cardNumber.search(validation.pattern) !== -1) + }; + if (valid.length && valid.pattern) { + validCard = true; + } + } + }); - // is valid number - number: function(value) { - return $.fn.form.settings.regExp.number.test(value); - }, + if (!validCard) { + return false; + } + } - // is value (case insensitive) - is: function(value, text) { - text = (typeof text == 'string') - ? text.toLowerCase() - : text - ; - value = (typeof value == 'string') - ? value.toLowerCase() - : value - ; - return (value == text); - }, + // skip luhn for UnionPay + unionPay = { + number: ($.inArray(cardNumber.length, cards.unionPay.length) !== -1), + pattern: (cardNumber.search(cards.unionPay.pattern) !== -1) + }; + if (unionPay.number && unionPay.pattern) { + return true; + } - // is value - isExactly: function(value, text) { - return (value == text); - }, + // verify luhn, adapted from + var + length = cardNumber.length, + multiple = 0, + producedValue = [ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + [0, 2, 4, 6, 8, 1, 3, 5, 7, 9] + ], + sum = 0 + ; + while (length--) { + sum += producedValue[multiple][parseInt(cardNumber.charAt(length), 10)]; + multiple ^= 1; + } + return (sum % 10 === 0 && sum > 0); + }, - // value is not another value (case insensitive) - not: function(value, notValue) { - value = (typeof value == 'string') - ? value.toLowerCase() - : value - ; - notValue = (typeof notValue == 'string') - ? notValue.toLowerCase() - : notValue - ; - return (value != notValue); - }, + minCount: function (value, minCount) { + if (minCount == 0) { + return true; + } + if (minCount == 1) { + return (value !== ''); + } + return (value.split(',').length >= minCount); + }, - // value is not another value (case sensitive) - notExactly: function(value, notValue) { - return (value != notValue); - }, + exactCount: function (value, exactCount) { + if (exactCount == 0) { + return (value === ''); + } + if (exactCount == 1) { + return (value !== '' && value.search(',') === -1); + } + return (value.split(',').length == exactCount); + }, - // value contains text (insensitive) - contains: function(value, text) { - // escape regex characters - text = text.replace($.fn.form.settings.regExp.escape, "\\$&"); - return (value.search( new RegExp(text, 'i') ) !== -1); - }, - - // value contains text (case sensitive) - containsExactly: function(value, text) { - // escape regex characters - text = text.replace($.fn.form.settings.regExp.escape, "\\$&"); - return (value.search( new RegExp(text) ) !== -1); - }, - - // value contains text (insensitive) - doesntContain: function(value, text) { - // escape regex characters - text = text.replace($.fn.form.settings.regExp.escape, "\\$&"); - return (value.search( new RegExp(text, 'i') ) === -1); - }, - - // value contains text (case sensitive) - doesntContainExactly: function(value, text) { - // escape regex characters - text = text.replace($.fn.form.settings.regExp.escape, "\\$&"); - return (value.search( new RegExp(text) ) === -1); - }, - - // is at least string length - minLength: function(value, requiredLength) { - return (value !== undefined) - ? (value.length >= requiredLength) - : false - ; - }, - - // see rls notes for 2.0.6 (this is a duplicate of minLength) - length: function(value, requiredLength) { - return (value !== undefined) - ? (value.length >= requiredLength) - : false - ; - }, - - // is exactly length - exactLength: function(value, requiredLength) { - return (value !== undefined) - ? (value.length == requiredLength) - : false - ; - }, - - // is less than length - maxLength: function(value, maxLength) { - return (value !== undefined) - ? (value.length <= maxLength) - : false - ; - }, - - // matches another field - match: function(value, identifier) { - var - $form = $(this), - matchingValue - ; - if( $('[data-validate="'+ identifier +'"]').length > 0 ) { - matchingValue = $('[data-validate="'+ identifier +'"]').val(); - } - else if($('#' + identifier).length > 0) { - matchingValue = $('#' + identifier).val(); - } - else if($('[name="' + identifier +'"]').length > 0) { - matchingValue = $('[name="' + identifier + '"]').val(); - } - else if( $('[name="' + identifier +'[]"]').length > 0 ) { - matchingValue = $('[name="' + identifier +'[]"]'); - } - return (matchingValue !== undefined) - ? ( value.toString() == matchingValue.toString() ) - : false - ; - }, - - // different than another field - different: function(value, identifier) { - // use either id or name of field - var - $form = $(this), - matchingValue - ; - if( $('[data-validate="'+ identifier +'"]').length > 0 ) { - matchingValue = $('[data-validate="'+ identifier +'"]').val(); - } - else if($('#' + identifier).length > 0) { - matchingValue = $('#' + identifier).val(); - } - else if($('[name="' + identifier +'"]').length > 0) { - matchingValue = $('[name="' + identifier + '"]').val(); - } - else if( $('[name="' + identifier +'[]"]').length > 0 ) { - matchingValue = $('[name="' + identifier +'[]"]'); - } - return (matchingValue !== undefined) - ? ( value.toString() !== matchingValue.toString() ) - : false - ; - }, - - creditCard: function(cardNumber, cardTypes) { - var - cards = { - visa: { - pattern : /^4/, - length : [16] - }, - amex: { - pattern : /^3[47]/, - length : [15] - }, - mastercard: { - pattern : /^5[1-5]/, - length : [16] - }, - discover: { - pattern : /^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)/, - length : [16] - }, - unionPay: { - pattern : /^(62|88)/, - length : [16, 17, 18, 19] - }, - jcb: { - pattern : /^35(2[89]|[3-8][0-9])/, - length : [16] - }, - maestro: { - pattern : /^(5018|5020|5038|6304|6759|676[1-3])/, - length : [12, 13, 14, 15, 16, 17, 18, 19] - }, - dinersClub: { - pattern : /^(30[0-5]|^36)/, - length : [14] - }, - laser: { - pattern : /^(6304|670[69]|6771)/, - length : [16, 17, 18, 19] - }, - visaElectron: { - pattern : /^(4026|417500|4508|4844|491(3|7))/, - length : [16] - } - }, - valid = {}, - validCard = false, - requiredTypes = (typeof cardTypes == 'string') - ? cardTypes.split(',') - : false, - unionPay, - validation - ; - - if(typeof cardNumber !== 'string' || cardNumber.length === 0) { - return; - } - - // allow dashes in card - cardNumber = cardNumber.replace(/[\-]/g, ''); - - // verify card types - if(requiredTypes) { - $.each(requiredTypes, function(index, type){ - // verify each card type - validation = cards[type]; - if(validation) { - valid = { - length : ($.inArray(cardNumber.length, validation.length) !== -1), - pattern : (cardNumber.search(validation.pattern) !== -1) - }; - if(valid.length && valid.pattern) { - validCard = true; + maxCount: function (value, maxCount) { + if (maxCount == 0) { + return false; + } + if (maxCount == 1) { + return (value.search(',') === -1); + } + return (value.split(',').length <= maxCount); } - } - }); - - if(!validCard) { - return false; } - } - // skip luhn for UnionPay - unionPay = { - number : ($.inArray(cardNumber.length, cards.unionPay.length) !== -1), - pattern : (cardNumber.search(cards.unionPay.pattern) !== -1) - }; - if(unionPay.number && unionPay.pattern) { - return true; - } + }; - // verify luhn, adapted from - var - length = cardNumber.length, - multiple = 0, - producedValue = [ - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], - [0, 2, 4, 6, 8, 1, 3, 5, 7, 9] - ], - sum = 0 - ; - while (length--) { - sum += producedValue[multiple][parseInt(cardNumber.charAt(length), 10)]; - multiple ^= 1; - } - return (sum % 10 === 0 && sum > 0); - }, - - minCount: function(value, minCount) { - if(minCount == 0) { - return true; - } - if(minCount == 1) { - return (value !== ''); - } - return (value.split(',').length >= minCount); - }, - - exactCount: function(value, exactCount) { - if(exactCount == 0) { - return (value === ''); - } - if(exactCount == 1) { - return (value !== '' && value.search(',') === -1); - } - return (value.split(',').length == exactCount); - }, - - maxCount: function(value, maxCount) { - if(maxCount == 0) { - return false; - } - if(maxCount == 1) { - return (value.search(',') === -1); - } - return (value.split(',').length <= maxCount); - } - } - -}; - -})( jQuery, window, document ); +})(jQuery, window, document); /*! * # Semantic UI 2.4.2 - Accordion @@ -2215,606 +2160,592 @@ $.fn.form.settings = { ;(function ($, window, document, undefined) { -'use strict'; + 'use strict'; -window = (typeof window != 'undefined' && window.Math == Math) - ? window - : (typeof self != 'undefined' && self.Math == Math) - ? self - : Function('return this')() -; + window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() + ; -$.fn.accordion = function(parameters) { - var - $allModules = $(this), + $.fn.accordion = function (parameters) { + var + $allModules = $(this), - time = new Date().getTime(), - performance = [], + time = new Date().getTime(), + performance = [], - query = arguments[0], - methodInvoked = (typeof query == 'string'), - queryArguments = [].slice.call(arguments, 1), + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), - requestAnimationFrame = window.requestAnimationFrame - || window.mozRequestAnimationFrame - || window.webkitRequestAnimationFrame - || window.msRequestAnimationFrame - || function(callback) { setTimeout(callback, 0); }, + requestAnimationFrame = window.requestAnimationFrame + || window.mozRequestAnimationFrame + || window.webkitRequestAnimationFrame + || window.msRequestAnimationFrame + || function (callback) { + setTimeout(callback, 0); + }, - returnedValue - ; - $allModules - .each(function() { - var - settings = ( $.isPlainObject(parameters) ) - ? $.extend(true, {}, $.fn.accordion.settings, parameters) - : $.extend({}, $.fn.accordion.settings), + returnedValue + ; + $allModules + .each(function () { + var + settings = ($.isPlainObject(parameters)) + ? $.extend(true, {}, $.fn.accordion.settings, parameters) + : $.extend({}, $.fn.accordion.settings), - className = settings.className, - namespace = settings.namespace, - selector = settings.selector, - error = settings.error, + className = settings.className, + namespace = settings.namespace, + selector = settings.selector, + error = settings.error, - eventNamespace = '.' + namespace, - moduleNamespace = 'module-' + namespace, - moduleSelector = $allModules.selector || '', + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + moduleSelector = $allModules.selector || '', - $module = $(this), - $title = $module.find(selector.title), - $content = $module.find(selector.content), + $module = $(this), + $title = $module.find(selector.title), + $content = $module.find(selector.content), - element = this, - instance = $module.data(moduleNamespace), - observer, - module - ; + element = this, + instance = $module.data(moduleNamespace), + observer, + module + ; - module = { + module = { - initialize: function() { - module.debug('Initializing', $module); - module.bind.events(); - if(settings.observeChanges) { - module.observeChanges(); - } - module.instantiate(); - }, + initialize: function () { + module.debug('Initializing', $module); + module.bind.events(); + if (settings.observeChanges) { + module.observeChanges(); + } + module.instantiate(); + }, - instantiate: function() { - instance = module; - $module - .data(moduleNamespace, module) - ; - }, + instantiate: function () { + instance = module; + $module + .data(moduleNamespace, module) + ; + }, - destroy: function() { - module.debug('Destroying previous instance', $module); - $module - .off(eventNamespace) - .removeData(moduleNamespace) - ; - }, + destroy: function () { + module.debug('Destroying previous instance', $module); + $module + .off(eventNamespace) + .removeData(moduleNamespace) + ; + }, - refresh: function() { - $title = $module.find(selector.title); - $content = $module.find(selector.content); - }, + refresh: function () { + $title = $module.find(selector.title); + $content = $module.find(selector.content); + }, - observeChanges: function() { - if('MutationObserver' in window) { - observer = new MutationObserver(function(mutations) { - module.debug('DOM tree modified, updating selector cache'); - module.refresh(); - }); - observer.observe(element, { - childList : true, - subtree : true - }); - module.debug('Setting up mutation observer', observer); - } - }, + observeChanges: function () { + if ('MutationObserver' in window) { + observer = new MutationObserver(function (mutations) { + module.debug('DOM tree modified, updating selector cache'); + module.refresh(); + }); + observer.observe(element, { + childList: true, + subtree: true + }); + module.debug('Setting up mutation observer', observer); + } + }, - bind: { - events: function() { - module.debug('Binding delegated events'); - $module - .on(settings.on + eventNamespace, selector.trigger, module.event.click) - ; - } - }, + bind: { + events: function () { + module.debug('Binding delegated events'); + $module + .on(settings.on + eventNamespace, selector.trigger, module.event.click) + ; + } + }, - event: { - click: function() { - module.toggle.call(this); - } - }, + event: { + click: function () { + module.toggle.call(this); + } + }, - toggle: function(query) { - var - $activeTitle = (query !== undefined) - ? (typeof query === 'number') - ? $title.eq(query) - : $(query).closest(selector.title) - : $(this).closest(selector.title), - $activeContent = $activeTitle.next($content), - isAnimating = $activeContent.hasClass(className.animating), - isActive = $activeContent.hasClass(className.active), - isOpen = (isActive && !isAnimating), - isOpening = (!isActive && isAnimating) - ; - module.debug('Toggling visibility of content', $activeTitle); - if(isOpen || isOpening) { - if(settings.collapsible) { - module.close.call($activeTitle); - } - else { - module.debug('Cannot close accordion content collapsing is disabled'); - } - } - else { - module.open.call($activeTitle); - } - }, + toggle: function (query) { + var + $activeTitle = (query !== undefined) + ? (typeof query === 'number') + ? $title.eq(query) + : $(query).closest(selector.title) + : $(this).closest(selector.title), + $activeContent = $activeTitle.next($content), + isAnimating = $activeContent.hasClass(className.animating), + isActive = $activeContent.hasClass(className.active), + isOpen = (isActive && !isAnimating), + isOpening = (!isActive && isAnimating) + ; + module.debug('Toggling visibility of content', $activeTitle); + if (isOpen || isOpening) { + if (settings.collapsible) { + module.close.call($activeTitle); + } else { + module.debug('Cannot close accordion content collapsing is disabled'); + } + } else { + module.open.call($activeTitle); + } + }, - open: function(query) { - var - $activeTitle = (query !== undefined) - ? (typeof query === 'number') - ? $title.eq(query) - : $(query).closest(selector.title) - : $(this).closest(selector.title), - $activeContent = $activeTitle.next($content), - isAnimating = $activeContent.hasClass(className.animating), - isActive = $activeContent.hasClass(className.active), - isOpen = (isActive || isAnimating) - ; - if(isOpen) { - module.debug('Accordion already open, skipping', $activeContent); - return; - } - module.debug('Opening accordion content', $activeTitle); - settings.onOpening.call($activeContent); - settings.onChanging.call($activeContent); - if(settings.exclusive) { - module.closeOthers.call($activeTitle); - } - $activeTitle - .addClass(className.active) - ; - $activeContent - .stop(true, true) - .addClass(className.animating) - ; - if(settings.animateChildren) { - if($.fn.transition !== undefined && $module.transition('is supported')) { - $activeContent - .children() - .transition({ - animation : 'fade in', - queue : false, - useFailSafe : true, - debug : settings.debug, - verbose : settings.verbose, - duration : settings.duration - }) - ; - } - else { - $activeContent - .children() - .stop(true, true) - .animate({ - opacity: 1 - }, settings.duration, module.resetOpacity) - ; - } - } - $activeContent - .slideDown(settings.duration, settings.easing, function() { - $activeContent - .removeClass(className.animating) - .addClass(className.active) - ; - module.reset.display.call(this); - settings.onOpen.call(this); - settings.onChange.call(this); + open: function (query) { + var + $activeTitle = (query !== undefined) + ? (typeof query === 'number') + ? $title.eq(query) + : $(query).closest(selector.title) + : $(this).closest(selector.title), + $activeContent = $activeTitle.next($content), + isAnimating = $activeContent.hasClass(className.animating), + isActive = $activeContent.hasClass(className.active), + isOpen = (isActive || isAnimating) + ; + if (isOpen) { + module.debug('Accordion already open, skipping', $activeContent); + return; + } + module.debug('Opening accordion content', $activeTitle); + settings.onOpening.call($activeContent); + settings.onChanging.call($activeContent); + if (settings.exclusive) { + module.closeOthers.call($activeTitle); + } + $activeTitle + .addClass(className.active) + ; + $activeContent + .stop(true, true) + .addClass(className.animating) + ; + if (settings.animateChildren) { + if ($.fn.transition !== undefined && $module.transition('is supported')) { + $activeContent + .children() + .transition({ + animation: 'fade in', + queue: false, + useFailSafe: true, + debug: settings.debug, + verbose: settings.verbose, + duration: settings.duration + }) + ; + } else { + $activeContent + .children() + .stop(true, true) + .animate({ + opacity: 1 + }, settings.duration, module.resetOpacity) + ; + } + } + $activeContent + .slideDown(settings.duration, settings.easing, function () { + $activeContent + .removeClass(className.animating) + .addClass(className.active) + ; + module.reset.display.call(this); + settings.onOpen.call(this); + settings.onChange.call(this); + }) + ; + }, + + close: function (query) { + var + $activeTitle = (query !== undefined) + ? (typeof query === 'number') + ? $title.eq(query) + : $(query).closest(selector.title) + : $(this).closest(selector.title), + $activeContent = $activeTitle.next($content), + isAnimating = $activeContent.hasClass(className.animating), + isActive = $activeContent.hasClass(className.active), + isOpening = (!isActive && isAnimating), + isClosing = (isActive && isAnimating) + ; + if ((isActive || isOpening) && !isClosing) { + module.debug('Closing accordion content', $activeContent); + settings.onClosing.call($activeContent); + settings.onChanging.call($activeContent); + $activeTitle + .removeClass(className.active) + ; + $activeContent + .stop(true, true) + .addClass(className.animating) + ; + if (settings.animateChildren) { + if ($.fn.transition !== undefined && $module.transition('is supported')) { + $activeContent + .children() + .transition({ + animation: 'fade out', + queue: false, + useFailSafe: true, + debug: settings.debug, + verbose: settings.verbose, + duration: settings.duration + }) + ; + } else { + $activeContent + .children() + .stop(true, true) + .animate({ + opacity: 0 + }, settings.duration, module.resetOpacity) + ; + } + } + $activeContent + .slideUp(settings.duration, settings.easing, function () { + $activeContent + .removeClass(className.animating) + .removeClass(className.active) + ; + module.reset.display.call(this); + settings.onClose.call(this); + settings.onChange.call(this); + }) + ; + } + }, + + closeOthers: function (index) { + var + $activeTitle = (index !== undefined) + ? $title.eq(index) + : $(this).closest(selector.title), + $parentTitles = $activeTitle.parents(selector.content).prev(selector.title), + $activeAccordion = $activeTitle.closest(selector.accordion), + activeSelector = selector.title + '.' + className.active + ':visible', + activeContent = selector.content + '.' + className.active + ':visible', + $openTitles, + $nestedTitles, + $openContents + ; + if (settings.closeNested) { + $openTitles = $activeAccordion.find(activeSelector).not($parentTitles); + $openContents = $openTitles.next($content); + } else { + $openTitles = $activeAccordion.find(activeSelector).not($parentTitles); + $nestedTitles = $activeAccordion.find(activeContent).find(activeSelector).not($parentTitles); + $openTitles = $openTitles.not($nestedTitles); + $openContents = $openTitles.next($content); + } + if (($openTitles.length > 0)) { + module.debug('Exclusive enabled, closing other content', $openTitles); + $openTitles + .removeClass(className.active) + ; + $openContents + .removeClass(className.animating) + .stop(true, true) + ; + if (settings.animateChildren) { + if ($.fn.transition !== undefined && $module.transition('is supported')) { + $openContents + .children() + .transition({ + animation: 'fade out', + useFailSafe: true, + debug: settings.debug, + verbose: settings.verbose, + duration: settings.duration + }) + ; + } else { + $openContents + .children() + .stop(true, true) + .animate({ + opacity: 0 + }, settings.duration, module.resetOpacity) + ; + } + } + $openContents + .slideUp(settings.duration, settings.easing, function () { + $(this).removeClass(className.active); + module.reset.display.call(this); + }) + ; + } + }, + + reset: { + + display: function () { + module.verbose('Removing inline display from element', this); + $(this).css('display', ''); + if ($(this).attr('style') === '') { + $(this) + .attr('style', '') + .removeAttr('style') + ; + } + }, + + opacity: function () { + module.verbose('Removing inline opacity from element', this); + $(this).css('opacity', ''); + if ($(this).attr('style') === '') { + $(this) + .attr('style', '') + .removeAttr('style') + ; + } + }, + + }, + + setting: function (name, value) { + module.debug('Changing setting', name, value); + if ($.isPlainObject(name)) { + $.extend(true, settings, name); + } else if (value !== undefined) { + if ($.isPlainObject(settings[name])) { + $.extend(true, settings[name], value); + } else { + settings[name] = value; + } + } else { + return settings[name]; + } + }, + internal: function (name, value) { + module.debug('Changing internal', name, value); + if (value !== undefined) { + if ($.isPlainObject(name)) { + $.extend(true, module, name); + } else { + module[name] = value; + } + } else { + return module[name]; + } + }, + debug: function () { + if (!settings.silent && settings.debug) { + if (settings.performance) { + module.performance.log(arguments); + } else { + module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.debug.apply(console, arguments); + } + } + }, + verbose: function () { + if (!settings.silent && settings.verbose && settings.debug) { + if (settings.performance) { + module.performance.log(arguments); + } else { + module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.verbose.apply(console, arguments); + } + } + }, + error: function () { + if (!settings.silent) { + module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); + module.error.apply(console, arguments); + } + }, + performance: { + log: function (message) { + var + currentTime, + executionTime, + previousTime + ; + if (settings.performance) { + currentTime = new Date().getTime(); + previousTime = time || currentTime; + executionTime = currentTime - previousTime; + time = currentTime; + performance.push({ + 'Name': message[0], + 'Arguments': [].slice.call(message, 1) || '', + 'Element': element, + 'Execution Time': executionTime + }); + } + clearTimeout(module.performance.timer); + module.performance.timer = setTimeout(module.performance.display, 500); + }, + display: function () { + var + title = settings.name + ':', + totalTime = 0 + ; + time = false; + clearTimeout(module.performance.timer); + $.each(performance, function (index, data) { + totalTime += data['Execution Time']; + }); + title += ' ' + totalTime + 'ms'; + if (moduleSelector) { + title += ' \'' + moduleSelector + '\''; + } + if ((console.group !== undefined || console.table !== undefined) && performance.length > 0) { + console.groupCollapsed(title); + if (console.table) { + console.table(performance); + } else { + $.each(performance, function (index, data) { + console.log(data['Name'] + ': ' + data['Execution Time'] + 'ms'); + }); + } + console.groupEnd(); + } + performance = []; + } + }, + invoke: function (query, passedArguments, context) { + var + object = instance, + maxDepth, + found, + response + ; + passedArguments = passedArguments || queryArguments; + context = element || context; + if (typeof query == 'string' && object !== undefined) { + query = query.split(/[\. ]/); + maxDepth = query.length - 1; + $.each(query, function (depth, value) { + var camelCaseValue = (depth != maxDepth) + ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) + : query + ; + if ($.isPlainObject(object[camelCaseValue]) && (depth != maxDepth)) { + object = object[camelCaseValue]; + } else if (object[camelCaseValue] !== undefined) { + found = object[camelCaseValue]; + return false; + } else if ($.isPlainObject(object[value]) && (depth != maxDepth)) { + object = object[value]; + } else if (object[value] !== undefined) { + found = object[value]; + return false; + } else { + module.error(error.method, query); + return false; + } + }); + } + if ($.isFunction(found)) { + response = found.apply(context, passedArguments); + } else if (found !== undefined) { + response = found; + } + if ($.isArray(returnedValue)) { + returnedValue.push(response); + } else if (returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } else if (response !== undefined) { + returnedValue = response; + } + return found; + } + }; + if (methodInvoked) { + if (instance === undefined) { + module.initialize(); + } + module.invoke(query); + } else { + if (instance !== undefined) { + instance.invoke('destroy'); + } + module.initialize(); + } }) - ; + ; + return (returnedValue !== undefined) + ? returnedValue + : this + ; + }; + + $.fn.accordion.settings = { + + name: 'Accordion', + namespace: 'accordion', + + silent: false, + debug: false, + verbose: false, + performance: true, + + on: 'click', // event on title that opens accordion + + observeChanges: true, // whether accordion should automatically refresh on DOM insertion + + exclusive: true, // whether a single accordion content panel should be open at once + collapsible: true, // whether accordion content can be closed + closeNested: false, // whether nested content should be closed when a panel is closed + animateChildren: true, // whether children opacity should be animated + + duration: 350, // duration of animation + easing: 'easeOutQuad', // easing equation for animation + + onOpening: function () { + }, // callback before open animation + onClosing: function () { + }, // callback before closing animation + onChanging: function () { + }, // callback before closing or opening animation + + onOpen: function () { + }, // callback after open animation + onClose: function () { + }, // callback after closing animation + onChange: function () { + }, // callback after closing or opening animation + + error: { + method: 'The method you called is not defined' }, - close: function(query) { - var - $activeTitle = (query !== undefined) - ? (typeof query === 'number') - ? $title.eq(query) - : $(query).closest(selector.title) - : $(this).closest(selector.title), - $activeContent = $activeTitle.next($content), - isAnimating = $activeContent.hasClass(className.animating), - isActive = $activeContent.hasClass(className.active), - isOpening = (!isActive && isAnimating), - isClosing = (isActive && isAnimating) - ; - if((isActive || isOpening) && !isClosing) { - module.debug('Closing accordion content', $activeContent); - settings.onClosing.call($activeContent); - settings.onChanging.call($activeContent); - $activeTitle - .removeClass(className.active) - ; - $activeContent - .stop(true, true) - .addClass(className.animating) - ; - if(settings.animateChildren) { - if($.fn.transition !== undefined && $module.transition('is supported')) { - $activeContent - .children() - .transition({ - animation : 'fade out', - queue : false, - useFailSafe : true, - debug : settings.debug, - verbose : settings.verbose, - duration : settings.duration - }) - ; - } - else { - $activeContent - .children() - .stop(true, true) - .animate({ - opacity: 0 - }, settings.duration, module.resetOpacity) - ; - } - } - $activeContent - .slideUp(settings.duration, settings.easing, function() { - $activeContent - .removeClass(className.animating) - .removeClass(className.active) - ; - module.reset.display.call(this); - settings.onClose.call(this); - settings.onChange.call(this); - }) - ; - } + className: { + active: 'active', + animating: 'animating' }, - closeOthers: function(index) { - var - $activeTitle = (index !== undefined) - ? $title.eq(index) - : $(this).closest(selector.title), - $parentTitles = $activeTitle.parents(selector.content).prev(selector.title), - $activeAccordion = $activeTitle.closest(selector.accordion), - activeSelector = selector.title + '.' + className.active + ':visible', - activeContent = selector.content + '.' + className.active + ':visible', - $openTitles, - $nestedTitles, - $openContents - ; - if(settings.closeNested) { - $openTitles = $activeAccordion.find(activeSelector).not($parentTitles); - $openContents = $openTitles.next($content); - } - else { - $openTitles = $activeAccordion.find(activeSelector).not($parentTitles); - $nestedTitles = $activeAccordion.find(activeContent).find(activeSelector).not($parentTitles); - $openTitles = $openTitles.not($nestedTitles); - $openContents = $openTitles.next($content); - } - if( ($openTitles.length > 0) ) { - module.debug('Exclusive enabled, closing other content', $openTitles); - $openTitles - .removeClass(className.active) - ; - $openContents - .removeClass(className.animating) - .stop(true, true) - ; - if(settings.animateChildren) { - if($.fn.transition !== undefined && $module.transition('is supported')) { - $openContents - .children() - .transition({ - animation : 'fade out', - useFailSafe : true, - debug : settings.debug, - verbose : settings.verbose, - duration : settings.duration - }) - ; - } - else { - $openContents - .children() - .stop(true, true) - .animate({ - opacity: 0 - }, settings.duration, module.resetOpacity) - ; - } - } - $openContents - .slideUp(settings.duration , settings.easing, function() { - $(this).removeClass(className.active); - module.reset.display.call(this); - }) - ; - } - }, - - reset: { - - display: function() { - module.verbose('Removing inline display from element', this); - $(this).css('display', ''); - if( $(this).attr('style') === '') { - $(this) - .attr('style', '') - .removeAttr('style') - ; - } - }, - - opacity: function() { - module.verbose('Removing inline opacity from element', this); - $(this).css('opacity', ''); - if( $(this).attr('style') === '') { - $(this) - .attr('style', '') - .removeAttr('style') - ; - } - }, - - }, - - setting: function(name, value) { - module.debug('Changing setting', name, value); - if( $.isPlainObject(name) ) { - $.extend(true, settings, name); - } - else if(value !== undefined) { - if($.isPlainObject(settings[name])) { - $.extend(true, settings[name], value); - } - else { - settings[name] = value; - } - } - else { - return settings[name]; - } - }, - internal: function(name, value) { - module.debug('Changing internal', name, value); - if(value !== undefined) { - if( $.isPlainObject(name) ) { - $.extend(true, module, name); - } - else { - module[name] = value; - } - } - else { - return module[name]; - } - }, - debug: function() { - if(!settings.silent && settings.debug) { - if(settings.performance) { - module.performance.log(arguments); - } - else { - module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); - module.debug.apply(console, arguments); - } - } - }, - verbose: function() { - if(!settings.silent && settings.verbose && settings.debug) { - if(settings.performance) { - module.performance.log(arguments); - } - else { - module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); - module.verbose.apply(console, arguments); - } - } - }, - error: function() { - if(!settings.silent) { - module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); - module.error.apply(console, arguments); - } - }, - performance: { - log: function(message) { - var - currentTime, - executionTime, - previousTime - ; - if(settings.performance) { - currentTime = new Date().getTime(); - previousTime = time || currentTime; - executionTime = currentTime - previousTime; - time = currentTime; - performance.push({ - 'Name' : message[0], - 'Arguments' : [].slice.call(message, 1) || '', - 'Element' : element, - 'Execution Time' : executionTime - }); - } - clearTimeout(module.performance.timer); - module.performance.timer = setTimeout(module.performance.display, 500); - }, - display: function() { - var - title = settings.name + ':', - totalTime = 0 - ; - time = false; - clearTimeout(module.performance.timer); - $.each(performance, function(index, data) { - totalTime += data['Execution Time']; - }); - title += ' ' + totalTime + 'ms'; - if(moduleSelector) { - title += ' \'' + moduleSelector + '\''; - } - if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { - console.groupCollapsed(title); - if(console.table) { - console.table(performance); - } - else { - $.each(performance, function(index, data) { - console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); - }); - } - console.groupEnd(); - } - performance = []; - } - }, - invoke: function(query, passedArguments, context) { - var - object = instance, - maxDepth, - found, - response - ; - passedArguments = passedArguments || queryArguments; - context = element || context; - if(typeof query == 'string' && object !== undefined) { - query = query.split(/[\. ]/); - maxDepth = query.length - 1; - $.each(query, function(depth, value) { - var camelCaseValue = (depth != maxDepth) - ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) - : query - ; - if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { - object = object[camelCaseValue]; - } - else if( object[camelCaseValue] !== undefined ) { - found = object[camelCaseValue]; - return false; - } - else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { - object = object[value]; - } - else if( object[value] !== undefined ) { - found = object[value]; - return false; - } - else { - module.error(error.method, query); - return false; - } - }); - } - if ( $.isFunction( found ) ) { - response = found.apply(context, passedArguments); - } - else if(found !== undefined) { - response = found; - } - if($.isArray(returnedValue)) { - returnedValue.push(response); - } - else if(returnedValue !== undefined) { - returnedValue = [returnedValue, response]; - } - else if(response !== undefined) { - returnedValue = response; - } - return found; + selector: { + accordion: '.accordion', + title: '.title', + trigger: '.title', + content: '.content' } - }; - if(methodInvoked) { - if(instance === undefined) { - module.initialize(); - } - module.invoke(query); - } - else { - if(instance !== undefined) { - instance.invoke('destroy'); - } - module.initialize(); - } - }) - ; - return (returnedValue !== undefined) - ? returnedValue - : this - ; -}; -$.fn.accordion.settings = { - - name : 'Accordion', - namespace : 'accordion', - - silent : false, - debug : false, - verbose : false, - performance : true, - - on : 'click', // event on title that opens accordion - - observeChanges : true, // whether accordion should automatically refresh on DOM insertion - - exclusive : true, // whether a single accordion content panel should be open at once - collapsible : true, // whether accordion content can be closed - closeNested : false, // whether nested content should be closed when a panel is closed - animateChildren : true, // whether children opacity should be animated - - duration : 350, // duration of animation - easing : 'easeOutQuad', // easing equation for animation - - onOpening : function(){}, // callback before open animation - onClosing : function(){}, // callback before closing animation - onChanging : function(){}, // callback before closing or opening animation - - onOpen : function(){}, // callback after open animation - onClose : function(){}, // callback after closing animation - onChange : function(){}, // callback after closing or opening animation - - error: { - method : 'The method you called is not defined' - }, - - className : { - active : 'active', - animating : 'animating' - }, - - selector : { - accordion : '.accordion', - title : '.title', - trigger : '.title', - content : '.content' - } - -}; + }; // Adds easing -$.extend( $.easing, { - easeOutQuad: function (x, t, b, c, d) { - return -c *(t/=d)*(t-2) + b; - } -}); + $.extend($.easing, { + easeOutQuad: function (x, t, b, c, d) { + return -c * (t /= d) * (t - 2) + b; + } + }); -})( jQuery, window, document ); +})(jQuery, window, document); /*! @@ -2829,825 +2760,815 @@ $.extend( $.easing, { ;(function ($, window, document, undefined) { -'use strict'; + 'use strict'; -window = (typeof window != 'undefined' && window.Math == Math) - ? window - : (typeof self != 'undefined' && self.Math == Math) - ? self - : Function('return this')() -; + window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() + ; -$.fn.checkbox = function(parameters) { - var - $allModules = $(this), - moduleSelector = $allModules.selector || '', + $.fn.checkbox = function (parameters) { + var + $allModules = $(this), + moduleSelector = $allModules.selector || '', - time = new Date().getTime(), - performance = [], + time = new Date().getTime(), + performance = [], - query = arguments[0], - methodInvoked = (typeof query == 'string'), - queryArguments = [].slice.call(arguments, 1), - returnedValue - ; + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + returnedValue + ; - $allModules - .each(function() { - var - settings = $.extend(true, {}, $.fn.checkbox.settings, parameters), + $allModules + .each(function () { + var + settings = $.extend(true, {}, $.fn.checkbox.settings, parameters), - className = settings.className, - namespace = settings.namespace, - selector = settings.selector, - error = settings.error, + className = settings.className, + namespace = settings.namespace, + selector = settings.selector, + error = settings.error, - eventNamespace = '.' + namespace, - moduleNamespace = 'module-' + namespace, + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, - $module = $(this), - $label = $(this).children(selector.label), - $input = $(this).children(selector.input), - input = $input[0], + $module = $(this), + $label = $(this).children(selector.label), + $input = $(this).children(selector.input), + input = $input[0], - initialLoad = false, - shortcutPressed = false, - instance = $module.data(moduleNamespace), + initialLoad = false, + shortcutPressed = false, + instance = $module.data(moduleNamespace), - observer, - element = this, - module - ; + observer, + element = this, + module + ; - module = { + module = { - initialize: function() { - module.verbose('Initializing checkbox', settings); + initialize: function () { + module.verbose('Initializing checkbox', settings); - module.create.label(); - module.bind.events(); + module.create.label(); + module.bind.events(); - module.set.tabbable(); - module.hide.input(); + module.set.tabbable(); + module.hide.input(); - module.observeChanges(); - module.instantiate(); - module.setup(); - }, + module.observeChanges(); + module.instantiate(); + module.setup(); + }, - instantiate: function() { - module.verbose('Storing instance of module', module); - instance = module; - $module - .data(moduleNamespace, module) - ; - }, + instantiate: function () { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, - destroy: function() { - module.verbose('Destroying module'); - module.unbind.events(); - module.show.input(); - $module.removeData(moduleNamespace); - }, + destroy: function () { + module.verbose('Destroying module'); + module.unbind.events(); + module.show.input(); + $module.removeData(moduleNamespace); + }, - fix: { - reference: function() { - if( $module.is(selector.input) ) { - module.debug('Behavior called on adjusting invoked element'); - $module = $module.closest(selector.checkbox); - module.refresh(); - } - } - }, + fix: { + reference: function () { + if ($module.is(selector.input)) { + module.debug('Behavior called on adjusting invoked element'); + $module = $module.closest(selector.checkbox); + module.refresh(); + } + } + }, - setup: function() { - module.set.initialLoad(); - if( module.is.indeterminate() ) { - module.debug('Initial value is indeterminate'); - module.indeterminate(); - } - else if( module.is.checked() ) { - module.debug('Initial value is checked'); - module.check(); - } - else { - module.debug('Initial value is unchecked'); - module.uncheck(); - } - module.remove.initialLoad(); - }, + setup: function () { + module.set.initialLoad(); + if (module.is.indeterminate()) { + module.debug('Initial value is indeterminate'); + module.indeterminate(); + } else if (module.is.checked()) { + module.debug('Initial value is checked'); + module.check(); + } else { + module.debug('Initial value is unchecked'); + module.uncheck(); + } + module.remove.initialLoad(); + }, - refresh: function() { - $label = $module.children(selector.label); - $input = $module.children(selector.input); - input = $input[0]; - }, + refresh: function () { + $label = $module.children(selector.label); + $input = $module.children(selector.input); + input = $input[0]; + }, - hide: { - input: function() { - module.verbose('Modifying z-index to be unselectable'); - $input.addClass(className.hidden); - } - }, - show: { - input: function() { - module.verbose('Modifying z-index to be selectable'); - $input.removeClass(className.hidden); - } - }, + hide: { + input: function () { + module.verbose('Modifying z-index to be unselectable'); + $input.addClass(className.hidden); + } + }, + show: { + input: function () { + module.verbose('Modifying z-index to be selectable'); + $input.removeClass(className.hidden); + } + }, - observeChanges: function() { - if('MutationObserver' in window) { - observer = new MutationObserver(function(mutations) { - module.debug('DOM tree modified, updating selector cache'); - module.refresh(); - }); - observer.observe(element, { - childList : true, - subtree : true - }); - module.debug('Setting up mutation observer', observer); - } - }, + observeChanges: function () { + if ('MutationObserver' in window) { + observer = new MutationObserver(function (mutations) { + module.debug('DOM tree modified, updating selector cache'); + module.refresh(); + }); + observer.observe(element, { + childList: true, + subtree: true + }); + module.debug('Setting up mutation observer', observer); + } + }, - attachEvents: function(selector, event) { - var - $element = $(selector) - ; - event = $.isFunction(module[event]) - ? module[event] - : module.toggle - ; - if($element.length > 0) { - module.debug('Attaching checkbox events to element', selector, event); - $element - .on('click' + eventNamespace, event) + attachEvents: function (selector, event) { + var + $element = $(selector) + ; + event = $.isFunction(module[event]) + ? module[event] + : module.toggle + ; + if ($element.length > 0) { + module.debug('Attaching checkbox events to element', selector, event); + $element + .on('click' + eventNamespace, event) + ; + } else { + module.error(error.notFound); + } + }, + + event: { + click: function (event) { + var + $target = $(event.target) + ; + if ($target.is(selector.input)) { + module.verbose('Using default check action on initialized checkbox'); + return; + } + if ($target.is(selector.link)) { + module.debug('Clicking link inside checkbox, skipping toggle'); + return; + } + module.toggle(); + $input.focus(); + event.preventDefault(); + }, + keydown: function (event) { + var + key = event.which, + keyCode = { + enter: 13, + space: 32, + escape: 27 + } + ; + if (key == keyCode.escape) { + module.verbose('Escape key pressed blurring field'); + $input.blur(); + shortcutPressed = true; + } else if (!event.ctrlKey && (key == keyCode.space || key == keyCode.enter)) { + module.verbose('Enter/space key pressed, toggling checkbox'); + module.toggle(); + shortcutPressed = true; + } else { + shortcutPressed = false; + } + }, + keyup: function (event) { + if (shortcutPressed) { + event.preventDefault(); + } + } + }, + + check: function () { + if (!module.should.allowCheck()) { + return; + } + module.debug('Checking checkbox', $input); + module.set.checked(); + if (!module.should.ignoreCallbacks()) { + settings.onChecked.call(input); + settings.onChange.call(input); + } + }, + + uncheck: function () { + if (!module.should.allowUncheck()) { + return; + } + module.debug('Unchecking checkbox'); + module.set.unchecked(); + if (!module.should.ignoreCallbacks()) { + settings.onUnchecked.call(input); + settings.onChange.call(input); + } + }, + + indeterminate: function () { + if (module.should.allowIndeterminate()) { + module.debug('Checkbox is already indeterminate'); + return; + } + module.debug('Making checkbox indeterminate'); + module.set.indeterminate(); + if (!module.should.ignoreCallbacks()) { + settings.onIndeterminate.call(input); + settings.onChange.call(input); + } + }, + + determinate: function () { + if (module.should.allowDeterminate()) { + module.debug('Checkbox is already determinate'); + return; + } + module.debug('Making checkbox determinate'); + module.set.determinate(); + if (!module.should.ignoreCallbacks()) { + settings.onDeterminate.call(input); + settings.onChange.call(input); + } + }, + + enable: function () { + if (module.is.enabled()) { + module.debug('Checkbox is already enabled'); + return; + } + module.debug('Enabling checkbox'); + module.set.enabled(); + settings.onEnable.call(input); + // preserve legacy callbacks + settings.onEnabled.call(input); + }, + + disable: function () { + if (module.is.disabled()) { + module.debug('Checkbox is already disabled'); + return; + } + module.debug('Disabling checkbox'); + module.set.disabled(); + settings.onDisable.call(input); + // preserve legacy callbacks + settings.onDisabled.call(input); + }, + + get: { + radios: function () { + var + name = module.get.name() + ; + return $('input[name="' + name + '"]').closest(selector.checkbox); + }, + otherRadios: function () { + return module.get.radios().not($module); + }, + name: function () { + return $input.attr('name'); + } + }, + + is: { + initialLoad: function () { + return initialLoad; + }, + radio: function () { + return ($input.hasClass(className.radio) || $input.attr('type') == 'radio'); + }, + indeterminate: function () { + return $input.prop('indeterminate') !== undefined && $input.prop('indeterminate'); + }, + checked: function () { + return $input.prop('checked') !== undefined && $input.prop('checked'); + }, + disabled: function () { + return $input.prop('disabled') !== undefined && $input.prop('disabled'); + }, + enabled: function () { + return !module.is.disabled(); + }, + determinate: function () { + return !module.is.indeterminate(); + }, + unchecked: function () { + return !module.is.checked(); + } + }, + + should: { + allowCheck: function () { + if (module.is.determinate() && module.is.checked() && !module.should.forceCallbacks()) { + module.debug('Should not allow check, checkbox is already checked'); + return false; + } + if (settings.beforeChecked.apply(input) === false) { + module.debug('Should not allow check, beforeChecked cancelled'); + return false; + } + return true; + }, + allowUncheck: function () { + if (module.is.determinate() && module.is.unchecked() && !module.should.forceCallbacks()) { + module.debug('Should not allow uncheck, checkbox is already unchecked'); + return false; + } + if (settings.beforeUnchecked.apply(input) === false) { + module.debug('Should not allow uncheck, beforeUnchecked cancelled'); + return false; + } + return true; + }, + allowIndeterminate: function () { + if (module.is.indeterminate() && !module.should.forceCallbacks()) { + module.debug('Should not allow indeterminate, checkbox is already indeterminate'); + return false; + } + if (settings.beforeIndeterminate.apply(input) === false) { + module.debug('Should not allow indeterminate, beforeIndeterminate cancelled'); + return false; + } + return true; + }, + allowDeterminate: function () { + if (module.is.determinate() && !module.should.forceCallbacks()) { + module.debug('Should not allow determinate, checkbox is already determinate'); + return false; + } + if (settings.beforeDeterminate.apply(input) === false) { + module.debug('Should not allow determinate, beforeDeterminate cancelled'); + return false; + } + return true; + }, + forceCallbacks: function () { + return (module.is.initialLoad() && settings.fireOnInit); + }, + ignoreCallbacks: function () { + return (initialLoad && !settings.fireOnInit); + } + }, + + can: { + change: function () { + return !($module.hasClass(className.disabled) || $module.hasClass(className.readOnly) || $input.prop('disabled') || $input.prop('readonly')); + }, + uncheck: function () { + return (typeof settings.uncheckable === 'boolean') + ? settings.uncheckable + : !module.is.radio() + ; + } + }, + + set: { + initialLoad: function () { + initialLoad = true; + }, + checked: function () { + module.verbose('Setting class to checked'); + $module + .removeClass(className.indeterminate) + .addClass(className.checked) + ; + if (module.is.radio()) { + module.uncheckOthers(); + } + if (!module.is.indeterminate() && module.is.checked()) { + module.debug('Input is already checked, skipping input property change'); + return; + } + module.verbose('Setting state to checked', input); + $input + .prop('indeterminate', false) + .prop('checked', true) + ; + module.trigger.change(); + }, + unchecked: function () { + module.verbose('Removing checked class'); + $module + .removeClass(className.indeterminate) + .removeClass(className.checked) + ; + if (!module.is.indeterminate() && module.is.unchecked()) { + module.debug('Input is already unchecked'); + return; + } + module.debug('Setting state to unchecked'); + $input + .prop('indeterminate', false) + .prop('checked', false) + ; + module.trigger.change(); + }, + indeterminate: function () { + module.verbose('Setting class to indeterminate'); + $module + .addClass(className.indeterminate) + ; + if (module.is.indeterminate()) { + module.debug('Input is already indeterminate, skipping input property change'); + return; + } + module.debug('Setting state to indeterminate'); + $input + .prop('indeterminate', true) + ; + module.trigger.change(); + }, + determinate: function () { + module.verbose('Removing indeterminate class'); + $module + .removeClass(className.indeterminate) + ; + if (module.is.determinate()) { + module.debug('Input is already determinate, skipping input property change'); + return; + } + module.debug('Setting state to determinate'); + $input + .prop('indeterminate', false) + ; + }, + disabled: function () { + module.verbose('Setting class to disabled'); + $module + .addClass(className.disabled) + ; + if (module.is.disabled()) { + module.debug('Input is already disabled, skipping input property change'); + return; + } + module.debug('Setting state to disabled'); + $input + .prop('disabled', 'disabled') + ; + module.trigger.change(); + }, + enabled: function () { + module.verbose('Removing disabled class'); + $module.removeClass(className.disabled); + if (module.is.enabled()) { + module.debug('Input is already enabled, skipping input property change'); + return; + } + module.debug('Setting state to enabled'); + $input + .prop('disabled', false) + ; + module.trigger.change(); + }, + tabbable: function () { + module.verbose('Adding tabindex to checkbox'); + if ($input.attr('tabindex') === undefined) { + $input.attr('tabindex', 0); + } + } + }, + + remove: { + initialLoad: function () { + initialLoad = false; + } + }, + + trigger: { + change: function () { + var + events = document.createEvent('HTMLEvents'), + inputElement = $input[0] + ; + if (inputElement) { + module.verbose('Triggering native change event'); + events.initEvent('change', true, false); + inputElement.dispatchEvent(events); + } + } + }, + + + create: { + label: function () { + if ($input.prevAll(selector.label).length > 0) { + $input.prev(selector.label).detach().insertAfter($input); + module.debug('Moving existing label', $label); + } else if (!module.has.label()) { + $label = $('