@@ -35,6 +35,39 @@ function getFocusedElement() {
35
35
return focusedElem ;
36
36
}
37
37
38
+ function getElementsWithSelections ( acc , win ) {
39
+ acc = acc || [ ] ;
40
+ win = win || window ;
41
+ var doc ;
42
+ try {
43
+ doc = win . document ;
44
+ } catch ( e ) {
45
+ return acc ;
46
+ }
47
+ var element = null ;
48
+ if ( win . getSelection ) {
49
+ var selection = win . getSelection ( ) ;
50
+ var startNode = selection . anchorNode ;
51
+ var endNode = selection . focusNode ;
52
+ var startOffset = selection . anchorOffset ;
53
+ var endOffset = selection . focusOffset ;
54
+ if ( startNode . childNodes . length ) {
55
+ if ( startNode . childNodes [ startOffset ] === endNode . childNodes [ endOffset ] ) {
56
+ element = startNode . childNodes [ startOffset ] ;
57
+ }
58
+ } else {
59
+ element = startNode ;
60
+ }
61
+ } else if ( doc . selection ) {
62
+ var range = doc . selection . createRange ( ) ;
63
+ element = range . parentElement ( ) ;
64
+ }
65
+ if ( ReactInputSelection . hasSelectionCapabilities ( element ) ) {
66
+ acc = acc . concat ( element ) ;
67
+ }
68
+ return Array . prototype . reduce . call ( win . frames , getElementsWithSelections , acc ) ;
69
+ }
70
+
38
71
/**
39
72
* @ReactInputSelection : React input selection module. Based on Selection.js,
40
73
* but modified to be suitable for react and has a couple of bug fixes (doesn't
@@ -53,13 +86,15 @@ var ReactInputSelection = {
53
86
} ,
54
87
55
88
getSelectionInformation : function ( ) {
56
- var focusedElem = getFocusedElement ( ) ;
89
+ var focusedElement = getFocusedElement ( ) ;
57
90
return {
58
- focusedElem : focusedElem ,
59
- selectionRange :
60
- ReactInputSelection . hasSelectionCapabilities ( focusedElem ) ?
61
- ReactInputSelection . getSelection ( focusedElem ) :
62
- null ,
91
+ focusedElement : focusedElement ,
92
+ activeElements : getElementsWithSelections ( ) . map ( function ( element ) {
93
+ return {
94
+ element : element ,
95
+ selectionRange : ReactInputSelection . getSelection ( element ) ,
96
+ } ;
97
+ } ) ,
63
98
} ;
64
99
} ,
65
100
@@ -69,18 +104,27 @@ var ReactInputSelection = {
69
104
* nodes and place them back in, resulting in focus being lost.
70
105
*/
71
106
restoreSelection : function ( priorSelectionInformation ) {
72
- var curFocusedElem = getFocusedElement ( ) ;
73
- var priorFocusedElem = priorSelectionInformation . focusedElem ;
74
- var priorSelectionRange = priorSelectionInformation . selectionRange ;
75
- if ( curFocusedElem !== priorFocusedElem &&
76
- isInDocument ( priorFocusedElem ) ) {
77
- if ( ReactInputSelection . hasSelectionCapabilities ( priorFocusedElem ) ) {
78
- ReactInputSelection . setSelection (
79
- priorFocusedElem ,
80
- priorSelectionRange
81
- ) ;
107
+ priorSelectionInformation . activeElements . forEach ( function ( activeElement ) {
108
+ var element = activeElement . element ;
109
+ if ( ! isInDocument ( element ) ||
110
+ getActiveElement ( element . ownerDocument ) === element ) {
111
+ return ;
82
112
}
83
- focusNode ( priorFocusedElem ) ;
113
+ if ( ! ReactInputSelection . hasSelectionCapabilities ( element ) ) {
114
+ return ;
115
+ }
116
+ ReactInputSelection . setSelection (
117
+ element ,
118
+ activeElement . selectionRange
119
+ ) ;
120
+ focusNode ( element ) ;
121
+ } ) ;
122
+
123
+ var curFocusedElement = getFocusedElement ( ) ;
124
+ var priorFocusedElement = priorSelectionInformation . focusedElement ;
125
+ if ( curFocusedElement !== priorFocusedElement &&
126
+ isInDocument ( priorFocusedElement ) ) {
127
+ focusNode ( priorFocusedElement ) ;
84
128
}
85
129
} ,
86
130
0 commit comments