UNPKG

feeles-ide

Version:

The hackable and serializable IDE to make learning material

405 lines (311 loc) 11.5 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _screen = _interopRequireDefault(require("../../lib/screen")); var _runtime = _interopRequireDefault(require("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 */ var _default = /*#__PURE__*/ function () { var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/ _regenerator.default.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 _regenerator.default.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: ".concat(JSON.stringify(env), " };")); // 1. headタグの一番上に screenJs を埋め込む appendScript((0, _screen.default)(env.MODULE)); // 2. src 属性を BinaryFile の Data URL に差し替える binaries = (0, _toConsumableArray2.default)(doc.images); _iteratorNormalCompletion = true; _didIteratorError = false; _iteratorError = undefined; _context.prev = 9; _iterator = binaries[Symbol.iterator](); 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 != null) { _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 = (0, _toConsumableArray2.default)(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 = (0, _toConsumableArray2.default)(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 = (0, _toConsumableArray2.default)(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('".concat(href, "')")); case 88: _i3++; _context.next = 81; break; case 91: // 6. regeneratorRuntime appendScript(_runtime.default); 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); }; }(); exports.default = _default; var requireTemplate = function requireTemplate(src) { return "requirejs(['".concat(src, "'])"); }; var replaceUrls = /*#__PURE__*/ function () { var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/ _regenerator.default.mark(function _callee2(text, findFile) { var regExp, matches, _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, token, path, file, dataURL; return _regenerator.default.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 = matches[Symbol.iterator](); 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(".concat(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 != null) { _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); }; }();