7.1.9 release
This commit is contained in:
parent
1b26c37237
commit
eb74e038aa
83 changed files with 3213 additions and 2109 deletions
|
@ -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
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
7.1.8
|
||||
7.1.9
|
|
@ -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
|
||||
|
|
|
@ -46,6 +46,7 @@ function createWindow (opt = {})
|
|||
'gapi': 0,
|
||||
'od': 0,
|
||||
'gh': 0,
|
||||
'tr': 0,
|
||||
'analytics': 0,
|
||||
'picker': 0,
|
||||
'mode': 'device',
|
||||
|
|
32
war/images/trello-logo.svg
Normal file
32
war/images/trello-logo.svg
Normal file
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
1333
war/js/app.min.js
vendored
File diff suppressed because it is too large
Load diff
180
war/js/atlas-viewer.min.js
vendored
180
war/js/atlas-viewer.min.js
vendored
File diff suppressed because one or more lines are too long
1775
war/js/atlas.min.js
vendored
1775
war/js/atlas.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -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';
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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,
|
||||
|
|
531
war/js/diagramly/TrelloClient.js
Normal file
531
war/js/diagramly/TrelloClient.js
Normal 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();
|
||||
};
|
185
war/js/diagramly/TrelloFile.js
Normal file
185
war/js/diagramly/TrelloFile.js
Normal 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});
|
||||
}
|
||||
};
|
28
war/js/diagramly/TrelloLibrary.js
Normal file
28
war/js/diagramly/TrelloLibrary.js
Normal 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
|
||||
};
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
|
2
war/js/embed-static.min.js
vendored
2
war/js/embed-static.min.js
vendored
|
@ -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/")||
|
||||
|
|
|
@ -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(); }));
|
||||
|
|
|
@ -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);
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
2
war/js/reader.min.js
vendored
2
war/js/reader.min.js
vendored
|
@ -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
180
war/js/viewer.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -373,6 +373,7 @@ lessThanAMinute=по-малко от една минута
|
|||
licensingError=Грешка при лицензирането
|
||||
licenseHasExpired=Лицензът за {1} изтече на {2}. Кликнете тук.
|
||||
licenseWillExpire=Лицензът за {1} ще изтече на {2}. Кликнете тук.
|
||||
lineJumps=Line jumps
|
||||
linkAccountRequired=Ако диаграмата не е публична, е необходим профил в Google, за да видите линка.
|
||||
linkText=Текст на линка
|
||||
list=Списък
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -373,6 +373,7 @@ lessThanAMinute=λιγότερο από ένα λεπτό
|
|||
licensingError=Σφάλμα στην άδεια χρήση
|
||||
licenseHasExpired=Η άδεια χρήσης για {1} έχει λήξει στις {2}. Πατήστε εδώ.
|
||||
licenseWillExpire=Η άδεια χρήσης για {1} θα λήξει στις {2}. Πατήστε εδώ.
|
||||
lineJumps=Line jumps
|
||||
linkAccountRequired=Εάν το διάγραμμα δεν είναι δημόσιο, χρειάζεται λογαριασμός Google για να δείτε τον σύνδεσμο.
|
||||
linkText=Κείμενο συνδέσμου
|
||||
list=Λίστα
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -373,6 +373,7 @@ lessThanAMinute=کمتر از یک دقیقه
|
|||
licensingError=خطای مجوز
|
||||
licenseHasExpired=مجوز مربوط به {1} در {2} منقضی شده است. اینجا کلیک کنید.
|
||||
licenseWillExpire=مجوز مربوط به {1} در {2} منقضی خواهد شد. اینجا کلیک کنید.
|
||||
lineJumps=Line jumps
|
||||
linkAccountRequired=اگر نمودار عمومی نیست، برای مشاهده لینک به حساب گوگل نیاز است.
|
||||
linkText=لینک متن
|
||||
list=لیست
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -373,6 +373,7 @@ lessThanAMinute=פחות מדקה
|
|||
licensingError=שגיאת רישיון
|
||||
licenseHasExpired=הרשיון עבור {1} אינו בתוקף מתאריך {2}. לחץ כאן.
|
||||
licenseWillExpire=תוקף הרשיון עבור {1} יפוג בתאריך {2}. לחץ כאן.
|
||||
lineJumps=Line jumps
|
||||
linkAccountRequired=אם הדיאגרמה אינה ציבורית, נדרש חשבון גוגל כדי לפתוח את הקישור.
|
||||
linkText=טקסט מקושר
|
||||
list=רשימה
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -373,6 +373,7 @@ lessThanAMinute=lessThanAMinute
|
|||
licensingError=licensingError
|
||||
licenseHasExpired=licenseHasExpired
|
||||
licenseWillExpire=licenseWillExpire
|
||||
lineJumps=lineJumps
|
||||
linkAccountRequired=linkAccountRequired
|
||||
linkText=linkText
|
||||
list=list
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -373,6 +373,7 @@ lessThanAMinute=1分以内に
|
|||
licensingError=ライセンス エラー
|
||||
licenseHasExpired=ライセンス{1} は{2}に期限がきれました。 ここをクリックしてください。
|
||||
licenseWillExpire=ライセンス{1} に期限切れになります{2}. ここをクリックしてください。
|
||||
lineJumps=Line jumps
|
||||
linkAccountRequired=図が公式表示されていない場合は、リンクを表示するために Google アカウントが必要です。
|
||||
linkText=リンク テキスト
|
||||
list=リスト
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -373,6 +373,7 @@ lessThanAMinute=방금
|
|||
licensingError=라이선스 오류
|
||||
licenseHasExpired={1} 관련 라이선스가 {2}에 만료되었습니다. 여기를 클릭해 주시기 바랍니다.
|
||||
licenseWillExpire={1} 관련 라이선스가 {2}에 만료될 예정입니다. 여기를 클릭해 주시기 바랍니다.
|
||||
lineJumps=Line jumps
|
||||
linkAccountRequired=다이어그램이 공개상태가 아닌 경우, 링크를 확인하기 위해 구글 계정이 필요합니다.
|
||||
linkText=링크 텍스트
|
||||
list=목록
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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ă
|
||||
|
|
|
@ -373,6 +373,7 @@ lessThanAMinute=меньше минуты
|
|||
licensingError=Ошибка лицензирования
|
||||
licenseHasExpired=Лицензия на {1} истекла {2}. Нажмите сюда.
|
||||
licenseWillExpire=Лицензия на {1} истекает {2}. Нажмите сюда.
|
||||
lineJumps=Line jumps
|
||||
linkAccountRequired=Если диаграмма не опубликована, для просмотра понадобится войти в учетную запись Google.
|
||||
linkText=Текст ссылки
|
||||
list=Список
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -373,6 +373,7 @@ lessThanAMinute=น้อยกว่าหนึ่งนาที
|
|||
licensingError=ข้อผิดพลาดในการให้สิทธิ์
|
||||
licenseHasExpired=ใบอนุญาตของ {1} หมดอายุแล้วเมื่อ {2} คลิกที่นี่
|
||||
licenseWillExpire=ใบอนุุญาตของ {1} จะหมดอายุเมื่อ {2} คลิกที่นี่
|
||||
lineJumps=Line jumps
|
||||
linkAccountRequired=หากแผนภาพไม่ได้เป็นสาธารณะต้องใช้บัญชี Google เพื่อดูลิงก์
|
||||
linkText=เชื่อมโยงข้อความ
|
||||
list=รายการ
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -373,6 +373,7 @@ lessThanAMinute=менше хвилини
|
|||
licensingError=Помилка ліцензії
|
||||
licenseHasExpired=Строк дії ліцензії на {1} завершено {2}. Натисніть тут.
|
||||
licenseWillExpire=Строк дії ліцензії на {1} завершиться {2}. Натисніть тут.
|
||||
lineJumps=Line jumps
|
||||
linkAccountRequired=Якщо діаграма не є публічною, для перегляду посилання необхідно увійти в акаунт Google.
|
||||
linkText=Текст посилання
|
||||
list=Список
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -373,6 +373,7 @@ lessThanAMinute=一分鐘內
|
|||
licensingError=授權出錯
|
||||
licenseHasExpired={1}的授權已在{2}過期。請點擊這裡。
|
||||
licenseWillExpire={1}的授權將在{2}過期。請點擊這裡。
|
||||
lineJumps=Line jumps
|
||||
linkAccountRequired=如果圖表非公開,則需要Google帳戶才能查看該連結。
|
||||
linkText=連結文字
|
||||
list=清單
|
||||
|
|
|
@ -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 |
Loading…
Reference in a new issue