소스 검색

refactoring, second part

Emanuele Marchi 11 년 전
부모
커밋
22913aed47

+ 19 - 4
Gruntfile.coffee

@@ -28,12 +28,18 @@ module.exports = (grunt) ->
       build: ["Gruntfile.coffee", "src/**/*.coffee"]
 
     coffee:
-      build:
+      default:
         expand: true
         cwd: "src/coffee"
         src: "**/*.coffee"
         dest: "build/js"
         ext: ".js"
+      test:
+        expand: true
+        cwd: "src/test"
+        src: "**/*.coffee"
+        dest: "test/"
+        ext: ".js"
 
     uglify:
       build:
@@ -86,8 +92,9 @@ module.exports = (grunt) ->
       all: ["*.json"]
 
     clean:
-      css: ["build/css"]
-      js: ["build/js"]
+      css: "build/css"
+      js: "build/js"
+      test: "test"
 
     connect:
       go:
@@ -104,6 +111,13 @@ module.exports = (grunt) ->
         commitFiles: ["-a"]
         push: false
 
+    jasmine:
+      options:
+        keepRunner: true
+        specs: "test/**/*.js"
+        vendor: ["docs/vendor/jquery.min.js", "docs/vendor/bootstrap.min.js"]
+      src: "build/js/bootstrap-switch.js"
+
     watch:
       coffee:
         files: ["src/**/*.coffee"]
@@ -113,4 +127,5 @@ module.exports = (grunt) ->
         tasks: ["clean:css", "less", "cssmin", "usebanner:css"]
 
   grunt.registerTask "go", ["build", "connect", "open", "watch"]
-  grunt.registerTask "build", ["clean", "coffeelint", "coffee", "uglify", "usebanner:js", "less", "cssmin", "usebanner:css"]
+  grunt.registerTask "build", ["clean", "coffeelint", "coffee", "uglify", "less", "cssmin", "usebanner"]
+  grunt.registerTask "test", ["build", "jasmine"]

+ 100 - 106
build/css/bootstrap2/bootstrap-switch.css

@@ -46,7 +46,7 @@
   -moz-box-sizing: border-box;
   box-sizing: border-box;
 }
-.has-switch {
+.switch {
   display: inline-block;
   cursor: pointer;
   -webkit-border-radius: 5px;
@@ -70,17 +70,17 @@
   -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
   transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
 }
-.has-switch.switch-mini {
+.switch.switch-mini {
   min-width: 72px;
 }
-.has-switch.switch-mini > div > span,
-.has-switch.switch-mini > div > label {
+.switch.switch-mini > div > span,
+.switch.switch-mini > div > label {
   padding-bottom: 4px;
   padding-top: 4px;
   font-size: 10px;
   line-height: 9px;
 }
-.has-switch.switch-mini .switch-mini-icons {
+.switch.switch-mini .switch-mini-icons {
   height: 1.20em;
   line-height: 9px;
   vertical-align: text-top;
@@ -89,62 +89,65 @@
   margin-top: -1px;
   margin-bottom: -1px;
 }
-.has-switch.switch-small {
+.switch.switch-small {
   min-width: 80px;
 }
-.has-switch.switch-small > div > span,
-.has-switch.switch-small > div > label {
+.switch.switch-small > div > span,
+.switch.switch-small > div > label {
   padding-bottom: 3px;
   padding-top: 3px;
   font-size: 12px;
   line-height: 18px;
 }
-.has-switch.switch-large {
+.switch.switch-large {
   min-width: 120px;
 }
-.has-switch.switch-large > div > span,
-.has-switch.switch-large > div > label {
+.switch.switch-large > div > span,
+.switch.switch-large > div > label {
   padding-bottom: 9px;
   padding-top: 9px;
   font-size: 16px;
   line-height: normal;
 }
-.has-switch.switch-animate > div {
+.switch.switch-animate > div {
   -webkit-transition: left 0.5s;
   -moz-transition: left 0.5s;
   -o-transition: left 0.5s;
   transition: left 0.5s;
 }
-.has-switch.switch-off > div {
+.switch.switch-off > div {
   left: -50%;
 }
-.has-switch.switch-on > div {
+.switch.switch-on > div {
   left: 0%;
 }
-.has-switch.disabled {
+.switch.switch-disabled,
+.switch.switch-readonly {
   opacity: 0.5;
   filter: alpha(opacity=50);
   cursor: default !important;
 }
-.has-switch.disabled > div > span,
-.has-switch.disabled > div > label {
+.switch.switch-disabled > div > span,
+.switch.switch-readonly > div > span,
+.switch.switch-disabled > div > label,
+.switch.switch-readonly > div > label {
   cursor: default !important;
 }
-.has-switch:focus {
+.switch:focus {
   border-color: #0088cc;
   outline: 0;
   -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(red(@btnPrimaryBackground), green(@btnPrimaryBackground), blue(@btnPrimaryBackground), .6);
   -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(red(@btnPrimaryBackground), green(@btnPrimaryBackground), blue(@btnPrimaryBackground), .6);
   box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(red(@btnPrimaryBackground), green(@btnPrimaryBackground), blue(@btnPrimaryBackground), .6);
 }
-.has-switch > div {
+.switch > div {
   display: inline-block;
   width: 150%;
   position: relative;
   top: 0;
 }
-.has-switch > div > span,
-.has-switch > div > label {
+.switch > div > span,
+.switch > div > label {
   -webkit-box-sizing: border-box;
   -moz-box-sizing: border-box;
   box-sizing: border-box;
@@ -157,17 +160,17 @@
   font-size: 14px;
   line-height: 20px;
 }
-.has-switch > div > span {
+.switch > div > span {
   text-align: center;
   z-index: 1;
   width: 33%;
 }
-.has-switch > div > span.switch-left {
+.switch > div > span.switch-handle-on {
   -webkit-border-top-left-radius: 4px;
   -moz-border-radius-topleft: 4px;
   border-top-left-radius: 4px;
 }
-.has-switch > div > span.switch-right {
+.switch > div > span.switch-handle-off {
   color: #333333;
   text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
   background-color: #f0f0f0;
@@ -184,22 +187,21 @@
   /* Darken IE7 buttons by default so they stand out more given they won't have borders */
   filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
 }
-.has-switch > div > span.switch-right:hover,
-.has-switch > div > span.switch-right:focus,
-.has-switch > div > span.switch-right:active,
-.has-switch > div > span.switch-right.active,
-.has-switch > div > span.switch-right.disabled,
-.has-switch > div > span.switch-right[disabled] {
+.switch > div > span.switch-handle-off:hover,
+.switch > div > span.switch-handle-off:focus,
+.switch > div > span.switch-handle-off:active,
+.switch > div > span.switch-handle-off.active,
+.switch > div > span.switch-handle-off.disabled,
+.switch > div > span.switch-handle-off[disabled] {
   color: #333333;
   background-color: #ffffff;
   *background-color: #f2f2f2;
 }
-.has-switch > div > span.switch-right:active,
-.has-switch > div > span.switch-right.active {
+.switch > div > span.switch-handle-off:active,
+.switch > div > span.switch-handle-off.active {
   background-color: #e6e6e6 \9;
 }
-.has-switch > div > span.switch-primary,
-.has-switch > div > span.switch-left {
+.switch > div > span.switch-primary {
   color: #ffffff;
   text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
   background-color: #005fcc;
@@ -216,29 +218,21 @@
   /* Darken IE7 buttons by default so they stand out more given they won't have borders */
   filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
 }
-.has-switch > div > span.switch-primary:hover,
-.has-switch > div > span.switch-left:hover,
-.has-switch > div > span.switch-primary:focus,
-.has-switch > div > span.switch-left:focus,
-.has-switch > div > span.switch-primary:active,
-.has-switch > div > span.switch-left:active,
-.has-switch > div > span.switch-primary.active,
-.has-switch > div > span.switch-left.active,
-.has-switch > div > span.switch-primary.disabled,
-.has-switch > div > span.switch-left.disabled,
-.has-switch > div > span.switch-primary[disabled],
-.has-switch > div > span.switch-left[disabled] {
+.switch > div > span.switch-primary:hover,
+.switch > div > span.switch-primary:focus,
+.switch > div > span.switch-primary:active,
+.switch > div > span.switch-primary.active,
+.switch > div > span.switch-primary.disabled,
+.switch > div > span.switch-primary[disabled] {
   color: #ffffff;
   background-color: #0088cc;
   *background-color: #0077b3;
 }
-.has-switch > div > span.switch-primary:active,
-.has-switch > div > span.switch-left:active,
-.has-switch > div > span.switch-primary.active,
-.has-switch > div > span.switch-left.active {
+.switch > div > span.switch-primary:active,
+.switch > div > span.switch-primary.active {
   background-color: #006699 \9;
 }
-.has-switch > div > span.switch-info {
+.switch > div > span.switch-info {
   color: #ffffff;
   text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
   background-color: #41a7c5;
@@ -255,21 +249,21 @@
   /* Darken IE7 buttons by default so they stand out more given they won't have borders */
   filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
 }
-.has-switch > div > span.switch-info:hover,
-.has-switch > div > span.switch-info:focus,
-.has-switch > div > span.switch-info:active,
-.has-switch > div > span.switch-info.active,
-.has-switch > div > span.switch-info.disabled,
-.has-switch > div > span.switch-info[disabled] {
+.switch > div > span.switch-info:hover,
+.switch > div > span.switch-info:focus,
+.switch > div > span.switch-info:active,
+.switch > div > span.switch-info.active,
+.switch > div > span.switch-info.disabled,
+.switch > div > span.switch-info[disabled] {
   color: #ffffff;
   background-color: #5bc0de;
   *background-color: #46b8da;
 }
-.has-switch > div > span.switch-info:active,
-.has-switch > div > span.switch-info.active {
+.switch > div > span.switch-info:active,
+.switch > div > span.switch-info.active {
   background-color: #31b0d5 \9;
 }
-.has-switch > div > span.switch-success {
+.switch > div > span.switch-success {
   color: #ffffff;
   text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
   background-color: #58b058;
@@ -286,21 +280,21 @@
   /* Darken IE7 buttons by default so they stand out more given they won't have borders */
   filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
 }
-.has-switch > div > span.switch-success:hover,
-.has-switch > div > span.switch-success:focus,
-.has-switch > div > span.switch-success:active,
-.has-switch > div > span.switch-success.active,
-.has-switch > div > span.switch-success.disabled,
-.has-switch > div > span.switch-success[disabled] {
+.switch > div > span.switch-success:hover,
+.switch > div > span.switch-success:focus,
+.switch > div > span.switch-success:active,
+.switch > div > span.switch-success.active,
+.switch > div > span.switch-success.disabled,
+.switch > div > span.switch-success[disabled] {
   color: #ffffff;
   background-color: #62c462;
   *background-color: #4fbd4f;
 }
-.has-switch > div > span.switch-success:active,
-.has-switch > div > span.switch-success.active {
+.switch > div > span.switch-success:active,
+.switch > div > span.switch-success.active {
   background-color: #42b142 \9;
 }
-.has-switch > div > span.switch-warning {
+.switch > div > span.switch-warning {
   color: #ffffff;
   text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
   background-color: #f9a123;
@@ -317,21 +311,21 @@
   /* Darken IE7 buttons by default so they stand out more given they won't have borders */
   filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
 }
-.has-switch > div > span.switch-warning:hover,
-.has-switch > div > span.switch-warning:focus,
-.has-switch > div > span.switch-warning:active,
-.has-switch > div > span.switch-warning.active,
-.has-switch > div > span.switch-warning.disabled,
-.has-switch > div > span.switch-warning[disabled] {
+.switch > div > span.switch-warning:hover,
+.switch > div > span.switch-warning:focus,
+.switch > div > span.switch-warning:active,
+.switch > div > span.switch-warning.active,
+.switch > div > span.switch-warning.disabled,
+.switch > div > span.switch-warning[disabled] {
   color: #ffffff;
   background-color: #fbb450;
   *background-color: #faa937;
 }
-.has-switch > div > span.switch-warning:active,
-.has-switch > div > span.switch-warning.active {
+.switch > div > span.switch-warning:active,
+.switch > div > span.switch-warning.active {
   background-color: #fa9f1e \9;
 }
-.has-switch > div > span.switch-danger {
+.switch > div > span.switch-danger {
   color: #ffffff;
   text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
   background-color: #d14641;
@@ -348,21 +342,21 @@
   /* Darken IE7 buttons by default so they stand out more given they won't have borders */
   filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
 }
-.has-switch > div > span.switch-danger:hover,
-.has-switch > div > span.switch-danger:focus,
-.has-switch > div > span.switch-danger:active,
-.has-switch > div > span.switch-danger.active,
-.has-switch > div > span.switch-danger.disabled,
-.has-switch > div > span.switch-danger[disabled] {
+.switch > div > span.switch-danger:hover,
+.switch > div > span.switch-danger:focus,
+.switch > div > span.switch-danger:active,
+.switch > div > span.switch-danger.active,
+.switch > div > span.switch-danger.disabled,
+.switch > div > span.switch-danger[disabled] {
   color: #ffffff;
   background-color: #ee5f5b;
   *background-color: #ec4844;
 }
-.has-switch > div > span.switch-danger:active,
-.has-switch > div > span.switch-danger.active {
+.switch > div > span.switch-danger:active,
+.switch > div > span.switch-danger.active {
   background-color: #e9322d \9;
 }
-.has-switch > div > span.switch-default {
+.switch > div > span.switch-default {
   color: #333333;
   text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
   background-color: #f0f0f0;
@@ -379,21 +373,21 @@
   /* Darken IE7 buttons by default so they stand out more given they won't have borders */
   filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
 }
-.has-switch > div > span.switch-default:hover,
-.has-switch > div > span.switch-default:focus,
-.has-switch > div > span.switch-default:active,
-.has-switch > div > span.switch-default.active,
-.has-switch > div > span.switch-default.disabled,
-.has-switch > div > span.switch-default[disabled] {
+.switch > div > span.switch-default:hover,
+.switch > div > span.switch-default:focus,
+.switch > div > span.switch-default:active,
+.switch > div > span.switch-default.active,
+.switch > div > span.switch-default.disabled,
+.switch > div > span.switch-default[disabled] {
   color: #333333;
   background-color: #ffffff;
   *background-color: #f2f2f2;
 }
-.has-switch > div > span.switch-default:active,
-.has-switch > div > span.switch-default.active {
+.switch > div > span.switch-default:active,
+.switch > div > span.switch-default.active {
   background-color: #e6e6e6 \9;
 }
-.has-switch > div > label {
+.switch > div > label {
   text-align: center;
   margin-top: -1px;
   margin-bottom: -1px;
@@ -417,21 +411,21 @@
   /* Darken IE7 buttons by default so they stand out more given they won't have borders */
   filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
 }
-.has-switch > div > label:hover,
-.has-switch > div > label:focus,
-.has-switch > div > label:active,
-.has-switch > div > label.active,
-.has-switch > div > label.disabled,
-.has-switch > div > label[disabled] {
+.switch > div > label:hover,
+.switch > div > label:focus,
+.switch > div > label:active,
+.switch > div > label.active,
+.switch > div > label.disabled,
+.switch > div > label[disabled] {
   color: #333333;
   background-color: #e6e6e6;
   *background-color: #d9d9d9;
 }
-.has-switch > div > label:active,
-.has-switch > div > label.active {
+.switch > div > label:active,
+.switch > div > label.active {
   background-color: #cccccc \9;
 }
-.has-switch input[type=radio],
-.has-switch input[type=checkbox] {
+.switch input[type=radio],
+.switch input[type=checkbox] {
   display: none;
 }

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
build/css/bootstrap2/bootstrap-switch.min.css


+ 45 - 40
build/css/bootstrap3/bootstrap-switch.css

@@ -19,7 +19,7 @@
  * ========================================================================
  */
 
-.has-switch {
+.switch {
   display: inline-block;
   cursor: pointer;
   border-radius: 4px;
@@ -39,23 +39,17 @@
   -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
   transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
 }
-.has-switch:focus {
-  border-color: #66afe9;
-  outline: 0;
-  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
-  box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
-}
-.has-switch.switch-mini {
+.switch.switch-mini {
   min-width: 72px;
 }
-.has-switch.switch-mini > div > span,
-.has-switch.switch-mini > div > label {
+.switch.switch-mini > div > span,
+.switch.switch-mini > div > label {
   padding-bottom: 4px;
   padding-top: 4px;
   font-size: 10px;
   line-height: 9px;
 }
-.has-switch.switch-mini .switch-mini-icons {
+.switch.switch-mini .switch-mini-icons {
   height: 1.20em;
   line-height: 9px;
   vertical-align: text-top;
@@ -64,46 +58,55 @@
   margin-top: -1px;
   margin-bottom: -1px;
 }
-.has-switch.switch-small {
+.switch.switch-small {
   min-width: 80px;
 }
-.has-switch.switch-small > div > span,
-.has-switch.switch-small > div > label {
+.switch.switch-small > div > span,
+.switch.switch-small > div > label {
   padding-bottom: 3px;
   padding-top: 3px;
   font-size: 12px;
   line-height: 18px;
 }
-.has-switch.switch-large {
+.switch.switch-large {
   min-width: 120px;
 }
-.has-switch.switch-large > div > span,
-.has-switch.switch-large > div > label {
+.switch.switch-large > div > span,
+.switch.switch-large > div > label {
   padding-bottom: 9px;
   padding-top: 9px;
   font-size: 16px;
   line-height: normal;
 }
-.has-switch.switch-animate > div {
+.switch.switch-animate > div {
   -webkit-transition: margin-left 0.5s;
   transition: margin-left 0.5s;
 }
-.has-switch.switch-off > div {
+.switch.switch-off > div {
   margin-left: -50%;
 }
-.has-switch.switch-on > div {
+.switch.switch-on > div {
   margin-left: 0%;
 }
-.has-switch.disabled {
+.switch.switch-disabled,
+.switch.switch-readonly {
   opacity: 0.5;
   filter: alpha(opacity=50);
   cursor: default !important;
 }
-.has-switch.disabled > div > span,
-.has-switch.disabled > div > label {
+.switch.switch-disabled > div > span,
+.switch.switch-readonly > div > span,
+.switch.switch-disabled > div > label,
+.switch.switch-readonly > div > label {
   cursor: default !important;
 }
-.has-switch > div {
+.switch.switch-focused {
+  border-color: #66afe9;
+  outline: 0;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
+  box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
+}
+.switch > div {
   display: inline-block;
   width: 150%;
   top: 0;
@@ -111,8 +114,8 @@
   -webkit-transform: translate3d(0, 0, 0);
   transform: translate3d(0, 0, 0);
 }
-.has-switch > div > span,
-.has-switch > div > label {
+.switch > div > span,
+.switch > div > label {
   -webkit-box-sizing: border-box;
   -moz-box-sizing: border-box;
   box-sizing: border-box;
@@ -124,46 +127,45 @@
   font-size: 14px;
   line-height: 20px;
 }
-.has-switch > div > span {
+.switch > div > span {
   text-align: center;
   z-index: 1;
   width: 33.333333333%;
 }
-.has-switch > div > span.switch-left {
+.switch > div > span.switch-handle-on {
   color: #f00;
   border-bottom-left-radius: 3px;
   border-top-left-radius: 3px;
 }
-.has-switch > div > span.switch-right {
+.switch > div > span.switch-handle-off {
   color: #000;
   background: #eeeeee;
 }
-.has-switch > div > span.switch-primary,
-.has-switch > div > span.switch-left {
+.switch > div > span.switch-primary {
   color: #fff;
   background: #428bca;
 }
-.has-switch > div > span.switch-info {
+.switch > div > span.switch-info {
   color: #fff;
   background: #5bc0de;
 }
-.has-switch > div > span.switch-success {
+.switch > div > span.switch-success {
   color: #fff;
   background: #5cb85c;
 }
-.has-switch > div > span.switch-warning {
+.switch > div > span.switch-warning {
   background: #f0ad4e;
   color: #fff;
 }
-.has-switch > div > span.switch-danger {
+.switch > div > span.switch-danger {
   color: #fff;
   background: #d9534f;
 }
-.has-switch > div > span.switch-default {
+.switch > div > span.switch-default {
   color: #000;
   background: #eeeeee;
 }
-.has-switch > div > label {
+.switch > div > label {
   text-align: center;
   margin-top: -1px;
   margin-bottom: -1px;
@@ -172,7 +174,10 @@
   color: #333333;
   background: #ffffff;
 }
-.has-switch input[type=radio],
-.has-switch input[type=checkbox] {
-  display: none;
+.switch input[type='radio'],
+.switch input[type='checkbox'] {
+  position: absolute !important;
+  top: 0;
+  left: 0;
+  z-index: -1;
 }

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
build/css/bootstrap3/bootstrap-switch.min.css


+ 224 - 260
build/js/bootstrap-switch.js

@@ -26,91 +26,77 @@
     "use strict";
     var BootstrapSwitch;
     BootstrapSwitch = (function() {
-      function BootstrapSwitch(element, option) {
+      BootstrapSwitch.prototype.defaults = {
+        state: true,
+        size: null,
+        animate: true,
+        disabled: false,
+        readonly: false,
+        onColor: "primary",
+        offColor: "default",
+        onText: "ON",
+        offText: "OFF",
+        labelText: " "
+      };
+
+      function BootstrapSwitch(element, options) {
         var _this = this;
+        if (options == null) {
+          options = {};
+        }
         this.$element = $(element);
-        this.$switchLeft = $("<span>", {
-          "class": function() {
-            var cls, color;
-            cls = "switch-left";
-            color = _this.$element.data("on-color");
-            if (color != null) {
-              cls += " switch-" + color;
-            }
-            return cls;
-          },
-          html: function() {
-            var html, text;
-            html = "ON";
-            text = _this.$element.data("on-text");
-            if (text != null) {
-              html = text;
-            }
-            return html;
-          }
+        this.options = $.extend({}, this.defaults, options, {
+          state: this.$element.is(":checked"),
+          size: this.$element.data("size"),
+          animate: this.$element.data("animate"),
+          disabled: this.$element.is(":disabled"),
+          readonly: this.$element.is("[readonly]"),
+          onColor: this.$element.data("on-color"),
+          offColor: this.$element.data("off-color"),
+          onText: this.$element.data("on-text"),
+          offText: this.$element.data("off-text"),
+          labelText: this.$element.data("label-text")
         });
-        this.$switchRight = $("<span>", {
-          "class": function() {
-            var cls, color;
-            cls = "switch-right";
-            color = _this.$element.data("off-color");
-            if (color != null) {
-              cls += " switch-" + color;
-            }
-            return cls;
-          },
-          html: function() {
-            var html, text;
-            html = "OFF";
-            text = _this.$element.data("off-text");
-            if (text != null) {
-              html = text;
-            }
-            return html;
-          }
+        this.$on = $("<span>", {
+          "class": "switch-handle-on switch-" + this.options.onColor,
+          html: this.options.onText
+        });
+        this.$off = $("<span>", {
+          "class": "switch-handle-off switch-" + this.options.offColor,
+          html: this.options.offText
         });
         this.$label = $("<label>", {
           "for": this.$element.attr("id"),
-          html: function() {
-            var html, text;
-            html = "&nbsp;";
-            text = _this.$element.data("label-text");
-            if (text != null) {
-              html = text;
-            }
-            return html;
-          }
+          html: this.options.labelText
         });
         this.$wrapper = $("<div>", {
           "class": function() {
-            var classes, cls, _i, _len, _ref;
-            classes = ["has-switch"];
-            if (_this.$element.attr("class")) {
-              _ref = ["mini", "small", "large"];
-              for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-                cls = _ref[_i];
-                if (_this.$element.hasClass("switch-" + cls)) {
-                  classes.push("switch-" + cls);
-                }
-              }
+            var classes;
+            classes = ["switch"];
+            classes.push(_this.options.state ? "switch-on" : "switch-off");
+            if (_this.options.size != null) {
+              classes.push("switch-" + _this.options.size);
             }
-            classes.push(_this.$element.is(":checked") ? "switch-on" : "switch-off");
-            if (_this.$element.data("animate") !== false) {
+            if (_this.options.animate) {
               classes.push("switch-animate");
             }
-            if (_this.$element.is(":disabled") || _this.$element.is("[readonly]")) {
-              classes.push("disabled");
+            if (_this.options.disabled) {
+              classes.push("switch-disabled");
+            }
+            if (_this.options.readonly) {
+              classes.push("switch-readonly");
+            }
+            if (_this.$element.attr("id")) {
+              classes.push("switch-id-" + (_this.$element.attr("id")));
             }
             return classes.join(" ");
-          },
-          tabindex: 0
+          }
         });
         this.$div = this.$element.wrap($("<div>")).parent();
         this.$wrapper = this.$div.wrap(this.$wrapper).parent();
-        this.$element.before(this.$switchLeft).before(this.$label).before(this.$switchRight);
+        this.$element.before(this.$on).before(this.$label).before(this.$off);
         this._elementHandlers();
-        this._wrapperHandlers();
-        this._switchesHandlers();
+        this._handleHandlers();
         this._labelHandlers();
         this._form();
       }
@@ -119,15 +105,20 @@
 
       BootstrapSwitch.prototype.state = function(value, skip) {
         if (typeof value === "undefined") {
-          return this.$element.is(":checked");
+          return this.options.state;
+        }
+        if (this.options.disabled || this.options.readonly) {
+          return this.$element;
         }
         this.$element.prop("checked", !!value).trigger("change", skip);
         return this.$element;
       };
 
       BootstrapSwitch.prototype.toggleState = function(skip) {
-        this.$element.prop("checked", !this.$element.is(":checked")).trigger("change", skip);
-        return this.$element;
+        if (this.options.disabled || this.options.readonly) {
+          return this.$element;
+        }
+        return this.$element.prop("checked", !this.options.state).trigger("change", skip);
       };
 
       /*
@@ -143,275 +134,247 @@
       */
 
 
-      BootstrapSwitch.prototype.disabled = function(value) {
+      BootstrapSwitch.prototype.size = function(value) {
         if (typeof value === "undefined") {
-          return this.$element.is(":disabled");
+          return this.options.size;
         }
-        value = !!value;
-        this.$wrapper[value ? "addClass" : "removeClass"]("disabled");
-        this.$element.prop("disabled", value);
-        return this.$element;
-      };
-
-      BootstrapSwitch.prototype.toggleDisabled = function() {
-        this.$element.prop("disabled", !this.$element.is(":disabled"));
-        this.$wrapper.toggleClass("disabled");
+        if (this.options.size != null) {
+          this.$wrapper.removeClass("switch-" + this.options.size);
+        }
+        this.$wrapper.addClass("switch-" + value);
+        this.options.size = value;
         return this.$element;
       };
 
-      BootstrapSwitch.prototype.readOnly = function(value) {
+      BootstrapSwitch.prototype.animate = function(value) {
         if (typeof value === "undefined") {
-          return this.$element.is("[readonly]");
-        }
-        if (readonly) {
-          this.$wrapper.addClass("disabled");
-          this.$element.prop("readonly", true);
-        } else {
-          this.$wrapper.removeClass("disabled");
-          this.$element.prop("readonly", false);
+          return this.options.animate;
         }
+        value = !!value;
+        this.$wrapper[value ? "addClass" : "removeClass"]("switch-animate");
+        this.options.animate = value;
         return this.$element;
       };
 
-      BootstrapSwitch.prototype.toggleReadOnly = function() {
-        this.$element.prop("readonly", !this.$element.is("[readonly]")).parents(".has-switch").toggleClass("disabled");
+      BootstrapSwitch.prototype.disabled = function(value) {
+        if (typeof value === "undefined") {
+          return this.options.disabled;
+        }
+        value = !!value;
+        this.$wrapper[value ? "addClass" : "removeClass"]("switch-disabled");
+        this.$element.prop("disabled", value);
+        this.options.disabled = value;
         return this.$element;
       };
 
-      BootstrapSwitch.prototype.labelText = function(value) {
-        this.$element.siblings("label").html(value || "&nbsp");
+      BootstrapSwitch.prototype.toggleDisabled = function() {
+        this.$element.prop("disabled", !this.options.disabled);
+        this.$wrapper.toggleClass("switch-disabled");
+        this.options.disabled = !this.options.disabled;
         return this.$element;
       };
 
-      BootstrapSwitch.prototype.onText = function(value) {
+      BootstrapSwitch.prototype.readonly = function(value) {
         if (typeof value === "undefined") {
-          return this.$switchLeft.html();
+          return this.options.readonly;
         }
-        this.$switchLeft.html(value);
+        value = !!value;
+        this.$wrapper[value ? "addClass" : "removeClass"]("switch-readonly");
+        this.$element.prop("readonly", value);
+        this.options.readonly = value;
         return this.$element;
       };
 
-      BootstrapSwitch.prototype.offText = function(value) {
-        if (typeof value === "undefined") {
-          return this.$switchRight.html();
-        }
-        this.$switchRight.html(value);
+      BootstrapSwitch.prototype.toggleReadonly = function() {
+        this.$element.prop("readonly", !this.options.readonly);
+        this.$wrapper.toggleClass("switch-readonly");
+        this.options.readonly = !this.options.readonly;
         return this.$element;
       };
 
       BootstrapSwitch.prototype.onColor = function(value) {
         var color;
-        color = this.$element.data("on-color");
+        color = this.options.onColor;
         if (typeof value === "undefined") {
           return color;
         }
         if (color != null) {
-          this.$switchLeft.removeClass("switch-" + color);
+          this.$on.removeClass("switch-" + color);
         }
-        this.$switchLeft.addClass("switch-" + value);
-        this.$element.data("on-color", value);
+        this.$on.addClass("switch-" + value);
+        this.options.onColor = value;
         return this.$element;
       };
 
       BootstrapSwitch.prototype.offColor = function(value) {
         var color;
-        color = this.$element.data("off-color");
+        color = this.options.offColor;
         if (typeof value === "undefined") {
           return color;
         }
         if (color != null) {
-          this.$switchRight.removeClass("switch-" + color);
+          this.$off.removeClass("switch-" + color);
         }
-        this.$switchRight.addClass("switch-" + value);
-        this.$element.data("off-color", value);
+        this.$off.addClass("switch-" + value);
+        this.options.offColor = value;
         return this.$element;
       };
 
-      BootstrapSwitch.prototype.animate = function(value) {
+      BootstrapSwitch.prototype.onText = function(value) {
         if (typeof value === "undefined") {
-          return this.$element.data("animate");
+          return this.options.onText;
         }
-        value = !!value;
-        this.$wrapper[value ? "addClass" : "removeClass"]("switch-animate");
-        this.$element.data("animate", value);
+        this.$on.html(value);
+        this.options.onText = value;
         return this.$element;
       };
 
-      BootstrapSwitch.prototype.size = function(value) {
-        var cls, _i, _len, _ref;
+      BootstrapSwitch.prototype.offText = function(value) {
         if (typeof value === "undefined") {
-          return this.$wrapper.hasClass("switch-" + value);
+          return this.options.offText;
         }
-        _ref = ["mini", "small", "large"];
-        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-          cls = _ref[_i];
-          this.$wrapper[cls !== value ? "removeClass" : "addClass"]("switch-" + cls);
+        this.$off.html(value);
+        this.options.offText = value;
+        return this.$element;
+      };
+
+      BootstrapSwitch.prototype.labelText = function(value) {
+        if (typeof value === "undefined") {
+          return this.options.labelText;
         }
+        this.$label.html(value);
+        this.options.labelText = value;
         return this.$element;
       };
 
       BootstrapSwitch.prototype.destroy = function() {
         var $form;
         $form = this.$element.closest("form");
-        this.$div.children().not(this.$element).remove();
-        this.$element.unwrap().unwrap().off("change");
         if ($form.length) {
-          $form.off("reset").removeData("bootstrap-switch");
+          $form.off("reset.bootstrapSwitch").removeData("bootstrap-switch");
         }
+        this.$div.children().not(this.$element).remove();
+        this.$element.unwrap().unwrap().off(".bootstrapSwitch").removeData("bootstrap-switch");
         return this.$element;
       };
 
       BootstrapSwitch.prototype._elementHandlers = function() {
         var _this = this;
-        return this.$element.on("change", function(e, skip) {
-          var isChecked, state;
-          e.preventDefault();
-          isChecked = _this.$element.is(":checked");
-          state = _this.$wrapper.hasClass("switch-off");
-          _this.$div.css("margin-left", "");
-          if (state !== isChecked) {
-            return;
-          }
-          if (isChecked) {
-            _this.$wrapper.removeClass("switch-off").addClass("switch-on");
-          } else {
-            _this.$wrapper.removeClass("switch-on").addClass("switch-off");
-          }
-          if (_this.$element.data("animate") !== false) {
-            _this.$wrapper.addClass("switch-animate");
-          }
-          if (typeof skip === "boolean" && skip) {
-            return;
-          }
-          return _this.$element.trigger("switch-change", {
-            el: _this.$element,
-            value: isChecked
-          });
-        });
-      };
-
-      BootstrapSwitch.prototype._wrapperHandlers = function() {
-        var _this = this;
-        return this.$wrapper.on("keydown", function(e) {
-          if (!e.which || _this.$element.is(":disabled") || _this.$element.is("[readonly]")) {
-            return;
-          }
-          switch (e.which) {
-            case 32:
-              e.preventDefault();
-              return _this.toggleState();
-            case 37:
-              e.preventDefault();
-              if (_this.$element.is(":checked")) {
-                return _this.toggleState();
-              }
-              break;
-            case 39:
-              e.preventDefault();
-              if (!_this.$element.is(":checked")) {
+        return this.$element.on({
+          "change.bootstrapSwitch": function(e, skip) {
+            var checked;
+            e.preventDefault();
+            e.stopPropagation();
+            e.stopImmediatePropagation();
+            checked = _this.$element.is(":checked");
+            if (checked === _this.options.state) {
+              return;
+            }
+            _this.options.state = checked;
+            _this.$wrapper.removeClass(checked ? "switch-off" : "switch-on").addClass(checked ? "switch-on" : "switch-off");
+            if (!skip) {
+              return _this.$element.trigger("switchChange", {
+                el: _this.$element,
+                value: checked
+              });
+            }
+          },
+          "focus.bootstrapSwitch": function(e) {
+            e.preventDefault();
+            e.stopPropagation();
+            e.stopImmediatePropagation();
+            return _this.$wrapper.addClass("switch-focused");
+          },
+          "blur.bootstrapSwitch": function(e) {
+            e.preventDefault();
+            e.stopPropagation();
+            e.stopImmediatePropagation();
+            return _this.$wrapper.removeClass("switch-focused");
+          },
+          "keydown.bootstrapSwitch": function(e) {
+            if (!e.which || _this.options.disabled || _this.options.readonly) {
+              return;
+            }
+            switch (e.which) {
+              case 32:
+                e.preventDefault();
+                e.stopPropagation();
+                e.stopImmediatePropagation();
                 return _this.toggleState();
-              }
+              case 37:
+                e.preventDefault();
+                e.stopPropagation();
+                e.stopImmediatePropagation();
+                return _this.state(false);
+              case 39:
+                e.preventDefault();
+                e.stopPropagation();
+                e.stopImmediatePropagation();
+                return _this.state(true);
+            }
           }
         });
       };
 
-      BootstrapSwitch.prototype._switchesHandlers = function() {
+      BootstrapSwitch.prototype._handleHandlers = function() {
         var _this = this;
-        this.$switchLeft.on("click", function() {
-          return _this.toggleState();
+        this.$on.on("click.bootstrapSwitch", function(e) {
+          _this.state(false);
+          return _this.$element.trigger("focus");
         });
-        return this.$switchRight.on("click", function() {
-          return _this.toggleState();
+        return this.$off.on("click.bootstrapSwitch", function(e) {
+          _this.state(true);
+          return _this.$element.trigger("focus");
         });
       };
 
       BootstrapSwitch.prototype._labelHandlers = function() {
-        /*
-        @$label.on "click", =>
-          e.preventDefault()
-          e.stopImmediatePropagation()
-        
-          @toggleState()
-        */
-
         var _this = this;
-        return this.$label.on("click", function(e) {
-          e.preventDefault();
-          e.stopImmediatePropagation();
-          _this.$wrapper.removeClass("switch-animate");
-          if (_this.moving) {
-            return;
-          }
-          _this.$label.on("mousemove", function(e) {
-            var left, percent, relativeX, right;
-            relativeX = (e.pageX || e.originalEvent.targetTouches[0].pageX) - _this.$wrapper.offset().left;
-            percent = (relativeX / _this.$wrapper.width()) * 100;
+        return this.$label.on({
+          "mousemove.bootstrapSwitch": function(e) {
+            var left, percent, right;
+            if (!_this.drag) {
+              return;
+            }
+            percent = ((e.pageX - _this.$wrapper.offset().left) / _this.$wrapper.width()) * 100;
             left = 25;
             right = 75;
-            _this.moving = true;
             if (percent < left) {
               percent = left;
             } else if (percent > right) {
               percent = right;
             }
-            return _this.$div.css("margin-left", "" + (percent - right) + "%");
-          });
-          _this.$label.on("mouseup mouseleave", function(e) {
+            _this.$div.css("margin-left", "" + (percent - right) + "%");
+            return _this.$element.trigger("focus");
+          },
+          "mousedown.bootstrapSwitch": function(e) {
+            if (_this.drag || _this.options.disabled || _this.options.readonly) {
+              return;
+            }
+            _this.drag = true;
+            if (_this.options.animate) {
+              _this.$wrapper.removeClass("switch-animate");
+            }
+            return _this.$element.trigger("focus");
+          },
+          "mouseup.bootstrapSwitch": function(e) {
+            if (!_this.drag) {
+              return;
+            }
+            _this.drag = false;
+            _this.$element.prop("checked", parseInt(_this.$div.css("margin-left"), 10) > -25).trigger("change");
+            _this.$div.css("margin-left", "");
+            if (_this.options.animate) {
+              return _this.$wrapper.addClass("switch-animate");
+            }
+          },
+          "click.bootstrapSwitch": function(e) {
             e.preventDefault();
             e.stopImmediatePropagation();
-            _this.$element.prop("checked", parseInt(_this.$div.css("margin-left"), 10) > -25).trigger("change");
-            return _this.$label.off("mousemove");
-          });
-          return _this.$label.trigger("mousemove");
+            _this.toggleState();
+            return _this.$element.trigger("focus");
+          }
         });
-        /*
-        @$label.on
-          "click touchstart": (e) =>
-            @moving = false
-        
-            e.preventDefault()
-            e.stopImmediatePropagation()
-        
-            @$wrapper.removeClass "switch-animate"
-        
-            if @moving
-              @$element.prop "checked", (parseInt(@$div.css("margin-left"), 10) > -25)
-            else
-              @$element.prop "checked", not @$element.is(":checked")
-        
-            @$element.trigger "change"
-            # @$label.off "click" if @$element.is(":disabled") or @$element.is("[readonly]") or @$element.hasClass "radio-no-uncheck"
-          "mousemove touchmove": (e) =>
-            relativeX = (e.pageX or e.originalEvent.targetTouches[0].pageX) - @$wrapper.offset().left
-            percent = (relativeX / @$wrapper.width()) * 100
-            left = 25
-            right = 75
-        
-            @moving = true
-            if percent < left
-              percent = left
-            else if percent > right
-              percent = right
-        
-            @$div.css "margin-left", "#{percent - right}%"
-          "click touchend": (e) =>
-            e.stopImmediatePropagation()
-            e.preventDefault()
-        
-            @$label.off "mouseleave"
-          mouseleave: (e) =>
-            e.preventDefault()
-            e.stopImmediatePropagation()
-        
-            @$label.off("mouseleave mousemove").trigger "mouseup"
-            @$element.prop("checked", (parseInt(@$div.css("margin-left"), 10) > -25)).trigger "change"
-          mouseup: (e) =>
-            e.stopImmediatePropagation()
-            e.preventDefault()
-        
-            @$label.trigger "mouseleave"
-        */
-
       };
 
       BootstrapSwitch.prototype._form = function() {
@@ -420,21 +383,21 @@
         if ($form.data("bootstrap-switch")) {
           return;
         }
-        return $form.data("bootstrap-switch", true).on("reset", function() {
+        return $form.on("reset.bootstrapSwitch", function() {
           return window.setTimeout(function() {
-            return $form.find(".has-switch").each(function() {
-              var $input;
-              $input = $(this).find("input");
-              return $input.prop("checked", $input.is(":checked")).trigger("change");
+            return $form.find("input").filter(function() {
+              return $(this).data("bootstrap-switch");
+            }).each(function() {
+              return $(this).bootstrapSwitch("state", false);
             });
           }, 1);
-        });
+        }).data("bootstrap-switch", true);
       };
 
       return BootstrapSwitch;
 
     })();
-    return $.fn.extend({
+    $.fn.extend({
       bootstrapSwitch: function() {
         var args, option, ret;
         option = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
@@ -444,7 +407,7 @@
           $this = $(this);
           data = $this.data("bootstrap-switch");
           if (!data) {
-            $this.data("bootstrap-switch", (data = new BootstrapSwitch(this, option)));
+            $this.data("bootstrap-switch", data = new BootstrapSwitch(this, option));
           }
           if (typeof option === "string") {
             return ret = data[option].apply(data, args);
@@ -453,6 +416,7 @@
         return ret;
       }
     });
+    return $.fn.bootstrapSwitch.Constructor = BootstrapSwitch;
   })(window.jQuery, window);
 
 }).call(this);

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
build/js/bootstrap-switch.min.js


+ 5 - 5
docs/index.js

@@ -59,16 +59,16 @@ $(function() {
   // readonly
   var $readonly = $('#readonly-switch');
   $('#btn-readonly-is').on('click', function () {
-    alert($readonly.bootstrapSwitch('readOnly'));
+    alert($readonly.bootstrapSwitch('readonly'));
   });
   $('#btn-readonly-toggle').on('click', function () {
-    $readonly.bootstrapSwitch('toggleReadOnly');
+    $readonly.bootstrapSwitch('toggleReadonly');
   });
   $('#btn-readonly-set').on('click', function () {
-    $readonly.bootstrapSwitch('readOnly', true);
+    $readonly.bootstrapSwitch('readonly', true);
   });
   $('#btn-readonly-remove').on('click', function () {
-    $readonly.bootstrapSwitch('readOnly', false);
+    $readonly.bootstrapSwitch('readonly', false);
   });
 
   // label
@@ -87,7 +87,7 @@ $(function() {
   });
 
   // event handler
-  $('#switch-change').on('switch-change', function (e, data) {
+  $('#switch-change').on('switchChange', function (e, data) {
     var $element = $(data.el),
       value = data.value;
 

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 6 - 0
docs/vendor/bootstrap.min.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
docs/vendor/jquery.min.js


+ 18 - 24
index.html

@@ -55,10 +55,10 @@
           <div class="page-header">
             <h2><a href="#sizes">Sizes</a></h2>
           </div>
-          <input type="checkbox" checked class="switch-large">
+          <input type="checkbox" checked data-size="large">
           <input type="checkbox" checked>
-          <input type="checkbox" checked class="switch-small">
-          <input type="checkbox" checked class="switch-mini">
+          <input type="checkbox" checked data-size="small">
+          <input type="checkbox" checked data-size="mini">
           <br>
           <br>
           <p>Change the size programmatically:</p>
@@ -70,10 +70,10 @@
           <button id="btn-size-small-switch" class="btn btn-default">Small</button>
           <button id="btn-size-mini-switch" class="btn btn-default">Mini</button>
           <br>
-          <pre class="language-markup"><code>&lt;input type="checkbox" checked class="switch-large">
+          <pre class="language-markup"><code>&lt;input type="checkbox" checked data-size="large">
 &lt;input type="checkbox" checked>
-&lt;input type="checkbox" checked class="switch-small">
-&lt;input type="checkbox" checked class="switch-mini">
+&lt;input type="checkbox" checked data-size="small">
+&lt;input type="checkbox" checked data-size="mini">
 &lt;input id="dimension-switch" type="checkbox" checked></code></pre>
           <pre class="language-javascript"><code>// Resets to the regular style
 $('#dimension-switch').bootstrapSwitch('size', '');
@@ -165,15 +165,15 @@ $('#label-switch').bootstrapSwitch('offText', 'O');</code></pre>
             <h2><a name="icon-label-text" class="anchor" href="#html-text-label-icon">Icon Label Text</a></h2>
           </div>
 
-          Standard <input type="checkbox" checked class="switch-large" data-label-text="<span class='glyphicon glyphicon-fullscreen'></span>" data-on-text="<span class='glyphicon glyphicon-ok'></span>" data-off-text="<span class='glyphicon glyphicon-remove'></span>"> &nbsp;&nbsp;
+          Standard <input type="checkbox" checked data-size="large" data-label-text="<span class='glyphicon glyphicon-fullscreen'></span>" data-on-text="<span class='glyphicon glyphicon-ok'></span>" data-off-text="<span class='glyphicon glyphicon-remove'></span>"> &nbsp;&nbsp;
 
-          Font Awesome <input type="checkbox" checked class="switch-large" data-label-text="<span class='fa fa-youtube fa-lg'></span>" data-on-text="<span class='fa fa-thumbs-up fa-lg'></span>" data-off-text="<span class='fa fa-thumbs-down fa-lg'></span>"> &nbsp;&nbsp;
+          Font Awesome <input type="checkbox" checked data-size="large" data-label-text="<span class='fa fa-youtube fa-lg'></span>" data-on-text="<span class='fa fa-thumbs-up fa-lg'></span>" data-off-text="<span class='fa fa-thumbs-down fa-lg'></span>"> &nbsp;&nbsp;
 
-          Flat UI <input type="checkbox" class="switch-large" checked data-label-text="<span class='fui-video'></span>" data-on-text="<span class='fui-check'></span>" data-off-text="<span class='fui-cross'></span>">
+          Flat UI <input type="checkbox" data-size="large" checked data-label-text="<span class='fui-video'></span>" data-on-text="<span class='fui-check'></span>" data-off-text="<span class='fui-cross'></span>">
 
-          <pre class="language-markup"><code>&lt;input type="checkbox" checked class="switch-large" data-label-text="&lt;span class='glyphicon glyphicon-fullscreen'>&lt;/span>" data-on-text="&lt;span class='glyphicon glyphicon-ok'>&lt;/span>" data-off-text="&lt;span class='glyphicon glyphicon-remove'>&lt;/span>">
-&lt;input type="checkbox" checked class="switch-large" data-label-text="&lt;span class='fa fa-youtube fa-lg'>&lt;/span>" data-on-text="&lt;span class='fa fa-thumbs-up fa-lg'>&lt;/span>" data-off-text="&lt;span class='fa fa-thumbs-down fa-lg'>&lt;/span>">
-&lt;input type="checkbox" class="switch-large" checked data-label-text="&lt;span class='fui-video'>&lt;/span>" data-on-text="&lt;span class='fui-check'>&lt;/span>" data-off-text="&lt;span class='fui-cross'>&lt;/span>"></code></pre>
+          <pre class="language-markup"><code>&lt;input type="checkbox" checked data-size="large" data-label-text="&lt;span class='glyphicon glyphicon-fullscreen'>&lt;/span>" data-on-text="&lt;span class='glyphicon glyphicon-ok'>&lt;/span>" data-off-text="&lt;span class='glyphicon glyphicon-remove'>&lt;/span>">
+&lt;input type="checkbox" checked data-size="large" data-label-text="&lt;span class='fa fa-youtube fa-lg'>&lt;/span>" data-on-text="&lt;span class='fa fa-thumbs-up fa-lg'>&lt;/span>" data-off-text="&lt;span class='fa fa-thumbs-down fa-lg'>&lt;/span>">
+&lt;input type="checkbox" data-size="large" checked data-label-text="&lt;span class='fui-video'>&lt;/span>" data-on-text="&lt;span class='fui-check'>&lt;/span>" data-off-text="&lt;span class='fui-cross'>&lt;/span>"></code></pre>
         </section>
           <div class="page-header">
             <h2><a name="event-handler-javascript" class="anchor" href="#event-handler-javascript">Event Handler <small>JavaScript</small></a></h2>
@@ -181,7 +181,7 @@ $('#label-switch').bootstrapSwitch('offText', 'O');</code></pre>
           <div class="bs-docs-example">
             <input type="checkbox" id="switch-change" checked>
           </div>
-          <pre class="language-javascript"><code>$('#switch-change').on('switch-change', function (e, data) {
+          <pre class="language-javascript"><code>$('#switch-change').on('switchChange', function (e, data) {
   var $element = $(data.el),
       value = data.value;
 
@@ -250,13 +250,13 @@ $('#toggle-state-switch').bootstrapSwitch('state', false); // true || false</cod
             <button id="btn-readonly-set" class="btn btn-default">Set readonly</button>
             <button id="btn-readonly-remove" class="btn btn-default">Remove readonly</button>
           </div>
-          <pre class="language-javascript"><code>$('#disable-switch').bootstrapSwitch('isDisabled');
+          <pre class="language-javascript"><code>$('#disable-switch').bootstrapSwitch('disabled');
 $('#disable-switch').bootstrapSwitch('toggleDisabled');
-$('#disable-switch').bootstrapSwitch('setDisabled', true);  // true || false
+$('#disable-switch').bootstrapSwitch('disabled', true);  // true || false
 
-$('#readonly-switch').bootstrapSwitch('isReadOnly');
-$('#readonly-switch').bootstrapSwitch('toggleReadOnly');
-$('#readonly-switch').bootstrapSwitch('setReadOnly', true);  // true || false</code></pre>
+$('#readonly-switch').bootstrapSwitch('readonly');
+$('#readonly-switch').bootstrapSwitch('toggleReadonly');
+$('#readonly-switch').bootstrapSwitch('readonly', true);  // true || false</code></pre>
           <div class="page-header">
             <h2><a name="radio-javascript" class="anchor" href="#radio-javascript">Radio <small>JavaScript</small></a></h2>
           </div>
@@ -278,9 +278,6 @@ $('#readonly-switch').bootstrapSwitch('setReadOnly', true);  // true || false</c
   &lt;label for="option3">Option 3&lt;/label>
   &lt;input id="option3" type="radio" name="radio1" value="option3">
 &lt;/div></code></pre>
-          <pre class="language-javascript"><code>$('.radio1').on('switch-change', function () {
-    $('.radio1').bootstrapSwitch('toggleRadioState');
-});</code></pre>
           <div class="page-header">
             <h2><a name="radio-javascript-allow-uncheck" class="anchor" href="#radio-javascript-allow-uncheck">Radio + uncheck <small>JavaScript</small></a></h2>
           </div>
@@ -302,9 +299,6 @@ $('#readonly-switch').bootstrapSwitch('setReadOnly', true);  // true || false</c
   &lt;label for="option13">Option 3&lt;/label>
   &lt;input id="option13" type="radio" name="radio2" value="option3">
 &lt;/div></code></pre>
-          <pre class="language-javascript"><code>$('.radio2').on('switch-change', function () {
-    $('.radio2').bootstrapSwitch('toggleRadioState', true);
-});</code></pre>
           <div class="page-header">
             <h2><a name="form" class="anchor" href="#form">Form</a></h2>
           </div>

+ 2 - 1
package.json

@@ -50,6 +50,7 @@
     "grunt-contrib-watch": "~0.5.3",
     "grunt-contrib-clean": "~0.5.0",
     "grunt-contrib-connect": "~0.6.0",
-    "grunt-open": "~0.2.2"
+    "grunt-open": "~0.2.2",
+    "grunt-contrib-jasmine": "~0.5.2"
   }
 }

+ 184 - 215
src/coffee/bootstrap-switch.coffee

@@ -2,67 +2,62 @@
   "use strict"
 
   class BootstrapSwitch
-    constructor: (element, option) ->
-      # @options = $.extend {}, @defaults, options
+    defaults:
+      state: true
+      size: null
+      animate: true
+      disabled: false
+      readonly: false
+      onColor: "primary"
+      offColor: "default"
+      onText: "ON"
+      offText: "OFF"
+      labelText: "&nbsp;"
+
+    constructor: (element, options = {}) ->
       @$element = $ element
-      @$switchLeft = $ "<span>",
-        class: =>
-          cls = "switch-left"
-          color = @$element.data "on-color"
-
-          cls += " switch-#{color}" if color?
-          cls
-        html: =>
-          html = "ON"
-          text = @$element.data "on-text"
-
-          html = text if text?
-          html
-      @$switchRight = $ "<span>",
-        class: =>
-          cls = "switch-right"
-          color = @$element.data "off-color"
-
-          cls += " switch-#{color}" if color?
-          cls
-        html: =>
-          html = "OFF"
-          text = @$element.data "off-text"
-
-          html = text if text?
-          html
+      @options = $.extend {}, @defaults, options,
+        state: @$element.is ":checked"
+        size: @$element.data "size"
+        animate: @$element.data "animate"
+        disabled: @$element.is ":disabled"
+        readonly: @$element.is "[readonly]"
+        onColor: @$element.data "on-color"
+        offColor: @$element.data "off-color"
+        onText: @$element.data "on-text"
+        offText: @$element.data "off-text"
+        labelText: @$element.data "label-text"
+      @$on = $ "<span>",
+        class: "switch-handle-on switch-#{@options.onColor}"
+        html: @options.onText
+      @$off = $ "<span>",
+        class: "switch-handle-off switch-#{@options.offColor}"
+        html: @options.offText
       @$label = $ "<label>",
-        for: @$element.attr("id")
-        html: =>
-          html = "&nbsp;"
-          text = @$element.data "label-text"
-          html = text if text?
-          html
+        for: @$element.attr "id"
+        html: @options.labelText
       @$wrapper = $ "<div>",
         class: =>
-          classes = ["has-switch"]
-
-          # apply size class
-          if @$element.attr("class")
-            for cls in ["mini", "small", "large"]
-              classes.push "switch-#{cls}" if @$element.hasClass "switch-#{cls}"
-
-          classes.push if @$element.is ":checked" then "switch-on" else "switch-off"
-          classes.push "switch-animate" if @$element.data("animate") isnt false
-          classes.push "disabled" if @$element.is(":disabled") or @$element.is "[readonly]"
+          classes = ["switch"]
+
+          classes.push if @options.state then "switch-on" else "switch-off"
+          classes.push "switch-#{@options.size}" if @options.size?
+          classes.push "switch-animate" if @options.animate
+          classes.push "switch-disabled" if @options.disabled
+          classes.push "switch-readonly" if @options.readonly
+          classes.push "switch-id-#{@$element.attr("id")}" if @$element.attr "id"
           classes.join " "
-        tabindex: 0
 
       # reassign elements after dom modification
       @$div = @$element.wrap($("<div>")).parent()
       @$wrapper = @$div.wrap(@$wrapper).parent()
 
-      # insert label and switch parts
-      @$element.before(@$switchLeft).before(@$label).before @$switchRight
+      # insert handles and label
+      @$element.before(@$on).before(@$label).before @$off
 
       @_elementHandlers()
-      @_wrapperHandlers()
-      @_switchesHandlers()
+      # @_wrapperHandlers()
+      @_handleHandlers()
       @_labelHandlers()
       @_form()
 
@@ -71,14 +66,16 @@
     _constructor: BootstrapSwitch
 
     state: (value, skip) ->
-      return @$element.is ":checked" if typeof value is "undefined"
+      return @options.state if typeof value is "undefined"
+      return @$element if @options.disabled or @options.readonly
 
       @$element.prop("checked", not not value).trigger "change", skip
       @$element
 
     toggleState: (skip) ->
-      @$element.prop("checked", not @$element.is ":checked").trigger "change", skip
-      @$element
+      return @$element if @options.disabled or @options.readonly
+
+      @$element.prop("checked", not @options.state).trigger "change", skip
 
     ###
     TODO: refactor
@@ -92,229 +89,199 @@
       @$element
     ###
 
-    disabled: (value) ->
-      return @$element.is ":disabled" if typeof value is "undefined"
+    size: (value) ->
+      return @options.size if typeof value is "undefined"
+
+      @$wrapper.removeClass "switch-#{@options.size}" if @options.size?
+      @$wrapper.addClass "switch-#{value}"
+      @options.size = value
+      @$element
+
+    animate: (value) ->
+      return @options.animate if typeof value is "undefined"
 
       value = not not value
 
-      @$wrapper[if value then "addClass" else "removeClass"]("disabled")
-      @$element.prop "disabled", value
+      @$wrapper[if value then "addClass" else "removeClass"]("switch-animate")
+      @options.animate = value
       @$element
 
-    toggleDisabled: ->
-      @$element.prop("disabled", not @$element.is ":disabled")
-      @$wrapper.toggleClass "disabled"
-      @$element
+    disabled: (value) ->
+      return @options.disabled if typeof value is "undefined"
 
-    readOnly: (value) ->
-      return @$element.is "[readonly]" if typeof value is "undefined"
+      value = not not value
 
-      if readonly
-        @$wrapper.addClass "disabled"
-        @$element.prop "readonly", true
-      else
-        @$wrapper.removeClass "disabled"
-        @$element.prop "readonly", false
+      @$wrapper[if value then "addClass" else "removeClass"]("switch-disabled")
+      @$element.prop "disabled", value
+      @options.disabled = value
       @$element
 
-    toggleReadOnly: ->
-      @$element
-      .prop("readonly", not @$element.is("[readonly]"))
-      .parents(".has-switch")
-      .toggleClass "disabled"
+    toggleDisabled: ->
+      @$element.prop "disabled", not @options.disabled
+      @$wrapper.toggleClass "switch-disabled"
+      @options.disabled = not @options.disabled
       @$element
 
-    labelText: (value) ->
-      @$element.siblings("label").html value or "&nbsp"
-      @$element
+    readonly: (value) ->
+      return @options.readonly if typeof value is "undefined"
 
-    onText: (value) ->
-      return @$switchLeft.html() if typeof value is "undefined"
+      value = not not value
 
-      @$switchLeft.html value
+      @$wrapper[if value then "addClass" else "removeClass"]("switch-readonly")
+      @$element.prop "readonly", value
+      @options.readonly = value
       @$element
 
-    offText: (value) ->
-      return @$switchRight.html() if typeof value is "undefined"
-
-      @$switchRight.html value
+    toggleReadonly: ->
+      @$element.prop "readonly", not @options.readonly
+      @$wrapper.toggleClass "switch-readonly"
+      @options.readonly = not @options.readonly
       @$element
 
     onColor: (value) ->
-      # TODO: add data-on-color in init (defaults)
-      color = @$element.data "on-color"
+      color = @options.onColor
 
       return color if typeof value is "undefined"
 
-      @$switchLeft.removeClass "switch-#{color}" if color?
-      @$switchLeft.addClass "switch-#{value}"
-      @$element.data "on-color", value
+      @$on.removeClass "switch-#{color}" if color?
+      @$on.addClass "switch-#{value}"
+      @options.onColor = value
       @$element
 
     offColor: (value) ->
-      # TODO: add data-on-color in init (defaults)
-      color = @$element.data "off-color"
+      color = @options.offColor
 
       return color if typeof value is "undefined"
 
-      @$switchRight.removeClass "switch-#{color}" if color?
-      @$switchRight.addClass "switch-#{value}"
-      @$element.data "off-color", value
+      @$off.removeClass "switch-#{color}" if color?
+      @$off.addClass "switch-#{value}"
+      @options.offColor = value
       @$element
 
-    animate: (value) ->
-      return @$element.data "animate" if typeof value is "undefined"
+    onText: (value) ->
+      return @options.onText if typeof value is "undefined"
 
-      value = not not value
+      @$on.html value
+      @options.onText = value
+      @$element
 
-      @$wrapper[if value then "addClass" else "removeClass"]("switch-animate")
-      @$element.data "animate", value
+    offText: (value) ->
+      return @options.offText if typeof value is "undefined"
+
+      @$off.html value
+      @options.offText = value
       @$element
 
-    size: (value) ->
-      return @$wrapper.hasClass "switch-#{value}" if typeof value is "undefined"
+    labelText: (value) ->
+      return @options.labelText if typeof value is "undefined"
 
-      for cls in ["mini", "small", "large"]
-        @$wrapper[if cls isnt value then "removeClass" else "addClass"]("switch-#{cls}")
+      @$label.html value
+      @options.labelText = value
       @$element
 
     destroy: ->
       $form = @$element.closest "form"
 
+      $form.off("reset.bootstrapSwitch").removeData "bootstrap-switch" if $form.length
       @$div.children().not(@$element).remove()
-      @$element.unwrap().unwrap().off "change"
-
-      $form.off("reset").removeData "bootstrap-switch" if $form.length
+      @$element.unwrap().unwrap().off(".bootstrapSwitch").removeData "bootstrap-switch"
       @$element
 
     _elementHandlers: ->
-      @$element.on "change", (e, skip) =>
-        e.preventDefault()
-
-        isChecked = @$element.is ":checked"
-        state = @$wrapper.hasClass "switch-off"
-
-        @$div.css "margin-left", ""
-        return unless state is isChecked
-
-        if isChecked
-          @$wrapper.removeClass("switch-off").addClass "switch-on"
-        else
-          @$wrapper.removeClass("switch-on").addClass "switch-off"
-
-        @$wrapper.addClass "switch-animate" if @$element.data("animate") isnt false
-        return if typeof skip is "boolean" and skip
-
-        @$element.trigger "switch-change",
-          el: @$element
-          value: isChecked
-
-    _wrapperHandlers: ->
-      @$wrapper.on "keydown", (e) =>
-        return if not e.which or @$element.is(":disabled") or @$element.is "[readonly]"
-
-        switch e.which
-          when 32
-            e.preventDefault()
-            @toggleState()
-          when 37
-            e.preventDefault()
-            @toggleState() if @$element.is ":checked"
-          when 39
-            e.preventDefault()
-            @toggleState() unless @$element.is ":checked"
-
-    _switchesHandlers: ->
-      @$switchLeft.on "click", => @toggleState()
-      @$switchRight.on "click", => @toggleState()
-
-    _labelHandlers: ->
-      ###
-      @$label.on "click", =>
-        e.preventDefault()
-        e.stopImmediatePropagation()
-
-        @toggleState()
-      ###
-
-      @$label.on "click", (e) =>
-        e.preventDefault()
-        e.stopImmediatePropagation()
-
-        @$wrapper.removeClass "switch-animate"
-        return if @moving # @$element.prop "checked", (parseInt(@$div.css("margin-left"), 10) > -25)
+      @$element.on
+        "change.bootstrapSwitch": (e, skip) =>
+          e.preventDefault()
+          e.stopPropagation()
+          e.stopImmediatePropagation()
 
-        @$label.on "mousemove", (e) =>
-          relativeX = (e.pageX or e.originalEvent.targetTouches[0].pageX) - @$wrapper.offset().left
-          percent = (relativeX / @$wrapper.width()) * 100
-          left = 25
-          right = 75
+          checked = @$element.is ":checked"
 
-          @moving = true
-          if percent < left
-            percent = left
-          else if percent > right
-            percent = right
+          return if checked is @options.state
 
-          @$div.css "margin-left", "#{percent - right}%"
+          @options.state = checked
+          @$wrapper
+          .removeClass(if checked then "switch-off" else "switch-on")
+          .addClass if checked then "switch-on" else "switch-off"
 
-        @$label.on "mouseup mouseleave", (e) =>
+          @$element.trigger "switchChange", el: @$element, value: checked if not skip
+        "focus.bootstrapSwitch": (e) =>
           e.preventDefault()
+          e.stopPropagation()
           e.stopImmediatePropagation()
 
-          # @$label.off("mouseleave mousemove").trigger "mouseup"
-          @$element.prop("checked", (parseInt(@$div.css("margin-left"), 10) > -25)).trigger "change"
-          @$label.off("mousemove")
-
-        @$label.trigger "mousemove"
-
-      ###
-      @$label.on
-        "click touchstart": (e) =>
-          @moving = false
-
+          @$wrapper.addClass "switch-focused"
+        "blur.bootstrapSwitch": (e) =>
           e.preventDefault()
+          e.stopPropagation()
           e.stopImmediatePropagation()
 
-          @$wrapper.removeClass "switch-animate"
+          @$wrapper.removeClass "switch-focused"
+        "keydown.bootstrapSwitch": (e) =>
+          return if not e.which or @options.disabled or @options.readonly
+
+          switch e.which
+            when 32
+              e.preventDefault()
+              e.stopPropagation()
+              e.stopImmediatePropagation()
+
+              @toggleState()
+            when 37
+              e.preventDefault()
+              e.stopPropagation()
+              e.stopImmediatePropagation()
+
+              @state false
+            when 39
+              e.preventDefault()
+              e.stopPropagation()
+              e.stopImmediatePropagation()
+
+              @state true
+
+    _handleHandlers: ->
+      @$on.on "click.bootstrapSwitch", (e) =>
+        @state false
+        @$element.trigger "focus"
+      @$off.on "click.bootstrapSwitch", (e) =>
+        @state true
+        @$element.trigger "focus"
 
-          if @moving
-            @$element.prop "checked", (parseInt(@$div.css("margin-left"), 10) > -25)
-          else
-            @$element.prop "checked", not @$element.is(":checked")
+    _labelHandlers: ->
+      @$label.on
+        "mousemove.bootstrapSwitch": (e) =>
+          return unless @drag
 
-          @$element.trigger "change"
-          # @$label.off "click" if @$element.is(":disabled") or @$element.is("[readonly]") or @$element.hasClass "radio-no-uncheck"
-        "mousemove touchmove": (e) =>
-          relativeX = (e.pageX or e.originalEvent.targetTouches[0].pageX) - @$wrapper.offset().left
-          percent = (relativeX / @$wrapper.width()) * 100
+          percent = ((e.pageX - @$wrapper.offset().left) / @$wrapper.width()) * 100
           left = 25
           right = 75
 
-          @moving = true
           if percent < left
             percent = left
           else if percent > right
             percent = right
 
           @$div.css "margin-left", "#{percent - right}%"
-        "click touchend": (e) =>
-          e.stopImmediatePropagation()
-          e.preventDefault()
+          @$element.trigger "focus"
+        "mousedown.bootstrapSwitch": (e) =>
+          return if @drag or @options.disabled or @options.readonly
 
-          @$label.off "mouseleave"
-        mouseleave: (e) =>
-          e.preventDefault()
-          e.stopImmediatePropagation()
+          @drag = true
+          @$wrapper.removeClass "switch-animate" if @options.animate
+          @$element.trigger "focus"
+        "mouseup.bootstrapSwitch": (e) =>
+          return unless @drag
 
-          @$label.off("mouseleave mousemove").trigger "mouseup"
+          @drag = false
           @$element.prop("checked", (parseInt(@$div.css("margin-left"), 10) > -25)).trigger "change"
-        mouseup: (e) =>
-          e.stopImmediatePropagation()
+          @$div.css "margin-left", ""
+          @$wrapper.addClass "switch-animate" if @options.animate
+        "click.bootstrapSwitch": (e) =>
           e.preventDefault()
+          e.stopImmediatePropagation()
 
-          @$label.trigger "mouseleave"
-      ###
+          @toggleState()
+          @$element.trigger "focus"
 
     _form: ->
       $form = @$element.closest "form"
@@ -322,13 +289,14 @@
       return if $form.data "bootstrap-switch"
 
       $form
-      .data("bootstrap-switch", true)
-      .on "reset", ->
-        window.setTimeout(->
-          $form.find(".has-switch").each ->
-            $input = $(@).find("input")
-            $input.prop("checked", $input.is(":checked")).trigger "change"
-        , 1)
+      .on "reset.bootstrapSwitch", ->
+        window.setTimeout ->
+          $form
+          .find("input")
+          .filter( -> $(@).data "bootstrap-switch")
+          .each -> $(@).bootstrapSwitch "state", false
+        , 1
+      .data "bootstrap-switch", true
 
   $.fn.extend bootstrapSwitch: (option, args...) ->
     ret = @
@@ -336,8 +304,9 @@
       $this = $(@)
       data = $this.data "bootstrap-switch"
 
-      $this.data "bootstrap-switch", (data = new BootstrapSwitch @, option) if not data
+      $this.data "bootstrap-switch", data = new BootstrapSwitch @, option if not data
       ret = data[option].apply data, args if typeof option is "string"
     ret
-  # $.fn.bootstrapSwitch.Constructor = BootstrapSwitch
+
+  $.fn.bootstrapSwitch.Constructor = BootstrapSwitch
 ) window.jQuery, window

+ 6 - 6
src/less/bootstrap2/bootstrap-switch.less

@@ -1,4 +1,4 @@
-.has-switch {
+.switch {
   display: inline-block;
   cursor: pointer;
   .border-radius(5px);
@@ -80,7 +80,8 @@
     }
   }
 
-  &.disabled {
+  &.switch-disabled,
+  &.switch-readonly {
     .opacity(50);
     cursor: default !important;
 
@@ -120,16 +121,15 @@
       z-index: 1;
       width: 33%;
 
-      &.switch-left {
+      &.switch-handle-on {
         .border-top-left-radius(4px);
       }
 
-      &.switch-right {
+      &.switch-handle-off {
         .buttonBackground(@btnBackgroundHighlight, @btnBackground, @grayDark, 0 1px 1px rgba(255,255,255,.75));
       }
 
-      &.switch-primary,
-      &.switch-left {
+      &.switch-primary {
         .buttonBackground(@btnPrimaryBackgroundHighlight, @btnPrimaryBackground);
       }
 

+ 19 - 10
src/less/bootstrap3/bootstrap-switch.less

@@ -1,4 +1,4 @@
-.has-switch {
+.switch {
   display: inline-block;
   cursor: pointer;
   border-radius: @border-radius-base;
@@ -11,7 +11,6 @@
   .user-select(none);
   vertical-align: middle;
   min-width: 100px;
-  .form-control-focus();
   .transition(~"border-color ease-in-out .15s, box-shadow ease-in-out .15s");
 
   &.switch-mini {
@@ -81,7 +80,8 @@
     }
   }
 
-  &.disabled {
+  &.switch-disabled,
+  &.switch-readonly {
     .opacity(.5);
     cursor: default !important;
 
@@ -91,6 +91,13 @@
     }
   }
 
+  &.switch-focused {
+    @color-rgba: rgba(red(@input-border-focus), green(@input-border-focus), blue(@input-border-focus), .6);
+    border-color: @input-border-focus;
+    outline: 0;
+    .box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}");
+  }
+
   > div {
     display: inline-block;
     width: 150%;
@@ -117,18 +124,17 @@
       z-index: 1;
       width: 33.333333333%;
 
-      &.switch-left {
+      &.switch-handle-on {
         color: #f00;
         .border-left-radius(@border-radius-base - 1);
       }
 
-      &.switch-right {
+      &.switch-handle-off {
         color: #000;
         background: @gray-lighter;
       }
 
-      &.switch-primary,
-      &.switch-left {
+      &.switch-primary {
         color: #fff;
         background: @btn-primary-bg;
       }
@@ -170,8 +176,11 @@
     }
   }
 
-  input[type=radio],
-  input[type=checkbox] {
-    display: none;
+  input[type='radio'],
+  input[type='checkbox'] {
+    position: absolute !important;
+    top: 0;
+    left: 0;
+    z-index: -1;
   }
 }

+ 1 - 0
src/test/bootstrap-switch.coffee

@@ -0,0 +1 @@
+describe "Bootstrap Switch", ->

+ 4 - 0
test/bootstrap-switch.js

@@ -0,0 +1,4 @@
+(function() {
+  describe("Bootstrap Switch", function() {});
+
+}).call(this);

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.