Refactor editor init

Add inline images to editor footer
Move playground to editor
This commit is contained in:
Matias Arriola 2022-01-24 17:22:39 -03:00
parent 3576d025e9
commit 8ccc4e798e
103 changed files with 1265 additions and 1512 deletions

6
packages/editor/.babelrc Normal file
View File

@ -0,0 +1,6 @@
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}

4
packages/editor/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
cypress/screenshots
cypress/videos
cypress/downloads
cypress/snapshots/*/__diff_output__

View File

@ -0,0 +1,6 @@
{
"video": false,
"videoUploadOnPasses": false,
"baseUrl": "http://localhost:8081"
}

View File

@ -0,0 +1,22 @@
context('Playground', () => {
it('viewmode page should match its snapshot', () => {
['welcome', 'sample1', 'sample2', 'sample3', 'sample4', 'sample5', 'sample6', 'complex', 'img-support', 'icon-sample'].forEach((mapId) => {
cy.visit(`/viewmode.html?id=${mapId}`);
cy.get('#mindplot.ready').should('exist');
cy.matchImageSnapshot(`viewmode-${mapId}`);
});
});
it('the playground container.html page should match its snapshot', () => {
cy.visit('/container.html');
cy.getIframeBody()
.find('#mindplot.ready')
.should('exist');
cy.matchImageSnapshot('container');
});
it('the playground editor.html page should match its snapshot', () => {
cy.visit('/editor.html');
cy.get('#mindplot.ready').should('exist');
// TODO: why is the editor appearing twice in the snapshot?
cy.matchImageSnapshot('editor');
});
});

View File

@ -0,0 +1,24 @@
/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
const { addMatchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin');
/**
* @type {Cypress.PluginConfig}
*/
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
addMatchImageSnapshotPlugin(on, config);
};

View File

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

View File

@ -0,0 +1,24 @@
import { addMatchImageSnapshotCommand } from 'cypress-image-snapshot/command';
// make matchImageSnapshot() call the real implementation only if CYPRESS_imageSnaphots is set
// otherwise it calls a noop
if (Cypress.env('imageSnaphots')) {
addMatchImageSnapshotCommand({
failureThreshold: 0.001,
failureThresholdType: 'percent',
});
} else {
Cypress.Commands.add(
'matchImageSnapshot',
{
prevSubject: ['optional', 'element', 'window', 'document'],
},
() => Promise.resolve(),
);
}
// https://www.cypress.io/blog/2020/02/12/working-with-iframes-in-cypress/
Cypress.Commands.add('getIframeBody', () => cy
.get('iframe')
.its('0.contentDocument.body').should('not.be.empty')
.then(cy.wrap));

View File

@ -0,0 +1,20 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands';
// Alternatively you can use CommonJS syntax:
// require('./commands')

View File

@ -1,13 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Wisemapping</title>
</head>
<body>
<!-- React app root element -->
<div id="root"></div>
</body>
</html>

View File

@ -3,13 +3,19 @@
"version": "0.1.0",
"main": "dist/editor.bundle.js",
"scripts": {
"build": "webpack --config webpack.prod.js"
"build": "webpack --config webpack.prod.js",
"playground": "webpack serve --config webpack.playground.js",
"cy:run": "cypress run",
"test:integration": "start-server-and-test 'yarn playground' http-get://localhost:8081 'yarn cy:run'",
"test": "yarn test:integration"
},
"repository": "http://www.wisemapping.com",
"author": "Paulo Veiga <pveiga@gmail.com>, Ezequiel Bergamaschi <ezequielbergamaschi@gmail.com>",
"license": "MIT",
"private": false,
"devDependencies": {
"@babel/preset-env": "^7.16.11",
"@babel/preset-react": "^7.16.7",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@typescript-eslint/eslint-plugin": "^4.8.1",
@ -17,12 +23,16 @@
"clean-webpack-plugin": "^4.0.0",
"compression-webpack-plugin": "^9.2.0",
"copy-webpack-plugin": "^10.2.1",
"cypress": "^9.3.1",
"cypress-image-snapshot": "^4.0.1",
"eslint": "^7.14.0",
"eslint-config-prettier": "^8.0.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-react": "^7.21.5",
"eslint-plugin-react-hooks": "^4.2.0",
"html-webpack-plugin": "^5.5.0",
"prettier": "^2.2.1",
"react": "^17.0.0",
"ts-loader": "^8.0.11",
"ts-node": "^9.0.0",
"typescript": "^4.1.2",

View File

@ -1,7 +1,12 @@
import React from 'react';
import { StyledFooter } from './styled';
import { StyledLogo } from './styled';
import { useIntl } from 'react-intl';
import KeyboardSvg from '../../../images/keyboard.svg';
import AddSvg from '../../../images/add.svg';
import MinusSvg from '../../../images/minus.svg';
import CenterFocusSvg from '../../../images/center_focus.svg';
export type FooterPropsType = {
showTryPanel?: boolean;
};
@ -13,23 +18,23 @@ const Footer = ({ showTryPanel }: FooterPropsType): React.ReactElement => {
<>
<div id="floating-panel">
<div id="keyboardShortcuts" className="buttonExtOn">
<img src="../../images/editor/keyboard.svg" />
<img src={KeyboardSvg} />
</div>
<div id="zoom-button">
<button id="zoom-plus">
<img src="../../images/editor/add.svg" />
<img src={AddSvg} />
</button>
<button id="zoom-minus">
<img src="../../images/editor/minus.svg" />
<img src={MinusSvg} />
</button>
</div>
<div id="position">
<button id="position-button">
<img src="../../images/editor/center_focus.svg" />
<img src={CenterFocusSvg} />
</button>
</div>
</div>
<div id="bottom-logo"></div>
<StyledLogo id="bottom-logo"></StyledLogo>
<div id="headerNotifier"></div>
{showTryPanel && (
<div id="tryInfoPanel">

View File

@ -1,8 +1,18 @@
import styled from 'styled-components';
import { times } from '../../size';
import LogoTextBlackSvg from '../../../images/logo-text-black.svg';
export const StyledFooter = styled.div`
height: ${times(10)};
width: 100%;
border: 1px solid black;
`;
export const StyledLogo = styled.div`
position: fixed;
left: 20px;
bottom: 10px;
background: url(${LogoTextBlackSvg}) no-repeat;
width: 90px;
height: 40px;
`

View File

@ -11,22 +11,14 @@ declare global {
var historyId: string;
var isAuth: boolean;
var mapId: number;
var userOptions: { zoom: string | number };
var userOptions: { zoom: string | number } | null;
var locale: string;
var mindmapLocked: boolean;
var mindmapLockedMsg: string;
}
const {
PersistenceManager,
RESTPersistenceManager,
LocalStorageManager,
DesignerOptionsBuilder,
buildDesigner,
$notify,
} = mindplot;
export type EditorPropsType = {
initCallback?: (m: typeof mindplot) => () => void;
mapId: number;
memoryPersistence: boolean;
readOnlyMode: boolean;
@ -34,7 +26,14 @@ export type EditorPropsType = {
onAction: (action: ToolbarActionType) => void;
};
const initMindplot = () => {
const initMindplot = ({
PersistenceManager,
RESTPersistenceManager,
LocalStorageManager,
DesignerOptionsBuilder,
buildDesigner,
$notify,
}: typeof mindplot) => () => {
let persistence: typeof PersistenceManager;
if (!global.memoryPersistence && !global.readOnly) {
persistence = new RESTPersistenceManager({
@ -61,7 +60,7 @@ const initMindplot = () => {
readOnly: Boolean(global.readOnly || false),
mapId: global.mapId,
container: 'mindplot',
zoom: zoomParam || global.userOptions.zoom,
zoom: zoomParam || global.userOptions ? global.userOptions.zoom : 1,
locale: global.locale,
});
@ -79,14 +78,15 @@ const initMindplot = () => {
};
export default function Editor({
initCallback = initMindplot,
mapId,
memoryPersistence,
readOnlyMode,
locale,
locale = 'en',
onAction,
}: EditorPropsType): React.ReactElement {
React.useEffect(initMindplot, []);
React.useEffect(initCallback(mindplot), []);
return (
<IntlProvider locale={locale} defaultLocale="en" messages={{}}>

View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@wisemapping/editor - Playground</title>
<style>
html * {
font-family: Arial !important;
}
tbody tr td:first-child {
width: 20%;
}
</style>
</head>
<body>
<h1>@wisemapping/editor - Playground</h1>
<p>You will find here a set of examples that shows how you can use integrate WiseMapping Editor</p>
<div>
<ul>
<li><a href="/viewmode.html">View mode:</a> Simple integration to load and render mindaps in read
only mode</li>
<li><a href="/editor.html">Editor mode:</a> Example on how mindplot can be used for mindmap edition. Browser local storage is used for persistance.</li>
<li><a href="/container.html">Embedded:</a> Example on how to embeded editor in a iframe.</li>
</ul>
</div>
</body>
</html>

View File

@ -138,15 +138,6 @@ div.shareModalDialog {
right: 20px;
}
div#bottom-logo {
position: fixed;
left: 20px;
bottom: 10px;
background: url(../images/logo-text-black.svg) no-repeat;
width: 90px;
height: 40px;
}
div#position {
margin-top: 5px;
}

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<title>WiseMapping - Editor </title>
<meta name="viewport" content="initial-scale=1">
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<link rel="icon" href="favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
</head>
<body>
<div id="root"></div>
</body>
</html>

View File

@ -0,0 +1,16 @@
<!DOCTYPE HTML>
<html>
<head>
<title>WiseMapping - Editor </title>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<link rel="icon" href="images/favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon">
</head>
<body>
<div id="root" onselectstart="return false;"></div>
</body>
</html>

View File

@ -10,7 +10,7 @@
</head>
<body>
<div id="mindplot" onselectstart="return false;"></div>
<div id="root" onselectstart="return false;"></div>
<div id="footer">
<div id="footer-logo"><img src="../images/logo-small.svg" /></div>
<div id="footer-desc">

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,48 @@
import '../css/editor.css';
import React from 'react';
import ReactDOM from 'react-dom';
import Editor from '../../../../src/index';
global.accountName = 'Test User';
global.accountEmail = 'test@example.com';
global.memoryPersistence = false;
global.readOnly = false;
global.mapId = 'welcome';
global.locale = 'en';
const initialization = ({
LocalStorageManager,
DesignerOptionsBuilder,
buildDesigner,
PersistenceManager
}) => () => {
const p = new LocalStorageManager('samples/{id}.wxml');
const options = DesignerOptionsBuilder.buildOptions({
persistenceManager: p
});
const designer = buildDesigner(options);
designer.addEvent('loadSuccess', () => {
// Hack for automation testing ...
document.getElementById('mindplot').classList.add('ready');
});
// Load map from XML file persisted on disk...
const mapId = 'welcome';
const persistence = PersistenceManager.getInstance();
const mindmap = persistence.load(mapId);
designer.loadMap(mindmap);
}
ReactDOM.render(
<Editor
mapId={global.mapId}
memoryPersistence={global.memoryPersistence}
readOnlyMode={global.readOnly}
locale={global.locale}
onAction={(action) => console.log('action called:', action)}
initCallback={initialization}
/>,
document.getElementById('root'),
);

View File

@ -0,0 +1,35 @@
import '../css/embedded.css';
import React from 'react';
import ReactDOM from 'react-dom';
import Editor from '../../../../src/index';
const initialization =
({ LocalStorageManager, DesignerOptionsBuilder, buildDesigner, PersistenceManager }) =>
() => {
// Options has been defined in by a external file ?
const p = new LocalStorageManager('samples/{id}.wxml');
const options = DesignerOptionsBuilder.buildOptions({ persistenceManager: p });
const designer = buildDesigner(options);
designer.addEvent('loadSuccess', () => {
document.getElementById('mindplot').classList.add('ready');
});
// Load map from XML file persisted on disk...
const mapId = 'welcome';
const persistence = PersistenceManager.getInstance();
const mindmap = persistence.load(mapId);
designer.loadMap(mindmap);
};
ReactDOM.render(
<Editor
mapId={global.mapId}
memoryPersistence={global.memoryPersistence}
readOnlyMode={global.readOnly}
locale={global.locale}
onAction={(action) => console.log('action called:', action)}
initCallback={initialization}
/>,
document.getElementById('root')
);

View File

@ -0,0 +1,52 @@
import '../css/viewmode.css';
import React from 'react';
import ReactDOM from 'react-dom';
import Editor from '../../../../src/index';
const initialization = ({
LocalStorageManager,
DesignerOptionsBuilder,
buildDesigner,
PersistenceManager
}) => () => {
const p = new LocalStorageManager('samples/{id}.wxml');
const options = DesignerOptionsBuilder.buildOptions({ persistenceManager: p, readOnly: true, saveOnLoad: false });
// Obtain map id from query param
const params = new URLSearchParams(window.location.search.substring(1));
const mapId = params.get('id') || 'welcome';
const designer = buildDesigner(options);
designer.addEvent('loadSuccess', () => {
document.getElementById('mindplot').classList.add('ready');
});
// Load map from XML file persisted on disk...
const persistence = PersistenceManager.getInstance();
const mindmap = persistence.load(mapId);
designer.loadMap(mindmap);
// Code for selector of map.
const mapSelectElem = document.getElementById('map-select');
mapSelectElem.addEventListener('change', (e) => {
const selectMap = e.target.value;
window.location = `${window.location.pathname}?id=${selectMap}`;
});
Array.from(mapSelectElem.options).forEach((option) => {
option.selected = option.value === mapId;
});
};
ReactDOM.render(
<Editor
mapId={global.mapId}
memoryPersistence={global.memoryPersistence}
readOnlyMode={global.readOnly}
locale={global.locale}
onAction={(action) => console.log('action called:', action)}
initCallback={initialization}
/>,
document.getElementById('root'),
);

View File

@ -9,6 +9,5 @@
"allowJs": true,
"esModuleInterop": true,
},
"exclude": ["node_modules"],
"files": ["src/custom.d.ts"]
"exclude": ["node_modules"]
}

View File

@ -15,16 +15,11 @@ module.exports = {
editor: path.join(__dirname, 'src', 'index.tsx')
},
mode: 'development',
devtool: 'eval-source-map',
devtool: 'source-map',
target: 'web',
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx']
},
externals: {
react: 'react',
reactDOM: 'react-dom',
reactIntl: 'react-intl',
},
module: {
rules: [
{
@ -36,14 +31,16 @@ module.exports = {
test: /\.(png|jpe?g|gif|svg)$/,
type: 'asset/inline',
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
],
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: path.join(__dirname, 'index.html')
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development')
})

View File

@ -8,11 +8,17 @@ const { merge } = require('webpack-merge');
const playgroundConfig = {
mode: 'development',
entry: {
layout: path.resolve(__dirname, './test/playground/layout/context-loader'),
viewmode: path.resolve(__dirname, './test/playground/map-render/js/viewmode'),
embedded: path.resolve(__dirname, './test/playground/map-render/js/embedded'),
editor: path.resolve(__dirname, './test/playground/map-render/js/editor'),
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
library: {
type: 'umd',
},
},
devServer: {
historyApiFallback: true,
port: 8081,
@ -43,11 +49,6 @@ const playgroundConfig = {
{ from: 'test/playground/map-render/html/container.html', to: 'container.html' },
],
}),
new HtmlWebpackPlugin({
chunks: ['layout'],
filename: 'layout.html',
template: 'test/playground/layout/index.html',
}),
new HtmlWebpackPlugin({
chunks: ['viewmode'],
filename: 'viewmode.html',

View File

@ -6,6 +6,11 @@ const prodConfig = {
usedExports: true,
minimize: true,
},
externals: {
react: 'react',
reactDOM: 'react-dom',
reactIntl: 'react-intl',
},
};
module.exports = merge(common, prodConfig);

View File

@ -1,6 +1,6 @@
{
"video": false,
"videoUploadOnPasses": false,
"baseUrl": "http://localhost:8081",
"baseUrl": "http://localhost:8083",
"projectId": "it9g7s"
}

View File

@ -8,24 +8,4 @@ context('Playground', () => {
cy.visit('/layout.html');
cy.matchImageSnapshot('layout');
});
it('viewmode page should match its snapshot', () => {
['welcome', 'sample1', 'sample2', 'sample3', 'sample4', 'sample5', 'sample6', 'complex', 'img-support', 'icon-sample'].forEach((mapId) => {
cy.visit(`/viewmode.html?id=${mapId}`);
cy.get('#mindplot.ready').should('exist');
cy.matchImageSnapshot(`viewmode-${mapId}`);
});
});
it('the playground container.html page should match its snapshot', () => {
cy.visit('/container.html');
cy.getIframeBody()
.find('#mindplot.ready')
.should('exist');
cy.matchImageSnapshot('container');
});
it('the playground editor.html page should match its snapshot', () => {
cy.visit('/editor.html');
cy.get('#mindplot.ready').should('exist');
// TODO: why is the editor appearing twice in the snapshot?
cy.matchImageSnapshot('editor');
});
});

View File

@ -27,7 +27,7 @@
"playground": "webpack serve --config webpack.playground.js",
"cy:run": "cypress run",
"test:unit": "jest ./test/unit/export/*.ts ./test/unit/layout/*.js",
"test:integration": "start-server-and-test playground http-get://localhost:8081 cy:run",
"test:integration": "start-server-and-test playground http-get://localhost:8083 cy:run",
"test": "yarn test:unit && yarn test:integration"
},
"private": false,

View File

@ -22,10 +22,6 @@
<p>You will find here a set of examples that shows how you can use integrate WiseMapping Mindplot.</p>
<div>
<ul>
<li><a href="/viewmode.html">Mindmap Render:</a> Simple integration to load and render mindaps in read
only mode</li>
<li><a href="/editor.html">Mindmap Editor:</a> Example on how mindplot can be used for mindmap edition. Browser local storage is used for persistance.</li>
<li><a href="/container.html">Embedded:</a> Example on how to embeded editor in a iframe.</li>
<li><a href="/layout.html">Layout Renders:</a> Showcase the different supported layouts.</li>
</ul>
</div>

View File

@ -1,130 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>WiseMapping - Editor </title>
<meta name="viewport" content="initial-scale=1">
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<link rel="icon" href="favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
</head>
<body>
<div id="header">
<div id="toolbar">
<div id="backToList">
<img src="images/back-icon.svg" />
</div>
<div id="editTab" class="tabContent">
<div id="persist" class="buttonContainer">
<div id="save" class="buttonOn">
<img src="images/save.svg" />
</div>
<div id="discard" class="buttonOn">
<img src="images/discard.svg" />
</div>
</div>
<div id="edit" class="buttonContainer">
<div id="undoEdition" class="buttonOn">
<img src="images/undo.svg"/>
</div>
<div id="redoEdition" class="buttonOn">
<img src="images/redo.svg"/>
</div>
</div>
<div id="node" class="buttonContainer">
<div id="addTopic" class="buttonOn">
<img src="images/topic-add.svg"/>
</div>
<div id="deleteTopic" class="buttonOn">
<img src="images/topic-delete.svg"/>
</div>
<div id="topicBorder" class="buttonExtOn">
<img src="images/topic-border.svg"/>
</div>
<div id="topicColor" class="buttonExtOn">
<img src="images/topic-color.svg"/>
</div>
<div id="topicShape" class="buttonExtOn">
<img src="images/topic-shape.svg"/>
</div>
</div>
<div id="font" class="buttonContainer">
<div id="fontFamily" class="buttonExtOn">
<img src="images/font-type.svg"/>
</div>
<div id="fontSize" class="buttonExtOn">
<img src="images/font-size.svg"/>
</div>
<div id="fontBold" class="buttonOn">
<img src="images/font-bold.svg"/>
</div>
<div id="fontItalic" class="buttonOn">
<img src="images/font-italic.svg"/>
</div>
<div id="fontColor" class="buttonExtOn">
<img src="images/font-color.svg"/>
</div>
</div>
<div id="node" class="buttonContainer">
<div id="topicIcon" class="buttonExtOn">
<img src="images/topic-icon.svg"/>
</div>
<div id="topicNote" class="buttonOn" >
<img src="images/topic-note.svg"/>
</div>
<div id="topicLink" class="buttonOn">
<img src="images/topic-link.svg"/>
</div>
<div id="topicRelation" class="buttonOn">
<img src="images/topic-relation.svg"/>
</div>
</div>
<div id="font" class="buttonContainer"></div>
</div>
<div id="toolbarRight">
<div id="share" class="actionButton">Share</div>
<div id="export" class="buttonOn">
<img src="images/export.svg" />
</div>
<div id="print" class="buttonOn">
<img src="images/print.svg" />
</div>
<div id="history" class="buttonOn">
<img src="images/history.svg" />
</div>
<div id="account">
<img src="images/account.svg"/>
</div>
</div>
</div>
</div>
<div id="mindplot" onselectstart="return false;"></div>
<!-- Side Actions -->
<div id="floating-panel">
<div id="keyboardShortcuts" class="buttonExtOn">
<img src="images/keyboard.svg"/>
</div>
<div id="zoom-button">
<button id="zoom-plus">
<img src="images/add.svg" />
</button>
<button id="zoom-minus">
<img src="images/minus.svg" />
</button>
</div>
<div id="position">
<button id="position-button">
<img src="images/center_focus.svg" />
</button>
</div>
</div>
<div id="bottom-logo"></div>
<div id="headerNotifier"></div>
</body>
</html>

View File

@ -1,102 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>WiseMapping - Editor </title>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<link rel="icon" href="images/favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon">
</head>
<body>
<div id="header">
<div id="headerInfo">
<div id="headerActions"></div>
<div id="headerLogo"></div>
<div id="headerMapTitle">Title: <span>Welcome</span></div>
</div>
<div id="toolbar">
<div id="editTab" class="tabContent">
<div id="persist" class="buttonContainer">
<div id="save" class="buttonOn">
<img src="images/save.svg" />
</div>
<div id="discard" class="buttonOn">
<img src="images/discard.svg" />
</div>
<div id="export" class="buttonOn">
<img src="images/export.svg" />
</div>
</div>
<div id="edit" class="buttonContainer">
<div id="undoEdition" class="buttonOn">
<img src="images/undo.svg"/>
</div>
<div id="redoEdition" class="buttonOn">
<img src="images/redo.svg"/>
</div>
</div>
<div id="zoom" class="buttonContainer">
<div id="zoomOut" class="buttonOn">
<img src="images/zoom-out.svg"/>
</div>
<div id="zoomIn" class="buttonOn">
<img src="images/zoom-in.svg"/>
</div>
</div>
<div id="node" class="buttonContainer">
<div id="topicShape" class="buttonExtOn">
<img src="images/topic-shape.svg"/>
</div>
<div id="addTopic" class="buttonOn">
<img src="images/topic-add.svg"/>
</div>
<div id="deleteTopic" class="buttonOn">
<img src="images/topic-delete.svg"/>
</div>
<div id="topicBorder" class="buttonExtOn">
<img src="images/topic-border.svg"/>
</div>
<div id="topicColor" class="buttonExtOn">
<img src="images/topic-color.svg"/>
</div>
<div id="topicIcon" class="buttonExtOn">
<img src="images/topic-icon.svg"/>
</div>
<div id="topicNote" class="buttonOn" >
<img src="images/topic-note.svg"/>
</div>
<div id="topicLink" class="buttonOn">
<img src="images/topic-link.svg"/>
</div>
<div id="topicRelation" class="buttonOn">
<img src="images/topic-relation.svg"/>
</div>
</div>
<div id="font" class="buttonContainer">
<div id="fontFamily" class="buttonExtOn">
<img src="images/font-type.svg"/>
</div>
<div id="fontSize" class="buttonExtOn">
<img src="images/font-size.svg"/>
</div>
<div id="fontBold" class="buttonOn">
<img src="images/font-bold.svg"/>
</div>
<div id="fontItalic" class="buttonOn">
<img src="images/font-italic.svg"/>
</div>
<div id="fontColor" class="buttonExtOn">
<img src="images/font-color.svg"/>
</div>
</div>
</div>
</div>
</div>
<div id="mindplot" onselectstart="return false;"></div>
</body>
</html>

View File

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-hidden="true" style="color: black;">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z"></path>
</svg>

Before

Width:  |  Height:  |  Size: 382 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>

Before

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M11.67 3.87L9.9 2.1 0 12l9.9 9.9 1.77-1.77L3.54 12z"/></svg>

Before

Width:  |  Height:  |  Size: 189 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm8.94 3c-.46-4.17-3.77-7.48-7.94-7.94V1h-2v2.06C6.83 3.52 3.52 6.83 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c4.17-.46 7.48-3.77 7.94-7.94H23v-2h-2.06zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/></svg>

Before

Width:  |  Height:  |  Size: 440 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>

Before

Width:  |  Height:  |  Size: 258 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/></g><g><path d="M5,20h14v-2H5V20z M19,9h-4V3H9v6H5l7,7L19,9z"/></g></svg>

Before

Width:  |  Height:  |  Size: 254 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z"/></svg>

Before

Width:  |  Height:  |  Size: 386 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><path d="M2,20h20v4H2V20z M5.49,17h2.42l1.27-3.58h5.65L16.09,17h2.42L13.25,3h-2.5L5.49,17z M9.91,11.39l2.03-5.79h0.12l2.03,5.79 H9.91z"/></svg>

Before

Width:  |  Height:  |  Size: 321 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z"/></svg>

Before

Width:  |  Height:  |  Size: 205 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/></g><g><g><g><path d="M2.5,4v3h5v12h3V7h5V4H2.5z M21.5,9h-9v3h3v7h3v-7h3V9z"/></g></g></g></svg>

Before

Width:  |  Height:  |  Size: 277 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" baseProfile="tiny" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M9.93 13.5h4.14L12 7.98zM20 2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-4.05 16.5l-1.14-3H9.17l-1.12 3H5.96l5.11-13h1.86l5.11 13h-2.09z"/></svg>

Before

Width:  |  Height:  |  Size: 343 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z"/></svg>

Before

Width:  |  Height:  |  Size: 381 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="36" viewBox="0 0 24 24" width="36"><path d="M20 5H4c-1.1 0-1.99.9-1.99 2L2 17c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-9 3h2v2h-2V8zm0 3h2v2h-2v-2zM8 8h2v2H8V8zm0 3h2v2H8v-2zm-1 2H5v-2h2v2zm0-3H5V8h2v2zm9 7H8v-2h8v2zm0-4h-2v-2h2v2zm0-3h-2V8h2v2zm3 3h-2v-2h2v2zm0-3h-2V8h2v2z"/><path d="M0 0h24v24H0zm0 0h24v24H0z" fill="none"/></svg>

Before

Width:  |  Height:  |  Size: 391 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.0 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 13H5v-2h14v2z"/></svg>

Before

Width:  |  Height:  |  Size: 155 B

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"/></svg>

Before

Width:  |  Height:  |  Size: 302 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M18.4 10.6C16.55 8.99 14.15 8 11.5 8c-4.65 0-8.58 3.03-9.96 7.22L3.9 16c1.05-3.19 4.05-5.5 7.6-5.5 1.95 0 3.73.72 5.12 1.88L13 16h9V7l-3.6 3.6z"/></svg>

Before

Width:  |  Height:  |  Size: 300 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z"/></svg>

Before

Width:  |  Height:  |  Size: 299 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"/></svg>

Before

Width:  |  Height:  |  Size: 257 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><path d="M22,24H2v-4h20V24z M13.06,5.19l3.75,3.75L7.75,18H4v-3.75L13.06,5.19z M17.88,7.87l-3.75-3.75 l1.83-1.83c0.39-0.39,1.02-0.39,1.41,0l2.34,2.34c0.39,0.39,0.39,1.02,0,1.41L17.88,7.87z" enable-background="new"/></svg>

Before

Width:  |  Height:  |  Size: 398 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/></g><g><path d="M12,2C6.49,2,2,6.49,2,12s4.49,10,10,10c1.38,0,2.5-1.12,2.5-2.5c0-0.61-0.23-1.2-0.64-1.67c-0.08-0.1-0.13-0.21-0.13-0.33 c0-0.28,0.22-0.5,0.5-0.5H16c3.31,0,6-2.69,6-6C22,6.04,17.51,2,12,2z M17.5,13c-0.83,0-1.5-0.67-1.5-1.5c0-0.83,0.67-1.5,1.5-1.5 s1.5,0.67,1.5,1.5C19,12.33,18.33,13,17.5,13z M14.5,9C13.67,9,13,8.33,13,7.5C13,6.67,13.67,6,14.5,6S16,6.67,16,7.5 C16,8.33,15.33,9,14.5,9z M5,11.5C5,10.67,5.67,10,6.5,10S8,10.67,8,11.5C8,12.33,7.33,13,6.5,13S5,12.33,5,11.5z M11,7.5 C11,8.33,10.33,9,9.5,9S8,8.33,8,7.5C8,6.67,8.67,6,9.5,6S11,6.67,11,7.5z"/></g></svg>

Before

Width:  |  Height:  |  Size: 758 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11H7v-2h10v2z"/></svg>

Before

Width:  |  Height:  |  Size: 239 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"/></svg>

Before

Width:  |  Height:  |  Size: 510 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0" fill="none"/><path d="M8 11h8v2H8zm12.1 1H22c0-2.76-2.24-5-5-5h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1zM3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM19 12h-2v3h-3v2h3v3h2v-3h3v-2h-3z"/></svg>

Before

Width:  |  Height:  |  Size: 366 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M13 11h-2v3H8v2h3v3h2v-3h3v-2h-3zm1-9H6c-1.1 0-2 .9-2 2v16c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11z"/></svg>

Before

Width:  |  Height:  |  Size: 280 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M13 11h-2v3H8v2h3v3h2v-3h3v-2h-3zm1-9H6c-1.1 0-2 .9-2 2v16c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11z"/></svg>

Before

Width:  |  Height:  |  Size: 280 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M7.77 6.76L6.23 5.48.82 12l5.41 6.52 1.54-1.28L3.42 12l4.35-5.24zM7 13h2v-2H7v2zm10-2h-2v2h2v-2zm-6 2h2v-2h-2v2zm6.77-7.52l-1.54 1.28L20.58 12l-4.35 5.24 1.54 1.28L23.18 12l-5.41-6.52z"/></svg>

Before

Width:  |  Height:  |  Size: 341 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 2l-5.5 9h11z"/><circle cx="17.5" cy="17.5" r="4.5"/><path d="M3 13.5h8v8H3z"/></svg>

Before

Width:  |  Height:  |  Size: 236 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z"/></svg>

Before

Width:  |  Height:  |  Size: 299 B

View File

@ -1,25 +0,0 @@
import '../css/editor.css';
import { buildDesigner } from '../../../../src/components/DesignerBuilder';
import { PersistenceManager, LocalStorageManager } from '../../../../src';
import DesignerOptionsBuilder from '../../../../src/components/DesignerOptionsBuilder';
// Account details ...
global.accountName = 'Test User';
global.accountEmail = 'test@example.com';
const p = new LocalStorageManager('samples/{id}.wxml');
const options = DesignerOptionsBuilder.buildOptions({
persistenceManager: p
});
const designer = buildDesigner(options);
designer.addEvent('loadSuccess', () => {
// Hack for automation testing ...
document.getElementById('mindplot').classList.add('ready');
});
// Load map from XML file persisted on disk...
const mapId = 'welcome';
const persistence = PersistenceManager.getInstance();
const mindmap = persistence.load(mapId);
designer.loadMap(mindmap);

View File

@ -1,19 +0,0 @@
import '../css/embedded.css';
import { buildDesigner } from '../../../../src/components/DesignerBuilder';
import { PersistenceManager, LocalStorageManager } from '../../../../src';
import DesignerOptionsBuilder from '../../../../src/components/DesignerOptionsBuilder';
// Options has been defined in by a external ile ?
const p = new LocalStorageManager('samples/{id}.wxml');
const options = DesignerOptionsBuilder.buildOptions({ persistenceManager: p });
const designer = buildDesigner(options);
designer.addEvent('loadSuccess', () => {
document.getElementById('mindplot').classList.add('ready');
});
// Load map from XML file persisted on disk...
const mapId = 'welcome';
const persistence = PersistenceManager.getInstance();
const mindmap = persistence.load(mapId);
designer.loadMap(mindmap);

Some files were not shown because too many files have changed in this diff Show More