{"action":"opened","issue":{"url":"https://api.github.com/repos/xdan/datetimepicker/issues/669","repository_url":"https://api.github.com/repos/xdan/datetimepicker","labels_url":"https://api.github.com/repos/xdan/datetimepicker/issues/669/labels{/name}","comments_url":"https://api.github.com/repos/xdan/datetimepicker/issues/669/comments","events_url":"https://api.github.com/repos/xdan/datetimepicker/issues/669/events","html_url":"https://github.com/xdan/datetimepicker/issues/669","id":332580901,"node_id":"MDU6SXNzdWUzMzI1ODA5MDE=","number":669,"title":"Paste event fired multiple times and overflows legal mask length","user":{"login":"KyleMit","id":4307307,"node_id":"MDQ6VXNlcjQzMDczMDc=","avatar_url":"https://avatars2.githubusercontent.com/u/4307307?v=4","gravatar_id":"","url":"https://api.github.com/users/KyleMit","html_url":"https://github.com/KyleMit","followers_url":"https://api.github.com/users/KyleMit/followers","following_url":"https://api.github.com/users/KyleMit/following{/other_user}","gists_url":"https://api.github.com/users/KyleMit/gists{/gist_id}","starred_url":"https://api.github.com/users/KyleMit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/KyleMit/subscriptions","organizations_url":"https://api.github.com/users/KyleMit/orgs","repos_url":"https://api.github.com/users/KyleMit/repos","events_url":"https://api.github.com/users/KyleMit/events{/privacy}","received_events_url":"https://api.github.com/users/KyleMit/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-06-14T22:06:23Z","updated_at":"2018-06-14T22:06:23Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"One issue is that the paste event handler gets attached (and subsequently fired) multiple times.  \r\n\r\nHere's a Minimal, Complete, and Verifiable example which  showcases the problems when pasting\r\n\r\n### [MCVE in Plunker][0]\r\n\r\n![datetimepicker-paste][5]\r\n\r\nYou can verify this by selecting the element and looking at the attached handlers:\r\n\r\n![Paste Event Handlers][1]\r\n\r\nIf we navigate to the [code that attaches the listener][2], and put a breakpoint there, we can look at the call stack to see who's attaching it repeatedly:\r\n\r\n![Listener Call Stack][3]\r\n\r\nWhich is added by [this function][4] that fires on every focus:\r\n\r\n```js\r\n.on('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', function () {\r\n    /* ... */\r\n    if(options.mask) {\r\n        setMask(options); // <-- adds event handler on each call\r\n    }\r\n```\r\n\r\nOne solution would be to call `.off` and remove any existing handlers (within the xdsoft namespace) before attaching like this:\r\n\r\n<pre><code>input<b>.off('paste.xdsoft')</b>.on('paste.xdsoft', function (event) { /* ... */ }\r\n</code></pre>\r\n\r\nWe can also add better handling to the paste.  The field is currently composed like this:\r\n\r\n```js\r\nval = valueBeforeCursor + pastedData + valueAfterPaste;  \r\n```\r\n\r\nBut if a very long string was pasted in, it'll break the mask format length and allow the insert.  We'll never want input that is longer than the format mask, so it's marginally better to just arbitrarily just cut off the total input when it hits that size like this:\r\n\r\n<pre><code class=\"hljs\">val = valueBeforeCursor + pastedData + valueAfterPaste;  \r\n<b>val = val.substring(0, options.mask.length)</b>\r\n</code></pre>\r\n\r\nThis is a subsequent iteration of the changes to paste as part of #416 \r\n\r\n[0]: https://next.plnkr.co/edit/vRu8ONwFovMrGAtA\r\n[1]: https://user-images.githubusercontent.com/4307307/41439517-10985ec8-6ff9-11e8-8149-ca41ac54f872.png\r\n[2]: https://github.com/xdan/datetimepicker/blob/2.5.20/jquery.datetimepicker.js#L2373\r\n[3]: https://user-images.githubusercontent.com/4307307/41439718-d8447de4-6ff9-11e8-99cf-50bc381f2196.png\r\n[4]: https://github.com/xdan/datetimepicker/blob/2.5.20/jquery.datetimepicker.js#L2515\r\n[5]: https://user-images.githubusercontent.com/4307307/41440595-1ce48414-6ffd-11e8-9baf-7efbeb5526b2.gif"}}
{"actor":{"display_login":"KyleMit"}}