Brak opisu

Injection.tsx 10KB

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