7.1.9 release

This commit is contained in:
Gaudenz Alder 2017-08-21 11:25:31 +02:00
parent 1b26c37237
commit eb74e038aa
83 changed files with 3213 additions and 2109 deletions

View file

@ -1,3 +1,10 @@
21-AUG-2017: 7.1.9
- Adds persistent autosave setting in Electron App
- Adds File, Page Setup and Publish in Electron/Chrome App
- Fixes keyboard shortcut labels on Mac
- Changes keyboard shortcuts for connection points/arrows
18-AUG-2017: 7.1.8
- Fixes bounding box margins for vertical labels

View file

@ -1 +1 @@
7.1.8
7.1.9

View file

@ -1,7 +1,7 @@
CACHE MANIFEST
# THIS FILE WAS GENERATED. DO NOT MODIFY!
# 08/18/2017 03:55 PM
# 08/21/2017 11:21 AM
app.html
index.html?offline=1

View file

@ -46,6 +46,7 @@ function createWindow (opt = {})
'gapi': 0,
'od': 0,
'gh': 0,
'tr': 0,
'analytics': 0,
'picker': 0,
'mode': 'device',

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.9 KiB

1333
war/js/app.min.js vendored

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

1775
war/js/atlas.min.js vendored

File diff suppressed because one or more lines are too long

View file

@ -151,6 +151,11 @@ App.MODE_DEVICE = 'device';
*/
App.MODE_BROWSER = 'browser';
/**
* Trello App Mode
*/
App.MODE_TRELLO = 'trello';
/**
* Sets the delay for autosave in milliseconds. Default is 2000.
*/
@ -171,6 +176,16 @@ App.DROPINS_URL = 'https://www.dropbox.com/static/api/2/dropins.js';
*/
App.ONEDRIVE_URL = 'https://js.live.net/v7.2/OneDrive.js';
/**
* Trello URL
*/
App.TRELLO_URL = 'https://api.trello.com/1/client.js';
/**
* Trello JQuery dependency
*/
App.TRELLO_JQUERY_URL = 'https://code.jquery.com/jquery-1.7.1.min.js';
/**
* Defines plugin IDs for loading via p URL parameter. Update the table at
* https://desk.draw.io/solution/articles/16000042546
@ -338,6 +353,31 @@ App.getStoredMode = function()
window.OneDriveClient = null;
}
}
// Loads Trello for all browsers but < IE10 if not disabled or if enabled and in embed mode
if (typeof window.TrelloClient === 'function')
{
if (urlParams['tr'] != '0' && isSvgBrowser &&
(document.documentMode == null || document.documentMode >= 10))
{
// Immediately loads client
if (App.mode == App.MODE_TRELLO || (window.location.hash != null &&
window.location.hash.substring(0, 2) == '#T'))
{
mxscript(App.TRELLO_JQUERY_URL);
mxscript(App.TRELLO_URL);
}
else if (urlParams['chrome'] == '0')
{
window.TrelloClient = null;
}
}
else
{
// Disables loading of client
window.TrelloClient = null;
}
}
}
// Loads JSON for older browsers
@ -636,6 +676,28 @@ App.main = function(callback)
{
window.OneDriveClient = null;
}
// Loads Trello for all browsers but < IE10 if not disabled or if enabled and in embed mode
if (typeof window.TrelloClient === 'function' &&
(typeof window.Trello === 'undefined' && window.DrawTrelloClientCallback != null &&
(((urlParams['embed'] != '1' && urlParams['tr'] != '0') || (urlParams['embed'] == '1' &&
urlParams['tr'] == '1')) && (navigator.userAgent.indexOf('MSIE') < 0 || document.documentMode >= 10))))
{
mxscript(App.TRELLO_JQUERY_URL, function()
{
// Must load this after the dropbox SDK since they use the same namespace
mxscript(App.TRELLO_URL, function()
{
DrawTrelloClientCallback();
});
});
}
// Disables client
else if (typeof window.Trello === 'undefined')
{
window.TrelloClient = null;
}
}
if (callback != null)
@ -809,7 +871,7 @@ App.prototype.init = function()
{
this.updateUserElement();
this.restoreLibraries();
}))
}));
// Notifies listeners of new client
this.fireEvent(new mxEventObject('clientLoaded', 'client', this.oneDrive));
@ -823,6 +885,38 @@ App.prototype.init = function()
initOneDriveClient();
}
/**
* Lazy-loading for Trello
*/
if (urlParams['embed'] != '1' || urlParams['tr'] == '1')
{
/**
* Creates Trello client if all required libraries are available.
*/
var initTrelloClient = mxUtils.bind(this, function()
{
if (typeof window.Trello !== 'undefined')
{
this.trello = new TrelloClient(this);
this.trello.addListener('userChanged', mxUtils.bind(this, function()
{
// this.updateUserElement();
// this.restoreLibraries();
}));
// Notifies listeners of new client
this.fireEvent(new mxEventObject('clientLoaded', 'client', this.trello));
}
else if (window.DrawTrelloClientCallback == null)
{
window.DrawTrelloClientCallback = initTrelloClient;
}
});
initTrelloClient();
}
/**
* Creates drive client with all required libraries are available.
*/
@ -2981,7 +3075,7 @@ App.prototype.saveFile = function(forceDialog)
serviceCount++;
}
var rowLimit = (serviceCount <= 4) ? 2 : 3;
var rowLimit = (serviceCount <= 4) ? 2 : (serviceCount > 6 ? 4 : 3);
var dlg = new CreateDialog(this, filename, mxUtils.bind(this, function(name, mode)
{
@ -3101,6 +3195,10 @@ App.prototype.getPeerForMode = function(mode)
{
return this.oneDrive;
}
else if (mode == App.MODE_TRELLO)
{
return this.trello;
}
else
{
return null;
@ -3161,6 +3259,14 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold
}), error, false, folderId);
}));
}
else if (mode == App.MODE_TRELLO && this.trello != null)
{
this.trello.insertFile(title, data, mxUtils.bind(this, function(file)
{
complete();
this.fileCreated(file, libs, replace, done);
}), error, false, folderId);
}
else if (mode == App.MODE_DROPBOX && this.dropbox != null)
{
this.dropbox.insertFile(title, data, mxUtils.bind(this, function(file)
@ -3605,6 +3711,10 @@ App.prototype.loadFile = function(id, sameWindow, file)
{
peer = this.gitHub;
}
else if (id.charAt(0) == 'T')
{
peer = this.trello;
}
if (peer == null)
{
@ -4069,6 +4179,14 @@ App.prototype.pickFolder = function(mode, fn, enabled)
fn(folderPath);
}));
}
else if (enabled && mode == App.MODE_TRELLO && this.trello != null)
{
this.trello.pickFolder(mxUtils.bind(this, function(cardId)
{
resume();
fn(cardId);
}));
}
else
{
EditorUi.prototype.pickFolder.apply(this, arguments);
@ -4168,6 +4286,21 @@ App.prototype.exportFile = function(data, filename, mimeType, base64Encoded, mod
}), true, folderId, base64Encoded);
}
}
else if (mode == App.MODE_TRELLO)
{
if (this.trello != null && this.spinner.spin(document.body, mxResources.get('saving')))
{
this.trello.insertFile(filename, (base64Encoded) ? this.base64ToBlob(data, mimeType) :
data, mxUtils.bind(this, function()
{
this.spinner.stop();
}), mxUtils.bind(this, function(resp)
{
this.spinner.stop();
this.handleError(resp);
}), false, folderId);
}
}
else if (mode == App.MODE_BROWSER)
{
var fn = mxUtils.bind(this, function()
@ -4581,7 +4714,7 @@ App.prototype.updateHeader = function()
*/
this.toggleFormatElement = document.createElement('a');
this.toggleFormatElement.setAttribute('href', 'javascript:void(0);');
this.toggleFormatElement.setAttribute('title', mxResources.get('formatPanel') + ' (Ctrl+Shift+P)');
this.toggleFormatElement.setAttribute('title', mxResources.get('formatPanel') + ' (' + Editor.ctrlKey + '+Shift+P)');
this.toggleFormatElement.style.position = 'absolute';
this.toggleFormatElement.style.display = 'inline-block';
this.toggleFormatElement.style.top = '5px';

View file

@ -92,6 +92,9 @@ mxscript(drawDevUrl + 'js/diagramly/GitHubClient.js');
mxscript(drawDevUrl + 'js/diagramly/OneDriveFile.js');
mxscript(drawDevUrl + 'js/diagramly/OneDriveLibrary.js');
mxscript(drawDevUrl + 'js/diagramly/OneDriveClient.js');
mxscript(drawDevUrl + 'js/diagramly/TrelloFile.js');
mxscript(drawDevUrl + 'js/diagramly/TrelloLibrary.js');
mxscript(drawDevUrl + 'js/diagramly/TrelloClient.js');
mxscript(drawDevUrl + 'js/diagramly/ChatWindow.js');
mxscript(drawDevUrl + 'js/diagramly/App.js');

View file

@ -281,6 +281,11 @@ var StorageDialog = function(editorUi, fn, rowLimit)
addLogo(IMAGE_PATH + '/github-logo.svg', mxResources.get('github'), App.MODE_GITHUB, 'gitHub');
}
if (editorUi.trello != null)
{
addLogo(IMAGE_PATH + '/trello-logo.svg', mxResources.get('trello'), App.MODE_TRELLO, 'trello');
}
if (typeof window.DropboxClient === 'function')
{
addLogo(IMAGE_PATH + '/dropbox-logo.svg', mxResources.get('dropbox'), App.MODE_DROPBOX, 'dropbox');
@ -1011,7 +1016,7 @@ var EmbedDialog = function(editorUi, result, timeout, ignoreSize, previewFn)
var previewBtn = null;
// Loads forever in IE9
if (!mxClient.IS_CHROMEAPP && !navigator.standalone && (validUrl ||
if ((!mxClient.IS_CHROMEAPP || validUrl) && !navigator.standalone && (validUrl ||
(mxClient.IS_SVG && (document.documentMode == null || document.documentMode > 9))))
{
previewBtn = mxUtils.button(mxResources.get((result.length < maxSize) ? 'preview' : 'openInNewWindow'), function()
@ -1075,7 +1080,7 @@ var EmbedDialog = function(editorUi, result, timeout, ignoreSize, previewFn)
}
// Twitter-intent does not allow more characters, must be pasted manually
if (validUrl && !editorUi.isOffline())
if (validUrl && (!editorUi.isOffline() || mxClient.IS_CHROMEAPP))
{
if (result.length < maxFbSize)
{
@ -3144,6 +3149,16 @@ var CreateDialog = function(editorUi, title, createFn, cancelFn, dlgTitle, btnLa
addLogo(IMAGE_PATH + '/github-logo.svg', mxResources.get('github'), App.MODE_GITHUB, 'gitHub');
}
if (editorUi.trello != null)
{
var trelloOption = document.createElement('option');
trelloOption.setAttribute('value', App.MODE_TRELLO);
mxUtils.write(trelloOption, mxResources.get('trello'));
serviceSelect.appendChild(trelloOption);
addLogo(IMAGE_PATH + '/trello-logo.svg', mxResources.get('trello'), App.MODE_TRELLO, 'trello');
}
if (typeof window.DropboxClient === 'function')
{
var dropboxOption = document.createElement('option');
@ -3229,6 +3244,10 @@ var CreateDialog = function(editorUi, title, createFn, cancelFn, dlgTitle, btnLa
{
ext = editorUi.gitHub.extension;
}
else if (newMode == App.MODE_TRELLO)
{
ext = editorUi.trello.extension;
}
else if (newMode == App.MODE_DROPBOX)
{
ext = editorUi.dropbox.extension;

View file

@ -7004,7 +7004,7 @@
/**
* Persists autosave switch in Chrome app.
*/
if (mxClient.IS_CHROMEAPP)
if (mxClient.IS_CHROMEAPP || EditorUi.isElectronApp)
{
this.editor.addListener('autosaveChanged', mxUtils.bind(this, function(sender, evt)
{
@ -8417,7 +8417,7 @@
var button = document.createElement('button');
mxUtils.write(button, mxResources.get('save'));
button.setAttribute('title', mxResources.get('save') + ' (Ctrl+S)');
button.setAttribute('title', mxResources.get('save') + ' (' + Editor.ctrlKey + '+S)');
button.className = 'geBigButton';
button.style.fontSize = '12px';
button.style.padding = '4px 6px 4px 6px';
@ -9123,6 +9123,11 @@
serviceCount++
}
if (this.trello != null)
{
serviceCount++
}
if (allowBrowser && isLocalStorage && (urlParams['browser'] == '1' || mxClient.IS_IOS))
{
serviceCount++

View file

@ -86,9 +86,12 @@ FeedbackDialog.feedbackUrl = 'https://log.draw.io/email';
{
this.addMenuItems(menu, ['new', 'open', '-', 'save', 'saveAs', '-', 'import'], parent);
this.addSubmenu('exportAs', menu, parent);
menu.addSeparator(parent);
this.addSubmenu('embed', menu, parent);
this.addMenuItems(menu, ['-', 'newLibrary', 'openLibrary', '-', 'documentProperties',
'print', '-', 'close'], parent);
this.addSubmenu('publish', menu, parent);
menu.addSeparator(parent);
this.addMenuItems(menu, ['newLibrary', 'openLibrary', '-', 'pageSetup',
'print', '-', 'close'], parent);
// LATER: Find API for application.quit
})));
@ -107,7 +110,6 @@ FeedbackDialog.feedbackUrl = 'https://log.draw.io/email';
var editorUi = this;
var graph = this.editor.graph;
this.editor.autosave = false;
global.__emt_isModified = e => {
if (this.getCurrentFile())
@ -300,9 +302,9 @@ FeedbackDialog.feedbackUrl = 'https://log.draw.io/email';
ipc.sendSync('winman', {action: 'newfile', opt: {width: 1600}})
}
}), null, null, 'Ctrl+N');
}), null, null, Editor.ctrlKey + '+N');
this.actions.get('open').shortcut = 'Ctrl+O';
this.actions.get('open').shortcut = Editor.ctrlKey + '+O';
// Adds shortcut keys for file operations
editorUi.keyHandler.bindAction(78, true, 'new'); // Ctrl+N

View file

@ -58,6 +58,8 @@
(((urlParams['embed'] != '1' && urlParams['od'] != '0') || (urlParams['embed'] == '1' &&
urlParams['od'] == '1')) && !navigator.userAgent.match(/(iPad|iPhone|iPod)/g) &&
(navigator.userAgent.indexOf('MSIE') < 0 || document.documentMode >= 10));
var trelloEnabled = ((urlParams['embed'] != '1' && urlParams['tr'] != '0') || (urlParams['embed'] == '1' && urlParams['tr'] == '1')) &&
mxClient.IS_SVG && (document.documentMode == null || document.documentMode > 9);
if (!editorUi.isOffline())
{
@ -224,7 +226,7 @@
editorUi.actions.addAction('createRevision', function()
{
editorUi.actions.get('save').funct();
}, null, null, 'Ctrl+S');
}, null, null, Editor.ctrlKey + '+S');
editorUi.actions.addAction('upload...', function()
{
@ -296,7 +298,7 @@
editorUi.showDialog(dlg.container, 180, 180, true, true);
dlg.init();
}
}, null, null, 'Ctrl+Shift+M');
}, null, null, Editor.ctrlKey + '+Shift+M');
var copiedStyles = ['rounded', 'shadow', 'dashed', 'dashPattern', 'fontFamily', 'fontSize', 'fontColor', 'fontStyle',
'align', 'verticalAlign', 'strokeColor', 'strokeWidth', 'fillColor', 'gradientColor', 'swimlaneFillColor',
@ -333,7 +335,7 @@
}
}
}
}, null, null, 'Ctrl+Shift+C');
}, null, null, Editor.ctrlKey + '+Shift+C');
editorUi.actions.addAction('pasteStyle', function()
{
@ -366,7 +368,7 @@
graph.getModel().endUpdate();
}
}
}, null, null, 'Ctrl+Shift+V');
}, null, null, Editor.ctrlKey + '+Shift+V');
editorUi.actions.put('pageBackgroundImage', new Action(mxResources.get('backgroundImage') + '...', function()
{
@ -1651,6 +1653,21 @@
}, parent, null, false);
}
if (editorUi.trello != null)
{
menu.addItem(mxResources.get('trello', null, 'Trello') + '...', null, function()
{
pickFileFromService(editorUi.trello);
}, parent);
}
else if (trelloEnabled)
{
menu.addItem(mxResources.get('trello', null, 'Trello') + ' (' + mxResources.get('loading') + '...)', null, function()
{
// do nothing
}, parent, null, false);
}
menu.addSeparator(parent);
if (isLocalStorage && urlParams['browser'] != '0')
@ -1949,7 +1966,7 @@
cell.vertex = true;
graph.startEditingAtCell(graph.addCell(cell));
}
}, null, null, 'Ctrl+Shift+X').isEnabled = isGraphEnabled;
}, null, null, Editor.ctrlKey + '+Shift+X').isEnabled = isGraphEnabled;
editorUi.actions.addAction('insertRectangle', function()
{
@ -1961,7 +1978,7 @@
graph.setSelectionCell(graph.addCell(cell));
graph.scrollCellToVisible(graph.getSelectionCell());
}
}, null, null, 'Ctrl+K').isEnabled = isGraphEnabled;
}, null, null, Editor.ctrlKey + '+K').isEnabled = isGraphEnabled;
editorUi.actions.addAction('insertEllipse', function()
{
@ -1973,7 +1990,7 @@
graph.setSelectionCell(graph.addCell(cell));
graph.scrollCellToVisible(graph.getSelectionCell());
}
}, null, null, 'Ctrl+Shift+K').isEnabled = isGraphEnabled;
}, null, null, Editor.ctrlKey + '+Shift+K').isEnabled = isGraphEnabled;
this.put('insert', new Menu(mxUtils.bind(this, function(menu, parent)
{
@ -2086,6 +2103,21 @@
}, parent, null, false);
}
if (editorUi.trello != null)
{
menu.addItem(mxResources.get('trello', null, 'Trello') + '...', null, function()
{
editorUi.pickFile(App.MODE_TRELLO);
}, parent);
}
else if (trelloEnabled)
{
menu.addItem(mxResources.get('trello', null, 'Trello') + ' (' + mxResources.get('loading') + '...)', null, function()
{
// do nothing
}, parent, null, false);
}
menu.addSeparator(parent);
if (isLocalStorage && urlParams['browser'] != '0')

View file

@ -185,7 +185,7 @@ var mxSettings =
search: true,
showStartScreen: true,
gridColor: mxGraphView.prototype.gridColor,
autosave: true,
autosave: !EditorUi.isElectronApp,
resizeImages: null,
openCounter: 0,
version: mxSettings.currentVersion,

View file

@ -0,0 +1,531 @@
/**
* Copyright (c) 2006-2017, JGraph Ltd
* Copyright (c) 2006-2017, Gaudenz Alder
*/
TrelloClient = function(editorUi)
{
DrawioClient.call(this, editorUi, 'tauth');
Trello.setKey(this.key);
};
// Extends DrawioClient
mxUtils.extend(TrelloClient, DrawioClient);
TrelloClient.prototype.key = (window.location.hostname == 'test.draw.io') ?
'e73615c79cf7e381aef91c85936e9553' : 'e73615c79cf7e381aef91c85936e9553';
TrelloClient.prototype.baseUrl = 'https://api.trello.com/1/';
TrelloClient.prototype.SEPARATOR = '|$|';
/**
* Default extension for new files.
*/
TrelloClient.prototype.extension = '.xml'; //TODO export to png
/**
*
*/
TrelloClient.prototype.getLibrary = function(id, success, error)
{
this.getFile(id, success, error, false, true);
};
/**
*
*/
TrelloClient.prototype.getFile = function(id, success, error, denyConvert, asLibrary)
{
asLibrary = (asLibrary != null) ? asLibrary : false;
Trello.authorize({
type: 'popup',
name: 'Draw.io',
scope: {
read: 'true',
write: 'true' },
expiration: 'never',
success: mxUtils.bind(this, function() {
var ids = id.split(this.SEPARATOR);
Trello.cards.get(ids[0] + '/attachments/' + ids[1], mxUtils.bind(this, function(meta)
{
//TODO Trello doesn't allow CORS requests to load attachments. Confirm that and make sure that only a proxy technique can work!
// Handles .vsdx, Gliffy and PNG+XML files by creating a temporary file
if ((/\.vsdx$/i.test(meta.name) || /\.gliffy$/i.test(meta.name) || /\.png$/i.test(meta.name)))
{
this.ui.convertFile(PROXY_URL + '?url=' + encodeURIComponent(meta.url), meta.name, meta.mimeType,
this.extension, success, error);
}
else
{
var acceptResponse = true;
var timeoutThread = window.setTimeout(mxUtils.bind(this, function()
{
acceptResponse = false;
error({code: App.ERROR_TIMEOUT})
}), this.ui.timeout);
this.ui.loadUrl(PROXY_URL + '?url=' + encodeURIComponent(meta.url), mxUtils.bind(this, function(data)
{
window.clearTimeout(timeoutThread);
if (acceptResponse)
{
//keep our id which includes the cardId
meta.compoundId = id;
if (asLibrary)
{
success(new TrelloLibrary(this.ui, data, meta));
}
else
{
success(new TrelloFile(this.ui, data, meta));
}
}
}), mxUtils.bind(this, function(req)
{
window.clearTimeout(timeoutThread);
if (acceptResponse)
{
error();
}
}), meta.mimeType != null &&
meta.mimeType.substring(0, 6) == 'image/');
}
}));
}),
error: error
});
};
/**
*
*/
TrelloClient.prototype.insertLibrary = function(filename, data, success, error, folderId)
{
this.insertFile(filename, data, success, error, true, folderId);
};
/**
*
*/
TrelloClient.prototype.insertFile = function(filename, data, success, error, asLibrary, cardId)
{
asLibrary = (asLibrary != null) ? asLibrary : false;
this.writeFile(filename, data, cardId, mxUtils.bind(this, function(meta)
{
if (asLibrary)
{
success(new TrelloLibrary(this.ui, data, meta));
}
else
{
success(new TrelloFile(this.ui, data, meta));
}
}), error);
};
/**
*
*/
TrelloClient.prototype.saveFile = function(file, success, error)
{
//delete file first, then write it again
var ids = file.meta.compoundId.split(this.SEPARATOR);
Trello.authorize({
type: 'popup',
name: 'Draw.io',
scope: {
read: 'true',
write: 'true'
},
expiration: 'never',
success: mxUtils.bind(this, function()
{
Trello.del('cards/' + ids[0] + '/attachments/' + ids[1], mxUtils.bind(this, function()
{
this.writeFile(file.meta.name, file.getData(), ids[0], success, error);
}), error);
}),
error: error
});
};
/**
*
*/
TrelloClient.prototype.writeFile = function(filename, data, cardId, success, error)
{
if (filename != null && data != null)
{
Trello.authorize({
type: 'popup',
name: 'Draw.io',
scope: {
read: 'true',
write: 'true'
},
expiration: 'never',
success: mxUtils.bind(this, function()
{
var acceptResponse = true;
var timeoutThread = window.setTimeout(mxUtils.bind(this, function()
{
acceptResponse = false;
error({code: App.ERROR_TIMEOUT, retry: fn});
}), this.ui.timeout);
var formData = new FormData();
formData.append("key", Trello.key());
formData.append("token", Trello.token());
formData.append("file", data);
formData.append("name", filename);
var request = new XMLHttpRequest();
request.responseType = "json";
request.onreadystatechange = mxUtils.bind(this, function()
{
if (request.readyState === 4)
{
window.clearTimeout(timeoutThread);
if (acceptResponse)
{
if (request.status == 200)
{
var fileMeta = request.response;
fileMeta.compoundId = cardId + this.SEPARATOR + fileMeta.id
success(fileMeta);
}
else
{
error();
}
}
}
});
request.open("POST", this.baseUrl + 'cards/' + cardId + '/attachments');
request.send(formData);
}),
error: error
});
}
else
{
error({message: mxResources.get('unknownError')});
}
};
/**
* Checks if the client is authorized and calls the next step.
*/
TrelloClient.prototype.pickLibrary = function(fn)
{
this.pickFile(fn);
};
/**
*
*/
TrelloClient.prototype.pickFolder = function(fn)
{
Trello.authorize({
type: 'popup',
name: 'Draw.io',
scope: {
read: 'true',
write: 'true' },
expiration: 'never',
success: mxUtils.bind(this, function() {
//show file select
this.showTrelloDialog(false, fn);
}),
error: mxUtils.bind(this, function(e)
{
this.ui.showError(mxResources.get('error'), e);
})
});
};
/**
* Checks if the client is authorized and calls the next step.
*/
TrelloClient.prototype.pickFile = function(fn, returnObject)
{
fn = (fn != null) ? fn : mxUtils.bind(this, function(id)
{
this.ui.loadFile('T' + encodeURIComponent(id));
});
Trello.authorize({
type: 'popup',
name: 'Draw.io',
scope: {
read: 'true',
write: 'true' },
expiration: 'never',
success: mxUtils.bind(this, function() {
//show file select
this.showTrelloDialog(true, fn);
}),
error: mxUtils.bind(this, function(e)
{
this.ui.showError(mxResources.get('error'), e);
})
});
};
/**
*
*/
TrelloClient.prototype.showTrelloDialog = function(showFiles, fn)
{
var cardId = null;
var filter = null;
var linkCounter = 0;
var content = document.createElement('div');
content.style.whiteSpace = 'nowrap';
content.style.overflow = 'hidden';
content.style.height = '224px';
var hd = document.createElement('h3');
mxUtils.write(hd, showFiles? mxResources.get('selectFile') : mxResources.get('selectCard', null, 'Select Card'));
hd.style.cssText = 'width:100%;text-align:center;margin-top:0px;margin-bottom:12px';
content.appendChild(hd);
var div = document.createElement('div');
div.style.whiteSpace = 'nowrap';
div.style.overflow = 'auto';
div.style.height = '194px';
content.appendChild(div);
var dlg = new CustomDialog(this.ui, content);
this.ui.showDialog(dlg.container, 340, 270, true, true);
dlg.okButton.parentNode.removeChild(dlg.okButton);
var createLink = mxUtils.bind(this, function(label, fn, preview)
{
linkCounter++;
var div = document.createElement('div');
div.style = "width:100%;vertical-align:middle;background:" + (linkCounter % 2 == 0? "#eee" : "#fff");
var link = document.createElement('a');
link.setAttribute('href', 'javascript:void(0);');
if (preview != null)
{
var img = document.createElement('img');
img.src = preview.url;
img.width = preview.width;
img.height= preview.height;
img.style= "border: 1px solid black;margin:5px;vertical-align:middle"
link.appendChild(img);
}
mxUtils.write(link, label);
mxEvent.addListener(link, 'click', fn);
div.appendChild(link);
return div;
});
var error = mxUtils.bind(this, function(err)
{
this.ui.handleError(err, null, mxUtils.bind(this, function()
{
this.ui.spinner.stop();
this.ui.hideDialog();
}));
});
var selectAtt = mxUtils.bind(this, function()
{
linkCounter = 0;
div.innerHTML = '';
this.ui.spinner.spin(div, mxResources.get('loading'));
Trello.cards.get(cardId + '/attachments', {fields: 'id,name,previews'}, mxUtils.bind(this, function(data)
{
this.ui.spinner.stop();
var files = data;
div.appendChild(createLink('../ [Up]', mxUtils.bind(this, function()
{
selectCard();
})));
mxUtils.br(div);
if (files == null || files.length == 0)
{
mxUtils.write(div, mxResources.get('noFiles'));
}
else
{
var listFiles = mxUtils.bind(this, function()
{
for (var i = 0; i < files.length; i++)
{
(mxUtils.bind(this, function(file)
{
div.appendChild(createLink(file.name, mxUtils.bind(this, function()
{
this.ui.hideDialog();
fn(cardId + this.SEPARATOR + file.id);
}), file.previews != null? file.previews[0] : null));
}))(files[i]);
}
});
listFiles();
}
}), error);
});
// Adds paging for cards (files limited to 1000 by API)
var pageSize = 100;
var nextPageDiv = null;
var scrollFn = null;
var selectCard = mxUtils.bind(this, function(page)
{
if (page == null)
{
linkCounter = 0;
div.innerHTML = '';
page = 1;
}
this.ui.spinner.spin(div, mxResources.get('loading'));
if (nextPageDiv != null && nextPageDiv.parentNode != null)
{
nextPageDiv.parentNode.removeChild(nextPageDiv);
}
nextPageDiv = document.createElement('a');
nextPageDiv.style.display = 'block';
nextPageDiv.setAttribute('href', 'javascript:void(0);');
mxUtils.write(nextPageDiv, mxResources.get('more') + '...');
var nextPage = mxUtils.bind(this, function()
{
mxEvent.removeListener(div, 'scroll', scrollFn);
selectCard(page + 1);
});
mxEvent.addListener(nextPageDiv, 'click', nextPage);
Trello.get('search', {
'query': '@me' + (filter != null ? ' ' + filter : ''),
'cards_limit': pageSize,
'cards_page': page-1
},
mxUtils.bind(this, function(data)
{
this.ui.spinner.stop();
var cards = data.cards;
if (cards == null || cards.length == 0)
{
if (filter != null)
{
div.appendChild(createLink(mxResources.get('ClearFilter', null, 'Clear Filter'), mxUtils.bind(this, function()
{
filter = null;
selectCard();
})));
mxUtils.br(div);
}
mxUtils.write(div, mxResources.get('noFiles'));
}
else
{
if (page == 1)
{
if (filter != null)
{
div.appendChild(createLink(mxResources.get('ClearFilter', null, 'Clear Filter'), mxUtils.bind(this, function()
{
filter = null;
selectCard();
})));
}
else
{
div.appendChild(createLink(mxResources.get('FilterCards', null, 'Filter Cards') + '...', mxUtils.bind(this, function()
{
var dlg = new FilenameDialog(this.ui, mxResources.get('CardName', null, 'Card Name'), mxResources.get('ok'), mxUtils.bind(this, function(value)
{
if (value != null)
{
filter = value;
selectCard();
}
}), mxResources.get('CardName', null, 'Card Name'));
this.ui.showDialog(dlg.container, 300, 80, true, false);
dlg.init();
})));
}
mxUtils.br(div);
}
for (var i = 0; i < cards.length; i++)
{
(mxUtils.bind(this, function(card)
{
div.appendChild(createLink(card.name, mxUtils.bind(this, function()
{
if (showFiles)
{
cardId = card.id;
selectAtt();
}
else
{
this.ui.hideDialog();
fn(card.id);
}
})));
}))(cards[i]);
}
}
if (cards.length == pageSize)
{
div.appendChild(nextPageDiv);
scrollFn = function()
{
if (div.scrollTop >= div.scrollHeight - div.offsetHeight)
{
nextPage();
}
};
mxEvent.addListener(div, 'scroll', scrollFn);
}
}),
error);
});
selectCard();
};
/**
* Checks if the client is authorized and calls the next step.
*/
TrelloClient.prototype.logout = function()
{
Trello.deauthorize();
};

View file

@ -0,0 +1,185 @@
/**
* Copyright (c) 2006-2017, JGraph Ltd
* Copyright (c) 2006-2017, Gaudenz Alder
*/
TrelloFile = function(ui, data, meta)
{
DrawioFile.call(this, ui, data);
this.meta = meta;
};
//Extends mxEventSource
mxUtils.extend(TrelloFile, DrawioFile);
/**
*
*/
TrelloFile.prototype.getHash = function()
{
return 'T' + encodeURIComponent(this.meta.compoundId);
};
/**
*
*/
TrelloFile.prototype.getMode = function()
{
return App.MODE_TRELLO;
};
/**
* Overridden to disable the autosave
*/
TrelloFile.prototype.isAutosave = function()
{
return false;
};
/**
*
*/
TrelloFile.prototype.getTitle = function()
{
return this.meta.name;
};
/**
*
*/
TrelloFile.prototype.isRenamable = function()
{
return false;
};
/**
*
*/
TrelloFile.prototype.save = function(revision, success, error)
{
this.doSave(this.getTitle(), success, error);
};
/**
*
*/
TrelloFile.prototype.saveAs = function(title, success, error)
{
this.doSave(title, success, error);
};
/**
*
*/
TrelloFile.prototype.doSave = function(title, success, error)
{
// Forces update of data for new extensions
var prev = this.meta.name;
this.meta.name = title;
DrawioFile.prototype.save.apply(this, arguments);
this.meta.name = prev;
this.saveFile(title, false, success, error);
};
/**
*
*/
TrelloFile.prototype.saveFile = function(title, revision, success, error)
{
if (!this.isEditable())
{
if (success != null)
{
success();
}
}
else if (!this.savingFile)
{
this.savingFile = true;
if (this.getTitle() == title)
{
// Makes sure no changes get lost while the file is saved
var prevModified = this.isModified;
var modified = this.isModified();
var prepare = mxUtils.bind(this, function()
{
this.setModified(false);
this.isModified = function()
{
return modified;
};
});
prepare();
this.ui.trello.saveFile(this, mxUtils.bind(this, function(meta)
{
this.savingFile = false;
this.isModified = prevModified;
this.meta = meta;
this.contentChanged();
if (success != null)
{
success();
}
}),
mxUtils.bind(this, function(err)
{
this.savingFile = false;
this.isModified = prevModified;
this.setModified(modified || this.isModified());
if (error != null)
{
// Handles modified state for retries
if (err != null && err.retry != null)
{
var retry = err.retry;
err.retry = function()
{
prepare();
retry();
};
}
error(err);
}
}));
}
else
{
this.ui.pickFolder(App.MODE_TRELLO, mxUtils.bind(this, function(cardId)
{
this.ui.trello.insertFile(title, this.getData(), mxUtils.bind(this, function(file)
{
this.savingFile = false;
if (success != null)
{
success();
}
this.ui.fileLoaded(file);
}), mxUtils.bind(this, function()
{
this.savingFile = false;
if (error != null)
{
error();
}
}), false, cardId);
}));
}
}
else if (error != null)
{
error({code: App.ERROR_BUSY});
}
};

View file

@ -0,0 +1,28 @@
/**
* Copyright (c) 2006-2017, JGraph Ltd
* Copyright (c) 2006-2017, Gaudenz Alder
*/
TrelloLibrary = function(ui, data, meta)
{
TrelloFile.call(this, ui, data, meta);
};
//Extends mxEventSource
mxUtils.extend(TrelloLibrary, TrelloFile);
/**
* Overridden to avoid updating data with current file.
*/
TrelloLibrary.prototype.doSave = function(title, success, error)
{
this.saveFile(title, false, success, error);
};
/**
* Returns the location as a new object.
* @type mx.Point
*/
TrelloLibrary.prototype.open = function()
{
// Do nothing - this should never be called
};

View file

@ -16,323 +16,367 @@
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//TODO integrate this code in mxConnector
mxGraph.prototype.enableEdgeBridge = true;
mxConnector.prototype.bridgeSize = 10;
mxConnector.prototype.checkLineIntersection = function (line1Start, line1End, line2Start, line2End)
(function ()
{
// if the lines intersect, the result contains the the
// intersection point if both line segment 1 and line segment 2 contain the point
// null otherwise
var denominator = ((line2End.y - line2Start.y) * (line1End.x - line1Start.x)) - ((line2End.x - line2Start.x) * (line1End.y - line1Start.y));
if (denominator == 0)
{
return null;
}
else
{
var a = line1Start.y - line2Start.y;
var b = line1Start.x - line2Start.x;
var numerator1 = ((line2End.x - line2Start.x) * a) - ((line2End.y - line2Start.y) * b);
var numerator2 = ((line1End.x - line1Start.x) * a) - ((line1End.y - line1Start.y) * b);
a = numerator1 / denominator;
b = numerator2 / denominator;
mxConnector.prototype.defaultJumpSize = 6;
// if we cast these lines infinitely in both directions, they intersect here:
var x = line1Start.x + (a * (line1End.x - line1Start.x));
var y = line1Start.y + (a * (line1End.y - line1Start.y));
mxConnector.prototype.checkLineIntersection = function (line1Start, line1End, line2Start, line2End)
{
// if the lines intersect, the result contains the the
// intersection point if both line segment 1 and line segment 2 contain the point
// null otherwise
var denominator = ((line2End.y - line2Start.y) * (line1End.x - line1Start.x)) -
((line2End.x - line2Start.x) * (line1End.y - line1Start.y));
if (a > 0 && a < 1 && b > 0 && b < 1) // on both lines?
return new mxPoint(x, y);
else
return null;
}
}
if (denominator == 0)
{
return null;
}
else
{
var a = line1Start.y - line2Start.y;
var b = line1Start.x - line2Start.x;
var numerator1 = ((line2End.x - line2Start.x) * a) - ((line2End.y - line2Start.y) * b);
var numerator2 = ((line1End.x - line1Start.x) * a) - ((line1End.y - line1Start.y) * b);
a = numerator1 / denominator;
b = numerator2 / denominator;
//Code from https://stackoverflow.com/questions/27664298/calculating-intersection-point-of-quadratic-bezier-curve
mxConnector.prototype.calcQLintersects = function (p1, p2, p3, a1, a2)
{
//linear interpolation utility
var lerp=function(a,b,x){ return(a+x*(b-a)); };
var intersections=[];
// if we cast these lines infinitely in both directions, they intersect here:
var x = line1Start.x + (a * (line1End.x - line1Start.x));
var y = line1Start.y + (a * (line1End.y - line1Start.y));
// inverse line normal
var normal={
x: a1.y-a2.y,
y: a2.x-a1.x,
}
// on both lines?
if (a > 0 && a < 1 && b > 0 && b < 1)
{
return new mxPoint(x, y);
}
else
{
return null;
}
}
};
// Q-coefficients
var c2={
x: p1.x + p2.x*-2 + p3.x,
y: p1.y + p2.y*-2 + p3.y
}
// Code from https://stackoverflow.com/questions/27664298/calculating-intersection-point-of-quadratic-bezier-curve
mxConnector.prototype.calcQLintersects = function (p1, p2, p3, a1, a2)
{
//linear interpolation utility
var lerp = function (a, b, x)
{
return (a + x * (b - a));
};
var c1={
x: p1.x*-2 + p2.x*2,
y: p1.y*-2 + p2.y*2,
}
var intersections = [];
var c0={
x: p1.x,
y: p1.y
}
// inverse line normal
var normal = {
x: a1.y - a2.y,
y: a2.x - a1.x,
};
// Transform to line
var coefficient=a1.x*a2.y-a2.x*a1.y;
var a=normal.x*c2.x + normal.y*c2.y;
var b=(normal.x*c1.x + normal.y*c1.y)/a;
var c=(normal.x*c0.x + normal.y*c0.y + coefficient)/a;
// Q-coefficients
var c2 = {
x: p1.x + p2.x * -2 + p3.x,
y: p1.y + p2.y * -2 + p3.y
};
// solve the roots
var roots=[];
d=b*b-4*c;
if(d>0){
var e=Math.sqrt(d);
roots.push((-b+Math.sqrt(d))/2);
roots.push((-b-Math.sqrt(d))/2);
}else if(d==0){
roots.push(-b/2);
}
var c1 = {
x: p1.x * -2 + p2.x * 2,
y: p1.y * -2 + p2.y * 2,
};
// calc the solution points
for(var i=0;i<roots.length;i++){
var minX=Math.min(a1.x,a2.x);
var minY=Math.min(a1.y,a2.y);
var maxX=Math.max(a1.x,a2.x);
var maxY=Math.max(a1.y,a2.y);
var t = roots[i];
if (t>=0 && t<=1) {
// possible point -- pending bounds check
var point={
x:lerp(lerp(p1.x,p2.x,t),lerp(p2.x,p3.x,t),t),
y:lerp(lerp(p1.y,p2.y,t),lerp(p2.y,p3.y,t),t)
}
var x=point.x;
var y=point.y;
// bounds checks
if(a1.x==a2.x && y>=minY && y<=maxY){
// vertical line
intersections.push(point);
}else if(a1.y==a2.y && x>=minX && x<=maxX){
// horizontal line
intersections.push(point);
}else if(x>=minX && y>=minY && x<=maxX && y<=maxY){
// line passed bounds check
intersections.push(point);
}
}
}
return intersections;
};
var c0 = {
x: p1.x,
y: p1.y
};
mxConnector.prototype.getOnLinePointAtDist = function(x1, x2, y1, y2)
{
var dx = x1 - x2;
var dy = y1 - y2;
var d = Math.sqrt(dy * dy + dx * dx);
var t = this.bridgeSize / d;
return new mxPoint((1 - t) * x1 + t * x2, (1 - t) * y1 + t * y2);
};
// Transform to line
var coefficient = a1.x * a2.y - a2.x * a1.y;
var a = normal.x * c2.x + normal.y * c2.y;
var b = (normal.x * c1.x + normal.y * c1.y) / a;
var c = (normal.x * c0.x + normal.y * c0.y + coefficient) / a;
mxConnector.prototype.addBridgePoints = function(intersectPt, result, l2p1, l2p2, otherId, eState)
{
//instead of reordering, get the order and the top edge has the bridge
var dx = result.x - l2p2.x;
var dy = result.y - l2p2.y;
var dist = Math.sqrt(dx * dx + dy * dy);
dx /= dist;
dy /= dist;
intersectPt.push(this.getOnLinePointAtDist(result.x, l2p1.x, result.y, l2p1.y));
intersectPt.push(new mxPoint(result.x + this.bridgeSize * dy, result.y - this.bridgeSize * dx));
intersectPt.push(this.getOnLinePointAtDist(result.x, l2p2.x, result.y, l2p2.y));
//add others id here since here is the actual bridge!
if (eState.oldIntersectIds != null)
{
eState.oldIntersectIds[otherId] = true;
}
else
eState.oldIntersectIds = {otherId: true};
// solve the roots
var roots = [];
d = b * b - 4 * c;
if (d > 0)
{
var e = Math.sqrt(d);
roots.push((-b + Math.sqrt(d)) / 2);
roots.push((-b - Math.sqrt(d)) / 2);
}
else if (d == 0)
{
roots.push(-b / 2);
}
};
// calc the solution points
for (var i = 0; i < roots.length; i++)
{
var minX = Math.min(a1.x, a2.x);
var minY = Math.min(a1.y, a2.y);
var maxX = Math.max(a1.x, a2.x);
var maxY = Math.max(a1.y, a2.y);
var t = roots[i];
if (t >= 0 && t <= 1)
{
// possible point -- pending bounds check
var point = {
x: lerp(lerp(p1.x, p2.x, t), lerp(p2.x, p3.x, t), t),
y: lerp(lerp(p1.y, p2.y, t), lerp(p2.y, p3.y, t), t)
}
var x = point.x;
var y = point.y;
// bounds checks
if (a1.x == a2.x && y >= minY && y <= maxY)
{
// vertical line
intersections.push(point);
}
else if (a1.y == a2.y && x >= minX && x <= maxX)
{
// horizontal line
intersections.push(point);
}
else if (x >= minX && y >= minY && x <= maxX && y <= maxY)
{
// line passed bounds check
intersections.push(point);
}
}
}
return intersections;
};
mxConnector.prototype.scalePoint = function (point, scale)
{
return {x: point.x / scale, y: point.y / scale};
};
mxConnector.prototype.getOnLinePointAtDist = function (x1, x2, y1, y2)
{
var dx = x1 - x2;
var dy = y1 - y2;
var d = Math.sqrt(dy * dy + dx * dx);
var t = this.jumpSize / d;
//TODO Add curves support for curve edges (paintCurvedLine) for curve intersecting another curve
mxConnector.prototype.paintLine = function(canvas, pts, rounded)
{
var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
canvas.begin();
return new mxPoint((1 - t) * x1 + t * x2, (1 - t) * y1 + t * y2);
};
var ptsCln = pts;
var state = this.state;
var graph = state.view.graph;
if (graph.enableEdgeBridge && !graph.isMouseDown)
{
//during DnD we can save the extra calculations
var model = graph.getModel();
var noRedraw = state.redrawEdge;
ptsCln = [];
if (state.oldIntersectIds)
{
for (var id in state.oldIntersectIds)
{
var c = model.getCell(id);
if (c != null)
{
var eState = graph.view.getState(c);
if (eState != null && eState.style != null)
{
eState.redrawEdge = true;
eState.shape.redraw();
}
}
}
delete state.oldIntersectIds;
}
//for each pair find the intersection
for (var i = 0; i < pts.length - 1; i++)
{
var l2p1 = pts[i];
var l2p2 = pts[i+1];
ptsCln.push(l2p1);
var intersectPt = [];
for (var id in model.cells)
{
var edge = model.cells[id];
if (edge.isEdge() && edge != state.cell)
{
var eState = graph.view.getState(edge);
if (eState != null && eState.absolutePoints != null)
{
var eScale = eState.view.scale;
if (eState.style == null || eState.style[mxConstants.STYLE_CURVED] != 1) //line edge
{
for (var j = 0; j < eState.absolutePoints.length - 1; j++)
{
var l1p1 = eState.absolutePoints[j];
var l1p2 = eState.absolutePoints[j+1];
//the absolute points of current edge is scaled before calling this function, so we have to scale others to get correct intersections
var result = this.checkLineIntersection(this.scalePoint(l1p1, eScale), this.scalePoint(l1p2, eScale), l2p1, l2p2);
if (result != null)
{
var getEdgeOrder = function (edge1, edge2)
{
var p1 = edge1.getParent();
var p2 = edge2.getParent();
if (p1 == p2)
{
return p1.getIndex(edge1) - p1.getIndex(edge2); //+ve edge1 on top, -ve edge2 on top
}
else
{
return 0; //not the same parent, so we cannot determine
}
};
if (getEdgeOrder(state.cell, eState.cell) > 0) //instead of reordering, get the order and the top edge has the bridge
{
this.addBridgePoints(intersectPt, result, l2p1, l2p2, state.cell.id, eState);
}
else if (!noRedraw)
{
eState.redrawEdge = true;
eState.shape.redraw();
}
}
}
}
else //curve edge (guad Bezier)
{
//We'll not check edge order here as always line will have bridges as it is better than curve bridges
var ePts = eState.absolutePoints;
var pt = this.scalePoint(ePts[0], eScale);
var n = ePts.length;
var allPts = [];
for (var k = 1; k < n - 2; k++)
{
var p0 = this.scalePoint(ePts[k], eScale);
var p1 = this.scalePoint(ePts[k + 1], eScale);
var ip = {x: (p0.x + p1.x) / 2, y: (p0.y + p1.y) / 2};
allPts.push.apply(allPts, this.calcQLintersects(pt, p0, ip, l2p1, l2p2));
pt = ip;
}
var p0 = this.scalePoint(ePts[n - 2], eScale);
var p1 = this.scalePoint(ePts[n - 1], eScale);
allPts.push.apply(allPts, this.calcQLintersects(pt, p0, p1, l2p1, l2p2));
if (allPts.length > 0)
{
for (var o = 0; o < allPts.length; o++)
{
this.addBridgePoints(intersectPt, allPts[o], l2p1, l2p2, state.cell.id, eState);
}
}
}
}
}
}
if (intersectPt.length > 0)
{
//sort points and then add them
intersectPt.sort(function(p1, p2) {
var dx1 = p1.x - l2p1.x;
var dy1 = p1.y - l2p1.y;
var d1 = dx1 * dx1 + dy1 * dy1;
mxConnector.prototype.addBridgePoints = function (intersectPt, result, l2p1, l2p2, otherId, eState)
{
// instead of reordering, get the order and the top edge has the bridge
var dx = result.x - l2p2.x;
var dy = result.y - l2p2.y;
var dist = Math.sqrt(dx * dx + dy * dy);
dx /= dist;
dy /= dist;
var dx2 = p2.x - l2p1.x;
var dy2 = p2.y - l2p1.y;
var d2 = dx2 * dx2 + dy2 * dy2;
intersectPt.push(this.getOnLinePointAtDist(result.x, l2p1.x, result.y, l2p1.y));
intersectPt.push(new mxPoint(result.x + this.jumpSize * dy, result.y - this.jumpSize * dx));
intersectPt.push(this.getOnLinePointAtDist(result.x, l2p2.x, result.y, l2p2.y));
return d1 - d2;
});
ptsCln.push(intersectPt[0]);
this.addPoints(canvas, ptsCln, rounded, arcSize, false);
ptsCln = [intersectPt[intersectPt.length - 1]];
this.addPoints(canvas, intersectPt, true, arcSize, false);
}
ptsCln.push(l2p2);
}
if (noRedraw)
{
state.redrawEdge = false;
}
// add others id here since here is the actual bridge!
if (eState.oldIntersectIds != null)
{
eState.oldIntersectIds[otherId] = true;
}
else
{
eState.oldIntersectIds = {otherId: true};
}
};
}
this.addPoints(canvas, ptsCln, rounded, arcSize, false);
canvas.stroke();
};
mxConnector.prototype.scalePoint = function (point, scale)
{
return {
x: point.x / scale,
y: point.y / scale
};
};
//TODO Add curves support for curve edges (paintCurvedLine) for curve intersecting another curve
var mxConnectorPaintLine = mxConnector.prototype.paintLine;
mxConnector.prototype.paintLine = function (canvas, pts, rounded)
{
this.jumpSize = parseInt(mxUtils.getValue(this.style, 'jumpSize', this.defaultJumpSize));
var jumpStyle = mxUtils.getValue(this.style, 'jumpStyle', 'none');
if (this.outline || jumpStyle === 'none')
{
mxConnectorPaintLine.apply(this, arguments);
}
else
{
var arcSize = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, mxConstants.LINE_ARCSIZE) / 2;
canvas.begin();
var ptsCln = pts;
var state = this.state;
var graph = state.view.graph;
// during DnD we can save the extra calculations
var model = graph.getModel();
var noRedraw = state.redrawEdge;
ptsCln = [];
if (state.oldIntersectIds)
{
for (var id in state.oldIntersectIds)
{
var c = model.getCell(id);
if (c != null)
{
var eState = graph.view.getState(c);
if (eState != null && eState.style != null)
{
eState.redrawEdge = true;
eState.shape.redraw();
}
}
}
delete state.oldIntersectIds;
}
// for each pair find the intersection
for (var i = 0; i < pts.length - 1; i++)
{
var l2p1 = pts[i];
var l2p2 = pts[i + 1];
ptsCln.push(l2p1);
var intersectPt = [];
for (var id in model.cells)
{
var edge = model.cells[id];
if (edge.isEdge() && edge != state.cell)
{
var eState = graph.view.getState(edge);
if (eState != null && eState.absolutePoints != null)
{
var eScale = eState.view.scale;
if (eState.style == null || eState.style[mxConstants.STYLE_CURVED] != 1) //line edge
{
for (var j = 0; j < eState.absolutePoints.length - 1; j++)
{
var l1p1 = eState.absolutePoints[j];
var l1p2 = eState.absolutePoints[j + 1];
//the absolute points of current edge is scaled before calling this function, so we have to scale others to get correct intersections
var result = this.checkLineIntersection(this.scalePoint(l1p1, eScale), this.scalePoint(l1p2, eScale), l2p1, l2p2);
if (result != null)
{
var getEdgeOrder = function (edge1, edge2)
{
var p1 = edge1.getParent();
var p2 = edge2.getParent();
if (p1 == p2)
{
return p1.getIndex(edge1) - p1.getIndex(edge2); //+ve edge1 on top, -ve edge2 on top
}
else
{
return 0; //not the same parent, so we cannot determine
}
};
if (getEdgeOrder(state.cell, eState.cell) > 0) //instead of reordering, get the order and the top edge has the bridge
{
this.addBridgePoints(intersectPt, result, l2p1, l2p2, state.cell.id, eState);
}
else if (!noRedraw)
{
eState.redrawEdge = true;
eState.shape.redraw();
}
}
}
}
else // curve edge (guad Bezier)
{
// We'll not check edge order here as always line will have bridges as it is better than curve bridges
var ePts = eState.absolutePoints;
var pt = this.scalePoint(ePts[0], eScale);
var n = ePts.length;
var allPts = [];
for (var k = 1; k < n - 2; k++)
{
var p0 = this.scalePoint(ePts[k], eScale);
var p1 = this.scalePoint(ePts[k + 1], eScale);
var ip = {
x: (p0.x + p1.x) / 2,
y: (p0.y + p1.y) / 2
};
allPts.push.apply(allPts, this.calcQLintersects(pt, p0, ip, l2p1, l2p2));
pt = ip;
}
var p0 = this.scalePoint(ePts[n - 2], eScale);
var p1 = this.scalePoint(ePts[n - 1], eScale);
allPts.push.apply(allPts, this.calcQLintersects(pt, p0, p1, l2p1, l2p2));
if (allPts.length > 0)
{
for (var o = 0; o < allPts.length; o++)
{
this.addBridgePoints(intersectPt, allPts[o], l2p1, l2p2, state.cell.id, eState);
}
}
}
}
}
}
if (intersectPt.length > 0)
{
// sort points and then add them
intersectPt.sort(function (p1, p2)
{
var dx1 = p1.x - l2p1.x;
var dy1 = p1.y - l2p1.y;
var d1 = dx1 * dx1 + dy1 * dy1;
var dx2 = p2.x - l2p1.x;
var dy2 = p2.y - l2p1.y;
var d2 = dx2 * dx2 + dy2 * dy2;
return d1 - d2;
});
ptsCln.push(intersectPt[0]);
this.addPoints(canvas, ptsCln, rounded, arcSize, false);
ptsCln = [intersectPt[intersectPt.length - 1]];
if (jumpStyle !== 'gap')
{
this.addPoints(canvas, intersectPt, jumpStyle !== 'square', arcSize, false);
}
}
ptsCln.push(l2p2);
}
if (noRedraw)
{
state.redrawEdge = false;
}
this.addPoints(canvas, ptsCln, rounded, arcSize, false);
canvas.stroke();
}
};
})();

View file

@ -184,7 +184,7 @@ f)+"\n"+t+"}":"{"+x.join(",")+"}";f=t;return l}}"function"!==typeof Date.prototy
e=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,f,g,h={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},k;"function"!==typeof JSON.stringify&&(JSON.stringify=function(a,b,d){var e;g=f="";if("number"===typeof d)for(e=0;e<d;e+=1)g+=" ";else"string"===typeof d&&(g=d);if((k=b)&&"function"!==typeof b&&("object"!==typeof b||"number"!==typeof b.length))throw Error("JSON.stringify");return c("",{"":a})});
"function"!==typeof JSON.parse&&(JSON.parse=function(a,b){function c(a,d){var e,f,g=a[d];if(g&&"object"===typeof g)for(e in g)Object.prototype.hasOwnProperty.call(g,e)&&(f=c(g,e),void 0!==f?g[e]=f:delete g[e]);return b.call(a,d,g)}var e;a=""+a;d.lastIndex=0;d.test(a)&&(a=a.replace(d,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)}));if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return e=eval("("+a+")"),"function"===typeof b?c({"":e},""):e;throw new SyntaxError("JSON.parse");})})();var mxBasePath="https://www.draw.io/mxgraph/",mxLoadStylesheets=mxLoadResources=!1,mxLanguage="en";window.urlParams=window.urlParams||{};window.MAX_REQUEST_SIZE=window.MAX_REQUEST_SIZE||10485760;window.MAX_AREA=window.MAX_AREA||225E6;window.EXPORT_URL=window.EXPORT_URL||"/export";window.SAVE_URL=window.SAVE_URL||"/save";window.OPEN_URL=window.OPEN_URL||"/open";window.RESOURCES_PATH=window.RESOURCES_PATH||"resources";window.RESOURCE_BASE=window.RESOURCE_BASE||window.RESOURCES_PATH+"/grapheditor";window.STENCIL_PATH=window.STENCIL_PATH||"stencils";window.IMAGE_PATH=window.IMAGE_PATH||"images";
window.STYLE_PATH=window.STYLE_PATH||"styles";window.CSS_PATH=window.CSS_PATH||"styles";window.OPEN_FORM=window.OPEN_FORM||"open.html";window.mxBasePath=window.mxBasePath||"../../../src";window.mxLanguage=window.mxLanguage||urlParams.lang;window.mxLanguages=window.mxLanguages||["de"];var mxClient={VERSION:"7.1.8",IS_IE:0<=navigator.userAgent.indexOf("MSIE"),IS_IE6:0<=navigator.userAgent.indexOf("MSIE 6"),IS_IE11:!!navigator.userAgent.match(/Trident\/7\./),IS_EDGE:!!navigator.userAgent.match(/Edge\//),IS_QUIRKS:0<=navigator.userAgent.indexOf("MSIE")&&(null==document.documentMode||5==document.documentMode),IS_EM:"spellcheck"in document.createElement("textarea")&&8==document.documentMode,VML_PREFIX:"v",OFFICE_PREFIX:"o",IS_NS:0<=navigator.userAgent.indexOf("Mozilla/")&&0>navigator.userAgent.indexOf("MSIE")&&
window.STYLE_PATH=window.STYLE_PATH||"styles";window.CSS_PATH=window.CSS_PATH||"styles";window.OPEN_FORM=window.OPEN_FORM||"open.html";window.mxBasePath=window.mxBasePath||"../../../src";window.mxLanguage=window.mxLanguage||urlParams.lang;window.mxLanguages=window.mxLanguages||["de"];var mxClient={VERSION:"7.1.9",IS_IE:0<=navigator.userAgent.indexOf("MSIE"),IS_IE6:0<=navigator.userAgent.indexOf("MSIE 6"),IS_IE11:!!navigator.userAgent.match(/Trident\/7\./),IS_EDGE:!!navigator.userAgent.match(/Edge\//),IS_QUIRKS:0<=navigator.userAgent.indexOf("MSIE")&&(null==document.documentMode||5==document.documentMode),IS_EM:"spellcheck"in document.createElement("textarea")&&8==document.documentMode,VML_PREFIX:"v",OFFICE_PREFIX:"o",IS_NS:0<=navigator.userAgent.indexOf("Mozilla/")&&0>navigator.userAgent.indexOf("MSIE")&&
0>navigator.userAgent.indexOf("Edge/"),IS_OP:0<=navigator.userAgent.indexOf("Opera/")||0<=navigator.userAgent.indexOf("OPR/"),IS_OT:0<=navigator.userAgent.indexOf("Presto/")&&0>navigator.userAgent.indexOf("Presto/2.4.")&&0>navigator.userAgent.indexOf("Presto/2.3.")&&0>navigator.userAgent.indexOf("Presto/2.2.")&&0>navigator.userAgent.indexOf("Presto/2.1.")&&0>navigator.userAgent.indexOf("Presto/2.0.")&&0>navigator.userAgent.indexOf("Presto/1."),IS_SF:0<=navigator.userAgent.indexOf("AppleWebKit/")&&
0>navigator.userAgent.indexOf("Chrome/")&&0>navigator.userAgent.indexOf("Edge/"),IS_IOS:navigator.userAgent.match(/(iPad|iPhone|iPod)/g)?!0:!1,IS_GC:0<=navigator.userAgent.indexOf("Chrome/")&&0>navigator.userAgent.indexOf("Edge/"),IS_CHROMEAPP:null!=window.chrome&&null!=chrome.app&&null!=chrome.app.runtime,IS_FF:0<=navigator.userAgent.indexOf("Firefox/"),IS_MT:0<=navigator.userAgent.indexOf("Firefox/")&&0>navigator.userAgent.indexOf("Firefox/1.")&&0>navigator.userAgent.indexOf("Firefox/2.")||0<=navigator.userAgent.indexOf("Iceweasel/")&&
0>navigator.userAgent.indexOf("Iceweasel/1.")&&0>navigator.userAgent.indexOf("Iceweasel/2.")||0<=navigator.userAgent.indexOf("SeaMonkey/")&&0>navigator.userAgent.indexOf("SeaMonkey/1.")||0<=navigator.userAgent.indexOf("Iceape/")&&0>navigator.userAgent.indexOf("Iceape/1."),IS_SVG:0<=navigator.userAgent.indexOf("Firefox/")||0<=navigator.userAgent.indexOf("Iceweasel/")||0<=navigator.userAgent.indexOf("Seamonkey/")||0<=navigator.userAgent.indexOf("Iceape/")||0<=navigator.userAgent.indexOf("Galeon/")||

View file

@ -68,8 +68,8 @@ Actions.prototype.init = function()
window.openFile = null;
});
}).isEnabled = isGraphEnabled;
this.addAction('save', function() { ui.saveFile(false); }, null, null, 'Ctrl+S').isEnabled = isGraphEnabled;
this.addAction('saveAs...', function() { ui.saveFile(true); }, null, null, 'Ctrl+Shift+S').isEnabled = isGraphEnabled;
this.addAction('save', function() { ui.saveFile(false); }, null, null, Editor.ctrlKey + '+S').isEnabled = isGraphEnabled;
this.addAction('saveAs...', function() { ui.saveFile(true); }, null, null, Editor.ctrlKey + '+Shift+S').isEnabled = isGraphEnabled;
this.addAction('export...', function() { ui.showDialog(new ExportDialog(ui).container, 300, 230, true, true); });
this.addAction('editDiagram...', function()
{
@ -78,21 +78,21 @@ Actions.prototype.init = function()
dlg.init();
});
this.addAction('pageSetup...', function() { ui.showDialog(new PageSetupDialog(ui).container, 320, 220, true, true); }).isEnabled = isGraphEnabled;
this.addAction('print...', function() { ui.showDialog(new PrintDialog(ui).container, 300, 180, true, true); }, null, 'sprite-print', 'Ctrl+P');
this.addAction('print...', function() { ui.showDialog(new PrintDialog(ui).container, 300, 180, true, true); }, null, 'sprite-print', Editor.ctrlKey + '+P');
this.addAction('preview', function() { mxUtils.show(graph, null, 10, 10); });
// Edit actions
this.addAction('undo', function() { ui.undo(); }, null, 'sprite-undo', 'Ctrl+Z');
this.addAction('redo', function() { ui.redo(); }, null, 'sprite-redo', (!mxClient.IS_WIN) ? 'Ctrl+Shift+Z' : 'Ctrl+Y');
this.addAction('cut', function() { mxClipboard.cut(graph); }, null, 'sprite-cut', 'Ctrl+X');
this.addAction('copy', function() { mxClipboard.copy(graph); }, null, 'sprite-copy', 'Ctrl+C');
this.addAction('undo', function() { ui.undo(); }, null, 'sprite-undo', Editor.ctrlKey + '+Z');
this.addAction('redo', function() { ui.redo(); }, null, 'sprite-redo', (!mxClient.IS_WIN) ? Editor.ctrlKey + '+Shift+Z' : Editor.ctrlKey + '+Y');
this.addAction('cut', function() { mxClipboard.cut(graph); }, null, 'sprite-cut', Editor.ctrlKey + '+X');
this.addAction('copy', function() { mxClipboard.copy(graph); }, null, 'sprite-copy', Editor.ctrlKey + '+C');
this.addAction('paste', function()
{
if (graph.isEnabled() && !graph.isCellLocked(graph.getDefaultParent()))
{
mxClipboard.paste(graph);
}
}, false, 'sprite-paste', 'Ctrl+V');
}, false, 'sprite-paste', Editor.ctrlKey + '+V');
this.addAction('pasteHere', function(evt)
{
if (graph.isEnabled() && !graph.isCellLocked(graph.getDefaultParent()))
@ -165,19 +165,19 @@ Actions.prototype.init = function()
this.addAction('deleteAll', function()
{
deleteCells(true);
}, null, null, 'Ctrl+Delete');
}, null, null, Editor.ctrlKey + '+Delete');
this.addAction('duplicate', function()
{
graph.setSelectionCells(graph.duplicateCells());
}, null, null, 'Ctrl+D');
}, null, null, Editor.ctrlKey + '+D');
this.put('turn', new Action(mxResources.get('turn') + ' / ' + mxResources.get('reverse'), function()
{
graph.turnShapes(graph.getSelectionCells());
}, null, null, 'Ctrl+R'));
this.addAction('selectVertices', function() { graph.selectVertices(); }, null, null, 'Ctrl+Shift+I');
this.addAction('selectEdges', function() { graph.selectEdges(); }, null, null, 'Ctrl+Shift+E');
this.addAction('selectAll', function() { graph.selectAll(null, true); }, null, null, 'Ctrl+A');
this.addAction('selectNone', function() { graph.clearSelection(); }, null, null, 'Ctrl+Shift+A');
}, null, null, Editor.ctrlKey + '+R'));
this.addAction('selectVertices', function() { graph.selectVertices(); }, null, null, Editor.ctrlKey + '+Shift+I');
this.addAction('selectEdges', function() { graph.selectEdges(); }, null, null, Editor.ctrlKey + '+Shift+E');
this.addAction('selectAll', function() { graph.selectAll(null, true); }, null, null, Editor.ctrlKey + '+A');
this.addAction('selectNone', function() { graph.clearSelection(); }, null, null, Editor.ctrlKey + '+Shift+A');
this.addAction('lockUnlock', function()
{
if (!graph.isSelectionEmpty())
@ -198,18 +198,18 @@ Actions.prototype.init = function()
graph.getModel().endUpdate();
}
}
}, null, null, 'Ctrl+L');
}, null, null, Editor.ctrlKey + '+L');
// Navigation actions
this.addAction('home', function() { graph.home(); }, null, null, 'Home');
this.addAction('exitGroup', function() { graph.exitGroup(); }, null, null, 'Ctrl+Shift+Page Up');
this.addAction('enterGroup', function() { graph.enterGroup(); }, null, null, 'Ctrl+Shift+Page Down');
this.addAction('expand', function() { graph.foldCells(false); }, null, null, 'Ctrl+Page Down');
this.addAction('collapse', function() { graph.foldCells(true); }, null, null, 'Ctrl+Page Up');
this.addAction('exitGroup', function() { graph.exitGroup(); }, null, null, Editor.ctrlKey + '+Shift+Page Up');
this.addAction('enterGroup', function() { graph.enterGroup(); }, null, null, Editor.ctrlKey + '+Shift+Page Down');
this.addAction('expand', function() { graph.foldCells(false); }, null, null, Editor.ctrlKey + '+Page Down');
this.addAction('collapse', function() { graph.foldCells(true); }, null, null, Editor.ctrlKey + '+Page Up');
// Arrange actions
this.addAction('toFront', function() { graph.orderCells(false); }, null, null, 'Ctrl+Shift+F');
this.addAction('toBack', function() { graph.orderCells(true); }, null, null, 'Ctrl+Shift+B');
this.addAction('toFront', function() { graph.orderCells(false); }, null, null, Editor.ctrlKey + '+Shift+F');
this.addAction('toBack', function() { graph.orderCells(true); }, null, null, Editor.ctrlKey + '+Shift+B');
this.addAction('group', function()
{
if (graph.getSelectionCount() == 1)
@ -220,7 +220,7 @@ Actions.prototype.init = function()
{
graph.setSelectionCell(graph.groupCells(null, 0));
}
}, null, null, 'Ctrl+G');
}, null, null, Editor.ctrlKey + '+G');
this.addAction('ungroup', function()
{
if (graph.getSelectionCount() == 1 && graph.getModel().getChildCount(graph.getSelectionCell()) == 0)
@ -231,7 +231,7 @@ Actions.prototype.init = function()
{
graph.setSelectionCells(graph.ungroupCells());
}
}, null, null, 'Ctrl+Shift+U');
}, null, null, Editor.ctrlKey + '+Shift+U');
this.addAction('removeFromGroup', function() { graph.removeCellsFromParent(); });
// Adds action
this.addAction('edit', function()
@ -251,7 +251,7 @@ Actions.prototype.init = function()
ui.showDialog(dlg.container, 320, 320, true, false);
dlg.init();
}
}, null, null, 'Ctrl+M');
}, null, null, Editor.ctrlKey + '+M');
this.addAction('editTooltip...', function()
{
var graph = ui.editor.graph;
@ -426,7 +426,7 @@ Actions.prototype.init = function()
graph.getModel().endUpdate();
}
}
}, null, null, 'Ctrl+Shift+Y');
}, null, null, Editor.ctrlKey + '+Shift+Y');
this.addAction('formattedText', function()
{
var state = graph.getView().getState(graph.getSelectionCell());
@ -524,10 +524,10 @@ Actions.prototype.init = function()
{
graph.zoomTo(1);
ui.resetScrollbars();
}, null, null, 'Ctrl+H');
this.addAction('zoomIn', function(evt) { graph.zoomIn(); }, null, null, 'Ctrl + (Numpad) / Alt+Mousewheel');
this.addAction('zoomOut', function(evt) { graph.zoomOut(); }, null, null, 'Ctrl - (Numpad) / Alt+Mousewheel');
this.addAction('fitWindow', function() { graph.fit(); }, null, null, 'Ctrl+Shift+H');
}, null, null, Editor.ctrlKey + '+H');
this.addAction('zoomIn', function(evt) { graph.zoomIn(); }, null, null, Editor.ctrlKey + ' + (Numpad) / Alt+Mousewheel');
this.addAction('zoomOut', function(evt) { graph.zoomOut(); }, null, null, Editor.ctrlKey + ' - (Numpad) / Alt+Mousewheel');
this.addAction('fitWindow', function() { graph.fit(); }, null, null, Editor.ctrlKey + '+Shift+H');
this.addAction('fitPage', mxUtils.bind(this, function()
{
if (!graph.pageVisible)
@ -548,7 +548,7 @@ Actions.prototype.init = function()
graph.container.scrollTop = pad.y * graph.view.scale;
graph.container.scrollLeft = Math.min(pad.x * graph.view.scale, (graph.container.scrollWidth - graph.container.clientWidth) / 2);
}
}), null, null, 'Ctrl+J');
}), null, null, Editor.ctrlKey + '+J');
this.addAction('fitTwoPages', mxUtils.bind(this, function()
{
if (!graph.pageVisible)
@ -570,7 +570,7 @@ Actions.prototype.init = function()
graph.container.scrollTop = Math.min(pad.y, (graph.container.scrollHeight - graph.container.clientHeight) / 2);
graph.container.scrollLeft = Math.min(pad.x, (graph.container.scrollWidth - graph.container.clientWidth) / 2);
}
}), null, null, 'Ctrl+Shift+J');
}), null, null, Editor.ctrlKey + '+Shift+J');
this.addAction('fitPageWidth', mxUtils.bind(this, function()
{
if (!graph.pageVisible)
@ -605,7 +605,7 @@ Actions.prototype.init = function()
}), mxResources.get('zoom') + ' (%)');
this.editorUi.showDialog(dlg.container, 300, 80, true, true);
dlg.init();
}), null, null, 'Ctrl+0'));
}), null, null, Editor.ctrlKey + '+0'));
this.addAction('pageScale...', mxUtils.bind(this, function()
{
var dlg = new FilenameDialog(this.editorUi, parseInt(graph.pageScale * 100), mxResources.get('apply'), mxUtils.bind(this, function(newValue)
@ -627,7 +627,7 @@ Actions.prototype.init = function()
{
graph.setGridEnabled(!graph.isGridEnabled());
ui.fireEvent(new mxEventObject('gridEnabledChanged'));
}, null, null, 'Ctrl+Shift+G');
}, null, null, Editor.ctrlKey + '+Shift+G');
action.setToggleAction(true);
action.setSelectedCallback(function() { return graph.isGridEnabled(); });
action.setEnabled(false);
@ -671,14 +671,14 @@ Actions.prototype.init = function()
{
graph.connectionArrowsEnabled = !graph.connectionArrowsEnabled;
ui.fireEvent(new mxEventObject('connectionArrowsChanged'));
}, null, null, 'Ctrl+Q');
}, null, null, 'Alt+Shift+A');
action.setToggleAction(true);
action.setSelectedCallback(function() { return graph.connectionArrowsEnabled; });
action = this.addAction('connectionPoints', function()
{
graph.setConnectable(!graph.connectionHandler.isEnabled());
ui.fireEvent(new mxEventObject('connectionPointsChanged'));
}, null, null, 'Ctrl+Shift+Q');
}, null, null, 'Alt+Shift+P');
action.setToggleAction(true);
action.setSelectedCallback(function() { return graph.connectionHandler.isEnabled(); });
action = this.addAction('copyConnect', function()
@ -732,9 +732,9 @@ Actions.prototype.init = function()
}, null, null, shortcut);
});
toggleFontStyle('bold', mxConstants.FONT_BOLD, function() { document.execCommand('bold', false, null); }, 'Ctrl+B');
toggleFontStyle('italic', mxConstants.FONT_ITALIC, function() { document.execCommand('italic', false, null); }, 'Ctrl+I');
toggleFontStyle('underline', mxConstants.FONT_UNDERLINE, function() { document.execCommand('underline', false, null); }, 'Ctrl+U');
toggleFontStyle('bold', mxConstants.FONT_BOLD, function() { document.execCommand('bold', false, null); }, Editor.ctrlKey + '+B');
toggleFontStyle('italic', mxConstants.FONT_ITALIC, function() { document.execCommand('italic', false, null); }, Editor.ctrlKey + '+I');
toggleFontStyle('underline', mxConstants.FONT_UNDERLINE, function() { document.execCommand('underline', false, null); }, Editor.ctrlKey + '+U');
// Color actions
this.addAction('fontColor...', function() { ui.menus.pickColor(mxConstants.STYLE_FONTCOLOR, 'forecolor', '000000'); });
@ -893,21 +893,21 @@ Actions.prototype.init = function()
this.editorUi.showDialog(dlg.container, 420, 300, true, true);
dlg.init();
}
}), null, null, 'Ctrl+E');
}), null, null, Editor.ctrlKey + '+E');
this.addAction('setAsDefaultStyle', function()
{
if (graph.isEnabled() && !graph.isSelectionEmpty())
{
ui.setDefaultStyle(graph.getSelectionCell());
}
}, null, null, 'Ctrl+Shift+D');
}, null, null, Editor.ctrlKey + '+Shift+D');
this.addAction('clearDefaultStyle', function()
{
if (graph.isEnabled())
{
ui.clearDefaultStyle();
}
}, null, null, 'Ctrl+Shift+R');
}, null, null, Editor.ctrlKey + '+Shift+R');
this.addAction('addWaypoint', function()
{
var cell = graph.getSelectionCell();
@ -993,14 +993,14 @@ Actions.prototype.init = function()
{
document.execCommand('subscript', false, null);
}
}), null, null, 'Ctrl+,');
}), null, null, Editor.ctrlKey + '+,');
action = this.addAction('superscript', mxUtils.bind(this, function()
{
if (graph.cellEditor.isContentEditing())
{
document.execCommand('superscript', false, null);
}
}), null, null, 'Ctrl+.');
}), null, null, Editor.ctrlKey + '+.');
this.addAction('image...', function()
{
if (graph.isEnabled() && !graph.isCellLocked(graph.getDefaultParent()))
@ -1118,13 +1118,13 @@ Actions.prototype.init = function()
}
//ui.fireEvent(new mxEventObject('layers'));
}), null, null, 'Ctrl+Shift+L');
}), null, null, Editor.ctrlKey + '+Shift+L');
action.setToggleAction(true);
action.setSelectedCallback(mxUtils.bind(this, function() { return this.layersWindow != null && this.layersWindow.window.isVisible(); }));
action = this.addAction('formatPanel', mxUtils.bind(this, function()
{
ui.toggleFormatPanel();
}), null, null, 'Ctrl+Shift+P');
}), null, null, Editor.ctrlKey + '+Shift+P');
action.setToggleAction(true);
action.setSelectedCallback(mxUtils.bind(this, function() { return ui.formatWidth > 0; }));
action = this.addAction('outline', mxUtils.bind(this, function()
@ -1150,7 +1150,7 @@ Actions.prototype.init = function()
}
ui.fireEvent(new mxEventObject('outline'));
}), null, null, 'Ctrl+Shift+O');
}), null, null, Editor.ctrlKey + '+Shift+O');
action.setToggleAction(true);
action.setSelectedCallback(mxUtils.bind(this, function() { return this.outlineWindow != null && this.outlineWindow.window.isVisible(); }));

View file

@ -188,7 +188,14 @@ Editor.previousLargeImage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAA
*/
Editor.nextLargeImage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAPFBMVEUAAAD////////////////////////////////////////////////////////////////////////////YSWgTAAAAE3RSTlMA7fci493c0MW8uJ6CZks4MxQHEZL6ewAAAFRJREFUOMvd0skRgCAQBVEFwQ0V7fxzNQP6wI05v6pZ/kyj1b7FNgik2gQzzLcAwiUAigHOTwDHK4A1CmB5BJANJG1hQ9qafYcqFlZP3IFc9eVGrR+iIgkDQRUXIAAAAABJRU5ErkJggg==';
// Editor inherits from mxEventSource
/**
* Specifies the image URL to be used for the transparent background.
*/
Editor.ctrlKey = (mxClient.IS_MAC) ? 'Cmd' : 'Ctrl';
/**
* Editor inherits from mxEventSource
*/
mxUtils.extend(Editor, mxEventSource);
/**

View file

@ -3703,14 +3703,17 @@ EditorUi.prototype.createKeyHandler = function(editor)
var keyHandlerGetFunction = keyHandler.getFunction;
// Alt+Shift+Keycode mapping to action
var altShiftActions = {67: this.actions.get('clearWaypoints')}; // Alt+Shift+C
var altShiftActions = {67: this.actions.get('clearWaypoints'), // Alt+Shift+C
65: this.actions.get('connectionArrows'), // Alt+Shift+A
80: this.actions.get('connectionPoints') // Alt+Shift+P
};
mxKeyHandler.prototype.getFunction = function(evt)
{
if (graph.isEnabled())
{
// TODO: Add alt modified state in core API, here are some specific cases
if (!graph.isSelectionEmpty() && mxEvent.isShiftDown(evt) && mxEvent.isAltDown(evt))
if (mxEvent.isShiftDown(evt) && mxEvent.isAltDown(evt))
{
var action = altShiftActions[evt.keyCode];
@ -3887,8 +3890,6 @@ EditorUi.prototype.createKeyHandler = function(editor)
keyHandler.bindAction(89, true, 'autosize', true); // Ctrl+Shift+Y
keyHandler.bindAction(88, true, 'cut'); // Ctrl+X
keyHandler.bindAction(67, true, 'copy'); // Ctrl+C
keyHandler.bindAction(81, true, 'connectionArrows'); // Ctrl+Q
keyHandler.bindAction(81, true, 'connectionPoints', true); // Ctrl+Shift+Q
keyHandler.bindAction(86, true, 'paste'); // Ctrl+V
keyHandler.bindAction(71, true, 'group'); // Ctrl+G
keyHandler.bindAction(77, true, 'editData'); // Ctrl+M

View file

@ -2309,11 +2309,13 @@ TextFormatPanel.prototype.addFont = function(container)
document.execCommand('justifyfull', false, null);
}, stylePanel3);
this.styleButtons([full,
sub = this.editorUi.toolbar.addButton('geSprite-subscript', mxResources.get('subscript') + ' (Ctrl+,)',
sub = this.editorUi.toolbar.addButton('geSprite-subscript',
mxResources.get('subscript') + ' (' + Editor.ctrlKey + '+,)',
function()
{
document.execCommand('subscript', false, null);
}, stylePanel3), sup = this.editorUi.toolbar.addButton('geSprite-superscript', mxResources.get('superscript') + ' (Ctrl+.)',
}, stylePanel3), sup = this.editorUi.toolbar.addButton('geSprite-superscript',
mxResources.get('superscript') + ' (' + Editor.ctrlKey + '+.)',
function()
{
document.execCommand('superscript', false, null);

View file

@ -356,11 +356,11 @@ Toolbar.prototype.createTextToolbar = function()
{
elt = menu.addItem('', null, this.editorUi.actions.get('subscript').funct,
null, 'geIcon geSprite geSprite-subscript');
elt.setAttribute('title', mxResources.get('subscript') + ' (Ctrl+,)');
elt.setAttribute('title', mxResources.get('subscript') + ' (' + Editor.ctrlKey + '+,)');
elt = menu.addItem('', null, this.editorUi.actions.get('superscript').funct,
null, 'geIcon geSprite geSprite-superscript');
elt.setAttribute('title', mxResources.get('superscript') + ' (Ctrl+.)');
elt.setAttribute('title', mxResources.get('superscript') + ' (' + Editor.ctrlKey + '+.)');
// KNOWN: IE+FF don't return keyboard focus after color dialog (calling focus doesn't help)
elt = menu.addItem('', null, this.editorUi.actions.get('fontColor').funct,

View file

@ -184,7 +184,7 @@ f)+"\n"+t+"}":"{"+x.join(",")+"}";f=t;return l}}"function"!==typeof Date.prototy
e=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,f,g,h={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},k;"function"!==typeof JSON.stringify&&(JSON.stringify=function(a,b,d){var e;g=f="";if("number"===typeof d)for(e=0;e<d;e+=1)g+=" ";else"string"===typeof d&&(g=d);if((k=b)&&"function"!==typeof b&&("object"!==typeof b||"number"!==typeof b.length))throw Error("JSON.stringify");return c("",{"":a})});
"function"!==typeof JSON.parse&&(JSON.parse=function(a,b){function c(a,d){var e,f,g=a[d];if(g&&"object"===typeof g)for(e in g)Object.prototype.hasOwnProperty.call(g,e)&&(f=c(g,e),void 0!==f?g[e]=f:delete g[e]);return b.call(a,d,g)}var e;a=""+a;d.lastIndex=0;d.test(a)&&(a=a.replace(d,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)}));if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return e=eval("("+a+")"),"function"===typeof b?c({"":e},""):e;throw new SyntaxError("JSON.parse");})})();var mxBasePath="https://www.draw.io/mxgraph/",mxLoadStylesheets=mxLoadResources=!1,mxLanguage="en";window.urlParams=window.urlParams||{};window.MAX_REQUEST_SIZE=window.MAX_REQUEST_SIZE||10485760;window.MAX_AREA=window.MAX_AREA||225E6;window.EXPORT_URL=window.EXPORT_URL||"/export";window.SAVE_URL=window.SAVE_URL||"/save";window.OPEN_URL=window.OPEN_URL||"/open";window.RESOURCES_PATH=window.RESOURCES_PATH||"resources";window.RESOURCE_BASE=window.RESOURCE_BASE||window.RESOURCES_PATH+"/grapheditor";window.STENCIL_PATH=window.STENCIL_PATH||"stencils";window.IMAGE_PATH=window.IMAGE_PATH||"images";
window.STYLE_PATH=window.STYLE_PATH||"styles";window.CSS_PATH=window.CSS_PATH||"styles";window.OPEN_FORM=window.OPEN_FORM||"open.html";window.mxBasePath=window.mxBasePath||"../../../src";window.mxLanguage=window.mxLanguage||urlParams.lang;window.mxLanguages=window.mxLanguages||["de"];var mxClient={VERSION:"7.1.8",IS_IE:0<=navigator.userAgent.indexOf("MSIE"),IS_IE6:0<=navigator.userAgent.indexOf("MSIE 6"),IS_IE11:!!navigator.userAgent.match(/Trident\/7\./),IS_EDGE:!!navigator.userAgent.match(/Edge\//),IS_QUIRKS:0<=navigator.userAgent.indexOf("MSIE")&&(null==document.documentMode||5==document.documentMode),IS_EM:"spellcheck"in document.createElement("textarea")&&8==document.documentMode,VML_PREFIX:"v",OFFICE_PREFIX:"o",IS_NS:0<=navigator.userAgent.indexOf("Mozilla/")&&0>navigator.userAgent.indexOf("MSIE")&&
window.STYLE_PATH=window.STYLE_PATH||"styles";window.CSS_PATH=window.CSS_PATH||"styles";window.OPEN_FORM=window.OPEN_FORM||"open.html";window.mxBasePath=window.mxBasePath||"../../../src";window.mxLanguage=window.mxLanguage||urlParams.lang;window.mxLanguages=window.mxLanguages||["de"];var mxClient={VERSION:"7.1.9",IS_IE:0<=navigator.userAgent.indexOf("MSIE"),IS_IE6:0<=navigator.userAgent.indexOf("MSIE 6"),IS_IE11:!!navigator.userAgent.match(/Trident\/7\./),IS_EDGE:!!navigator.userAgent.match(/Edge\//),IS_QUIRKS:0<=navigator.userAgent.indexOf("MSIE")&&(null==document.documentMode||5==document.documentMode),IS_EM:"spellcheck"in document.createElement("textarea")&&8==document.documentMode,VML_PREFIX:"v",OFFICE_PREFIX:"o",IS_NS:0<=navigator.userAgent.indexOf("Mozilla/")&&0>navigator.userAgent.indexOf("MSIE")&&
0>navigator.userAgent.indexOf("Edge/"),IS_OP:0<=navigator.userAgent.indexOf("Opera/")||0<=navigator.userAgent.indexOf("OPR/"),IS_OT:0<=navigator.userAgent.indexOf("Presto/")&&0>navigator.userAgent.indexOf("Presto/2.4.")&&0>navigator.userAgent.indexOf("Presto/2.3.")&&0>navigator.userAgent.indexOf("Presto/2.2.")&&0>navigator.userAgent.indexOf("Presto/2.1.")&&0>navigator.userAgent.indexOf("Presto/2.0.")&&0>navigator.userAgent.indexOf("Presto/1."),IS_SF:0<=navigator.userAgent.indexOf("AppleWebKit/")&&
0>navigator.userAgent.indexOf("Chrome/")&&0>navigator.userAgent.indexOf("Edge/"),IS_IOS:navigator.userAgent.match(/(iPad|iPhone|iPod)/g)?!0:!1,IS_GC:0<=navigator.userAgent.indexOf("Chrome/")&&0>navigator.userAgent.indexOf("Edge/"),IS_CHROMEAPP:null!=window.chrome&&null!=chrome.app&&null!=chrome.app.runtime,IS_FF:0<=navigator.userAgent.indexOf("Firefox/"),IS_MT:0<=navigator.userAgent.indexOf("Firefox/")&&0>navigator.userAgent.indexOf("Firefox/1.")&&0>navigator.userAgent.indexOf("Firefox/2.")||0<=navigator.userAgent.indexOf("Iceweasel/")&&
0>navigator.userAgent.indexOf("Iceweasel/1.")&&0>navigator.userAgent.indexOf("Iceweasel/2.")||0<=navigator.userAgent.indexOf("SeaMonkey/")&&0>navigator.userAgent.indexOf("SeaMonkey/1.")||0<=navigator.userAgent.indexOf("Iceape/")&&0>navigator.userAgent.indexOf("Iceape/1."),IS_SVG:0<=navigator.userAgent.indexOf("Firefox/")||0<=navigator.userAgent.indexOf("Iceweasel/")||0<=navigator.userAgent.indexOf("Seamonkey/")||0<=navigator.userAgent.indexOf("Iceape/")||0<=navigator.userAgent.indexOf("Galeon/")||

180
war/js/viewer.min.js vendored

File diff suppressed because one or more lines are too long

View file

@ -183,13 +183,13 @@ Draw.loadPlugin(function(ui) {
if (recognizing != null)
{
td.innerHTML = '<img style="margin-right:4px;" align="absmiddle" border="0" src="' + micImage + '"/> Listening...';
td.setAttribute('title', 'Click to Stop (Ctrl+O)');
td.setAttribute('title', 'Click to Stop (' + Editor.ctrlKey + '+O)');
td.style.color = 'darkGray';
}
else
{
td.innerHTML = '<img style="margin-right:4px;" align="absmiddle" border="0" src="' + micImage + '"/> Click to Speak';
td.setAttribute('title', 'Click to Speak (Ctrl+O)');
td.setAttribute('title', 'Click to Speak (' + Editor.ctrlKey + '+O)');
td.style.color = '#235695';
}
}
@ -220,7 +220,7 @@ Draw.loadPlugin(function(ui) {
ui.actions.addAction('speechListenContinuous', function()
{
App.listen(true);
}, null, null, 'Ctrl+O');
}, null, null, Editor.ctrlKey + '+O');
ui.actions.addAction('speechHint', function()
{

View file

@ -373,6 +373,7 @@ lessThanAMinute=less than a minute
licensingError=Licensing Error
licenseHasExpired=The license for {1} has expired on {2}. Click here.
licenseWillExpire=The license for {1} will expire on {2}. Click here.
lineJumps=Line jumps
linkAccountRequired=If the diagram is not public a Google account is required to view the link.
linkText=Link Text
list=List

View file

@ -373,6 +373,7 @@ lessThanAMinute=less than a minute
licensingError=Licensing Error
licenseHasExpired=The license for {1} has expired on {2}. Click here.
licenseWillExpire=The license for {1} will expire on {2}. Click here.
lineJumps=Line jumps
linkAccountRequired=If the diagram is not public a Google account is required to view the link.
linkText=Link Text
list=List

View file

@ -373,6 +373,7 @@ lessThanAMinute=‫أقل من دقيقة‬
licensingError=Licensing Error
licenseHasExpired=The license for {1} has expired on {2}. Click here.
licenseWillExpire=The license for {1} will expire on {2}. Click here.
lineJumps=Line jumps
linkAccountRequired=If the diagram is not public a Google account is required to view the link.
linkText=Link Text
list=List

View file

@ -373,6 +373,7 @@ lessThanAMinute=по-малко от една минута
licensingError=Грешка при лицензирането
licenseHasExpired=Лицензът за {1} изтече на {2}. Кликнете тук.
licenseWillExpire=Лицензът за {1} ще изтече на {2}. Кликнете тук.
lineJumps=Line jumps
linkAccountRequired=Ако диаграмата не е публична, е необходим профил в Google, за да видите линка.
linkText=Текст на линка
list=Списък

View file

@ -373,6 +373,7 @@ lessThanAMinute=less than a minute
licensingError=Licensing Error
licenseHasExpired=The license for {1} has expired on {2}. Click here.
licenseWillExpire=The license for {1} will expire on {2}. Click here.
lineJumps=Line jumps
linkAccountRequired=If the diagram is not public a Google account is required to view the link.
linkText=Link Text
list=List

View file

@ -373,6 +373,7 @@ lessThanAMinute=manje od minute
licensingError=Greška pri licenciranju
licenseHasExpired=Licenca za {1} je istekla {2}. Kliknite ovdje.
licenseWillExpire=Licenca za {1} će isteći {2}. Kliknite ovdje.
lineJumps=Line jumps
linkAccountRequired=Ukoliko dijagram nije javni, potreban je Google nalog za pregledanje linka.
linkText=Poveži tekst
list=Lista

View file

@ -373,6 +373,7 @@ lessThanAMinute=menys d'un minut
licensingError=Error de llicència
licenseHasExpired=La llicència per a {1} ha expirat el {2}. Clica aquí.
licenseWillExpire=La llicència per a {1} expira el {2}. Clica aquí.
lineJumps=Line jumps
linkAccountRequired=Si el diagrama no és públic es requereix un compte de Google per a veure l'enllaç.
linkText=Text de l'enllaç
list=Llista

View file

@ -373,6 +373,7 @@ lessThanAMinute=méně než 1 min.
licensingError=Chyba licence
licenseHasExpired=Licence pro {1} vypršela {2}. Klepněte sem.
licenseWillExpire=Licence pro {1} vyprší {2}. Klepněte sem.
lineJumps=Line jumps
linkAccountRequired=Pokud je diagram neveřejný, k jeho zobrazení je potřeba účet Google.
linkText=Odkaz na text
list=Seznam

View file

@ -373,6 +373,7 @@ lessThanAMinute=mindre end et minut
licensingError=Licens Fejl
licenseHasExpired=Licensen for {1} udløb den {2}. Klik her.
licenseWillExpire=Licensen for {1} vil udløbe den {2}. Klik her.
lineJumps=Line jumps
linkAccountRequired=Hvis diagrammet ikke er offentligt er en Google konto nødvendig for at kunne se linket.
linkText=Link tekst
list=Liste

View file

@ -373,6 +373,7 @@ lessThanAMinute=weniger als einer Minute
licensingError=Lizenzfehler
licenseHasExpired=Die Lizenz für {1} ist am {2} abgelaufen. Hier klicken.
licenseWillExpire=Die Lizenz für {1} läuft am {2} ab. Hier klicken.
lineJumps=Liniensprünge
linkAccountRequired=Wenn das Diagramm nicht öffentlich ist, wird ein Google Konto für die Ansicht benötigt.
linkText=Link Text
list=Liste

View file

@ -373,6 +373,7 @@ lessThanAMinute=λιγότερο από ένα λεπτό
licensingError=Σφάλμα στην άδεια χρήση
licenseHasExpired=Η άδεια χρήσης για {1} έχει λήξει στις {2}. Πατήστε εδώ.
licenseWillExpire=Η άδεια χρήσης για {1} θα λήξει στις {2}. Πατήστε εδώ.
lineJumps=Line jumps
linkAccountRequired=Εάν το διάγραμμα δεν είναι δημόσιο, χρειάζεται λογαριασμός Google για να δείτε τον σύνδεσμο.
linkText=Κείμενο συνδέσμου
list=Λίστα

View file

@ -373,6 +373,7 @@ lessThanAMinute=less than a minute
licensingError=Licensing Error
licenseHasExpired=The license for {1} has expired on {2}. Click here.
licenseWillExpire=The license for {1} will expire on {2}. Click here.
lineJumps=Line jumps
linkAccountRequired=If the diagram is not public a Google account is required to view the link.
linkText=Link Text
list=List

View file

@ -373,6 +373,7 @@ lessThanAMinute=menos de un minuto
licensingError=Error de licencia
licenseHasExpired=La licencia para {1} ha expirado en {2}. Haga clic aquí.
licenseWillExpire=La licencia para {1} expirará en {2}. Haga clic aquí.
lineJumps=Line jumps
linkAccountRequired=Se requiere una cuenta de Google para ver el enlace si el diagrama no es público.
linkText=Texto del enlace
list=Lista

View file

@ -373,6 +373,7 @@ lessThanAMinute=vähem kui minut
licensingError=Litsentsiviga
licenseHasExpired=Litsents {1} jaoks aegub {2}. Vajuta siia.
licenseWillExpire=Litsents {1} jaoks aegub {2}. Vajuta siia.
lineJumps=Line jumps
linkAccountRequired=Kui diagramm pole avalik, siis läheb lingi vaatamiseks Google'i kasutajakontot vaja.
linkText=Lingi tekst
list=Nimekiri

View file

@ -373,6 +373,7 @@ lessThanAMinute=‫کمتر از یک دقیقه‬
licensingError=‫خطای مجوز‬
licenseHasExpired=‫مجوز مربوط به {1} در {2} منقضی شده است. اینجا کلیک کنید.
licenseWillExpire=‫مجوز مربوط به {1} در {2} منقضی خواهد شد. اینجا کلیک کنید.
lineJumps=Line jumps
linkAccountRequired=‫اگر نمودار عمومی نیست، برای مشاهده لینک به حساب گوگل نیاز است.
linkText=‫لینک متن‬
list=‫لیست‬

View file

@ -373,6 +373,7 @@ lessThanAMinute=alle minuutti sitten
licensingError=Lisenssi virhe
licenseHasExpired={1} lisenssi on päättynyt {2}. Klikkaa tästä.
licenseWillExpire={1} lisenssi päättyy {2}. Klikkaa tästä.
lineJumps=Line jumps
linkAccountRequired=Jos kaavio ei ole julkinen, tarkistamiseen tarvitaan Google tiliä.
linkText=Linkin teksti
list=Lista

View file

@ -373,6 +373,7 @@ lessThanAMinute=Mababa sa isang minuto
licensingError=Pagkakamali sa paglilisensya
licenseHasExpired=Ang lisensya para kay {1} ay nagwakas ng {2}. Pindutin dito
licenseWillExpire=Ang lisensya para kay {1} ay magwawakas sa {2}. Pindutin dito
lineJumps=Line jumps
linkAccountRequired=Kung ang Dayagram ay di pampubliko, kailangan ng Google account para tingnan ang Link
linkText=I-link ang teksto
list=Listahan

View file

@ -373,6 +373,7 @@ lessThanAMinute=moins d'une minute
licensingError=Erreur de licence
licenseHasExpired=La license pour {1} a expiré le {2}. Cliquez ici.
licenseWillExpire=La license pour {1} expirera le {2}. Cliquez ici.
lineJumps=Line jumps
linkAccountRequired=Si le diagramme n'est pas public, un compte Google est requis pour voir le lien.
linkText=Texte du lien
list=Liste

View file

@ -373,6 +373,7 @@ lessThanAMinute=less than a minute
licensingError=Licensing Error
licenseHasExpired=The license for {1} has expired on {2}. Click here.
licenseWillExpire=The license for {1} will expire on {2}. Click here.
lineJumps=Line jumps
linkAccountRequired=If the diagram is not public a Google account is required to view the link.
linkText=Link Text
list=List

View file

@ -373,6 +373,7 @@ lessThanAMinute=‫פחות מדקה‬
licensingError=‫שגיאת רישיון‬
licenseHasExpired=‫הרשיון עבור {1} אינו בתוקף מתאריך {2}. לחץ כאן.
licenseWillExpire=‫תוקף הרשיון עבור {1} יפוג בתאריך {2}. לחץ כאן.
lineJumps=Line jumps
linkAccountRequired=‫אם הדיאגרמה אינה ציבורית, נדרש חשבון גוגל כדי לפתוח את הקישור.
linkText=‫טקסט מקושר‬
list=‫רשימה‬

View file

@ -373,6 +373,7 @@ lessThanAMinute=less than a minute
licensingError=Licensing Error
licenseHasExpired=The license for {1} has expired on {2}. Click here.
licenseWillExpire=The license for {1} will expire on {2}. Click here.
lineJumps=Line jumps
linkAccountRequired=If the diagram is not public a Google account is required to view the link.
linkText=Link Text
list=List

View file

@ -373,6 +373,7 @@ lessThanAMinute=less than a minute
licensingError=Licensing Error
licenseHasExpired=The license for {1} has expired on {2}. Click here.
licenseWillExpire=The license for {1} will expire on {2}. Click here.
lineJumps=Line jumps
linkAccountRequired=If the diagram is not public a Google account is required to view the link.
linkText=Link Text
list=List

View file

@ -373,6 +373,7 @@ lessThanAMinute=kevesebb mint egy perc
licensingError=Engedélyezési hiba
licenseHasExpired={2}-n lejárt az engedély a(z) {1}-hez. Kattintson ide.
licenseWillExpire={2}-n lejár az engedély a(z) {1}-hez. Kattintson ide.
lineJumps=Line jumps
linkAccountRequired=Amiben a diagram nem nyilvános, Google számla szükséges a link megtekintéséhez.
linkText=Szöveg link
list=Lista

View file

@ -373,6 +373,7 @@ lessThanAMinute=lessThanAMinute
licensingError=licensingError
licenseHasExpired=licenseHasExpired
licenseWillExpire=licenseWillExpire
lineJumps=lineJumps
linkAccountRequired=linkAccountRequired
linkText=linkText
list=list

View file

@ -373,6 +373,7 @@ lessThanAMinute=kurang dari satu menit
licensingError=Galat Lisensi
licenseHasExpired=Lisensi {1} telah berakhir pada {2}. Klik di sini.
licenseWillExpire=Lisensi {1} akan berakhir pada {2}. Klik di sini.
lineJumps=Line jumps
linkAccountRequired=Jika diagram tidak bersifat publik, akun Google diperlukan untuk membaca tautan.
linkText=Teks Tautan
list=Daftar

View file

@ -373,6 +373,7 @@ lessThanAMinute=meno di un minuto
licensingError=Errore di licenza
licenseHasExpired=La licenza per {1} è scaduta il {2}. Clicca qui.
licenseWillExpire=La licenza per {1} scadrà il {2}. Clicca qui.
lineJumps=Line jumps
linkAccountRequired=Se il diagramma non è pubblico, è necessario un account Google per visualizzare il link.
linkText=Testo del link
list=Lista

View file

@ -373,6 +373,7 @@ lessThanAMinute=1分以内に
licensingError=ライセンス エラー
licenseHasExpired=ライセンス{1} は{2}に期限がきれました。 ここをクリックしてください。
licenseWillExpire=ライセンス{1} に期限切れになります{2}. ここをクリックしてください。
lineJumps=Line jumps
linkAccountRequired=図が公式表示されていない場合は、リンクを表示するために Google アカウントが必要です。
linkText=リンク テキスト
list=リスト

View file

@ -373,6 +373,7 @@ lessThanAMinute=less than a minute
licensingError=Licensing Error
licenseHasExpired=The license for {1} has expired on {2}. Click here.
licenseWillExpire=The license for {1} will expire on {2}. Click here.
lineJumps=Line jumps
linkAccountRequired=If the diagram is not public a Google account is required to view the link.
linkText=Link Text
list=List

View file

@ -373,6 +373,7 @@ lessThanAMinute=방금
licensingError=라이선스 오류
licenseHasExpired={1} 관련 라이선스가 {2}에 만료되었습니다. 여기를 클릭해 주시기 바랍니다.
licenseWillExpire={1} 관련 라이선스가 {2}에 만료될 예정입니다. 여기를 클릭해 주시기 바랍니다.
lineJumps=Line jumps
linkAccountRequired=다이어그램이 공개상태가 아닌 경우, 링크를 확인하기 위해 구글 계정이 필요합니다.
linkText=링크 텍스트
list=목록

View file

@ -373,6 +373,7 @@ lessThanAMinute=less than a minute
licensingError=Licensing Error
licenseHasExpired=The license for {1} has expired on {2}. Click here.
licenseWillExpire=The license for {1} will expire on {2}. Click here.
lineJumps=Line jumps
linkAccountRequired=If the diagram is not public a Google account is required to view the link.
linkText=Link Text
list=List

View file

@ -373,6 +373,7 @@ lessThanAMinute=less than a minute
licensingError=Licensing Error
licenseHasExpired=The license for {1} has expired on {2}. Click here.
licenseWillExpire=The license for {1} will expire on {2}. Click here.
lineJumps=Line jumps
linkAccountRequired=If the diagram is not public a Google account is required to view the link.
linkText=Link Text
list=List

View file

@ -373,6 +373,7 @@ lessThanAMinute=less than a minute
licensingError=Licensing Error
licenseHasExpired=The license for {1} has expired on {2}. Click here.
licenseWillExpire=The license for {1} will expire on {2}. Click here.
lineJumps=Line jumps
linkAccountRequired=If the diagram is not public a Google account is required to view the link.
linkText=Link Text
list=List

View file

@ -373,6 +373,7 @@ lessThanAMinute=less than a minute
licensingError=Licensing Error
licenseHasExpired=The license for {1} has expired on {2}. Click here.
licenseWillExpire=The license for {1} will expire on {2}. Click here.
lineJumps=Line jumps
linkAccountRequired=If the diagram is not public a Google account is required to view the link.
linkText=Link Text
list=List

View file

@ -373,6 +373,7 @@ lessThanAMinute=kurang dari satu minit
licensingError=Ralat Pelesenan
licenseHasExpired=Lesen untuk {1} telah luput pada {2}. Klik di sini.
licenseWillExpire=Lesen untuk {1} akan luput pada {2}. Klik di sini.
lineJumps=Line jumps
linkAccountRequired=Jika gambarajah tidak umum, akaun Google diperlukan untuk melihat pautan tersebut.
linkText=Teks Pautan
list=Senarai

View file

@ -373,6 +373,7 @@ lessThanAMinute=minder dan een minuut
licensingError=Licentiefout
licenseHasExpired=De licentie voor {1} is verlopen op {2}. Klik hier.
licenseWillExpire=De licentie voor {1} zal op {2} verlopen. Klik hier
lineJumps=Line jumps
linkAccountRequired=Als het diagram niet openbaar is, is een Google-account vereist om de link te bekijken.
linkText=Linktekst
list=Lijst

View file

@ -373,6 +373,7 @@ lessThanAMinute=mindre enn ett minutt
licensingError=Lisensieringsfeil
licenseHasExpired=Linsensen for {1} utgikk på {2}. Klikk her.
licenseWillExpire=Linsensen for {1} utgår på {2}. Klikk her.
lineJumps=Line jumps
linkAccountRequired=Om diagrammet ikke er offentlig er en Google-konto påkrevd for å åpne linken.
linkText=Linktekst
list=Liste

View file

@ -373,6 +373,7 @@ lessThanAMinute=poniżej minuty
licensingError=Błąd licencji
licenseHasExpired=Licencja dla {1} wygasła {2}. Kliknij tutaj.
licenseWillExpire=Licencja dla {1} wygaśnie {2}. Kliknij tutaj.
lineJumps=Line jumps
linkAccountRequired=Jeśli diagram nie jest publiczny, wymagane jest konto Google, by zobaczyć link.
linkText=Hiperłącze tekstu
list=Lista

View file

@ -373,6 +373,7 @@ lessThanAMinute=menos de um minuto
licensingError=Erro de licenciamento
licenseHasExpired=A licença para {1} expirou em {2}. Clique aqui.
licenseWillExpire=A licença para {1} irá expirar em {2}. Clique aqui.
lineJumps=Line jumps
linkAccountRequired=Se o diagrama não é público é necessário ter uma conta no Google para visualizar o link.
linkText=Texto do link
list=Lista

View file

@ -373,6 +373,7 @@ lessThanAMinute=menos de um minuto
licensingError=Erro de licença
licenseHasExpired=A licença para {1} expirou em {2}. Carregar aqui.
licenseWillExpire=A licença para {1} expira em {2}. Carregar aqui.
lineJumps=Line jumps
linkAccountRequired=Se o diagrama não é público é necessário ter uma conta no Google para ver o link.
linkText=Texto do link
list=Lista

View file

@ -373,6 +373,7 @@ lessThanAMinute=mai puţin de un minut
licensingError=Eroare la licențiere
licenseHasExpired=Licența pentru {1} a expirat pe {2}, Apăsați aici.
licenseWillExpire=Licența pentru {1} va expira pe {2}, Apăsați aici.
lineJumps=Line jumps
linkAccountRequired=Dacă diagrama nu este public, un cont Google este necesar pentru a deschide acest link.
linkText=Textul linkului
list=Listă

View file

@ -373,6 +373,7 @@ lessThanAMinute=меньше минуты
licensingError=Ошибка лицензирования
licenseHasExpired=Лицензия на {1} истекла {2}. Нажмите сюда.
licenseWillExpire=Лицензия на {1} истекает {2}. Нажмите сюда.
lineJumps=Line jumps
linkAccountRequired=Если диаграмма не опубликована, для просмотра понадобится войти в учетную запись Google.
linkText=Текст ссылки
list=Список

View file

@ -373,6 +373,7 @@ lessThanAMinute=less than a minute
licensingError=Licensing Error
licenseHasExpired=The license for {1} has expired on {2}. Click here.
licenseWillExpire=The license for {1} will expire on {2}. Click here.
lineJumps=Line jumps
linkAccountRequired=If the diagram is not public a Google account is required to view the link.
linkText=Link Text
list=List

View file

@ -373,6 +373,7 @@ lessThanAMinute=less than a minute
licensingError=Licensing Error
licenseHasExpired=The license for {1} has expired on {2}. Click here.
licenseWillExpire=The license for {1} will expire on {2}. Click here.
lineJumps=Line jumps
linkAccountRequired=If the diagram is not public a Google account is required to view the link.
linkText=Link Text
list=List

View file

@ -373,6 +373,7 @@ lessThanAMinute=manje od minut
licensingError=Licensing Error
licenseHasExpired=The license for {1} has expired on {2}. Click here.
licenseWillExpire=The license for {1} will expire on {2}. Click here.
lineJumps=Line jumps
linkAccountRequired=If the diagram is not public a Google account is required to view the link.
linkText=Link Text
list=List

View file

@ -373,6 +373,7 @@ lessThanAMinute=mindre än en minut
licensingError=Ett fel uppstod med licensen
licenseHasExpired=Licensen för {1} utgick den {2}. Klicka här.
licenseWillExpire=Licensen för {1} kommer utgå den {2}. Klicka här.
lineJumps=Line jumps
linkAccountRequired=Om inte diagrammet är offentligt krävs ett Googlekonto för att visa länken.
linkText=Länktext
list=Lista

View file

@ -373,6 +373,7 @@ lessThanAMinute=less than a minute
licensingError=Licensing Error
licenseHasExpired=The license for {1} has expired on {2}. Click here.
licenseWillExpire=The license for {1} will expire on {2}. Click here.
lineJumps=Line jumps
linkAccountRequired=If the diagram is not public a Google account is required to view the link.
linkText=Link Text
list=List

View file

@ -373,6 +373,7 @@ lessThanAMinute=less than a minute
licensingError=Licensing Error
licenseHasExpired=The license for {1} has expired on {2}. Click here.
licenseWillExpire=The license for {1} will expire on {2}. Click here.
lineJumps=Line jumps
linkAccountRequired=If the diagram is not public a Google account is required to view the link.
linkText=Link Text
list=List

View file

@ -373,6 +373,7 @@ lessThanAMinute=less than a minute
licensingError=Licensing Error
licenseHasExpired=The license for {1} has expired on {2}. Click here.
licenseWillExpire=The license for {1} will expire on {2}. Click here.
lineJumps=Line jumps
linkAccountRequired=If the diagram is not public a Google account is required to view the link.
linkText=Link Text
list=List

View file

@ -373,6 +373,7 @@ lessThanAMinute=น้อยกว่าหนึ่งนาที
licensingError=ข้อผิดพลาดในการให้สิทธิ์
licenseHasExpired=ใบอนุญาตของ {1} หมดอายุแล้วเมื่อ {2} คลิกที่นี่
licenseWillExpire=ใบอนุุญาตของ {1} จะหมดอายุเมื่อ {2} คลิกที่นี่
lineJumps=Line jumps
linkAccountRequired=หากแผนภาพไม่ได้เป็นสาธารณะต้องใช้บัญชี Google เพื่อดูลิงก์
linkText=เชื่อมโยงข้อความ
list=รายการ

View file

@ -373,6 +373,7 @@ lessThanAMinute=bir dakikadan az
licensingError=Lisans hatası
licenseHasExpired={1} için olan lisans {2} tarihinde sona ermiştir. Buraya tıklayınız.
licenseWillExpire={1} için olan lisans {2} tarihinde sona erecektir. Buraya tıklayınız.
lineJumps=Line jumps
linkAccountRequired=Eğer diyagram herkese açık değilse, linki görmek için bir google hesabına gerek vardır
linkText=Metni linkle
list=Listele

View file

@ -373,6 +373,7 @@ lessThanAMinute=менше хвилини
licensingError=Помилка ліцензії
licenseHasExpired=Строк дії ліцензії на {1} завершено {2}. Натисніть тут.
licenseWillExpire=Строк дії ліцензії на {1} завершиться {2}. Натисніть тут.
lineJumps=Line jumps
linkAccountRequired=Якщо діаграма не є публічною, для перегляду посилання необхідно увійти в акаунт Google.
linkText=Текст посилання
list=Список

View file

@ -373,6 +373,7 @@ lessThanAMinute=ít hơn một phút
licensingError=Lỗi cấp phép
licenseHasExpired=Giấy phép của {1} đã hết hạn vào {2}. Nhấn vào đây.
licenseWillExpire=Giấy phép của {1} sẽ hết hạn vào {2}. Nhấn vào đây.
lineJumps=Line jumps
linkAccountRequired=Nếu một biểu đồ không được công khai, bạn cần một tài khoản Google để xem liên kết.
linkText=Liên kết văn bản
list=Danh sách

View file

@ -373,6 +373,7 @@ lessThanAMinute=一分鐘內
licensingError=授權出錯
licenseHasExpired={1}的授權已在{2}過期。請點擊這裡。
licenseWillExpire={1}的授權將在{2}過期。請點擊這裡。
lineJumps=Line jumps
linkAccountRequired=如果圖表非公開則需要Google帳戶才能查看該連結。
linkText=連結文字
list=清單

View file

@ -373,6 +373,7 @@ lessThanAMinute=一分钟以内
licensingError=授权出错
licenseHasExpired={1} 的许可证已于 {2} 过期。请点击此处。
licenseWillExpire={1} 的许可证将于 {2} 过期。请点击此处。
lineJumps=Line jumps
linkAccountRequired=如果图表未公开,则需要提供谷歌账户才能查看该链接。
linkText=链接文本
list=列表

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB