@@ -114,6 +114,40 @@ module.exports =
114114 } ) ;
115115 } ;
116116
117+ _this . typeLine = function ( line , lineIdx ) {
118+ if ( ! _this . mounted ) {
119+ return Promise . resolve ( ) ;
120+ }
121+ var onLineTyped = _this . props . onLineTyped ;
122+
123+
124+ return new Promise ( function ( resolve , reject ) {
125+ _this . setState ( { text : _this . state . text . concat ( [ '' ] ) } , function ( ) {
126+ utils . eachPromise ( line , _this . typeCharacter , line , lineIdx ) . then ( function ( ) {
127+ return onLineTyped ( line , lineIdx ) ;
128+ } ) . then ( resolve ) . catch ( reject ) ;
129+ } ) ;
130+ } ) ;
131+ } ;
132+
133+ _this . typeCharacter = function ( character , charIdx , line , lineIdx ) {
134+ if ( ! _this . mounted ) {
135+ return Promise . resolve ( ) ;
136+ }
137+ var onCharacterTyped = _this . props . onCharacterTyped ;
138+
139+
140+ return new Promise ( function ( resolve ) {
141+ var text = _this . state . text . slice ( ) ;
142+ text [ lineIdx ] += character ;
143+ _this . setState ( { text : text } , function ( ) {
144+ onCharacterTyped ( character , charIdx ) ;
145+ var delay = _this . delayGenerator ( line , lineIdx , character , charIdx ) ;
146+ setTimeout ( resolve , delay ) ;
147+ } ) ;
148+ } ) ;
149+ } ;
150+
117151 _this . mounted = false ;
118152 _this . linesToType = [ ] ;
119153
@@ -163,38 +197,10 @@ module.exports =
163197
164198 var lines = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : this . linesToType ;
165199
166- return utils . eachPromise ( lines , function ( line , idx ) {
167- if ( ! _this2 . mounted ) {
168- return Promise . resolve ( ) ;
169- }
170- return new Promise ( function ( resolve ) {
171- _this2 . setState ( { text : _this2 . state . text . concat ( [ '' ] ) } , function ( ) {
172- _this2 . typeLine ( line , idx ) . then ( resolve ) ;
173- } ) ;
174- } ) ;
175- } ) . then ( function ( ) {
200+ return utils . eachPromise ( lines , this . typeLine ) . then ( function ( ) {
176201 return _this2 . onTypingDone ( ) ;
177202 } ) ;
178203 }
179- } , {
180- key : 'typeLine' ,
181- value : function typeLine ( line , lineIdx ) {
182- var _this3 = this ;
183-
184- return utils . eachPromise ( line , function ( character , charIdx ) {
185- if ( ! _this3 . mounted ) {
186- return Promise . resolve ( ) ;
187- }
188- return new Promise ( function ( resolve ) {
189- var text = _this3 . state . text . slice ( ) ;
190- text [ lineIdx ] += character ;
191- _this3 . setState ( { text : text } , function ( ) {
192- var delay = _this3 . delayGenerator ( line , lineIdx , character , charIdx ) ;
193- setTimeout ( resolve , delay ) ;
194- } ) ;
195- } ) ;
196- } ) ;
197- }
198204 } , {
199205 key : 'render' ,
200206 value : function render ( ) {
@@ -224,6 +230,8 @@ module.exports =
224230 stdTypingDelay : _react . PropTypes . number ,
225231 startDelay : _react . PropTypes . number ,
226232 cursor : _react . PropTypes . object ,
233+ onCharacterTyped : _react . PropTypes . func ,
234+ onLineTyped : _react . PropTypes . func ,
227235 onTypingDone : _react . PropTypes . func ,
228236 delayGenerator : _react . PropTypes . func
229237 } ;
@@ -233,6 +241,8 @@ module.exports =
233241 stdTypingDelay : 25 ,
234242 startDelay : 0 ,
235243 cursor : { } ,
244+ onCharacterTyped : function onCharacterTyped ( ) { } ,
245+ onLineTyped : function onLineTyped ( ) { } ,
236246 onTypingDone : function onTypingDone ( ) { } ,
237247 delayGenerator : utils . gaussianRnd
238248 } ;
@@ -273,20 +283,16 @@ module.exports =
273283 var Cursor = function ( _Component ) {
274284 _inherits ( Cursor , _Component ) ;
275285
276- function Cursor ( ) {
277- var _ref ;
278-
279- var _temp , _this , _ret ;
280-
286+ function Cursor ( props ) {
281287 _classCallCheck ( this , Cursor ) ;
282288
283- for ( var _len = arguments . length , args = Array ( _len ) , _key = 0 ; _key < _len ; _key ++ ) {
284- args [ _key ] = arguments [ _key ] ;
285- }
289+ var _this = _possibleConstructorReturn ( this , ( Cursor . __proto__ || Object . getPrototypeOf ( Cursor ) ) . call ( this , props ) ) ;
286290
287- return _ret = ( _temp = ( _this = _possibleConstructorReturn ( this , ( _ref = Cursor . __proto__ || Object . getPrototypeOf ( Cursor ) ) . call . apply ( _ref , [ this ] . concat ( args ) ) ) , _this ) , _this . state = {
291+ _this . _isReRenderingCursor = false ;
292+ _this . state = {
288293 shouldRender : _this . props . show
289- } , _temp ) , _possibleConstructorReturn ( _this , _ret ) ;
294+ } ;
295+ return _this ;
290296 }
291297
292298 _createClass ( Cursor , [ {
@@ -301,6 +307,49 @@ module.exports =
301307 } , this . props . hideWhenDoneDelay ) ;
302308 }
303309 }
310+ } , {
311+ key : 'componentDidUpdate' ,
312+ value : function componentDidUpdate ( ) {
313+ var _props = this . props ;
314+ var show = _props . show ;
315+ var isDone = _props . isDone ;
316+
317+ if ( ! show ) {
318+ return ;
319+ }
320+ if ( isDone ) {
321+ return ;
322+ }
323+ if ( this . _isReRenderingCursor ) {
324+ return ;
325+ }
326+
327+ // In webkit and blink, rendering the cursor alongside the text as it
328+ // animates sometimes causes the text to stop rendering when it reaches
329+ // a new line break, even though the underlying DOM /does/ contain
330+ // the text. This seems to happen when the space available for the text is
331+ // at a specific width that makes it so the line break happens within a
332+ // word.
333+ // Using dev tools, when in this state, if you modify the dom or any style,
334+ // it immediately renders all of the text in its correct position.
335+ // Given that observation, this is a hackish solutions that re-renders the
336+ // cursor every time a character is rendered, just to ensure that the text
337+ // is rendered correctly.
338+ // See #13 and #15 for more details
339+ this . _reRenderCursor ( ) ;
340+ }
341+ } , {
342+ key : '_reRenderCursor' ,
343+ value : function _reRenderCursor ( ) {
344+ var _this3 = this ;
345+
346+ this . _isReRenderingCursor = true ;
347+ this . setState ( { shouldRender : false } , function ( ) {
348+ _this3 . setState ( { shouldRender : true } , function ( ) {
349+ _this3 . _isReRenderingCursor = false ;
350+ } ) ;
351+ } ) ;
352+ }
304353 } , {
305354 key : 'render' ,
306355 value : function render ( ) {
@@ -388,15 +437,16 @@ module.exports =
388437 }
389438
390439 function eachPromise ( arr , iterator ) {
391- var length = arr . length ;
440+ for ( var _len = arguments . length , extraArgs = Array ( _len > 2 ? _len - 2 : 0 ) , _key = 2 ; _key < _len ; _key ++ ) {
441+ extraArgs [ _key - 2 ] = arguments [ _key ] ;
442+ }
392443
393- return Array . from ( arr ) . reduce ( function ( prev , current , idx ) {
444+ var promiseReducer = function promiseReducer ( prev , current , idx ) {
394445 return prev . then ( function ( ) {
395- return Promise . resolve ( current ) . then ( function ( val ) {
396- return iterator ( val , idx , length ) ;
397- } ) ;
446+ return iterator . apply ( undefined , [ current , idx ] . concat ( extraArgs ) ) ;
398447 } ) ;
399- } , Promise . resolve ( ) ) ;
448+ } ;
449+ return Array . from ( arr ) . reduce ( promiseReducer , Promise . resolve ( ) ) ;
400450 }
401451
402452 function exclude ( obj , keys ) {
@@ -465,8 +515,8 @@ module.exports =
465515 }
466516
467517 function extractTreeWithText ( ) {
468- for ( var _len = arguments . length , args = Array ( _len ) , _key = 0 ; _key < _len ; _key ++ ) {
469- args [ _key ] = arguments [ _key ] ;
518+ for ( var _len2 = arguments . length , args = Array ( _len2 ) , _key2 = 0 ; _key2 < _len2 ; _key2 ++ ) {
519+ args [ _key2 ] = arguments [ _key2 ] ;
470520 }
471521
472522 if ( ! args [ 0 ] ) return void 0 ;
0 commit comments