Нет описания

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. 'use strict';
  2. import { Dimensions } from 'react-native';
  3. import Immutable from 'immutable';
  4. function appendFilesToHead(files, script) {
  5. if (!files) {
  6. return script;
  7. }
  8. return files.reduceRight((file, combinedScript) => {
  9. const { rel, type, href } = file;
  10. return `
  11. var link = document.createElement('link');
  12. link.rel = '${rel}';
  13. link.type = '${type}';
  14. link.href = '${href}';
  15. document.head.appendChild(link);
  16. ${combinedScript}
  17. `;
  18. }, script);
  19. }
  20. const screenWidth = Dimensions.get('window').width;
  21. const bodyStyle = `
  22. body {
  23. margin: 0;
  24. padding: 0;
  25. }
  26. `;
  27. function appendStylesToHead(styles, script) {
  28. const currentStyles = styles ? bodyStyle + styles : bodyStyle;
  29. // Escape any single quotes or newlines in the CSS with .replace()
  30. const escaped = currentStyles.replace(/\'/g, "\\'").replace(/\n/g, '\\n');
  31. return `
  32. var styleElement = document.createElement('style');
  33. styleElement.innerHTML = '${escaped}';
  34. document.head.appendChild(styleElement);
  35. ${script}
  36. `;
  37. }
  38. function getReloadRelatedData(props) {
  39. const { hasIframe, files, customStyle, customScript, style, source } = props;
  40. return {
  41. source,
  42. hasIframe,
  43. files,
  44. customStyle,
  45. customScript,
  46. style
  47. };
  48. }
  49. function isChanged(newValue, oldValue) {
  50. return !Immutable.is(Immutable.fromJS(newValue), Immutable.fromJS(oldValue));
  51. }
  52. function insertStringAfterAnotherString(raw, searchValue, insertValue) {
  53. const position = raw.indexOf(searchValue) + searchValue.length;
  54. return [raw.slice(0, position), insertValue, raw.slice(position)].join('');
  55. }
  56. function getInjectedSource(html, script) {
  57. const scriptString = `
  58. <script>
  59. ${script}
  60. </script>
  61. `;
  62. if (html.startsWith('<html')) {
  63. return insertStringAfterAnotherString(html, '>', scriptString);
  64. } else {
  65. return `
  66. ${html}
  67. ${scriptString}
  68. `;
  69. }
  70. }
  71. export function getScript(props, getBaseScript, getIframeBaseScript) {
  72. const { hasIframe, files, customStyle, customScript, style } = getReloadRelatedData(props);
  73. const baseScript = getBaseScript(style);
  74. let script = hasIframe ? getIframeBaseScript(style) : baseScript;
  75. script = files ? appendFilesToHead(files, baseScript) : baseScript;
  76. script = appendStylesToHead(customStyle, script);
  77. customScript && (script = customScript + script);
  78. return script;
  79. }
  80. export function getWidth(style) {
  81. return style && style.width ? style.width : screenWidth;
  82. }
  83. export function isEqual(newProps, oldProps) {
  84. return isChanged(getReloadRelatedData(newProps), getReloadRelatedData(oldProps));
  85. }
  86. export function setState(props, baseUrl, getBaseScript, getIframeBaseScript) {
  87. const { source } = props;
  88. const script = getScript(props, getBaseScript, getIframeBaseScript);
  89. let state = {};
  90. if (source.html) {
  91. let currentSource = { html: getInjectedSource(source.html, script) };
  92. baseUrl && Object.assign(currentSource, { baseUrl });
  93. Object.assign(state, { source: currentSource });
  94. } else {
  95. let currentSource = Object.assign({}, source);
  96. baseUrl && Object.assign(currentSource, { baseUrl });
  97. Object.assign(state, {
  98. source: currentSource,
  99. script
  100. });
  101. }
  102. return state;
  103. }
  104. export function handleSizeUpdated(height, width, onSizeUpdated) {
  105. onSizeUpdated &&
  106. onSizeUpdated({
  107. height,
  108. width
  109. });
  110. }
  111. export function isSizeChanged(height, oldHeight, width, oldWidth) {
  112. return (height && height !== oldHeight) || (width && width !== oldWidth);
  113. }
  114. export const domMutationObserveScript = `
  115. var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
  116. var observer = new MutationObserver(updateSize);
  117. observer.observe(document, {
  118. subtree: true,
  119. attributes: true
  120. });
  121. `;
  122. export const getCurrentSize = `
  123. function getSize(container) {
  124. var height = container.clientHeight || document.body.offsetHeight;
  125. var width = container.clientWidth || document.body.offsetWidth;
  126. return {
  127. height,
  128. width
  129. };
  130. }
  131. `;