126 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| // The error overlay is inspired (and mostly copied) from Create React App (https://github.com/facebookincubator/create-react-app)
 | |
| // They, in turn, got inspired by webpack-hot-middleware (https://github.com/glenjamin/webpack-hot-middleware).
 | |
| 
 | |
| var ansiHTML = require('ansi-html');
 | |
| var Entities = require('html-entities').AllHtmlEntities;
 | |
| 
 | |
| var entities = new Entities();
 | |
| 
 | |
| var colors = {
 | |
|   reset: ['transparent', 'transparent'],
 | |
|   black: '181818',
 | |
|   red: 'E36049',
 | |
|   green: 'B3CB74',
 | |
|   yellow: 'FFD080',
 | |
|   blue: '7CAFC2',
 | |
|   magenta: '7FACCA',
 | |
|   cyan: 'C3C2EF',
 | |
|   lightgrey: 'EBE7E3',
 | |
|   darkgrey: '6D7891'
 | |
| };
 | |
| ansiHTML.setColors(colors);
 | |
| 
 | |
| function createOverlayIframe(onIframeLoad) {
 | |
|   var iframe = document.createElement('iframe');
 | |
|   iframe.id = 'webpack-dev-server-client-overlay';
 | |
|   iframe.src = 'about:blank';
 | |
|   iframe.style.position = 'fixed';
 | |
|   iframe.style.left = 0;
 | |
|   iframe.style.top = 0;
 | |
|   iframe.style.right = 0;
 | |
|   iframe.style.bottom = 0;
 | |
|   iframe.style.width = '100vw';
 | |
|   iframe.style.height = '100vh';
 | |
|   iframe.style.border = 'none';
 | |
|   iframe.style.zIndex = 9999999999;
 | |
|   iframe.onload = onIframeLoad;
 | |
|   return iframe;
 | |
| }
 | |
| 
 | |
| function addOverlayDivTo(iframe) {
 | |
|   var div = iframe.contentDocument.createElement('div');
 | |
|   div.id = 'webpack-dev-server-client-overlay-div';
 | |
|   div.style.position = 'fixed';
 | |
|   div.style.boxSizing = 'border-box';
 | |
|   div.style.left = 0;
 | |
|   div.style.top = 0;
 | |
|   div.style.right = 0;
 | |
|   div.style.bottom = 0;
 | |
|   div.style.width = '100vw';
 | |
|   div.style.height = '100vh';
 | |
|   div.style.backgroundColor = 'rgba(0, 0, 0, 0.85)';
 | |
|   div.style.color = '#E8E8E8';
 | |
|   div.style.fontFamily = 'Menlo, Consolas, monospace';
 | |
|   div.style.fontSize = 'large';
 | |
|   div.style.padding = '2rem';
 | |
|   div.style.lineHeight = '1.2';
 | |
|   div.style.whiteSpace = 'pre-wrap';
 | |
|   div.style.overflow = 'auto';
 | |
|   iframe.contentDocument.body.appendChild(div);
 | |
|   return div;
 | |
| }
 | |
| 
 | |
| var overlayIframe = null;
 | |
| var overlayDiv = null;
 | |
| var lastOnOverlayDivReady = null;
 | |
| 
 | |
| function ensureOverlayDivExists(onOverlayDivReady) {
 | |
|   if (overlayDiv) {
 | |
|     // Everything is ready, call the callback right away.
 | |
|     onOverlayDivReady(overlayDiv);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   // Creating an iframe may be asynchronous so we'll schedule the callback.
 | |
|   // In case of multiple calls, last callback wins.
 | |
|   lastOnOverlayDivReady = onOverlayDivReady;
 | |
| 
 | |
|   if (overlayIframe) {
 | |
|     // We're already creating it.
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   // Create iframe and, when it is ready, a div inside it.
 | |
|   overlayIframe = createOverlayIframe(function () {
 | |
|     overlayDiv = addOverlayDivTo(overlayIframe);
 | |
|     // Now we can talk!
 | |
|     lastOnOverlayDivReady(overlayDiv);
 | |
|   });
 | |
| 
 | |
|   // Zalgo alert: onIframeLoad() will be called either synchronously
 | |
|   // or asynchronously depending on the browser.
 | |
|   // We delay adding it so `overlayIframe` is set when `onIframeLoad` fires.
 | |
|   document.body.appendChild(overlayIframe);
 | |
| }
 | |
| 
 | |
| function showMessageOverlay(message) {
 | |
|   ensureOverlayDivExists(function (div) {
 | |
|     // Make it look similar to our terminal.
 | |
|     div.innerHTML = '<span style="color: #' + colors.red + '">Failed to compile.</span><br><br>' + ansiHTML(entities.encode(message));
 | |
|   });
 | |
| }
 | |
| 
 | |
| function destroyErrorOverlay() {
 | |
|   if (!overlayDiv) {
 | |
|     // It is not there in the first place.
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   // Clean up and reset internal state.
 | |
|   document.body.removeChild(overlayIframe);
 | |
|   overlayDiv = null;
 | |
|   overlayIframe = null;
 | |
|   lastOnOverlayDivReady = null;
 | |
| }
 | |
| 
 | |
| // Successful compilation.
 | |
| exports.clear = function handleSuccess() {
 | |
|   destroyErrorOverlay();
 | |
| };
 | |
| 
 | |
| // Compilation with errors (e.g. syntax error or missing modules).
 | |
| exports.showMessage = function handleMessage(messages) {
 | |
|   showMessageOverlay(messages[0]);
 | |
| }; |