11/*!
2- * react-maskedinput 1.1 .0 - https://github.com/insin/react-maskedinput
2+ * react-maskedinput 2.0 .0 - https://github.com/insin/react-maskedinput
33 * MIT Licensed
44 */
55( function ( f ) { if ( typeof exports === "object" && typeof module !== "undefined" ) { module . exports = f ( ) } else if ( typeof define === "function" && define . amd ) { define ( [ ] , f ) } else { var g ; if ( typeof window !== "undefined" ) { g = window } else if ( typeof global !== "undefined" ) { g = global } else if ( typeof self !== "undefined" ) { g = self } else { g = this } g . MaskedInput = f ( ) } } ) ( function ( ) { var define , module , exports ; return ( function e ( t , n , r ) { function s ( o , u ) { if ( ! n [ o ] ) { if ( ! t [ o ] ) { var a = typeof require == "function" && require ; if ( ! u && a ) return a ( o , ! 0 ) ; if ( i ) return i ( o , ! 0 ) ; var f = new Error ( "Cannot find module '" + o + "'" ) ; throw f . code = "MODULE_NOT_FOUND" , f } var l = n [ o ] = { exports :{ } } ; t [ o ] [ 0 ] . call ( l . exports , function ( e ) { var n = t [ o ] [ 1 ] [ e ] ; return s ( n ?n :e ) } , l , l . exports , e , t , n , r ) } return n [ o ] . exports } var i = typeof require == "function" && require ; for ( var o = 0 ; o < r . length ; o ++ ) s ( r [ o ] ) ; return s } ) ( { 1 :[ function ( require , module , exports ) {
@@ -10,6 +10,17 @@ var $__0= require('react/lib/ReactInputSelection'),getSelection=$__0.getSelect
1010
1111var InputMask = require ( 'inputmask-core' )
1212
13+ var KEYCODE_Z = 90
14+ var KEYCODE_Y = 89
15+
16+ function isUndo ( e ) {
17+ return ( e . ctrlKey || e . metaKey ) && e . keyCode === ( e . shiftKey ? KEYCODE_Y : KEYCODE_Z )
18+ }
19+
20+ function isRedo ( e ) {
21+ return ( e . ctrlKey || e . metaKey ) && e . keyCode === ( e . shiftKey ? KEYCODE_Z : KEYCODE_Y )
22+ }
23+
1324var MaskedInput = React . createClass ( { displayName : "MaskedInput" ,
1425 propTypes : {
1526 pattern : React . PropTypes . string . isRequired ,
@@ -65,6 +76,25 @@ var MaskedInput = React.createClass({displayName: "MaskedInput",
6576 _onKeyDown :function ( e ) {
6677 // console.log('onKeyDown', JSON.stringify(getSelection(this.getDOMNode())), e.key, e.target.value)
6778
79+ if ( isUndo ( e ) ) {
80+ e . preventDefault ( )
81+ if ( this . mask . undo ( ) ) {
82+ e . target . value = this . _getDisplayValue ( )
83+ this . _updateInputSelection ( )
84+ this . props . onChange ( e )
85+ }
86+ return
87+ }
88+ else if ( isRedo ( e ) ) {
89+ e . preventDefault ( )
90+ if ( this . mask . redo ( ) ) {
91+ e . target . value = this . _getDisplayValue ( )
92+ this . _updateInputSelection ( )
93+ this . props . onChange ( e )
94+ }
95+ return
96+ }
97+
6898 if ( e . key == 'Backspace' ) {
6999 e . preventDefault ( )
70100 this . _updateMaskSelection ( )
@@ -323,10 +353,14 @@ function InputMask(options) {
323353 }
324354
325355 this . formatCharacters = mergeFormatCharacters ( options . formatCharacters )
326- this . setPattern ( options . pattern , options . value )
327- this . setSelection ( options . selection )
356+ this . setPattern ( options . pattern , {
357+ value : options . value ,
358+ selection : options . selection
359+ } )
328360}
329361
362+ // Editing
363+
330364/**
331365 * Applies a single character of input based on the current selection.
332366 * @param {string } char
@@ -340,6 +374,9 @@ InputMask.prototype.input = function input(char) {
340374 return false
341375 }
342376
377+ var selectionBefore = copy ( this . selection )
378+ var valueBefore = this . getValue ( )
379+
343380 var inputIndex = this . selection . start
344381
345382 // If a range of characters was selected and it includes the first editable
@@ -378,6 +415,21 @@ InputMask.prototype.input = function input(char) {
378415 this . selection . end ++
379416 }
380417
418+ // History
419+ if ( this . _historyIndex != null ) {
420+ // Took more input after undoing, so blow any subsequent history away
421+ console . log ( 'splice(' , this . _historyIndex , this . _history . length - this . _historyIndex , ')' )
422+ this . _history . splice ( this . _historyIndex , this . _history . length - this . _historyIndex )
423+ this . _historyIndex = null
424+ }
425+ if ( this . _lastOp != 'input' ||
426+ selectionBefore . start != selectionBefore . end ||
427+ this . _lastSelection != null && selectionBefore . start != this . _lastSelection . start ) {
428+ this . _history . push ( { value : valueBefore , selection : selectionBefore , lastOp : this . _lastOp } )
429+ }
430+ this . _lastOp = 'input'
431+ this . _lastSelection = copy ( this . selection )
432+
381433 return true
382434}
383435
@@ -393,6 +445,9 @@ InputMask.prototype.backspace = function backspace() {
393445 return false
394446 }
395447
448+ var selectionBefore = copy ( this . selection )
449+ var valueBefore = this . getValue ( )
450+
396451 var format
397452
398453 // No range selected - work on the character preceding the cursor
@@ -415,6 +470,19 @@ InputMask.prototype.backspace = function backspace() {
415470 this . selection . end = this . selection . start
416471 }
417472
473+ // History
474+ if ( this . _historyIndex != null ) {
475+ // Took more input after undoing, so blow any subsequent history away
476+ this . _history . splice ( this . _historyIndex , this . _history . length - this . _historyIndex )
477+ }
478+ if ( this . _lastOp != 'backspace' ||
479+ selectionBefore . start != selectionBefore . end ||
480+ this . _lastSelection != null && selectionBefore . start != this . _lastSelection . start ) {
481+ this . _history . push ( { value : valueBefore , selection : selectionBefore , lastOp : this . _lastOp } )
482+ }
483+ this . _lastOp = 'backspace'
484+ this . _lastSelection = copy ( this . selection )
485+
418486 return true
419487}
420488
@@ -427,8 +495,16 @@ InputMask.prototype.backspace = function backspace() {
427495 * @return {boolean } true if the paste was successful, false otherwise.
428496 */
429497InputMask . prototype . paste = function paste ( input ) {
430- var initialValue = this . value . slice ( )
431- var initialSelection = copy ( this . selection )
498+ // This is necessary because we're just calling input() with each character
499+ // and rolling back if any were invalid, rather than checking up-front.
500+ var initialState = {
501+ value : this . value . slice ( ) ,
502+ selection : copy ( this . selection ) ,
503+ _lastOp : this . _lastOp ,
504+ _history : this . _history . slice ( ) ,
505+ _historyIndex : this . _historyIndex ,
506+ _lastSelection : copy ( this . _lastSelection )
507+ }
432508
433509 // If there are static characters at the start of the pattern and the cursor
434510 // or selection is within them, the static characters must match for a valid
@@ -462,18 +538,77 @@ InputMask.prototype.paste = function paste(input) {
462538 continue
463539 }
464540 }
465- this . value = initialValue
466- this . selection = initialSelection
541+ extend ( this , initialState )
467542 return false
468543 }
469544 }
545+
470546 return true
471547}
472548
473- InputMask . prototype . setPattern = function setPattern ( pattern , value ) {
549+ // History
550+
551+ InputMask . prototype . undo = function undo ( ) {
552+ // If there is no history, or nothing more on the history stack, we can't undo
553+ if ( this . _history . length === 0 || this . _historyIndex === 0 ) {
554+ return false
555+ }
556+
557+ var historyItem
558+ if ( this . _historyIndex == null ) {
559+ // Not currently undoing, set up the initial history index
560+ this . _historyIndex = this . _history . length - 1
561+ historyItem = this . _history [ this . _historyIndex ]
562+ // Add a new history entry if anything has changed since the last one, so we
563+ // can redo back to the initial state we started undoing from.
564+ var value = this . getValue ( )
565+ if ( historyItem . value != value ||
566+ historyItem . selection . start != this . selection . start ||
567+ historyItem . selection . end != this . selection . end ) {
568+ this . _history . push ( { value : value , selection : copy ( this . selection ) , lastOp : this . _lastOp , startUndo : true } )
569+ }
570+ }
571+ else {
572+ historyItem = this . _history [ -- this . _historyIndex ]
573+ }
574+
575+ this . value = historyItem . value . split ( '' )
576+ this . selection = historyItem . selection
577+ this . _lastOp = historyItem . lastOp
578+ return true
579+ }
580+
581+ InputMask . prototype . redo = function redo ( ) {
582+ if ( this . _history . length === 0 || this . _historyIndex == null ) {
583+ return false
584+ }
585+ var historyItem = this . _history [ ++ this . _historyIndex ]
586+ // If this is the last history item, we're done redoing
587+ if ( this . _historyIndex === this . _history . length - 1 ) {
588+ this . _historyIndex = null
589+ // If the last history item was only added to start undoing, remove it
590+ if ( historyItem . startUndo ) {
591+ this . _history . pop ( )
592+ }
593+ }
594+ this . value = historyItem . value . split ( '' )
595+ this . selection = historyItem . selection
596+ this . _lastOp = historyItem . lastOp
597+ return true
598+ }
599+
600+ // Getters & setters
601+
602+ InputMask . prototype . setPattern = function setPattern ( pattern , options ) {
603+ options = extend ( {
604+ selection : { start : 0 , end : 0 } ,
605+ value : ''
606+ } , options )
474607 this . pattern = new Pattern ( pattern , this . formatCharacters )
475- this . setValue ( value || '' )
608+ this . setValue ( options . value )
476609 this . emptyValue = this . pattern . formatValue ( [ ] ) . join ( '' )
610+ this . selection = options . selection
611+ this . _resetHistory ( )
477612}
478613
479614InputMask . prototype . setSelection = function setSelection ( selection ) {
@@ -499,6 +634,13 @@ InputMask.prototype.getValue = function getValue() {
499634 return this . value . join ( '' )
500635}
501636
637+ InputMask . prototype . _resetHistory = function _resetHistory ( ) {
638+ this . _history = [ ]
639+ this . _historyIndex = null
640+ this . _lastOp = null
641+ this . _lastSelection = copy ( this . selection )
642+ }
643+
502644InputMask . Pattern = Pattern
503645
504646module . exports = InputMask
0 commit comments