Piotr or Alex, could you (or someone else familiar with TLF) please take a look at my commit? Let me know if you would have solved (or diagnosed) it differently. Also, do you have an idea how we could create a unit / mustella test for this bug?
PS: when I ran the unit tests, ContainerAttributeTest.paddingBottomTest was failing both before and after my commit, with this error: "Paragraph3's top value should be 87.55. - expected true but was false" On 22 October 2014 16:29, <mih...@apache.org> wrote: > Repository: flex-tlf > Updated Branches: > refs/heads/develop 129ec697e -> d1c83617f > > > FLEX-26478 > CAUSE: > When replacing ContainerControllers (triggered when the text changes in a > TextField / TextArea), StandardFlowComposer tried to dispose of the > discarded ones first. It did this by calling clearSelectionShapes() and > setRootElement(null) on the ContainerControllers. However, if that > controller was already listening for mouse scroll events (when the user > selects text and moves the mouse outside the text field in such a way that > causes the text to scroll), this listener wasn't removed. Which meant that > the next time scrollTimerHandler() was called (on the inactive > ContainerController), textFlow was null due to the call to > setRootElement(null). > > SOLUTION: > StandardFlowComposer now calls a new method 'discard' on the > ContainerControllers which are not needed anymore. This method now also > stops the selection scroll timer ('_scrollTimer'). > > > Project: http://git-wip-us.apache.org/repos/asf/flex-tlf/repo > Commit: http://git-wip-us.apache.org/repos/asf/flex-tlf/commit/d1c83617 > Tree: http://git-wip-us.apache.org/repos/asf/flex-tlf/tree/d1c83617 > Diff: http://git-wip-us.apache.org/repos/asf/flex-tlf/diff/d1c83617 > > Branch: refs/heads/develop > Commit: d1c83617f4a32b4c39417ed53dd26c5aa2df7503 > Parents: 129ec69 > Author: Mihai Chira <mih...@apache.org> > Authored: Wed Oct 22 16:23:40 2014 +0100 > Committer: Mihai Chira <mih...@apache.org> > Committed: Wed Oct 22 16:23:40 2014 +0100 > > ---------------------------------------------------------------------- > .../textLayout/compose/StandardFlowComposer.as | 3 +- > .../textLayout/container/ContainerController.as | 35 +++++++++++++++----- > 2 files changed, 27 insertions(+), 11 deletions(-) > ---------------------------------------------------------------------- > > > > http://git-wip-us.apache.org/repos/asf/flex-tlf/blob/d1c83617/textLayout/src/flashx/textLayout/compose/StandardFlowComposer.as > ---------------------------------------------------------------------- > diff --git > a/textLayout/src/flashx/textLayout/compose/StandardFlowComposer.as > b/textLayout/src/flashx/textLayout/compose/StandardFlowComposer.as > index cb0b38e..3393d32 100644 > --- a/textLayout/src/flashx/textLayout/compose/StandardFlowComposer.as > +++ b/textLayout/src/flashx/textLayout/compose/StandardFlowComposer.as > @@ -185,8 +185,7 @@ package flashx.textLayout.compose > var cont:ContainerController; > for each (cont in _controllerList) > { > - cont.clearSelectionShapes(); > - cont.setRootElement(null); > + cont.dispose(); > } > } > > > > http://git-wip-us.apache.org/repos/asf/flex-tlf/blob/d1c83617/textLayout/src/flashx/textLayout/container/ContainerController.as > ---------------------------------------------------------------------- > diff --git > a/textLayout/src/flashx/textLayout/container/ContainerController.as > b/textLayout/src/flashx/textLayout/container/ContainerController.as > index 4876884..de77fa7 100644 > --- a/textLayout/src/flashx/textLayout/container/ContainerController.as > +++ b/textLayout/src/flashx/textLayout/container/ContainerController.as > @@ -27,6 +27,7 @@ package flashx.textLayout.container > import flash.events.ContextMenuEvent; > import flash.events.Event; > import flash.events.FocusEvent; > + import flash.events.IEventDispatcher; > import flash.events.IMEEvent; > import flash.events.KeyboardEvent; > import flash.events.MouseEvent; > @@ -1770,6 +1771,29 @@ package flashx.textLayout.container > return createDefaultContextMenu(); > } > > + public function dispose():void > + { > + stopMouseSelectionScrolling(); > + clearSelectionShapes(); > + setRootElement(null); > + } > + > + private function > stopMouseSelectionScrolling(containerRoot:IEventDispatcher = null):void > + { > + if(_scrollTimer) > + { > + _scrollTimer.stop(); > + _scrollTimer.removeEventListener(TimerEvent.TIMER, > scrollTimerHandler); > + > + if(!containerRoot) > + containerRoot = getContainerRoot(); > + > + if(containerRoot) > + > containerRoot.removeEventListener(MouseEvent.MOUSE_UP, scrollTimerHandler); > + > + _scrollTimer = null; > + } > + } > /** @private */ > tlf_internal function scrollTimerHandler(event:Event):void > { > @@ -1785,19 +1809,12 @@ package flashx.textLayout.container > // We're listening for MOUSE_UP so we can cancel > autoscrolling > if (event is MouseEvent) > { > - _scrollTimer.stop(); > - > _scrollTimer.removeEventListener(TimerEvent.TIMER, scrollTimerHandler); > + > stopMouseSelectionScrolling(event.currentTarget as IEventDispatcher); > CONFIG::debug { assert(_container.stage > == null || getContainerRoot() == event.currentTarget,"scrollTimerHandler > bad target"); } > - > event.currentTarget.removeEventListener(MouseEvent.MOUSE_UP, > scrollTimerHandler); > - _scrollTimer = null; > } > else if (!event) > { > - _scrollTimer.stop(); > - > _scrollTimer.removeEventListener(TimerEvent.TIMER, scrollTimerHandler); > - if (getContainerRoot()) > - > getContainerRoot().removeEventListener( MouseEvent.MOUSE_UP, > scrollTimerHandler); > - _scrollTimer = null; > + stopMouseSelectionScrolling(); > } > else if (_container.stage) > { > >