No Description

common.js 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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, getBaseScript, getIframeBaseScript) {
  87. const { source, style } = props;
  88. const script = getScript(props, getBaseScript, getIframeBaseScript);
  89. let state = {
  90. height: style && style.height ? style.height : 0,
  91. width: getWidth(style)
  92. };
  93. if (source.html) {
  94. Object.assign(state, {
  95. source: Object.assign(
  96. {},
  97. {
  98. html: getInjectedSource(source.html, script),
  99. baseUrl: 'web/'
  100. }
  101. )
  102. });
  103. } else {
  104. Object.assign(state, {
  105. source: Object.assign({}, source, { baseUrl: 'web/' }),
  106. script
  107. });
  108. }
  109. return state;
  110. }
  111. export function handleSizeUpdated(height, width, onSizeUpdated) {
  112. onSizeUpdated &&
  113. onSizeUpdated({
  114. height,
  115. width
  116. });
  117. }
  118. export function getSize(newHeight, newWidth, height, width, updatingSize, calledOnce) {
  119. if (!calledOnce || updatingSize) {
  120. return {
  121. h: height,
  122. w: width
  123. };
  124. }
  125. return {
  126. h: height,
  127. w: width
  128. };
  129. }
  130. export const domMutationObserveScript = `
  131. var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
  132. var observer = new MutationObserver(updateSize);
  133. observer.observe(document, {
  134. subtree: true,
  135. attributes: true
  136. });
  137. `;
  138. export const getCurrentSize = `
  139. function getSize(container) {
  140. var height = container.clientHeight || document.body.offsetHeight;
  141. var width = container.clientWidth || document.body.offsetWidth;
  142. return {
  143. height,
  144. width
  145. };
  146. }
  147. `;