| 48 | |
| 49 | @pureRender |
| 50 | export default class extends Component { |
| 51 | |
| 52 | static defaultProps = { |
| 53 | assetRoot: '', |
| 54 | onRun: () => {}, |
| 55 | onError: () => {}, |
| 56 | } |
| 57 | |
| 58 | constructor(props) { |
| 59 | super(props) |
| 60 | } |
| 61 | |
| 62 | componentDidMount() { |
| 63 | window.onmessage = (e) => { |
| 64 | this.runApplication(e.data) |
| 65 | } |
| 66 | |
| 67 | window.onerror = (message, source, line) => { |
| 68 | line -= prefixLineCount |
| 69 | this.throwError(`${message} (${line})`) |
| 70 | return true |
| 71 | } |
| 72 | |
| 73 | parent.postMessage(JSON.stringify({ |
| 74 | id: this.props.id, |
| 75 | type: 'ready', |
| 76 | }), '*') |
| 77 | } |
| 78 | |
| 79 | buildErrorMessage(e) { |
| 80 | let message = `${e.name}: ${e.message}` |
| 81 | let line = null |
| 82 | |
| 83 | // Safari |
| 84 | if (e.line != null) { |
| 85 | line = e.line |
| 86 | |
| 87 | // FF |
| 88 | } else if (e.lineNumber != null) { |
| 89 | line = e.lineNumber |
| 90 | |
| 91 | // Chrome |
| 92 | } else if (e.stack) { |
| 93 | const matched = e.stack.match(/<anonymous>:(\d+)/) |
| 94 | if (matched) { |
| 95 | line = parseInt(matched[1]) |
| 96 | } |
| 97 | } |
| 98 | |
| 99 | if (typeof line === 'number') { |
| 100 | line -= prefixLineCount |
| 101 | message = `${message} (${line})` |
| 102 | } |
| 103 | |
| 104 | return message |
| 105 | } |
| 106 | |
| 107 | throwError(message) { |