| 140 | } |
| 141 | |
| 142 | function getVisibleChildren(element: Element): React$Node { |
| 143 | const children = []; |
| 144 | let node: any = element.firstChild; |
| 145 | while (node) { |
| 146 | if (node.nodeType === 1) { |
| 147 | if ( |
| 148 | ((node.tagName !== 'SCRIPT' && node.tagName !== 'script') || |
| 149 | node.hasAttribute('data-meaningful')) && |
| 150 | node.tagName !== 'TEMPLATE' && |
| 151 | node.tagName !== 'template' && |
| 152 | !node.hasAttribute('hidden') && |
| 153 | !node.hasAttribute('aria-hidden') && |
| 154 | // Ignore the render blocking expect |
| 155 | (node.getAttribute('rel') !== 'expect' || |
| 156 | node.getAttribute('blocking') !== 'render') |
| 157 | ) { |
| 158 | const props: any = {}; |
| 159 | const attributes = node.attributes; |
| 160 | for (let i = 0; i < attributes.length; i++) { |
| 161 | if ( |
| 162 | attributes[i].name === 'id' && |
| 163 | attributes[i].value.includes(':') |
| 164 | ) { |
| 165 | // We assume this is a React added ID that's a non-visual implementation detail. |
| 166 | continue; |
| 167 | } |
| 168 | props[attributes[i].name] = attributes[i].value; |
| 169 | } |
| 170 | const nestedChildren = getVisibleChildren(node); |
| 171 | if (nestedChildren !== undefined) { |
| 172 | props.children = nestedChildren; |
| 173 | } |
| 174 | children.push( |
| 175 | require('react').createElement(node.tagName.toLowerCase(), props), |
| 176 | ); |
| 177 | } |
| 178 | } else if (node.nodeType === 3) { |
| 179 | children.push(node.data); |
| 180 | } |
| 181 | node = node.nextSibling; |
| 182 | } |
| 183 | return children.length === 0 |
| 184 | ? undefined |
| 185 | : children.length === 1 |
| 186 | ? children[0] |
| 187 | : children; |
| 188 | } |
| 189 | |
| 190 | export { |
| 191 | insertNodesAndExecuteScripts, |