UNPKG

feeles-ide

Version:

The hackable and serializable IDE to make learning material

398 lines (302 loc) 11.3 kB
import _regeneratorRuntime from 'babel-runtime/regenerator'; import _getIterator from 'babel-runtime/core-js/get-iterator'; import _toConsumableArray from 'babel-runtime/helpers/toConsumableArray'; import _JSON$stringify from 'babel-runtime/core-js/json/stringify'; import _asyncToGenerator from 'babel-runtime/helpers/asyncToGenerator'; var _this = this; import screenJs from '../../lib/screen'; import regeneratorRuntimePolyfill from 'raw-loader!regenerator-runtime/runtime'; /** * @param html:String * @param findFile:Function * @param env:Object * @return Promise<String> * * iframe にユーザーが入力したHTMLに、次の操作を加える * 0. window.feeles と 環境変数 env のエクスポート * 1. headタグの一番上に screenJs を埋め込む * 2. src 属性を BinaryFile の Data URL に差し替える * REMOVED: 3. screenJs のすぐ下で、全てのスクリプトを define する * 4. スクリプトタグの src 属性を requirejs を Data URL に差し替える * 5. a 要素の href 属性を feeles.replace の Data URL に差し替える * 6. regeneratorRuntime */ export default (function () { var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(html, findFile, env) { var parser, doc, appendScript, binaries, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, node, file, dataURL, _arr, _i, _node, _file, replaced, _arr2, _i2, _node2, _file2, _dataURL, _arr3, _i3, _node3, href; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: parser = new DOMParser(); doc = parser.parseFromString(html, 'text/html'); appendScript = function (lastNode) { return function (text) { var script = doc.createElement('script'); script.type = 'text/javascript'; script.text = text; doc.head.insertBefore(script, lastNode && lastNode.nextSibling); lastNode = script; }; }(doc.head.firstChild); // 0. window.feeles と 環境変数 env のエクスポート appendScript('window.feeles = { env: ' + _JSON$stringify(env) + ' };'); // 1. headタグの一番上に screenJs を埋め込む appendScript(screenJs(env.MODULE)); // 2. src 属性を BinaryFile の Data URL に差し替える binaries = [].concat(_toConsumableArray(doc.images)); _iteratorNormalCompletion = true; _didIteratorError = false; _iteratorError = undefined; _context.prev = 9; _iterator = _getIterator(binaries); case 11: if (_iteratorNormalCompletion = (_step = _iterator.next()).done) { _context.next = 23; break; } node = _step.value; file = findFile(node.getAttribute('src')); if (file) { _context.next = 16; break; } return _context.abrupt('continue', 20); case 16: _context.next = 18; return file.toDataURL(); case 18: dataURL = _context.sent; node.setAttribute('src', dataURL); case 20: _iteratorNormalCompletion = true; _context.next = 11; break; case 23: _context.next = 29; break; case 25: _context.prev = 25; _context.t0 = _context['catch'](9); _didIteratorError = true; _iteratorError = _context.t0; case 29: _context.prev = 29; _context.prev = 30; if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } case 32: _context.prev = 32; if (!_didIteratorError) { _context.next = 35; break; } throw _iteratorError; case 35: return _context.finish(32); case 36: return _context.finish(29); case 37: // 2.1 link 要素の href 属性を Data URL に差し替える _arr = [].concat(_toConsumableArray(doc.querySelectorAll('link'))); _i = 0; case 39: if (!(_i < _arr.length)) { _context.next = 66; break; } _node = _arr[_i]; _file = findFile(_node.getAttribute('href')); if (_file) { _context.next = 44; break; } return _context.abrupt('continue', 63); case 44: if (!(_file.is('css') && _file.text.indexOf('url') >= 0)) { _context.next = 58; break; } _context.t1 = _file; _context.next = 48; return replaceUrls(_file.text, findFile); case 48: _context.t2 = _context.sent; _context.t3 = { text: _context.t2 }; replaced = _context.t1.set.call(_context.t1, _context.t3); _context.t4 = _node; _context.next = 54; return replaced.toDataURL(); case 54: _context.t5 = _context.sent; _context.t4.setAttribute.call(_context.t4, 'href', _context.t5); _context.next = 63; break; case 58: _context.t6 = _node; _context.next = 61; return _file.toDataURL(); case 61: _context.t7 = _context.sent; _context.t6.setAttribute.call(_context.t6, 'href', _context.t7); case 63: _i++; _context.next = 39; break; case 66: // 4. スクリプトタグの src 属性を requirejs を Data URL に差し替える _arr2 = [].concat(_toConsumableArray(doc.scripts)); _i2 = 0; case 68: if (!(_i2 < _arr2.length)) { _context.next = 79; break; } _node2 = _arr2[_i2]; if (!(_node2.type && _node2.type !== 'text/javascript')) { _context.next = 72; break; } return _context.abrupt('continue', 76); case 72: _file2 = findFile(_node2.getAttribute('src')); if (_file2) { _context.next = 75; break; } return _context.abrupt('continue', 76); case 75: if (env.MODULE) { _dataURL = 'data:text/javascript;charset=UTF-8,' + encodeURIComponent(requireTemplate(_file2.moduleName)); _node2.setAttribute('src', _dataURL); } else { _node2.text = _file2.text; _node2.removeAttribute('src'); } case 76: _i2++; _context.next = 68; break; case 79: // 5. a 要素の href 属性を feeles.replace に差し替える _arr3 = [].concat(_toConsumableArray(doc.links)); _i3 = 0; case 81: if (!(_i3 < _arr3.length)) { _context.next = 91; break; } _node3 = _arr3[_i3]; if (!(_node3.getAttribute('target') === '_blank')) { _context.next = 85; break; } return _context.abrupt('continue', 88); case 85: href = _node3.getAttribute('href') || ''; _node3.setAttribute('href', '#'); _node3.setAttribute('onclick', 'feeles.replace(\'' + href + '\')'); case 88: _i3++; _context.next = 81; break; case 91: // 6. regeneratorRuntime appendScript(regeneratorRuntimePolyfill); return _context.abrupt('return', doc.documentElement.outerHTML); case 93: case 'end': return _context.stop(); } } }, _callee, _this, [[9, 25, 29, 37], [30,, 32, 36]]); })); return function (_x, _x2, _x3) { return _ref.apply(this, arguments); }; })(); var requireTemplate = function requireTemplate(src) { return 'requirejs([\'' + src + '\'])'; }; var replaceUrls = function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(text, findFile) { var regExp, matches, _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, token, path, file, dataURL; return _regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: regExp = /url\(.*\)/g; matches = text.match(regExp); if (matches) { _context2.next = 4; break; } return _context2.abrupt('return', text); case 4: _iteratorNormalCompletion2 = true; _didIteratorError2 = false; _iteratorError2 = undefined; _context2.prev = 7; _iterator2 = _getIterator(matches); case 9: if (_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done) { _context2.next = 21; break; } token = _step2.value; path = token.substr(4, token.length - 5); file = findFile(path); if (!file) { _context2.next = 18; break; } _context2.next = 16; return file.toDataURL(); case 16: dataURL = _context2.sent; text = text.replace(token, 'url(' + dataURL + ')'); case 18: _iteratorNormalCompletion2 = true; _context2.next = 9; break; case 21: _context2.next = 27; break; case 23: _context2.prev = 23; _context2.t0 = _context2['catch'](7); _didIteratorError2 = true; _iteratorError2 = _context2.t0; case 27: _context2.prev = 27; _context2.prev = 28; if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } case 30: _context2.prev = 30; if (!_didIteratorError2) { _context2.next = 33; break; } throw _iteratorError2; case 33: return _context2.finish(30); case 34: return _context2.finish(27); case 35: return _context2.abrupt('return', text); case 36: case 'end': return _context2.stop(); } } }, _callee2, _this, [[7, 23, 27, 35], [28,, 30, 34]]); })); return function replaceUrls(_x4, _x5) { return _ref2.apply(this, arguments); }; }();