1 /**
  2  * @fileOverview  change bubble and checkbox/radio fix patch for ie<9
  3  * @author yiminghe@gmail.com
  4  */
  5 KISSY.add("event/change", function (S, UA, Event, DOM, special) {
  6     var mode = S.Env.host.document['documentMode'];
  7 
  8     if (UA['ie'] && (UA['ie'] < 9 || (mode && mode < 9))) {
  9 
 10         var rformElems = /^(?:textarea|input|select)$/i;
 11 
 12         function isFormElement(n) {
 13             return rformElems.test(n.nodeName);
 14         }
 15 
 16         function isCheckBoxOrRadio(el) {
 17             var type = el.type;
 18             return type == "checkbox" || type == "radio";
 19         }
 20 
 21         special['change'] = {
 22             setup:function () {
 23                 var el = this;
 24                 if (isFormElement(el)) {
 25                     // checkbox/radio only fires change when blur in ie<9
 26                     // so use another technique from jquery
 27                     if (isCheckBoxOrRadio(el)) {
 28                         // change in ie<9
 29                         // change = propertychange -> click
 30                         Event.on(el, "propertychange", propertyChange);
 31                         Event.on(el, "click", onClick);
 32                     } else {
 33                         // other form elements use native , do not bubble
 34                         return false;
 35                     }
 36                 } else {
 37                     // if bind on parentNode ,lazy bind change event to its form elements
 38                     // note event order : beforeactivate -> change
 39                     // note 2: checkbox/radio is exceptional
 40                     Event.on(el, "beforeactivate", beforeActivate);
 41                 }
 42             },
 43             tearDown:function () {
 44                 var el = this;
 45                 if (isFormElement(el)) {
 46                     if (isCheckBoxOrRadio(el)) {
 47                         Event.remove(el, "propertychange", propertyChange);
 48                         Event.remove(el, "click", onClick);
 49                     } else {
 50                         return false;
 51                     }
 52                 } else {
 53                     Event.remove(el, "beforeactivate", beforeActivate);
 54                     S.each(DOM.query("textarea,input,select", el), function (fel) {
 55                         if (fel.__changeHandler) {
 56                             fel.__changeHandler = 0;
 57                             Event.remove(fel, "change", {fn:changeHandler, last:1});
 58                         }
 59                     });
 60                 }
 61             }
 62         };
 63 
 64         function propertyChange(e) {
 65             if (e.originalEvent.propertyName == "checked") {
 66                 this.__changed = 1;
 67             }
 68         }
 69 
 70         function onClick(e) {
 71             if (this.__changed) {
 72                 this.__changed = 0;
 73                 // fire from itself
 74                 Event.fire(this, "change", e);
 75             }
 76         }
 77 
 78         function beforeActivate(e) {
 79             var t = e.target;
 80             if (isFormElement(t) && !t.__changeHandler) {
 81                 t.__changeHandler = 1;
 82                 // lazy bind change , always as last handler among user's handlers
 83                 Event.on(t, "change", {fn:changeHandler, last:1});
 84             }
 85         }
 86 
 87         function changeHandler(e) {
 88             var fel = this;
 89 
 90             if (
 91             // in case stopped by user's callback,same with submit
 92             // http://bugs.jquery.com/ticket/11049
 93             // see : test/change/bubble.html
 94                 e.isPropagationStopped ||
 95                     // checkbox/radio already bubble using another technique
 96                     isCheckBoxOrRadio(fel)) {
 97                 return;
 98             }
 99             var p;
100             if (p = fel.parentNode) {
101                 // fire from parent , itself is handled natively
102                 Event.fire(p, "change", e);
103             }
104         }
105 
106     }
107 }, {
108     requires:["ua", "./base", "dom", './special']
109 });