svgedit/dist/editor/extensions/ext-imagelib.js.map

1 line
24 KiB
Plaintext

{"version":3,"file":"ext-imagelib.js","sources":["../../../src/editor/extensions/ext-imagelib.js"],"sourcesContent":["/**\n * @file ext-imagelib.js\n *\n * @license MIT\n *\n * @copyright 2010 Alexis Deveria\n *\n */\n\nexport default {\n name: 'imagelib',\n async init ({$, decode64, importLocale, dropXMLInternalSubset}) {\n const imagelibStrings = await importLocale();\n\n const modularVersion = !('svgEditor' in window) ||\n !window.svgEditor ||\n window.svgEditor.modules !== false;\n\n const svgEditor = this;\n\n const {uiStrings, canvas: svgCanvas} = svgEditor;\n\n imagelibStrings.imgLibs = imagelibStrings.imgLibs.map(({name, url, description}) => {\n // Todo: Adopt some standard formatting library like `fluent.js` instead\n url = url\n // Keep these regexes as is in prep. for switching to `u` flag\n // which will require escaping\n .replace(\n // eslint-disable-next-line unicorn/better-regex\n /\\{modularVersion\\}/g,\n modularVersion\n ? (imagelibStrings.moduleEnding || '-es')\n : ''\n );\n return {name, url, description};\n });\n const allowedImageLibOrigins = imagelibStrings.imgLibs.map(({url}) => {\n try {\n return new URL(url).origin;\n } catch (err) {\n return location.origin;\n }\n });\n\n /**\n *\n * @returns {void}\n */\n function closeBrowser () {\n $('#imgbrowse_holder').hide();\n document.activeElement.blur(); // make sure focus is the body to correct issue #417\n }\n\n /**\n * @param {string} url\n * @returns {void}\n */\n function importImage (url) {\n const newImage = svgCanvas.addSVGElementFromJson({\n element: 'image',\n attr: {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n id: svgCanvas.getNextId(),\n style: 'pointer-events:inherit'\n }\n });\n svgCanvas.clearSelection();\n svgCanvas.addToSelection([newImage]);\n svgCanvas.setImageURL(url);\n }\n\n const pending = {};\n\n let mode = 's';\n let multiArr = [];\n let transferStopped = false;\n let preview, submit;\n\n /**\n * Contains the SVG to insert.\n * @typedef {PlainObject} ImageLibMessage\n * @property {\"imagelib\"} namespace Required to distinguish from any other messages of app.\n * @property {string} href Set to same value as previous `ImageLibMetaMessage` `id`.\n * @property {string} data The response (as an SVG string or URL)\n */\n\n /**\n * Used for setting meta-data before images are retrieved.\n * @typedef {PlainObject} ImageLibMetaMessage\n * @property {\"imagelib\"} namespace Required to distinguish from any other messages of app.\n * @property {string} name If the subsequent response is an SVG string or if `preview_url`\n * is present, will be used as the title for the preview image. When an\n * SVG string is present, will default to the first `<title>`'s contents or\n * \"(SVG #<Length of response>)\" if none is present. Otherwise, if `preview_url`\n * is present, will default to the empty string. Though `name` may be falsy,\n * it is always expected to be present for meta messages.\n * @property {string} id Identifier (the expected `href` for a subsequent response message);\n * used for ensuring the subsequent response can be tied to this `ImageLibMetaMessage` object.\n * @property {string} [preview_url] When import mode is multiple, used to set an image\n * source along with the name/title. If the subsequent response is an SVG string\n * and there is no `preview_url`, the default will just be to show the\n * name/title. If the response is not an SVG string, the default will be to\n * show that response (i.e., the URL).\n * @property {string} entry Set automatically with div holding retrieving\n * message (until ready to delete)\n * @todo Should use a separate Map instead of `entry`\n */\n\n /**\n * @param {PlainObject} cfg\n * @param {string} cfg.origin\n * @param {ImageLibMetaMessage|ImageLibMessage|string} cfg.data String is deprecated when parsed to JSON `ImageLibMessage`\n * @returns {void}\n */\n async function onMessage ({origin, data: response}) { // eslint-disable-line no-shadow\n if (!response || !['string', 'object'].includes(typeof response)) {\n // Do nothing\n return;\n }\n let id;\n let type;\n try {\n // Todo: This block can be removed (and the above check changed to\n // insist on an object) if embedAPI moves away from a string to\n // an object (if IE9 support not needed)\n response = typeof response === 'object' ? response : JSON.parse(response);\n if (response.namespace !== 'imagelib') {\n return;\n }\n if (!allowedImageLibOrigins.includes('*') && !allowedImageLibOrigins.includes(origin)) {\n // Todo: Surface this error to user?\n console.log(`Origin ${origin} not whitelisted for posting to ${window.origin}`); // eslint-disable-line no-console\n return;\n }\n const hasName = 'name' in response;\n const hasHref = 'href' in response;\n\n if (!hasName && transferStopped) {\n transferStopped = false;\n return;\n }\n\n if (hasHref) {\n id = response.href;\n response = response.data;\n }\n\n // Hide possible transfer dialog box\n $('#dialog_box').hide();\n type = hasName\n ? 'meta'\n : response.charAt(0);\n } catch (e) {\n // This block is for backward compatibility (for IAN and Openclipart);\n // should otherwise return\n if (typeof response === 'string') {\n const char1 = response.charAt(0);\n\n if (char1 !== '{' && transferStopped) {\n transferStopped = false;\n return;\n }\n\n if (char1 === '|') {\n const secondpos = response.indexOf('|', 1);\n id = response.substr(1, secondpos - 1);\n response = response.substr(secondpos + 1);\n type = response.charAt(0);\n }\n }\n }\n\n let entry, curMeta, svgStr, imgStr;\n switch (type) {\n case 'meta': {\n // Metadata\n transferStopped = false;\n curMeta = response;\n\n // Should be safe to add dynamic property as passed metadata\n pending[curMeta.id] = curMeta; // lgtm [js/remote-property-injection]\n\n const name = (curMeta.name || 'file');\n\n const message = uiStrings.notification.retrieving.replace('%s', name);\n\n if (mode !== 'm') {\n await $.process_cancel(message);\n transferStopped = true;\n // Should a message be sent back to the frame?\n\n $('#dialog_box').hide();\n } else {\n entry = $('<div>').text(message).data('id', curMeta.id);\n preview.append(entry);\n curMeta.entry = entry;\n }\n\n return;\n }\n case '<':\n svgStr = true;\n break;\n case 'd': {\n if (response.startsWith('data:image/svg+xml')) {\n const pre = 'data:image/svg+xml;base64,';\n const src = response.substring(pre.length);\n response = decode64(src);\n svgStr = true;\n break;\n } else if (response.startsWith('data:image/')) {\n imgStr = true;\n break;\n }\n }\n // Else fall through\n default:\n // TODO: See if there's a way to base64 encode the binary data stream\n // const str = 'data:;base64,' + svgedit.utilities.encode64(response, true);\n\n // Assume it's raw image data\n // importImage(str);\n\n // Don't give warning as postMessage may have been used by something else\n if (mode !== 'm') {\n closeBrowser();\n } else {\n pending[id].entry.remove();\n }\n // await $.alert('Unexpected data was returned: ' + response, function() {\n // if (mode !== 'm') {\n // closeBrowser();\n // } else {\n // pending[id].entry.remove();\n // }\n // });\n return;\n }\n\n switch (mode) {\n case 's':\n // Import one\n if (svgStr) {\n svgCanvas.importSvgString(response);\n } else if (imgStr) {\n importImage(response);\n }\n closeBrowser();\n break;\n case 'm': {\n // Import multiple\n multiArr.push([(svgStr ? 'svg' : 'img'), response]);\n curMeta = pending[id];\n let title;\n if (svgStr) {\n if (curMeta && curMeta.name) {\n title = curMeta.name;\n } else {\n // Try to find a title\n // `dropXMLInternalSubset` is to help prevent the billion laughs attack\n const xml = new DOMParser().parseFromString(dropXMLInternalSubset(response), 'text/xml').documentElement; // lgtm [js/xml-bomb]\n title = $(xml).children('title').first().text() || '(SVG #' + response.length + ')';\n }\n if (curMeta) {\n preview.children().each(function () {\n if ($(this).data('id') === id) {\n if (curMeta.preview_url) {\n $(this).html(\n $('<span>').append(\n $('<img>').attr('src', curMeta.preview_url),\n title\n )\n );\n } else {\n $(this).text(title);\n }\n submit.removeAttr('disabled');\n }\n });\n } else {\n preview.append(\n $('<div>').text(title)\n );\n submit.removeAttr('disabled');\n }\n } else {\n if (curMeta && curMeta.preview_url) {\n title = curMeta.name || '';\n entry = $('<span>').append(\n $('<img>').attr('src', curMeta.preview_url),\n title\n );\n } else {\n entry = $('<img>').attr('src', response);\n }\n\n if (curMeta) {\n preview.children().each(function () {\n if ($(this).data('id') === id) {\n $(this).html(entry);\n submit.removeAttr('disabled');\n }\n });\n } else {\n preview.append($('<div>').append(entry));\n submit.removeAttr('disabled');\n }\n }\n break;\n } case 'o': {\n // Open\n if (!svgStr) { break; }\n closeBrowser();\n const ok = await svgEditor.openPrep();\n if (!ok) { return; }\n svgCanvas.clear();\n svgCanvas.setSvgString(response);\n // updateCanvas();\n break;\n }\n }\n }\n\n // Receive `postMessage` data\n window.addEventListener('message', onMessage, true);\n\n /**\n * @param {boolean} show\n * @returns {void}\n */\n function toggleMulti (show) {\n $('#lib_framewrap, #imglib_opts').css({right: (show ? 200 : 10)});\n if (!preview) {\n preview = $('<div id=imglib_preview>').css({\n position: 'absolute',\n top: 45,\n right: 10,\n width: 180,\n bottom: 45,\n background: '#fff',\n overflow: 'auto'\n }).insertAfter('#lib_framewrap');\n\n submit = $('<button disabled>Import selected</button>')\n .appendTo('#imgbrowse')\n .on('click touchend', function () {\n $.each(multiArr, function (i) {\n const type = this[0];\n const data = this[1];\n if (type === 'svg') {\n svgCanvas.importSvgString(data);\n } else {\n importImage(data);\n }\n svgCanvas.moveSelectedElements(i * 20, i * 20, false);\n });\n preview.empty();\n multiArr = [];\n $('#imgbrowse_holder').hide();\n }).css({\n position: 'absolute',\n bottom: 10,\n right: -10\n });\n }\n\n preview.toggle(show);\n submit.toggle(show);\n }\n\n /**\n *\n * @returns {void}\n */\n function showBrowser () {\n let browser = $('#imgbrowse');\n if (!browser.length) {\n $('<div id=imgbrowse_holder><div id=imgbrowse class=toolbar_button>' +\n '</div></div>').insertAfter('#svg_docprops');\n browser = $('#imgbrowse');\n\n const allLibs = imagelibStrings.select_lib;\n\n const libOpts = $('<ul id=imglib_opts>').appendTo(browser);\n const frame = $('<iframe src=\"javascript:0\"/>').prependTo(browser).hide().wrap('<div id=lib_framewrap>');\n\n const header = $('<h1>').prependTo(browser).text(allLibs).css({\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%'\n });\n\n const cancel = $('<button>' + uiStrings.common.cancel + '</button>')\n .appendTo(browser)\n .on('click touchend', function () {\n $('#imgbrowse_holder').hide();\n }).css({\n position: 'absolute',\n top: 5,\n right: -10\n });\n\n const leftBlock = $('<span>').css({position: 'absolute', top: 5, left: 10}).appendTo(browser);\n\n const back = $('<button hidden>' + imagelibStrings.show_list + '</button>')\n .appendTo(leftBlock)\n .on('click touchend', function () {\n frame.attr('src', 'about:blank').hide();\n libOpts.show();\n header.text(allLibs);\n back.hide();\n }).css({\n 'margin-right': 5\n }).hide();\n\n /* const type = */ $('<select><option value=s>' +\n imagelibStrings.import_single + '</option><option value=m>' +\n imagelibStrings.import_multi + '</option><option value=o>' +\n imagelibStrings.open + '</option></select>').appendTo(leftBlock).change(function () {\n mode = $(this).val();\n switch (mode) {\n case 's':\n case 'o':\n toggleMulti(false);\n break;\n\n case 'm':\n // Import multiple\n toggleMulti(true);\n break;\n }\n }).css({\n 'margin-top': 10\n });\n\n cancel.prepend($.getSvgIcon('cancel', true));\n back.prepend($.getSvgIcon('tool_imagelib', true));\n\n imagelibStrings.imgLibs.forEach(function ({name, url, description}) {\n $('<li>')\n .appendTo(libOpts)\n .text(name)\n .on('click touchend', function () {\n frame.attr(\n 'src',\n url\n ).show();\n header.text(name);\n libOpts.hide();\n back.show();\n }).append(`<span>${description}</span>`);\n });\n } else {\n $('#imgbrowse_holder').show();\n }\n }\n\n const buttons = [{\n id: 'tool_imagelib',\n type: 'app_menu', // _flyout\n icon: 'imagelib.png',\n position: 4,\n events: {\n mouseup: showBrowser\n }\n }];\n\n return {\n svgicons: 'ext-imagelib.xml',\n buttons: imagelibStrings.buttons.map((button, i) => {\n return Object.assign(buttons[i], button);\n }),\n callback () {\n $('<style>').text(\n '#imgbrowse_holder {' +\n 'position: absolute;' +\n 'top: 0;' +\n 'left: 0;' +\n 'width: 100%;' +\n 'height: 100%;' +\n 'background-color: rgba(0, 0, 0, .5);' +\n 'z-index: 5;' +\n '}' +\n '#imgbrowse {' +\n 'position: absolute;' +\n 'top: 25px;' +\n 'left: 25px;' +\n 'right: 25px;' +\n 'bottom: 25px;' +\n 'min-width: 300px;' +\n 'min-height: 200px;' +\n 'background: #B0B0B0;' +\n 'border: 1px outset #777;' +\n '}' +\n '#imgbrowse h1 {' +\n 'font-size: 20px;' +\n 'margin: .4em;' +\n 'text-align: center;' +\n '}' +\n '#lib_framewrap,' +\n '#imgbrowse > ul {' +\n 'position: absolute;' +\n 'top: 45px;' +\n 'left: 10px;' +\n 'right: 10px;' +\n 'bottom: 10px;' +\n 'background: white;' +\n 'margin: 0;' +\n 'padding: 0;' +\n '}' +\n '#imgbrowse > ul {' +\n 'overflow: auto;' +\n '}' +\n '#imgbrowse > div {' +\n 'border: 1px solid #666;' +\n '}' +\n '#imglib_preview > div {' +\n 'padding: 5px;' +\n 'font-size: 12px;' +\n '}' +\n '#imglib_preview img {' +\n 'display: block;' +\n 'margin: 0 auto;' +\n 'max-height: 100px;' +\n '}' +\n '#imgbrowse li {' +\n 'list-style: none;' +\n 'padding: .5em;' +\n 'background: #E8E8E8;' +\n 'border-bottom: 1px solid #B0B0B0;' +\n 'line-height: 1.2em;' +\n 'font-style: sans-serif;' +\n '}' +\n '#imgbrowse li > span {' +\n 'color: #666;' +\n 'font-size: 15px;' +\n 'display: block;' +\n '}' +\n '#imgbrowse li:hover {' +\n 'background: #FFC;' +\n 'cursor: pointer;' +\n '}' +\n '#imgbrowse iframe {' +\n 'width: 100%;' +\n 'height: 100%;' +\n 'border: 0;' +\n '}'\n ).appendTo('head');\n }\n };\n }\n};\n"],"names":["name","init","closeBrowser","importImage","onMessage","toggleMulti","showBrowser","browser","$","length","show","insertAfter","allLibs","imagelibStrings","select_lib","libOpts","appendTo","frame","prependTo","hide","wrap","header","text","css","position","top","left","width","cancel","uiStrings","common","on","right","leftBlock","back","show_list","attr","import_single","import_multi","open","change","mode","this","val","prepend","getSvgIcon","imgLibs","forEach","url","description","append","preview","bottom","background","overflow","submit","each","multiArr","i","type","data","svgCanvas","importSvgString","moveSelectedElements","empty","toggle","origin","response","includes","_typeof","JSON","parse","namespace","allowedImageLibOrigins","console","log","window","hasHref","hasName","transferStopped","id","href","charAt","char1","secondpos","indexOf","substr","pending","curMeta","message","notification","retrieving","replace","process_cancel","entry","svgStr","startsWith","src","substring","decode64","imgStr","remove","push","title","xml","DOMParser","parseFromString","dropXMLInternalSubset","documentElement","children","first","preview_url","html","removeAttr","svgEditor","openPrep","clear","setSvgString","newImage","addSVGElementFromJson","element","x","y","height","getNextId","style","clearSelection","addToSelection","setImageURL","document","activeElement","blur","importLocale","modularVersion","modules","_this","canvas","map","moduleEnding","URL","err","location","addEventListener","buttons","icon","events","mouseup","svgicons","button","Object","assign","callback"],"mappings":"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"}