move untested components to Archive
This commit is contained in:
2
archive/untested-embedded-api/Readme.md
Normal file
2
archive/untested-embedded-api/Readme.md
Normal file
@@ -0,0 +1,2 @@
|
||||
The file below are working with V6 but were not tested with V7
|
||||
Please open an issue to make them back into the main project.
|
||||
131
archive/untested-embedded-api/embedapi-dom.js
Normal file
131
archive/untested-embedded-api/embedapi-dom.js
Normal file
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* Attaches items to DOM for Embedded SVG support.
|
||||
* @module EmbeddedSVGEditDOM
|
||||
*/
|
||||
import EmbeddedSVGEdit from './embedapi.js';
|
||||
import { isChrome } from '../common/browser.js';
|
||||
|
||||
let svgCanvas = null;
|
||||
|
||||
/**
|
||||
* @param {string} data
|
||||
* @param {string} error
|
||||
* @returns {void}
|
||||
*/
|
||||
function handleSvgData (data, error) {
|
||||
if (error) {
|
||||
// Todo: This should be replaced with a general purpose dialog alert library call
|
||||
alert('error ' + error);
|
||||
} else {
|
||||
// Todo: This should be replaced with a general purpose dialog alert library call
|
||||
alert('Congratulations. Your SVG string is back in the host page, do with it what you will\n\n' + data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the canvas with an example SVG string.
|
||||
* @returns {void}
|
||||
*/
|
||||
function loadSvg () {
|
||||
const svgexample = '<svg width="640" height="480" xmlns:xlink="' +
|
||||
'http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">' +
|
||||
'<g><title>Layer 1</title><rect stroke-width="5" stroke="#000000" ' +
|
||||
'fill="#FF0000" id="svg_1" height="35" width="51" y="35" x="32"/>' +
|
||||
'<ellipse ry="15" rx="24" stroke-width="5" stroke="#000000" ' +
|
||||
'fill="#0000ff" id="svg_2" cy="60" cx="66"/></g></svg>';
|
||||
svgCanvas.setSvgString(svgexample);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function saveSvg () {
|
||||
svgCanvas.getSvgString()(handleSvgData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a PNG export.
|
||||
* @returns {void}
|
||||
*/
|
||||
function exportPNG () {
|
||||
svgCanvas.getUIStrings()(function (uiStrings) {
|
||||
const str = uiStrings.notification.loadingImage;
|
||||
let exportWindow;
|
||||
if (!isChrome()) {
|
||||
exportWindow = window.open(
|
||||
'data:text/html;charset=utf-8,' + encodeURIComponent('<title>' + str + '</title><h1>' + str + '</h1>'),
|
||||
'svg-edit-exportWindow'
|
||||
);
|
||||
}
|
||||
svgCanvas.rasterExport('PNG', null, exportWindow && exportWindow.name)();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a PDF export.
|
||||
* @returns {void}
|
||||
*/
|
||||
function exportPDF () {
|
||||
svgCanvas.getUIStrings()(function (uiStrings) {
|
||||
const str = uiStrings.notification.loadingImage;
|
||||
|
||||
/*
|
||||
// If you want to handle the PDF blob yourself, do as follows
|
||||
svgCanvas.bind('exportedPDF', function (win, data) {
|
||||
alert(data.output);
|
||||
});
|
||||
svgCanvas.exportPDF(); // Accepts two args: optionalWindowName supplied back to bound exportPDF handler and optional outputType (defaults to dataurlstring)
|
||||
return;
|
||||
*/
|
||||
|
||||
if (isChrome()) {
|
||||
// Chrome will open an extra window if we follow the approach below
|
||||
svgCanvas.exportPDF();
|
||||
} else {
|
||||
const exportWindow = window.open(
|
||||
'data:text/html;charset=utf-8,' + encodeURIComponent('<title>' + str + '</title><h1>' + str + '</h1>'),
|
||||
'svg-edit-exportWindow'
|
||||
);
|
||||
svgCanvas.exportPDF(exportWindow && exportWindow.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const frameBase = 'https://raw.githack.com/SVG-Edit/svgedit/master';
|
||||
// const frameBase = 'http://localhost:8001';
|
||||
const framePath = '/editor/xdomain-svg-editor-es.html?extensions=ext-xdomain-messaging.js';
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.id = "svgedit";
|
||||
iframe.style.width = "900px";
|
||||
iframe.style.width = "600px";
|
||||
iframe.src = frameBase + framePath +
|
||||
(location.href.includes('?')
|
||||
// ? location.href.replace(/\?(?<search>.*)$/, '&$<search>')
|
||||
? location.href.replace(/\?(.*)$/, '&$1')
|
||||
: ''); // Append arguments to this file onto the iframe
|
||||
|
||||
iframe.addEventListener('load', function () {
|
||||
svgCanvas = new EmbeddedSVGEdit(frame, [ new URL(frameBase).origin ]);
|
||||
const { $id } = svgCanvas;
|
||||
// Hide main button, as we will be controlling new, load, save, etc. from the host document
|
||||
let doc;
|
||||
try {
|
||||
doc = frame.contentDocument || frame.contentWindow.document;
|
||||
} catch (err) {
|
||||
console.error('Blocked from accessing document', err);
|
||||
}
|
||||
if (doc) {
|
||||
// Todo: Provide a way to get this to occur by `postMessage`
|
||||
const mainButton = doc.getElementById('main_button');
|
||||
mainButton.style.display = 'none';
|
||||
}
|
||||
|
||||
// Add event handlers now that `svgCanvas` is ready
|
||||
$id('load').addEventListener('click', loadSvg);
|
||||
$id('save').addEventListener('click', saveSvg);
|
||||
$id('exportPNG').addEventListener('click', exportPNG);
|
||||
$id('exportPDF').addEventListener('click', exportPDF);
|
||||
});
|
||||
document.body.appendChild(iframe);
|
||||
const frame = document.getElementById('svgedit');
|
||||
17
archive/untested-embedded-api/embedapi.html
Normal file
17
archive/untested-embedded-api/embedapi.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Embed API</title>
|
||||
<link rel="icon" type="image/png" href="images/logo.svg"/>
|
||||
<script src="jquery.min.js"></script>
|
||||
<script type="module" src="embedapi-dom.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<button id="load">Load example</button>
|
||||
<button id="save">Save data</button>
|
||||
<button id="exportPNG">Export data to PNG</button>
|
||||
<button id="exportPDF">Export data to PDF</button>
|
||||
<br/>
|
||||
</body>
|
||||
</html>
|
||||
395
archive/untested-embedded-api/embedapi.js
Normal file
395
archive/untested-embedded-api/embedapi.js
Normal file
@@ -0,0 +1,395 @@
|
||||
/**
|
||||
* Handles underlying communication between the embedding window and the
|
||||
* editor frame.
|
||||
* @module EmbeddedSVGEdit
|
||||
*/
|
||||
|
||||
let cbid = 0;
|
||||
|
||||
/**
|
||||
* @callback module:EmbeddedSVGEdit.CallbackSetter
|
||||
* @param {GenericCallback} newCallback Callback to be stored (signature dependent on function)
|
||||
* @returns {void}
|
||||
*/
|
||||
/**
|
||||
* @callback module:EmbeddedSVGEdit.CallbackSetGetter
|
||||
* @param {...any} args Signature dependent on the function
|
||||
* @returns {module:EmbeddedSVGEdit.CallbackSetter}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {string} funcName
|
||||
* @returns {module:EmbeddedSVGEdit.CallbackSetGetter}
|
||||
*/
|
||||
function getCallbackSetter (funcName) {
|
||||
return function (...args) {
|
||||
const that = this; // New callback
|
||||
const callbackID = this.send(funcName, args, function () { /* empty fn */ }); // The callback (currently it's nothing, but will be set later)
|
||||
|
||||
return function (newCallback) {
|
||||
that.callbacks[callbackID] = newCallback; // Set callback
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Having this separate from messageListener allows us to
|
||||
* avoid using JSON parsing (and its limitations) in the case
|
||||
* of same domain control.
|
||||
* @param {module:EmbeddedSVGEdit.EmbeddedSVGEdit} t The `this` value
|
||||
* @param {PlainObject} data
|
||||
* @param {JSON} data.result
|
||||
* @param {string} data.error
|
||||
* @param {Integer} data.id
|
||||
* @returns {void}
|
||||
*/
|
||||
function addCallback (t, { result, error, id: callbackID }) {
|
||||
if (typeof callbackID === 'number' && t.callbacks[callbackID]) {
|
||||
// These should be safe both because we check `cbid` is numeric and
|
||||
// because the calls are from trusted origins
|
||||
if (result) {
|
||||
t.callbacks[callbackID](result); // lgtm [js/unvalidated-dynamic-method-call]
|
||||
} else {
|
||||
t.callbacks[callbackID](error, 'error'); // lgtm [js/unvalidated-dynamic-method-call]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Event} e
|
||||
* @returns {void}
|
||||
*/
|
||||
function messageListener (e) {
|
||||
// We accept and post strings as opposed to objects for the sake of IE9 support; this
|
||||
// will most likely be changed in the future
|
||||
if (!e.data || ![ 'string', 'object' ].includes(typeof e.data)) {
|
||||
return;
|
||||
}
|
||||
const { allowedOrigins } = this;
|
||||
const data = typeof e.data === 'object' ? e.data : JSON.parse(e.data);
|
||||
if (!data || typeof data !== 'object' || data.namespace !== 'svg-edit' ||
|
||||
e.source !== this.frame.contentWindow ||
|
||||
(!allowedOrigins.includes('*') && !allowedOrigins.includes(e.origin))
|
||||
) {
|
||||
console.error(
|
||||
`The origin ${e.origin} was not whitelisted as an origin from ` +
|
||||
`which responses may be received by this ${window.origin} script.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
addCallback(this, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @callback module:EmbeddedSVGEdit.MessageListener
|
||||
* @param {MessageEvent} e
|
||||
* @returns {void}
|
||||
*/
|
||||
/**
|
||||
* @param {module:EmbeddedSVGEdit.EmbeddedSVGEdit} t The `this` value
|
||||
* @returns {module:EmbeddedSVGEdit.MessageListener} Event listener
|
||||
*/
|
||||
function getMessageListener (t) {
|
||||
return function (e) {
|
||||
messageListener.call(t, e);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Embedded SVG-edit API.
|
||||
* General usage:
|
||||
* - Have an iframe somewhere pointing to a version of svg-edit > r1000.
|
||||
* @example
|
||||
// Initialize the magic with:
|
||||
const svgCanvas = new EmbeddedSVGEdit(window.frames.svgedit);
|
||||
|
||||
// Pass functions in this format:
|
||||
svgCanvas.setSvgString('string');
|
||||
|
||||
// Or if a callback is needed:
|
||||
svgCanvas.setSvgString('string')(function (data, error) {
|
||||
if (error) {
|
||||
// There was an error
|
||||
throw error
|
||||
} else {
|
||||
// Handle data
|
||||
}
|
||||
});
|
||||
|
||||
// Everything is done with the same API as the real svg-edit,
|
||||
// and all documentation is unchanged.
|
||||
|
||||
// However, this file depends on the postMessage API which
|
||||
// can only support JSON-serializable arguments and
|
||||
// return values, so, for example, arguments whose value is
|
||||
// 'undefined', a function, a non-finite number, or a built-in
|
||||
// object like Date(), RegExp(), etc. will most likely not behave
|
||||
// as expected. In such a case one may need to host
|
||||
// the SVG editor on the same domain and reference the
|
||||
// JavaScript methods on the frame itself.
|
||||
|
||||
// The only other difference is when handling returns:
|
||||
// the callback notation is used instead.
|
||||
const blah = new EmbeddedSVGEdit(window.frames.svgedit);
|
||||
blah.clearSelection('woot', 'blah', 1337, [1, 2, 3, 4, 5, 'moo'], -42, {
|
||||
a: 'tree', b: 6, c: 9
|
||||
})(function () { console.log('GET DATA', args); });
|
||||
*
|
||||
* @memberof module:EmbeddedSVGEdit
|
||||
*/
|
||||
class EmbeddedSVGEdit {
|
||||
/**
|
||||
* @param {HTMLIFrameElement} frame
|
||||
* @param {string[]} [allowedOrigins=[]] Array of origins from which incoming
|
||||
* messages will be allowed when same origin is not used; defaults to none.
|
||||
* If supplied, it should probably be the same as svgEditor's allowedOrigins
|
||||
*/
|
||||
constructor (frame, allowedOrigins) {
|
||||
const that = this;
|
||||
this.allowedOrigins = allowedOrigins || [];
|
||||
// Initialize communication
|
||||
this.frame = frame;
|
||||
this.callbacks = {};
|
||||
// List of functions extracted with this:
|
||||
// Run in firebug on http://svg-edit.googlecode.com/svn/trunk/docs/files/svgcanvas-js.html
|
||||
|
||||
// for (const i=0,q=[],f = document.querySelectorAll('div.CFunction h3.CTitle a'); i < f.length; i++) { q.push(f[i].name); }; q
|
||||
// const functions = ['clearSelection', 'addToSelection', 'removeFromSelection', 'open', 'save', 'getSvgString', 'setSvgString',
|
||||
// 'createLayer', 'deleteCurrentLayer', 'setCurrentLayer', 'renameCurrentLayer', 'setCurrentLayerPosition', 'setLayerVisibility',
|
||||
// 'moveSelectedToLayer', 'clear'];
|
||||
|
||||
// Newer, well, it extracts things that aren't documented as well. All functions accessible through the normal thingy can now be accessed though the API
|
||||
// const {svgCanvas} = frame.contentWindow;
|
||||
// const l = [];
|
||||
// for (const i in svgCanvas) { if (typeof svgCanvas[i] === 'function') { l.push(i);} };
|
||||
// alert("['" + l.join("', '") + "']");
|
||||
// Run in svgedit itself
|
||||
const functions = [
|
||||
'addExtension',
|
||||
'addSVGElementFromJson',
|
||||
'addToSelection',
|
||||
'alignSelectedElements',
|
||||
'assignAttributes',
|
||||
'bind',
|
||||
'call',
|
||||
'changeSelectedAttribute',
|
||||
'cleanupElement',
|
||||
'clear',
|
||||
'clearSelection',
|
||||
'clearSvgContentElement',
|
||||
'cloneLayer',
|
||||
'cloneSelectedElements',
|
||||
'convertGradients',
|
||||
'convertToGroup',
|
||||
'convertToNum',
|
||||
'convertToPath',
|
||||
'copySelectedElements',
|
||||
'createLayer',
|
||||
'cutSelectedElements',
|
||||
'cycleElement',
|
||||
'deleteCurrentLayer',
|
||||
'deleteSelectedElements',
|
||||
'embedImage',
|
||||
'exportPDF',
|
||||
'findDefs',
|
||||
'getBBox',
|
||||
'getBlur',
|
||||
'getBold',
|
||||
'getColor',
|
||||
'getContentElem',
|
||||
'getCurrentDrawing',
|
||||
'getDocumentTitle',
|
||||
'getEditorNS',
|
||||
'getElem',
|
||||
'getFillOpacity',
|
||||
'getFontColor',
|
||||
'getFontFamily',
|
||||
'getFontSize',
|
||||
'getHref',
|
||||
'getId',
|
||||
'getIntersectionList',
|
||||
'getItalic',
|
||||
'getMode',
|
||||
'getMouseTarget',
|
||||
'getNextId',
|
||||
'getOffset',
|
||||
'getOpacity',
|
||||
'getPaintOpacity',
|
||||
'getPrivateMethods',
|
||||
'getRefElem',
|
||||
'getResolution',
|
||||
'getRootElem',
|
||||
'getRotationAngle',
|
||||
'getSelectedElems',
|
||||
'getStrokeOpacity',
|
||||
'getStrokeWidth',
|
||||
'getStrokedBBox',
|
||||
'getStyle',
|
||||
'getSvgString',
|
||||
'getText',
|
||||
'getTitle',
|
||||
'getTransformList',
|
||||
'getUIStrings',
|
||||
'getUrlFromAttr',
|
||||
'getVersion',
|
||||
'getVisibleElements',
|
||||
'getVisibleElementsAndBBoxes',
|
||||
'getZoom',
|
||||
'groupSelectedElements',
|
||||
'groupSvgElem',
|
||||
'hasMatrixTransform',
|
||||
'identifyLayers',
|
||||
'importSvgString',
|
||||
'leaveContext',
|
||||
'linkControlPoints',
|
||||
'makeHyperlink',
|
||||
'matrixMultiply',
|
||||
'mergeAllLayers',
|
||||
'mergeLayer',
|
||||
'moveSelectedElements',
|
||||
'moveSelectedToLayer',
|
||||
'moveToBottomSelectedElement',
|
||||
'moveToTopSelectedElement',
|
||||
'moveUpDownSelected',
|
||||
'open',
|
||||
'pasteElements',
|
||||
'prepareSvg',
|
||||
'pushGroupProperties',
|
||||
'randomizeIds',
|
||||
'rasterExport',
|
||||
'ready',
|
||||
'recalculateAllSelectedDimensions',
|
||||
'recalculateDimensions',
|
||||
'remapElement',
|
||||
'removeFromSelection',
|
||||
'removeHyperlink',
|
||||
'removeUnusedDefElems',
|
||||
'renameCurrentLayer',
|
||||
'round',
|
||||
'runExtensions',
|
||||
'sanitizeSvg',
|
||||
'save',
|
||||
'selectAllInCurrentLayer',
|
||||
'selectOnly',
|
||||
'setBBoxZoom',
|
||||
'setBackground',
|
||||
'setBlur',
|
||||
'setBlurNoUndo',
|
||||
'setBlurOffsets',
|
||||
'setBold',
|
||||
'setColor',
|
||||
'setConfig',
|
||||
'setContext',
|
||||
'setCurrentLayer',
|
||||
'setCurrentLayerPosition',
|
||||
'setDocumentTitle',
|
||||
'setFillPaint',
|
||||
'setFontColor',
|
||||
'setFontFamily',
|
||||
'setFontSize',
|
||||
'setGoodImage',
|
||||
'setGradient',
|
||||
'setGroupTitle',
|
||||
'setHref',
|
||||
'setIdPrefix',
|
||||
'setImageURL',
|
||||
'setItalic',
|
||||
'setLayerVisibility',
|
||||
'setLinkURL',
|
||||
'setMode',
|
||||
'setOpacity',
|
||||
'setPaint',
|
||||
'setPaintOpacity',
|
||||
'setRectRadius',
|
||||
'setResolution',
|
||||
'setRotationAngle',
|
||||
'setSegType',
|
||||
'setStrokeAttr',
|
||||
'setStrokePaint',
|
||||
'setStrokeWidth',
|
||||
'setSvgString',
|
||||
'setTextContent',
|
||||
'setUiStrings',
|
||||
'setUseData',
|
||||
'setZoom',
|
||||
'svgCanvasToString',
|
||||
'svgToString',
|
||||
'transformListToTransform',
|
||||
'ungroupSelectedElement',
|
||||
'uniquifyElems',
|
||||
'updateCanvas',
|
||||
'zoomChanged'
|
||||
];
|
||||
|
||||
// TODO: rewrite the following, it's pretty scary.
|
||||
for (const func of functions) {
|
||||
this[func] = getCallbackSetter(func);
|
||||
}
|
||||
|
||||
// Older IE may need a polyfill for addEventListener, but so it would for SVG
|
||||
window.addEventListener('message', getMessageListener(this));
|
||||
window.addEventListener('keydown', (e) => {
|
||||
const { type, key } = e;
|
||||
if (key === 'Backspace') {
|
||||
e.preventDefault();
|
||||
const keyboardEvent = new KeyboardEvent(type, { key });
|
||||
that.frame.contentDocument.dispatchEvent(keyboardEvent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {ArgumentsArray} args Signature dependent on function
|
||||
* @param {GenericCallback} callback (This may be better than a promise in case adding an event.)
|
||||
* @returns {Integer}
|
||||
*/
|
||||
send (name, args, callback) {
|
||||
const that = this;
|
||||
cbid++;
|
||||
|
||||
this.callbacks[cbid] = callback;
|
||||
setTimeout((function (callbackID) {
|
||||
return function () { // Delay for the callback to be set in case its synchronous
|
||||
/*
|
||||
* Todo: Handle non-JSON arguments and return values (undefined,
|
||||
* nonfinite numbers, functions, and built-in objects like Date,
|
||||
* RegExp), etc.? Allow promises instead of callbacks? Review
|
||||
* SVG-Edit functions for whether JSON-able parameters can be
|
||||
* made compatile with all API functionality
|
||||
*/
|
||||
// We accept and post strings for the sake of IE9 support
|
||||
let sameOriginWithGlobal = false;
|
||||
try {
|
||||
sameOriginWithGlobal = window.location.origin === that.frame.contentWindow.location.origin &&
|
||||
that.frame.contentWindow.svgEditor.svgCanvas;
|
||||
}catch (err) {/* empty */}
|
||||
|
||||
if (sameOriginWithGlobal) {
|
||||
// Although we do not really need this API if we are working same
|
||||
// domain, it could allow us to write in a way that would work
|
||||
// cross-domain as well, assuming we stick to the argument limitations
|
||||
// of the current JSON-based communication API (e.g., not passing
|
||||
// callbacks). We might be able to address these shortcomings; see
|
||||
// the todo elsewhere in this file.
|
||||
const message = { id: callbackID };
|
||||
const { svgEditor: { canvas: svgCanvas } } = that.frame.contentWindow;
|
||||
try {
|
||||
message.result = svgCanvas[name](...args);
|
||||
} catch (err) {
|
||||
message.error = err.message;
|
||||
}
|
||||
addCallback(that, message);
|
||||
} else { // Requires the ext-xdomain-messaging.js extension
|
||||
that.frame.contentWindow.postMessage(JSON.stringify({
|
||||
namespace: 'svgCanvas', id: callbackID, name, args
|
||||
}), '*');
|
||||
}
|
||||
};
|
||||
}(cbid)), 0);
|
||||
|
||||
return cbid;
|
||||
}
|
||||
}
|
||||
|
||||
export default EmbeddedSVGEdit;
|
||||
Reference in New Issue
Block a user