fix(client): prevent endless SASS conversion
This commit is contained in:
		
							
								
								
									
										3
									
								
								client/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								client/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -9,6 +9,5 @@ config/env.json | |||||||
| /public | /public | ||||||
| .DS_Store | .DS_Store | ||||||
|  |  | ||||||
| ./static/js/frame-runner.js | /static/js | ||||||
| ./static/js/frame-runner.js.map |  | ||||||
| ./static/_redirects | ./static/_redirects | ||||||
							
								
								
									
										11
									
								
								client/src/client/workers/sass.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								client/src/client/workers/sass.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | /* eslint-disable */ | ||||||
|  | importScripts( | ||||||
|  |   'https://cdnjs.cloudflare.com/ajax/libs/sass.js/0.10.11/sass.sync.min.js' | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | onmessage = e => { | ||||||
|  |   const data = e.data; | ||||||
|  |   Sass.compile(data, result => { | ||||||
|  |     self.postMessage(result.text); | ||||||
|  |   }); | ||||||
|  | } | ||||||
| @@ -1,11 +1,10 @@ | |||||||
| import favicons from './favicons'; | import favicons from './favicons'; | ||||||
| import meta from './meta'; | import meta from './meta'; | ||||||
| import mathjax from './mathjax'; | import mathjax from './mathjax'; | ||||||
| import sassjs from './sassjs'; |  | ||||||
| import scripts from './scripts'; | import scripts from './scripts'; | ||||||
|  |  | ||||||
| const metaAndStyleSheets = meta | const metaAndStyleSheets = meta | ||||||
|   .concat(favicons, mathjax, sassjs, scripts) |   .concat(favicons, mathjax, scripts) | ||||||
|   .map((element, i) => ({ |   .map((element, i) => ({ | ||||||
|     ...element, |     ...element, | ||||||
|     key: `meta-stylesheet-${i}`, |     key: `meta-stylesheet-${i}`, | ||||||
|   | |||||||
| @@ -1,8 +0,0 @@ | |||||||
| import React from 'react'; |  | ||||||
|  |  | ||||||
| const cdnAddr = |  | ||||||
|   'https://cdnjs.cloudflare.com/ajax/libs/sass.js/0.10.9/sass.sync.min.js'; |  | ||||||
|  |  | ||||||
| const sassjs = [<script key='sassjs' src={cdnAddr} type='text/javascript' />]; |  | ||||||
|  |  | ||||||
| export default sassjs; |  | ||||||
| @@ -16,6 +16,7 @@ import presetReact from '@babel/preset-react'; | |||||||
| import protect from 'loop-protect'; | import protect from 'loop-protect'; | ||||||
|  |  | ||||||
| import * as vinyl from '../utils/polyvinyl.js'; | import * as vinyl from '../utils/polyvinyl.js'; | ||||||
|  | import WorkerExecutor from '../utils/worker-executor'; | ||||||
|  |  | ||||||
| const protectTimeout = 100; | const protectTimeout = 100; | ||||||
| Babel.registerPlugin('loopProtection', protect(protectTimeout)); | Babel.registerPlugin('loopProtection', protect(protectTimeout)); | ||||||
| @@ -74,27 +75,21 @@ export const babelTransformer = cond([ | |||||||
|   [stubTrue, identity] |   [stubTrue, identity] | ||||||
| ]); | ]); | ||||||
|  |  | ||||||
|  | const sass = new WorkerExecutor('sass'); | ||||||
|  |  | ||||||
| const htmlSassTransformCode = file => { | const htmlSassTransformCode = file => { | ||||||
|   let doc = document.implementation.createHTMLDocument(); |   const div = document.createElement('div'); | ||||||
|   doc.body.innerHTML = file.contents; |   div.innerHTML = file.contents; | ||||||
|   let styleTags = [].filter.call( |   const styleTags = div.querySelectorAll('style[type="text/sass"]'); | ||||||
|     doc.querySelectorAll('style'), |   if (styleTags.length > 0) { | ||||||
|     style => style.type === 'text/sass' |     return Promise.all([].map.call(styleTags, async style => { | ||||||
|   ); |  | ||||||
|   if (styleTags.length === 0 || typeof Sass === 'undefined') { |  | ||||||
|     return vinyl.transformContents(() => doc.body.innerHTML, file); |  | ||||||
|   } |  | ||||||
|   return Promise.all(styleTags.map(style => ( |  | ||||||
|     new Promise(resolve => { |  | ||||||
|       window.Sass.compile(style.innerHTML, function(result) { |  | ||||||
|       style.type = 'text/css'; |       style.type = 'text/css'; | ||||||
|         style.innerHTML = result.text; |       style.innerHTML = await sass.execute(style.innerHTML, 2000); | ||||||
|         resolve(); |     })).then(() => ( | ||||||
|       }); |       vinyl.transformContents(() => div.innerHTML, file) | ||||||
|     }) |  | ||||||
|   ))).then(() => ( |  | ||||||
|     vinyl.transformContents(() => doc.body.innerHTML, file) |  | ||||||
|     )); |     )); | ||||||
|  |   } | ||||||
|  |   return vinyl.transformContents(() => div.innerHTML, file); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| export const htmlSassTransformer = cond([ | export const htmlSassTransformer = cond([ | ||||||
|   | |||||||
							
								
								
									
										45
									
								
								client/src/templates/Challenges/utils/worker-executor.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								client/src/templates/Challenges/utils/worker-executor.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | |||||||
|  | export default class WorkerExecutor { | ||||||
|  |   constructor(workerName) { | ||||||
|  |     this.workerName = workerName; | ||||||
|  |     this.worker = null; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getWorker() { | ||||||
|  |     if (this.worker === null) { | ||||||
|  |       this.worker = new Worker(`js/${this.workerName}.js`); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return this.worker; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   killWorker() { | ||||||
|  |     if (this.worker !== null) { | ||||||
|  |       this.worker.terminate(); | ||||||
|  |       this.worker = null; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   execute(data, timeout = 1000) { | ||||||
|  |     const worker = this.getWorker(); | ||||||
|  |     return new Promise((resolve, reject) => { | ||||||
|  |       // Handle timeout | ||||||
|  |       const timeoutId = setTimeout(() => { | ||||||
|  |         this.killWorker(); | ||||||
|  |         reject('timeout'); | ||||||
|  |       }, timeout); | ||||||
|  |  | ||||||
|  |       worker.postMessage(data); | ||||||
|  |  | ||||||
|  |       // Handle result | ||||||
|  |       worker.onmessage = e => { | ||||||
|  |         clearTimeout(timeoutId); | ||||||
|  |         resolve(e.data); | ||||||
|  |       }; | ||||||
|  |  | ||||||
|  |       worker.onerror = e => { | ||||||
|  |         clearTimeout(timeoutId); | ||||||
|  |         reject(e.message); | ||||||
|  |       }; | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -4,10 +4,12 @@ module.exports = (env = {}) => { | |||||||
|   const __DEV__ = env.production !== true; |   const __DEV__ = env.production !== true; | ||||||
|   return { |   return { | ||||||
|     mode: __DEV__ ? 'development' : 'production', |     mode: __DEV__ ? 'development' : 'production', | ||||||
|     entry: './src/client/frame-runner.js', |     entry: { | ||||||
|  |       'frame-runner': './src/client/frame-runner.js', | ||||||
|  |       sass: './src/client/workers/sass.js' | ||||||
|  |     }, | ||||||
|     devtool: __DEV__ ? 'inline-source-map' : 'source-map', |     devtool: __DEV__ ? 'inline-source-map' : 'source-map', | ||||||
|     output: { |     output: { | ||||||
|       filename: 'frame-runner.js', |  | ||||||
|       path: path.join(__dirname, './static/js') |       path: path.join(__dirname, './static/js') | ||||||
|     }, |     }, | ||||||
|     stats: { |     stats: { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user