UNPKG

ep_images_extended

Version:

Insert images inline with text, float them, resize them, and more.

82 lines (67 loc) 3.39 kB
'use strict'; // Modified from ep_image_insert 1.0.7 const Changeset = require('ep_etherpad-lite/static/js/Changeset'); const Security = require('ep_etherpad-lite/static/js/security'); exports.getLineHTMLForExport = async (hook, context) => { const attribLine = context.attribLine; const apool = context.apool; if (attribLine) { let generatedHTML = ''; let currentPos = 0; const opIter = Changeset.opIterator(attribLine); while (opIter.hasNext()) { const op = opIter.next(); const opChars = op.chars; const textSegment = context.text.substring(currentPos, currentPos + opChars); let htmlSegment = Security.escapeHTML(textSegment); // Default: escaped text // Check for our image attribute const imageSrcAttrib = Changeset.opAttributeValue(op, 'image', apool); const imageWidthAttrib = Changeset.opAttributeValue(op, 'image-width', apool); const imageHeightAttrib = Changeset.opAttributeValue(op, 'image-height', apool); const imageIdAttrib = Changeset.opAttributeValue(op, 'image-id', apool); // const imageAspectRatioAttrib = Changeset.opAttributeValue(op, 'imageCssAspectRatio', apool); // Not directly used for img tag but good to know it exists if (imageSrcAttrib) { try { const decodedSrc = decodeURIComponent(imageSrcAttrib); if (decodedSrc && (decodedSrc.startsWith('data:') || decodedSrc.startsWith('http') || decodedSrc.startsWith('/'))) { let imgTag = `<img src="${Security.escapeHTML(decodedSrc)}"`; let styles = 'display:inline-block; max-width:100%; height:auto;'; // Default styles if (imageWidthAttrib) { const widthValue = imageWidthAttrib.replace(/px$/, ''); imgTag += ` width="${Security.escapeHTMLAttribute(widthValue)}"`; styles += ` width:${Security.escapeHTMLAttribute(imageWidthAttrib)};`; } if (imageHeightAttrib) { const heightValue = imageHeightAttrib.replace(/px$/, ''); imgTag += ` height="${Security.escapeHTMLAttribute(heightValue)}"`; // If height is set, override height:auto styles = styles.replace('height:auto;', `height:${Security.escapeHTMLAttribute(imageHeightAttrib)};`); } if (imageIdAttrib) { imgTag += ` data-image-id="${Security.escapeHTMLAttribute(imageIdAttrib)}"`; } imgTag += ` style="${styles}"`; imgTag += `>`; htmlSegment = imgTag; } else { console.warn(`[ep_images_extended exportHTML] Invalid unescaped image src: ${decodedSrc}`); // Keep default htmlSegment (escaped placeholder text) or specific error htmlSegment = '[Invalid Image Src]'; } } catch (e) { console.error(`[ep_images_extended exportHTML] Error processing image attribute: ${imageSrcAttrib}`, e); htmlSegment = '[Image Processing Error]'; } } generatedHTML += htmlSegment; currentPos += opChars; } context.lineContent = generatedHTML; } else { // Line has no attributes, just escape the text context.lineContent = Security.escapeHTML(context.text); } }; exports.stylesForExport = (hook, padId, cb) => { cb('img { max-width: 100%; vertical-align: middle; }'); };