zepto icon indicating copy to clipboard operation
zepto copied to clipboard

the event data assert has a bug on Chrome 60+

Open DemonCloud opened this issue 7 years ago • 4 comments

Uncaught TypeError: Cannot assign to read only property 'data' of object '#<InputEvent>'

the bug this if you delegate event , with bind data object

 div#a
  div#b: input(delegate)

then will throw the error on Chrome

DemonCloud avatar Jul 26 '17 06:07 DemonCloud

Could you please provide a full example and point out where it fails and what the expected result is? Ideally use something like https://codepen.io. Thanks!

madrobby avatar Aug 06 '17 12:08 madrobby

@madrobby difference data https://jsfiddle.net/CloudyWolf/4s31thg3/

DemonCloud avatar Aug 11 '17 06:08 DemonCloud

Hey, I'm running into a similar issue here. When using Zepto with jqueryMask plugin in mobile (Android/Chrome 60), I'm getting the same error message. I figured out that Zepto try to set an undefined data to a read-only prop from an #<InputEvent> type. The problem is occurring in this block of code:

https://github.com/madrobby/zepto/blob/master/src/event.js#L68

Wrapping this line with try-catch I could get things working, but it does not solves the problem.

try{
  e.data = data;
}
catch(error) {
  console.log(error);
}

allanesquina avatar Sep 20 '17 19:09 allanesquina

`function fixEvent(e) {

const Event = function(src){
  // Event object
  if ( src && src.type ) {
    this.originalEvent = src;
    this.type = src.type;

    // Events bubbling up the document may have been marked as prevented
    // by a handler lower down the tree; reflect the correct value.
    this.isDefaultPrevented = src.defaultPrevented ||
        src.defaultPrevented === undefined &&
      src.returnValue === false ?
      returnTrue :
      returnFalse;

    this.target = ( src.target && src.target.nodeType === 3 ) ?
      src.target.parentNode :
      src.target;

    this.currentTarget = src.currentTarget;
    this.relatedTarget = src.relatedTarget;

  // Event type
  } else {
    this.type = src;
  }
  this.timeStamp = src && src.timeStamp || Date.now();
 };

 Event.prototype = {
  constructor: $.Event,
  isDefaultPrevented: returnFalse,
  isPropagationStopped: returnFalse,
  isImmediatePropagationStopped: returnFalse,
  isSimulated: false,

  preventDefault: function() {
    var e = this.originalEvent;

    this.isDefaultPrevented = returnTrue;

    if ( e && !this.isSimulated ) {
      e.preventDefault();
    }
  },
  stopPropagation: function() {
    var e = this.originalEvent;
    this.isPropagationStopped = returnTrue;
    if ( e && !this.isSimulated ) {
      e.stopPropagation();
    }
  },
  stopImmediatePropagation: function() {
    var e = this.originalEvent;

    this.isImmediatePropagationStopped = returnTrue;

    if ( e && !this.isSimulated ) {
      e.stopImmediatePropagation();
    }

    this.stopPropagation();
  }
};

 //each and addProp 
 function addProp( name, hook) {
  Object.defineProperty(Event.prototype, name, {
    enumerable: true,
    configurable: true,
    get: isFunction( hook ) ?
      function() {
        if ( this.originalEvent ) {
            return hook( this.originalEvent );
        }
      } :
      function() {
        if ( this.originalEvent ) {
            return this.originalEvent[ name ];
        }
      },

    set: function( value ) {
      Object.defineProperty( this, name, {
        enumerable: true,
        configurable: true,
        writable: true,
        value: value
      } );
    }
  } );
};

 $.each({
  altKey: true,
  bubbles: true,
  cancelable: true,
  changedTouches: true,
  ctrlKey: true,
  detail: true,
  eventPhase: true,
  metaKey: true,
  pageX: true,
  pageY: true,
  shiftKey: true,
  view: true,
  "char": true,
  charCode: true,
  key: true,
  keyCode: true,
  button: true,
  buttons: true,
  clientX: true,
  clientY: true,
  offsetX: true,
  offsetY: true,
  pointerId: true,
  pointerType: true,
  screenX: true,
  screenY: true,
  targetTouches: true,
  toElement: true,
  touches: true,

  which: function( event ) {
    var button = event.button;

    // Add which for key events
    if ( event.which == null && rkeyEvent.test( event.type ) ) {
      return event.charCode != null ? event.charCode : event.keyCode;
    }

    if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
      if ( button & 1 ) {
        return 1;
      }

      if ( button & 2 ) {
        return 3;
      }

      if ( button & 4 ) {
        return 2;
      }

      return 0;
    }

    return event.which;
  }
}, addProp);

  return new Event(e);
}

function returnTrue() {
  return true;
}

function returnFalse() {
  return false;
}

// ... e = fixEvent(e); // ... `

beMySun avatar Apr 08 '18 04:04 beMySun