|
| 1 | +import React, {Component} from 'react'; |
| 2 | +import {Text, View, ScrollView} from 'react-native'; |
| 3 | + |
| 4 | +import WebView from 'react-native-webview'; |
| 5 | + |
| 6 | +// const HTML = ` |
| 7 | +// <!DOCTYPE html> |
| 8 | +// <html> |
| 9 | +// <head> |
| 10 | +// <meta charset="utf-8"> |
| 11 | +// <meta name="viewport" content="width=device-width, initial-scale=1"> |
| 12 | +// <title>iframe test</title> |
| 13 | +// </head> |
| 14 | +// <body> |
| 15 | +// <p style="">beforeContentLoaded on the top frame <span id="before_failed" style="display: inline-block;">failed</span><span id="before_succeeded" style="display: none;">succeeded</span>!</p> |
| 16 | +// <p style="">afterContentLoaded on the top frame <span id="after_failed" style="display: inline-block;">failed</span><span id="after_succeeded" style="display: none;">succeeded</span>!</p> |
| 17 | +// <iframe src="https://birchlabs.co.uk/linguabrowse/infopages/obsol/iframe.html?v=1" name="iframe_0" style="width: 100%; height: 25px;"></iframe> |
| 18 | +// <iframe src="https://birchlabs.co.uk/linguabrowse/infopages/obsol/iframe2.html?v=1" name="iframe_1" style="width: 100%; height: 25px;"></iframe> |
| 19 | +// <iframe src="https://www.ebay.co.uk" name="iframe_2" style="width: 100%; height: 25px;"></iframe> |
| 20 | +// </body> |
| 21 | +// </html> |
| 22 | +// `; |
| 23 | + |
| 24 | +type Props = {}; |
| 25 | +type State = { |
| 26 | + backgroundColor: string, |
| 27 | +}; |
| 28 | + |
| 29 | +export default class Injection extends Component<Props, State> { |
| 30 | + state = { |
| 31 | + backgroundColor: '#FF00FF00' |
| 32 | + }; |
| 33 | + |
| 34 | + render() { |
| 35 | + return ( |
| 36 | + <ScrollView> |
| 37 | + <View style={{ }}> |
| 38 | + <View style={{ height: 300 }}> |
| 39 | + <WebView |
| 40 | + /** |
| 41 | + * This HTML is a copy of a multi-frame JS injection test that I had lying around. |
| 42 | + * @see https://birchlabs.co.uk/linguabrowse/infopages/obsol/iframeTest.html |
| 43 | + */ |
| 44 | + // source={{ html: HTML }} |
| 45 | + source={{ uri: "https://birchlabs.co.uk/linguabrowse/infopages/obsol/rnw_iframe_test.html" }} |
| 46 | + automaticallyAdjustContentInsets={false} |
| 47 | + style={{backgroundColor:'#00000000'}} |
| 48 | + |
| 49 | + /* Must be populated in order for `messagingEnabled` to be `true` to activate the |
| 50 | + * JS injection user scripts, consistent with current behaviour. This is undesirable, |
| 51 | + * so needs addressing in a follow-up PR. */ |
| 52 | + onMessage={() => {}} |
| 53 | + |
| 54 | + /* We set this property in each frame */ |
| 55 | + injectedJavaScriptBeforeContentLoaded={` |
| 56 | + console.log("executing injectedJavaScriptBeforeContentLoaded..."); |
| 57 | + if(typeof window.top.injectedIframesBeforeContentLoaded === "undefined"){ |
| 58 | + window.top.injectedIframesBeforeContentLoaded = []; |
| 59 | + } |
| 60 | + window.self.colourToUse = "orange"; |
| 61 | + if(window.self === window.top){ |
| 62 | + console.log("Was window.top. window.frames.length is:", window.frames.length); |
| 63 | + window.self.numberOfFramesAtBeforeContentLoaded = window.frames.length; |
| 64 | + function declareSuccessOfBeforeContentLoaded(head){ |
| 65 | + var style = window.self.document.createElement('style'); |
| 66 | + style.type = 'text/css'; |
| 67 | + style.innerHTML = "#before_failed { display: none !important; }#before_succeeded { display: inline-block !important; }"; |
| 68 | + head.appendChild(style); |
| 69 | + } |
| 70 | +
|
| 71 | + const head = (window.self.document.head || window.self.document.getElementsByTagName('head')[0]); |
| 72 | +
|
| 73 | + if(head){ |
| 74 | + declareSuccessOfBeforeContentLoaded(head); |
| 75 | + } else { |
| 76 | + window.self.document.addEventListener("DOMContentLoaded", function (event) { |
| 77 | + const head = (window.self.document.head || window.self.document.getElementsByTagName('head')[0]); |
| 78 | + declareSuccessOfBeforeContentLoaded(head); |
| 79 | + }); |
| 80 | + } |
| 81 | + } else { |
| 82 | + window.top.injectedIframesBeforeContentLoaded.push(window.self.name); |
| 83 | + console.log("wasn't window.top."); |
| 84 | + console.log("wasn't window.top. Still going..."); |
| 85 | + } |
| 86 | + `} |
| 87 | + |
| 88 | + injectedJavaScriptForMainFrameOnly={false} |
| 89 | + |
| 90 | + /* We read the colourToUse property in each frame to recolour each frame */ |
| 91 | + injectedJavaScript={` |
| 92 | + console.log("executing injectedJavaScript..."); |
| 93 | + if(typeof window.top.injectedIframesAfterContentLoaded === "undefined"){ |
| 94 | + window.top.injectedIframesAfterContentLoaded = []; |
| 95 | + } |
| 96 | +
|
| 97 | + if(window.self.colourToUse){ |
| 98 | + window.self.document.body.style.backgroundColor = window.self.colourToUse; |
| 99 | + } else { |
| 100 | + window.self.document.body.style.backgroundColor = "cyan"; |
| 101 | + } |
| 102 | +
|
| 103 | + if(window.self === window.top){ |
| 104 | + function declareSuccessOfAfterContentLoaded(head){ |
| 105 | + var style = window.self.document.createElement('style'); |
| 106 | + style.type = 'text/css'; |
| 107 | + style.innerHTML = "#after_failed { display: none !important; }#after_succeeded { display: inline-block !important; }"; |
| 108 | + head.appendChild(style); |
| 109 | + } |
| 110 | +
|
| 111 | + declareSuccessOfAfterContentLoaded(window.self.document.head || window.self.document.getElementsByTagName('head')[0]); |
| 112 | +
|
| 113 | + // var numberOfFramesAtBeforeContentLoadedEle = document.createElement('p'); |
| 114 | + // numberOfFramesAtBeforeContentLoadedEle.textContent = "Number of iframes upon the main frame's beforeContentLoaded: " + |
| 115 | + // window.self.numberOfFramesAtBeforeContentLoaded; |
| 116 | +
|
| 117 | + // var numberOfFramesAtAfterContentLoadedEle = document.createElement('p'); |
| 118 | + // numberOfFramesAtAfterContentLoadedEle.textContent = "Number of iframes upon the main frame's afterContentLoaded: " + window.frames.length; |
| 119 | + // numberOfFramesAtAfterContentLoadedEle.id = "numberOfFramesAtAfterContentLoadedEle"; |
| 120 | +
|
| 121 | + var namedFramesAtBeforeContentLoadedEle = document.createElement('p'); |
| 122 | + namedFramesAtBeforeContentLoadedEle.textContent = "Names of iframes that called beforeContentLoaded: " + JSON.stringify(window.top.injectedIframesBeforeContentLoaded); |
| 123 | + namedFramesAtBeforeContentLoadedEle.id = "namedFramesAtBeforeContentLoadedEle"; |
| 124 | +
|
| 125 | + var namedFramesAtAfterContentLoadedEle = document.createElement('p'); |
| 126 | + namedFramesAtAfterContentLoadedEle.textContent = "Names of iframes that called afterContentLoaded: " + JSON.stringify(window.top.injectedIframesAfterContentLoaded); |
| 127 | + namedFramesAtAfterContentLoadedEle.id = "namedFramesAtAfterContentLoadedEle"; |
| 128 | +
|
| 129 | + // document.body.appendChild(numberOfFramesAtBeforeContentLoadedEle); |
| 130 | + // document.body.appendChild(numberOfFramesAtAfterContentLoadedEle); |
| 131 | + document.body.appendChild(namedFramesAtBeforeContentLoadedEle); |
| 132 | + document.body.appendChild(namedFramesAtAfterContentLoadedEle); |
| 133 | + } else { |
| 134 | + window.top.injectedIframesAfterContentLoaded.push(window.self.name); |
| 135 | + window.top.document.getElementById('namedFramesAtAfterContentLoadedEle').textContent = "Names of iframes that called afterContentLoaded: " + JSON.stringify(window.top.injectedIframesAfterContentLoaded); |
| 136 | + } |
| 137 | + `} |
| 138 | + /> |
| 139 | + </View> |
| 140 | + </View> |
| 141 | + <Text>This test presents three iframes: iframe_0 (yellow); iframe_1 (pink); and iframe_2 (transparent, because its 'X-Frame-Options' is set to 'SAMEORIGIN').</Text> |
| 142 | + <Text>Before injection, the main frame's background is the browser's default value (transparent or white) and each frame has its natural colour.</Text> |
| 143 | + {/*<Text>1a) At injection time "beforeContentLoaded", a variable will be set in each frame to set 'orange' as the "colour to be used".</Text>*/} |
| 144 | + {/*<Text>1b) Also upon "beforeContentLoaded", a style element to change the text "beforeContentLoaded failed" -> "beforeContentLoaded succeeded" will be applied as soon as the head has loaded.</Text>*/} |
| 145 | + {/*<Text>2a) At injection time "afterContentLoaded", that variable will be read – if present, the colour orange will be injected into all frames. Otherwise, cyan.</Text>*/} |
| 146 | + {/*<Text>2b) Also upon "afterContentLoaded", a style element to change the text "afterContentLoaded failed" -> "afterContentLoaded succeeded" will be applied as soon as the head has loaded.</Text>*/} |
| 147 | + <Text>✅ If the main frame becomes orange, then top-frame injection both beforeContentLoaded and afterContentLoaded is supported.</Text> |
| 148 | + <Text>✅ If iframe_0, and iframe_1 become orange, then multi-frame injection beforeContentLoaded and afterContentLoaded is supported.</Text> |
| 149 | + <Text>✅ If the two texts say "beforeContentLoaded on the top frame succeeded!" and "afterContentLoaded on the top frame succeeded!", then both injection times are supported at least on the main frame.</Text> |
| 150 | + <Text>⚠️ If either of the two iframes become coloured cyan, then for that given frame, JS injection succeeded after the content loaded, but didn't occur before the content loaded - please note that for iframes, this may not be a test failure, as it is not clear whether we would expect iframes to support an injection time of beforeContentLoaded anyway.</Text> |
| 151 | + <Text>⚠️ If "Names of iframes that called beforeContentLoaded: " is [], then see above.</Text> |
| 152 | + <Text>❌ If "Names of iframes that called afterContentLoaded: " is [], then afterContentLoaded is not supported in iframes.</Text> |
| 153 | + <Text>❌ If the main frame becomes coloured cyan, then JS injection succeeded after the content loaded, but didn't occur before the content loaded.</Text> |
| 154 | + <Text>❌ If the text "beforeContentLoaded on the top frame failed" remains unchanged, then JS injection has failed on the main frame before the content loaded.</Text> |
| 155 | + <Text>❌ If the text "afterContentLoaded on the top frame failed" remains unchanged, then JS injection has failed on the main frame after the content loaded.</Text> |
| 156 | + <Text>❌ If the iframes remain their original colours (yellow and pink), then multi-frame injection is not supported at all.</Text> |
| 157 | + </ScrollView> |
| 158 | + ); |
| 159 | + } |
| 160 | +} |
0 commit comments