import { result } from 'underscore'; import Component from './Component'; import { toLowerCase, buildBase64UrlFromSvg, hasWin } from '../../utils/mixins'; import { ObjectStrings } from '../../common'; const svgAttrs = 'xmlns="http://www.w3.org/2000/svg" width="100" viewBox="0 0 24 24" style="fill: rgba(0,0,0,0.15); transform: scale(0.75)"'; export default class ComponentImage extends Component { get defaults() { return { // @ts-ignore ...super.defaults, type: 'image', tagName: 'img', void: true, droppable: 0, editable: 1, highlightable: 0, resizable: { ratioDefault: 1 }, traits: ['alt'], src: ` `, // Fallback image in case the src can't be loaded // If you use SVG, xmlns="http://www.w3.org/2000/svg" is required fallback: ` `, // File to load asynchronously once the model is rendered file: '', }; } initialize(props: any, opts: any) { super.initialize(props, opts); const { src } = this.get('attributes')!; if (src && buildBase64UrlFromSvg(result(this, 'defaults').src) !== src) { this.set('src', src, { silent: true }); } } initToolbar() { super.initToolbar(); const { em } = this; if (em) { const cmd = em.Commands; const cmdName = 'image-editor'; // Add Image Editor button only if the default command exists if (cmd.has(cmdName)) { let hasButtonBool = false; const tb = this.get('toolbar')!; for (let i = 0; i < tb.length; i++) { if (tb[i].command === 'image-editor') { hasButtonBool = true; break; } } if (!hasButtonBool) { tb.push({ attributes: { class: 'fa fa-pencil' }, command: cmdName, }); this.set('toolbar', tb); } } } } /** * Returns object of attributes for HTML * @return {Object} * @private */ getAttrToHTML() { const attr = super.getAttrToHTML(); const src = this.getSrcResult(); if (src) attr.src = src; return attr; } getSrcResult(opt: { fallback?: boolean } = {}) { const src = this.get(opt.fallback ? 'fallback' : 'src') || ''; let result = src; if (src && src.substr(0, 4) === '[0]) { const obj = super.toJSON(opts); const { attributes } = obj; if (attributes && obj.src === attributes.src) { delete obj.src; } return obj; } /** * Parse uri * @param {string} uri * @return {object} * @private */ parseUri(uri: string) { let result: HTMLAnchorElement | URL | ObjectStrings = {}; const getQueryObject = (search = '') => { const query: ObjectStrings = {}; const qrs = search.substring(1).split('&'); for (let i = 0; i < qrs.length; i++) { const pair = qrs[i].split('='); const name = decodeURIComponent(pair[0]); if (name) query[name] = decodeURIComponent(pair[1] || ''); } return query; }; if (hasWin()) { result = document.createElement('a'); result.href = uri; } else if (typeof URL !== 'undefined') { try { result = new URL(uri); } catch (e) {} } return { hostname: result.hostname || '', pathname: result.pathname || '', protocol: result.protocol || '', search: result.search || '', hash: result.hash || '', port: result.port || '', query: getQueryObject(result.search), }; } static isComponent(el: HTMLElement) { return toLowerCase(el.tagName) === 'img'; } }