File tree Expand file tree Collapse file tree 13 files changed +253
-41
lines changed Expand file tree Collapse file tree 13 files changed +253
-41
lines changed Original file line number Diff line number Diff line change 12
12
"query-string" : " ^4.2.3" ,
13
13
"react" : " ^15.4.1" ,
14
14
"react-dom" : " ^15.4.1" ,
15
- "semver" : " ^5.3 .0"
15
+ "semver" : " ^5.5 .0"
16
16
},
17
17
"scripts" : {
18
18
"start" : " react-scripts start" ,
Original file line number Diff line number Diff line change 1
- const PropTypes = window . PropTypes ;
1
+ import PropTypes from 'prop-types' ;
2
2
const React = window . React ;
3
3
4
4
const propTypes = {
Original file line number Diff line number Diff line change @@ -66,6 +66,7 @@ class Header extends React.Component {
66
66
< option value = "/media-events" > Media Events</ option >
67
67
< option value = "/pointer-events" > Pointer Events</ option >
68
68
< option value = "/mouse-events" > Mouse Events</ option >
69
+ < option value = "/selection-events" > Selection Events</ option >
69
70
</ select >
70
71
</ label >
71
72
< label htmlFor = "react_version" >
Original file line number Diff line number Diff line change
1
+ const React = window . React ;
2
+ const ReactDOM = window . ReactDOM ;
3
+
4
+ class IframePortal extends React . Component {
5
+ iframeRef = null ;
6
+
7
+ handleRef = ref => {
8
+ if ( ref !== this . iframeRef ) {
9
+ this . iframeRef = ref ;
10
+ if ( ref ) {
11
+ if ( ref . contentDocument && this . props . head ) {
12
+ ref . contentDocument . head . innerHTML = this . props . head ;
13
+ }
14
+ // Re-render must take place in the next tick (Firefox)
15
+ setTimeout ( ( ) => {
16
+ this . forceUpdate ( ) ;
17
+ } ) ;
18
+ }
19
+ }
20
+ } ;
21
+
22
+ render ( ) {
23
+ const ref = this . iframeRef ;
24
+ let portal = null ;
25
+ if ( ref && ref . contentDocument ) {
26
+ portal = ReactDOM . createPortal (
27
+ this . props . children ,
28
+ ref . contentDocument . body
29
+ ) ;
30
+ }
31
+
32
+ return (
33
+ < div >
34
+ < iframe
35
+ style = { { border : 'none' , height : this . props . height } }
36
+ ref = { this . handleRef }
37
+ />
38
+ { portal }
39
+ </ div >
40
+ ) ;
41
+ }
42
+ }
43
+
44
+ class IframeSubtree extends React . Component {
45
+ warned = false ;
46
+ render ( ) {
47
+ if ( ! this . warned ) {
48
+ console . error (
49
+ `IFrame has not yet been implemented for React v${ React . version } `
50
+ ) ;
51
+ this . warned = true ;
52
+ }
53
+ return < div > { this . props . children } </ div > ;
54
+ }
55
+ }
56
+
57
+ export default ( ReactDOM . createPortal ? IframePortal : IframeSubtree ) ;
Original file line number Diff line number Diff line change @@ -13,6 +13,7 @@ import CustomElementFixtures from './custom-elements';
13
13
import MediaEventsFixtures from './media-events' ;
14
14
import PointerEventsFixtures from './pointer-events' ;
15
15
import MouseEventsFixtures from './mouse-events' ;
16
+ import SelectionEventsFixtures from './selection-events' ;
16
17
17
18
const React = window . React ;
18
19
@@ -52,6 +53,8 @@ function FixturesPage() {
52
53
return < PointerEventsFixtures /> ;
53
54
case '/mouse-events' :
54
55
return < MouseEventsFixtures /> ;
56
+ case '/selection-events' :
57
+ return < SelectionEventsFixtures /> ;
55
58
default :
56
59
return < p > Please select a test fixture.</ p > ;
57
60
}
Original file line number Diff line number Diff line change
1
+ import TestCase from '../../TestCase' ;
2
+ import Iframe from '../../Iframe' ;
3
+ const React = window . React ;
4
+
5
+ class OnSelectIframe extends React . Component {
6
+ state = { count : 0 , value : 'Select Me!' } ;
7
+
8
+ _onSelect = event => {
9
+ this . setState ( ( { count} ) => ( { count : count + 1 } ) ) ;
10
+ } ;
11
+
12
+ _onChange = event => {
13
+ this . setState ( { value : event . target . value } ) ;
14
+ } ;
15
+
16
+ render ( ) {
17
+ const { count, value} = this . state ;
18
+ return (
19
+ < Iframe height = { 60 } >
20
+ Selection Event Count: { count }
21
+ < input
22
+ type = "text"
23
+ onSelect = { this . _onSelect }
24
+ value = { value }
25
+ onChange = { this . _onChange }
26
+ />
27
+ </ Iframe >
28
+ ) ;
29
+ }
30
+ }
31
+
32
+ export default class OnSelectEventTestCase extends React . Component {
33
+ render ( ) {
34
+ return (
35
+ < TestCase
36
+ title = "onSelect events within iframes"
37
+ description = "onSelect events should fire for elements rendered inside iframes" >
38
+ < TestCase . Steps >
39
+ < li > Highlight some of the text in the input below</ li >
40
+ < li > Move the cursor around using the arrow keys</ li >
41
+ </ TestCase . Steps >
42
+ < TestCase . ExpectedResult >
43
+ The displayed count should increase as you highlight or move the
44
+ cursor
45
+ </ TestCase . ExpectedResult >
46
+ < OnSelectIframe />
47
+ </ TestCase >
48
+ ) ;
49
+ }
50
+ }
Original file line number Diff line number Diff line change
1
+ import TestCase from '../../TestCase' ;
2
+ import Iframe from '../../Iframe' ;
3
+ const React = window . React ;
4
+
5
+ export default class ReorderedInputsTestCase extends React . Component {
6
+ state = { count : 0 } ;
7
+
8
+ componentDidMount ( ) {
9
+ this . interval = setInterval ( ( ) => {
10
+ this . setState ( { count : this . state . count + 1 } ) ;
11
+ } , 2000 ) ;
12
+ }
13
+
14
+ componentWillUnmount ( ) {
15
+ clearInterval ( this . interval ) ;
16
+ }
17
+
18
+ renderInputs ( ) {
19
+ const inputs = [
20
+ < input key = { 1 } defaultValue = "Foo" /> ,
21
+ < input key = { 2 } defaultValue = "Bar" /> ,
22
+ ] ;
23
+ if ( this . state . count % 2 === 0 ) {
24
+ inputs . reverse ( ) ;
25
+ }
26
+ return inputs ;
27
+ }
28
+
29
+ render ( ) {
30
+ return (
31
+ < TestCase title = "Reordered input elements in iframes" description = "" >
32
+ < TestCase . Steps >
33
+ < li > The two inputs below swap positions every two seconds</ li >
34
+ < li > Select the text in either of them</ li >
35
+ < li > Wait for the swap to occur</ li >
36
+ </ TestCase . Steps >
37
+ < TestCase . ExpectedResult >
38
+ The selection you made should be maintained
39
+ </ TestCase . ExpectedResult >
40
+ < Iframe height = { 50 } > { this . renderInputs ( ) } </ Iframe >
41
+ </ TestCase >
42
+ ) ;
43
+ }
44
+ }
Original file line number Diff line number Diff line change
1
+ import FixtureSet from '../../FixtureSet' ;
2
+ import ReorderedInputsTestCase from './ReorderedInputsTestCase' ;
3
+ import OnSelectEventTestCase from './OnSelectEventTestCase' ;
4
+ const React = window . React ;
5
+
6
+ export default function SelectionEvents ( ) {
7
+ return (
8
+ < FixtureSet
9
+ title = "Selection Restoration"
10
+ description = "
11
+ When React commits changes it may perform operations which cause existing
12
+ selection state to be lost. This is manually managed by reading the
13
+ selection state before commits and then restoring it afterwards.
14
+ " >
15
+ < ReorderedInputsTestCase />
16
+ < OnSelectEventTestCase />
17
+ </ FixtureSet >
18
+ ) ;
19
+ }
Original file line number Diff line number Diff line change
1
+ import semver from 'semver' ;
2
+
1
3
/**
2
4
* Take a version from the window query string and load a specific
3
5
* version of React.
@@ -42,9 +44,11 @@ export default function loadReact() {
42
44
let version = query . version || 'local' ;
43
45
44
46
if ( version !== 'local' ) {
47
+ const { major, minor, prerelease} = semver ( version ) ;
48
+ const [ preReleaseStage , preReleaseVersion ] = prerelease ;
45
49
// The file structure was updated in 16. This wasn't the case for alphas.
46
50
// Load the old module location for anything less than 16 RC
47
- if ( parseInt ( version , 10 ) >= 16 && version . indexOf ( 'alpha' ) < 0 ) {
51
+ if ( major >= 16 && ! ( minor === 0 && preReleaseStage === 'alpha' ) ) {
48
52
REACT_PATH =
49
53
'https://unpkg.com/react@' + version + '/umd/react.development.js' ;
50
54
DOM_PATH =
Original file line number Diff line number Diff line change 2153
2153
version "4.0.0"
2154
2154
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-4.0.0.tgz#864ef1379aced55ce6f95debecdce179f7a0cd1d"
2155
2155
2156
+ draft-js@^0.10.5 :
2157
+ version "0.10.5"
2158
+ resolved "https://registry.yarnpkg.com/draft-js/-/draft-js-0.10.5.tgz#bfa9beb018fe0533dbb08d6675c371a6b08fa742"
2159
+ dependencies :
2160
+ fbjs "^0.8.15"
2161
+ immutable "~3.7.4"
2162
+ object-assign "^4.1.0"
2163
+
2156
2164
duplexer2@^0.1.4 :
2157
2165
version "0.1.4"
2158
2166
resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1"
@@ -2672,7 +2680,7 @@ fbjs@^0.8.1, fbjs@^0.8.4:
2672
2680
setimmediate "^1.0.5"
2673
2681
ua-parser-js "^0.7.9"
2674
2682
2675
- fbjs@^0.8.16 :
2683
+ fbjs@^0.8.15, fbjs@^0.8. 16 :
2676
2684
version "0.8.16"
2677
2685
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
2678
2686
dependencies :
@@ -3302,6 +3310,10 @@ ignore@^3.3.3:
3302
3310
version "3.3.3"
3303
3311
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d"
3304
3312
3313
+ immutable@~3.7.4 :
3314
+ version "3.7.6"
3315
+ resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.7.6.tgz#13b4d3cb12befa15482a26fe1b2ebae640071e4b"
3316
+
3305
3317
imurmurhash@^0.1.4 :
3306
3318
version "0.1.4"
3307
3319
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
@@ -5878,6 +5890,10 @@ semver@^5.0.3:
5878
5890
version "5.4.1"
5879
5891
resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
5880
5892
5893
+ semver@^5.5.0 :
5894
+ version "5.5.0"
5895
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
5896
+
5881
5897
5882
5898
version "0.14.1"
5883
5899
resolved "https://registry.yarnpkg.com/send/-/send-0.14.1.tgz#a954984325392f51532a7760760e459598c89f7a"
You can’t perform that action at this time.
0 commit comments