@@ -579,13 +579,44 @@ textAngular.directive("textAngular", [
579
579
} ;
580
580
}
581
581
] ) ;
582
- textAngular . service ( 'textAngularManager' , [ 'taToolExecuteAction' , 'taTools' , 'taRegisterTool' , function ( taToolExecuteAction , taTools , taRegisterTool ) {
582
+ textAngular . service ( 'textAngularManager' , [ 'taToolExecuteAction' , 'taTools' , 'taRegisterTool' , '$interval' , '$rootScope' , function ( taToolExecuteAction , taTools , taRegisterTool , $interval , $rootScope ) {
583
583
// this service is used to manage all textAngular editors and toolbars.
584
584
// All publicly published functions that modify/need to access the toolbar or editor scopes should be in here
585
585
// these contain references to all the editors and toolbars that have been initialised in this app
586
586
var toolbars = { } , editors = { } ;
587
587
// toolbarScopes is an ARRAY of toolbar scopes
588
588
var toolbarScopes = [ ] ;
589
+ // we touch the time any change occurs through register of an editor or tool so that we
590
+ // in the future will fire and event to trigger an updateSelection
591
+ var timeRecentModification = 0 ;
592
+ var updateStyles = function ( selectedElement ) {
593
+ angular . forEach ( editors , function ( editor ) {
594
+ editor . editorFunctions . updateSelectedStyles ( selectedElement ) ;
595
+ } ) ;
596
+ } ;
597
+ var triggerInterval = 50 ;
598
+ var triggerIntervalTimer ;
599
+ var setupTriggerUpdateStyles = function ( ) {
600
+ timeRecentModification = Date . now ( ) ;
601
+ /* istanbul ignore next: setup a one time updateStyles() */
602
+ triggerIntervalTimer = $interval ( function ( ) {
603
+ updateStyles ( ) ;
604
+ triggerIntervalTimer = undefined ;
605
+ } , triggerInterval , 1 , false ) ; // only trigger once
606
+ } ;
607
+ /* istanbul ignore next: make sure clean up on destroy */
608
+ $rootScope . $on ( 'destroy' , function ( ) {
609
+ if ( triggerIntervalTimer ) {
610
+ $interval . cancel ( triggerIntervalTimer ) ;
611
+ triggerIntervalTimer = undefined ;
612
+ }
613
+ } ) ;
614
+ var touchModification = function ( ) {
615
+ if ( Math . abs ( Date . now ( ) - timeRecentModification ) > triggerInterval ) {
616
+ // we have already triggered the updateStyles a long time back... so setup it again...
617
+ setupTriggerUpdateStyles ( ) ;
618
+ }
619
+ } ;
589
620
// when we focus into a toolbar, we need to set the TOOLBAR's $parent to be the toolbars it's linked to.
590
621
// We also need to set the tools to be updated to be the toolbars...
591
622
return {
@@ -639,6 +670,7 @@ textAngular.service('textAngularManager', ['taToolExecuteAction', 'taTools', 'ta
639
670
angular . forEach ( toolbarScope . tools , function ( toolScope ) {
640
671
if ( toolScope . activeState ) {
641
672
toolbarScope . _parent = scope ;
673
+ // selectedElement may be undefined if nothing selected
642
674
toolScope . active = toolScope . activeState ( selectedElement ) ;
643
675
}
644
676
} ) ;
@@ -721,6 +753,7 @@ textAngular.service('textAngularManager', ['taToolExecuteAction', 'taTools', 'ta
721
753
}
722
754
}
723
755
} ;
756
+ touchModification ( ) ;
724
757
return editors [ name ] . editorFunctions ;
725
758
} ,
726
759
// retrieve editor by name, largely used by testing suites only
@@ -729,6 +762,7 @@ textAngular.service('textAngularManager', ['taToolExecuteAction', 'taTools', 'ta
729
762
} ,
730
763
unregisterEditor : function ( name ) {
731
764
delete editors [ name ] ;
765
+ touchModification ( ) ;
732
766
} ,
733
767
// registers a toolbar such that it can be linked to editors
734
768
registerToolbar : function ( scope ) {
@@ -739,6 +773,7 @@ textAngular.service('textAngularManager', ['taToolExecuteAction', 'taTools', 'ta
739
773
angular . forEach ( editors , function ( _editor ) {
740
774
_editor . _registerToolbarScope ( scope ) ;
741
775
} ) ;
776
+ touchModification ( ) ;
742
777
} ,
743
778
// retrieve toolbar by name, largely used by testing suites only
744
779
retrieveToolbar : function ( name ) {
@@ -762,6 +797,7 @@ textAngular.service('textAngularManager', ['taToolExecuteAction', 'taTools', 'ta
762
797
}
763
798
}
764
799
toolbarScopes = tmp ;
800
+ touchModification ( ) ;
765
801
} ,
766
802
// functions for updating the toolbar buttons display
767
803
updateToolsDisplay : function ( newTaTools ) {
@@ -777,20 +813,23 @@ textAngular.service('textAngularManager', ['taToolExecuteAction', 'taTools', 'ta
777
813
angular . forEach ( taTools , function ( _newTool , key ) {
778
814
_this . resetToolDisplay ( key ) ;
779
815
} ) ;
816
+ touchModification ( ) ;
780
817
} ,
781
818
// update a tool on all toolbars
782
819
updateToolDisplay : function ( toolKey , _newTool ) {
783
820
var _this = this ;
784
821
angular . forEach ( toolbars , function ( toolbarScope , toolbarKey ) {
785
822
_this . updateToolbarToolDisplay ( toolbarKey , toolKey , _newTool ) ;
786
823
} ) ;
824
+ touchModification ( ) ;
787
825
} ,
788
826
// resets a tool to the default/starting state on all toolbars
789
827
resetToolDisplay : function ( toolKey ) {
790
828
var _this = this ;
791
829
angular . forEach ( toolbars , function ( toolbarScope , toolbarKey ) {
792
830
_this . resetToolbarToolDisplay ( toolbarKey , toolKey ) ;
793
831
} ) ;
832
+ touchModification ( ) ;
794
833
} ,
795
834
// update a tool on a specific toolbar
796
835
updateToolbarToolDisplay : function ( toolbarKey , toolKey , _newTool ) {
@@ -825,18 +864,21 @@ textAngular.service('textAngularManager', ['taToolExecuteAction', 'taTools', 'ta
825
864
}
826
865
}
827
866
} ) ;
867
+ touchModification ( ) ;
828
868
} ,
829
869
// toolkey, toolDefinition are required. If group is not specified will pick the last group, if index isnt defined will append to group
830
870
addTool : function ( toolKey , toolDefinition , group , index ) {
831
871
taRegisterTool ( toolKey , toolDefinition ) ;
832
872
angular . forEach ( toolbars , function ( toolbarScope ) {
833
873
toolbarScope . addTool ( toolKey , toolDefinition , group , index ) ;
834
874
} ) ;
875
+ touchModification ( ) ;
835
876
} ,
836
877
// adds a Tool but only to one toolbar not all
837
878
addToolToToolbar : function ( toolKey , toolDefinition , toolbarKey , group , index ) {
838
879
taRegisterTool ( toolKey , toolDefinition ) ;
839
880
toolbars [ toolbarKey ] . addTool ( toolKey , toolDefinition , group , index ) ;
881
+ touchModification ( ) ;
840
882
} ,
841
883
// this is used when externally the html of an editor has been changed and textAngular needs to be notified to update the model.
842
884
// this will call a $digest if not already happening
@@ -846,6 +888,7 @@ textAngular.service('textAngularManager', ['taToolExecuteAction', 'taTools', 'ta
846
888
/* istanbul ignore else: phase catch */
847
889
if ( ! editors [ name ] . scope . $$phase ) editors [ name ] . scope . $digest ( ) ;
848
890
} else throw ( 'textAngular Error: No Editor with name "' + name + '" exists' ) ;
891
+ touchModification ( ) ;
849
892
} ,
850
893
// this is used by taBind to send a key command in response to a special key event
851
894
sendKeyCommand : function ( scope , event ) {
@@ -860,6 +903,13 @@ textAngular.service('textAngularManager', ['taToolExecuteAction', 'taTools', 'ta
860
903
return false ;
861
904
}
862
905
} ,
906
+ //
907
+ // When a toolbar and tools are created, it isn't until there is a key event or mouse event
908
+ // that the updateSelectedStyles() is called behind the scenes.
909
+ // This function forces an update through the existing editors to help the application make sure
910
+ // the inital state is correct.
911
+ //
912
+ updateStyles : updateStyles ,
863
913
// for testing
864
914
getToolbarScopes : function ( ) { return toolbarScopes ; }
865
915
} ;
0 commit comments