No Description

common.js 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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. function getWidth(style) {
  22. return style && style.width ? style.width : screenWidth;
  23. }
  24. const bodyStyle = `
  25. body {
  26. margin: 0;
  27. padding: 0;
  28. }
  29. `;
  30. function appendStylesToHead(styles, script) {
  31. const currentStyles = styles ? bodyStyle + styles : bodyStyle;
  32. // Escape any single quotes or newlines in the CSS with .replace()
  33. const escaped = currentStyles.replace(/\'/g, "\\'").replace(/\n/g, '\\n');
  34. return `
  35. var styleElement = document.createElement('style');
  36. styleElement.innerHTML = '${escaped}';
  37. document.head.appendChild(styleElement);
  38. ${script}
  39. `;
  40. }
  41. function getReloadRelatedData(props) {
  42. const { hasIframe, files, customStyle, customScript, style, source } = props;
  43. return {
  44. source,
  45. hasIframe,
  46. files,
  47. customStyle,
  48. customScript,
  49. style
  50. };
  51. }
  52. function isChanged(newValue, oldValue) {
  53. return !Immutable.is(Immutable.fromJS(newValue), Immutable.fromJS(oldValue));
  54. }
  55. function getScript(props, getBaseScript, getIframeBaseScript) {
  56. const { hasIframe, files, customStyle, customScript, style } = getReloadRelatedData(props);
  57. const baseScript = getBaseScript(style);
  58. let script = hasIframe ? baseScript : getIframeBaseScript(style);
  59. script = files ? appendFilesToHead(files, baseScript) : baseScript;
  60. script = appendStylesToHead(customStyle, script);
  61. customScript && (script = customScript + script);
  62. return script;
  63. }
  64. function isEqual(newProps, oldProps) {
  65. return isChanged(getReloadRelatedData(newProps), getReloadRelatedData(oldProps));
  66. }
  67. function insertStringAfterAnotherString(raw, searchValue, insertValue) {
  68. const position = raw.indexOf(searchValue) + searchValue.length;
  69. return [raw.slice(0, position), insertValue, raw.slice(position)].join('');
  70. }
  71. function getInjectedSource(html, script) {
  72. const scriptString = `
  73. <script>
  74. ${script}
  75. </script>
  76. `;
  77. if (html.startsWith('<html')) {
  78. return insertStringAfterAnotherString(html, '>', scriptString);
  79. } else {
  80. return `
  81. ${html}
  82. ${scriptString}
  83. `;
  84. }
  85. }
  86. 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. function handleSizeUpdated(height, width, onSizeUpdated) {
  112. onSizeUpdated &&
  113. onSizeUpdated({
  114. height,
  115. width
  116. });
  117. }
  118. 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. 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 { isEqual, setState, getWidth, handleSizeUpdated, domMutationObserveScript, getSize };