breautek edited a comment on issue #228:
URL: https://github.com/apache/cordova/issues/228#issuecomment-704659502


   Hi there, I've finally got around to investigate this a bit.
   
   ## The Problem
   
   The reason why this is failing is because two things are overriding the 
`addEventListener` API.
   
   `zone-evergreen.js` does so at using this function: 
https://github.com/angular/zone.js/blob/b11bd466c20dc338b6d4d5bc3e59868ff263778d/dist/zone-evergreen.js#L1806
   
   `zone-evergreen.js` is kind of complicated, so I'm not sure at what point it 
actually overrides the `addEventListener` function, I just know that it does. 
AB testing both versions in your reproduction app shows the event leads to 
`platform-browser.js:395` (angular framework code) 
   
   ```javascript
   addEventListener(element, eventName, handler) {
       const plugin = this._findPluginFor(eventName);
       return plugin.addEventListener(element, eventName, handler);
   }
   ````
   
   Where on non-cordova, `plugin.addEventListener` method points to the 
function defined to `zone-evergreen.js` posted above,
   
   and on Cordova, the function points to 
https://github.com/apache/cordova-browser/blob/3b077ad590adc6f53a93b8af98efb20f8b1caeb7/cordova-lib/cordova.js#L123
   
   ```javascript
   document.addEventListener = function (evt, handler, capture) {
       var e = evt.toLowerCase();
       if (typeof documentEventHandlers[e] !== 'undefined') {
           documentEventHandlers[e].subscribe(handler);
       } else {
           m_document_addEventListener.call(document, evt, handler, capture);
       }
   };
   ```
   As you can see, Cordova overrides the addEventListener method to handle some 
cordova-specific events, such as `deviceready`, `pause`, `resume`, and 
`activated`. Cordova **will** fallback to the original implementation of 
`addEventListener` if the incoming event isn't a cordova-defined event. 
However, unfortunately that original implementation is a reference to the 
native `addEventListener` and not Angular's/Zone replacement implementation.
   
   Basically this means angular never receives events such as `mousemove`.
   
   Personally I see this as bad practice on both sides, no one should be 
touching/replacing native functions. This case is a prime example of the why. 
But obviously these are decisions well baked into both frameworks and is 
incredibly hard to change without virtually breaking every single project using 
the framework. This means Angular and Cordova doesn't really support each other.
   
   ## Workaround
   
   I tried moving the `cordova.js` script tag so it's loaded after the angular 
framework. I also had to remove the `defer` attribute on the angular script 
tags to ensure that are loaded and executed first. This will make Cordova store 
a reference to the modified `addEventListener` interface rather than the 
browser's native function. This appears to work but mileage may vary. I'm not 
sure if this will break anything else, but I don't see deviceready not invoked 
5 second warning, so *that's a good sign*.
   
   Because I don't believe Cordova will change anything in relation to this, 
I'll be closing this issue.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cordova.apache.org
For additional commands, e-mail: commits-h...@cordova.apache.org

Reply via email to