drawio.io secondary development pit record

Posted by holladb on Fri, 01 Oct 2021 20:27:11 +0200

drawio.io secondary development tutorial

Secondary development

basic data

Import ide

Add local and oss storage
Pure front-end function
Introduction to various modification positions

Modify code

Prepare environment

git clone  https://github.com/jgraph/drawio.git
cd drawid-dev\src\main\webapp  
python -m http.server 8081  

The project uses the packaged app.min.js by default. If you need to modify the code, you need to add dev=1 to the request parameter

At the same time, you need to modify index.html line:245 to comment out the remote address, otherwise the local modified js will not be requested in the test environment

if (urlParams['dev'] == '1')
{
	// Used to request grapheditor/mxgraph sources in dev mode
	var mxDevUrl = document.location.protocol ; //+ '//devhost.jgraph.com/drawio/src/main';
	
	// Used to request draw.io sources in dev mode
	var drawDevUrl = document.location.protocol ; //+ '//devhost.jgraph.com/drawio/src/main/webapp/';

Everything is ready

Modify menu

Menu related settings are in JS / diagrammatically / menus.js
To delete the file -- > share... Function

Search JS / diagrammatically / menus.js for share... As follows, just comment out the code

/*
	this.editorUi.actions.addAction('share...', mxUtils.bind(this, function()
	{
		try
		{
			var file = editorUi.getCurrentFile();
			
			if (file != null)
			{
				file.share();
			}
		}
		catch (e)
		{
			editorUi.handleError(e);
		}
	}));
*/

The same is true for modifying the function code. For example, change the share... Button to open Baidu, and the corresponding code is as follows

this.editorUi.actions.addAction('share...', mxUtils.bind(this, function()
{
	editorUi.openLink('https://www.baidu.com/',"_blank")

}));

You can view various variable information in the browser console, such as

console.log(mxResources.get('url'))

Modification takes effect

You cannot use dev mode every time, so you need to package the modified file

cd drawio/etc/build
ant 

Specific function realization

The SQL to ER box pops up by default

Discovery menu

Adjust drawing -> insert -> senior -> SQL... 

This function is very interesting. You can directly convert SQL statements into ER diagrams

However, this path is too long. You need to select several menus to find this function

How to open the page and pop up the edit box by default?

  • First find the original function
Adjust drawing -> insert -> senior -> SQL... 

The specific implementation of is in \ SRC \ main \ webapp \ JS \ diagrammatically \ menus.js
Function code

if (method == 'fromText' || method == 'formatSql' ||
						method == 'plantUml' || method == 'mermaid')
{
	var dlg = new ParseDialog(editorUi, title, method);
	editorUi.showDialog(dlg.container, 620, 420, true, false);
	editorUi.dialog.container.style.overflow = 'auto';
	dlg.init();
}

ParseDialog is implemented in \ SRC \ main \ webapp \ JS \ diagrammatically \ dialogs.js

  • splash dialog analysis

There is a splash dialog box by default. Check the implementation in \ SRC \ main \ webapp \ JS \ diagrammatically \ app.js

App.prototype.showSplash = function(force)
{
	
	console.log('show Splash is here');
	//Splash dialog shouldn't be shownn when running without a file menu
	if (urlParams['noFileMenu'] == '1')
	{
		return;	
	}
	
	var serviceCount = this.getServiceCount(true);
	
	var showSecondDialog = mxUtils.bind(this, function()
	{
		var dlg = new SplashDialog(this);  //The dialog box is implemented in \ SRC \ main \ webapp \ JS \ diagrammatically \ dialogs.js 
		

var SplashDialog = function(editorUi)  //You can see that this in app.js is equivalent to editorUi in Dialogs.js 
{
	console.log('dialogs SplashDialog');
	var div = document.createElement('div');
	div.style.textAlign = 'center';

Is a prototype definition, specific calling code

this.showSplash();
  • Add default pop-up function
    Look at the specific implementation of \ SRC \ main \ webapp \ JS \ diagrammatically \ app.js. Add function code at the top
this.load(); //Load many function codes 

//Self adding code 
if (urlParams['sql'] == '1') //If sql=1 exists in the parameter, the pop-up box will start 
{
	var dlg = new ParseDialog(this, 'title', 'formatSql');  //The third-party parameter needs to be specified in which box to pop up 
	this.showDialog(dlg.container, 620, 420, true, false);
	this.dialog.container.style.overflow = 'auto';
	dlg.init();
	console.log('app is here');
}

In this way, the function is basically realized
However, there are splash pop-up boxes by default, which causes the user to open two pop-up boxes. Therefore, the request url parameter is

?splash=0&sql=1 

Add question feedback

The feedback function uses Tencent's Rabbit nest
Change the sharing function in the upper right corner to URL sharing and add a question feedback button

Locate the shared function code in the upper right corner
Click Share - > right click - > check on the interface
See the following picture address in the source code

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8

The search results are defined in SRC \ main \ webapp \ JS \ diagrammatically \ app.js

App.prototype.shareImage =

When viewing shareImage, navigate to

if (this.shareButton == null)
{
	this.shareButton = document.createElement('div');
	this.shareButton.className = 'geBtn gePrimaryBtn';
	this.shareButton.style.display = 'inline-block';
	this.shareButton.style.backgroundColor = '#F2931E';
	this.shareButton.style.borderColor = '#F08705';
	this.shareButton.style.backgroundImage = 'none';
	this.shareButton.style.padding = '2px 10px 0 10px';
	this.shareButton.style.marginTop = '-10px';
	this.shareButton.style.height = '28px';
	this.shareButton.style.lineHeight = '28px';
	this.shareButton.style.minWidth = '0px';
	this.shareButton.style.cssFloat = 'right';
	this.shareButton.setAttribute('title', mxResources.get('share'));
	
	var icon = document.createElement('img');
	icon.setAttribute('src', this.shareImage);
	icon.setAttribute('align', 'absmiddle');
	icon.style.marginRight = '4px';
	icon.style.marginTop = '-3px';
	this.shareButton.appendChild(icon);
	
	if (!Editor.isDarkMode() && uiTheme != 'atlas')
	{
		this.shareButton.style.color = 'black';
		icon.style.filter = 'invert(100%)';
	}
	
	mxUtils.write(this.shareButton, mxResources.get('share'));
	
	mxEvent.addListener(this.shareButton, 'click', mxUtils.bind(this, function()
	{
		//  Modify to URL function 
		// this.actions.get('share').funct();
			this.actions.get('exportUrl').funct();
	}));
	
	this.buttonContainer.appendChild(this.shareButton);
}

if (this.suggestButton == null)
{
	this.suggestButton = document.createElement('div');
	this.suggestButton.className = 'geBtn gePrimaryBtn';
	this.suggestButton.style.display = 'inline-block';
	this.suggestButton.style.backgroundColor = '#F2931E';
	this.suggestButton.style.borderColor = '#F08705';
	this.suggestButton.style.backgroundImage = 'none';
	this.suggestButton.style.padding = '2px 10px 0 10px';
	this.suggestButton.style.marginTop = '-10px';
	this.suggestButton.style.height = '28px';
	this.suggestButton.style.lineHeight = '28px';
	this.suggestButton.style.minWidth = '0px';
	this.suggestButton.style.cssFloat = 'right';
	this.suggestButton.setAttribute('title', mxResources.get('suggestion'));
	
	var icon = document.createElement('img');
	icon.setAttribute('src', this.shareImage);
	icon.setAttribute('align', 'absmiddle');
	icon.style.marginRight = '4px';
	icon.style.marginTop = '-3px';
	this.suggestButton.appendChild(icon);
	
	if (!Editor.isDarkMode() && uiTheme != 'atlas')
	{
		this.suggestButton.style.color = 'black';
		icon.style.filter = 'invert(100%)';
	}
	
	mxUtils.write(this.suggestButton, mxResources.get('suggestion'));
	
	mxEvent.addListener(this.suggestButton, 'click', mxUtils.bind(this, function()
	{
		//  Modify to URL function 
		this.openLink('https://support.qq.com/product/352799');
		
	}));
	
	this.buttonContainer.appendChild(this.suggestButton);
}

dia.txt add suggestion=Suggestion

dia_zh.txt add suggestion = feedback

File menu function modification

  • Remove the synchronize share... Feature
    \SRC \ main \ webapp \ JS \ diagrammatically \ menus.js comment out the following code
//	var item = this.addMenuItem(menu, 'synchronize', parent);
//	this.addLinkToItem(item, 'https://www.diagrams.net/doc/faq/synchronize');
//	this.addMenuItems(menu, ['share', '-'], parent); 

The function is still there, but the function added to the menu is deleted

  • Delete embedded - > Google related functions
    Make the following code replacement
//	this.addMenuItems(menu, ['-', 'googleDocs', 'googleSlides', 'googleSheets', '-', 'microsoftOffice', '-', 'embedNotion'], parent);
	this.addMenuItems(menu, ['-',  'embedNotion'], parent);
  • Delete export as - > PDF function

Because of this function, you need to use the official address, and you don't know what the specific function is. Close it first

// this.addMenuItems(menu, ['exportPdf'], parent);

Help menu modification

Delete Fork me and get desktop version

/*	this.addMenuItems(menu, ['-', 'keyboardShortcuts', 'quickStart',
						'support', '-', 'forkme', 'downloadDesktop', '-', 'about'], parent);
				*/
				this.addMenuItems(menu, ['-', 'keyboardShortcuts', 'quickStart',
						'support', '-',  'about'], parent);

Each time you open the page, you will still be prompted to download the desktop version. This function code is displayed in the

src\main\webapp\js\diagramly\App.js
App.prototype.showDownloadDesktopBanner = function()
{
	/*
	this.showBanner('DesktopFooter', mxResources.get('downloadDesktop'), mxUtils.bind(this, function()
	{
		this.openLink('https://get.diagrams.net/');
	}));
	*/
};

If not, just comment out the code. You can use this function to do other functions, such as viewing tutorials

App.prototype.showDownloadDesktopBanner = function()
{
	this.showBanner('DesktopFooter', mxResources.get('quickStart'), mxUtils.bind(this, function()
	{
		this.openLink(window.quickStart_url);
	}));
};


Add a definition in \ src\main\webapp\js\PreConfig.js

window.quickStart_url = window.location.protocol + '//' + window.location.host + '/gif/index.gif'; 

In Dia_ Modified in zh.txt

downloadDesktop= Quick start video

Modify menu help - > QuickStart

editorUi.actions.addAction('quickStart...', function()
{
	//editorUi.openLink('https://www.youtube.com/watch?v=Z0D96ZikMkc');
	editorUi.openLink(window.quickStart_url);
	
});

Modify menu help - > support

editorUi.actions.addAction('support...', function()
{
	if (EditorUi.isElectronApp)
	{
		//editorUi.openLink('https://github.com/jgraph/drawio-desktop/wiki/Getting-Support');
		editorUi.openLink(window.Support_url);
	}
	else
	{
		//editorUi.openLink('https://github.com/jgraph/drawio/wiki/Getting-Support');
		editorUi.openLink(window.Support_url);
	}
});

Add a definition in \ src\main\webapp\js\PreConfig.js

window.Support_url = 'http://doc.github5.com/drawio/doc/base.html'; 

Language list modification in the upper right corner

Code in

src\main\webapp\js\diagramly\Init.js

window.mxLanguageMap = window.mxLanguageMap ||
{
	'i18n': '',
	'id' : 'Bahasa Indonesia',
	'ms' : 'Bahasa Melayu',
	'bs' : 'Bosanski',
	'bg' : 'Bulgarian',
	'ca' : 'Català',
	'cs' : 'Čeština',
	'da' : 'Dansk',
	'de' : 'Deutsch',
	'et' : 'Eesti',
	'en' : 'English',
	'es' : 'Español',
	'eu' : 'Euskara',
	'fil' : 'Filipino',
	'fr' : 'Français',
	'gl' : 'Galego',
	'it' : 'Italiano',
	'hu' : 'Magyar',
	'nl' : 'Nederlands',
	'no' : 'Norsk',
	'pl' : 'Polski',
	'pt-br' : 'Português (Brasil)',
	'pt' : 'Português (Portugal)',
	'ro' : 'Română',
	'fi' : 'Suomi',
	'sv' : 'Svenska',
	'vi' : 'Tiếng Việt',
	'tr' : 'Türkçe',
	'el' : 'Ελληνικά',
	'ru' : 'Русский',
	'sr' : 'Српски',
	'uk' : 'Українська',
	'he' : 'עברית',
	'ar' : 'العربية',
	'fa' : 'فارسی',
	'th' : 'ไทย',
	'ko' : '한국어',
	'ja' : 'Japanese',
	'zh' : 'Simplified Chinese',
	'zh-tw' : 'Traditional Chinese'
};

Change to   

window.mxLanguageMap = window.mxLanguageMap ||
{
	'en' : 'English',
	'zh' : 'Simplified Chinese',
	'zh-tw' : 'Traditional Chinese'
};

Just keep the required language

Modify notification function

Definition of notification path

src\main\webapp\js\diagramly\Init.js
window.NOTIFICATIONS_URL = window.NOTIFICATIONS_URL ||  'https://www.draw.io/notifications';

src\main\webapp\js\diagramly\App.js

App.prototype.fetchAndShowNotification = function(target)
{
	if (this.fetchingNotif)
	{
		return;	
	}
	
Change to 
App.prototype.fetchAndShowNotification = function(target)
{
	if (this.fetchingNotif)
	{
		
	}
	return;	
	

Home page modification

Modify menu search

Search modified to Baidu
src\main\webapp\js\diagramly\Menus.js

// this.editorUi.openLink('https://www.diagrams.net/search?search=' +
							encodeURIComponent(term));
//this.editorUi.openLink('https://www.google.com/search?q=site%3Adiagrams.net+inurl%3A%2Fdoc%2Ffaq%2F+' +
			//	encodeURIComponent(term));
this.editorUi.openLink('https://www.baidu.com/s?wd=site%3Agithub5.com+' + encodeURIComponent(term));

Home page error

Sometimes a dialog box is prompted when the page is opened
Error loading file and No file selected
As a result, it cannot be used. Locate the code according to the keyword
src\main\webapp\js\diagramly\App.js

if (this.editor.isChromelessView())
	{  
		this.handleError({message: mxResources.get('noFileSelected')},
			mxResources.get('errorLoadingFile'), mxUtils.bind(this, function()
		{
			this.showSplash();
		}));
	}

But I don't know when the isChromelessView is set to true? Comment out this section for a while, but it will report an error after running for a period of time

The final result is \ src\main\webapp\js\PreConfig.js

window.EXPORT_URL = 'REPLACE_WITH_YOUR_IMAGE_SERVER';
window.PLANT_URL = 'REPLACE_WITH_YOUR_PLANTUML_SERVER';
window.DRAWIO_BASE_URL = window.location.protocol + '//' + window.location.host; // Replace with path to base of deployment, e.g. https://www.example.com/folder
window.DRAWIO_VIEWER_URL = window.location.protocol + '//' + window.location.host + '/js/viewer.min.js'; // Replace your path to the viewer js, e.g.
window.DRAWIO_LIGHTBOX_URL = null; // window.location.protocol + '//' + window.location.host; // Replace with your lightbox URL, eg. https://www.example.com
window.DRAW_MATH_URL = 'math';
window.DRAWIO_CONFIG = null; // Replace with your custom draw.io configurations. For more details, https://www.diagrams.net/doc/faq/configure-diagram-editor
window.quickStart_url = window.location.protocol + '//' + window.location.host + '/gif/index.gif'; 
window.Support_url = 'http://doc.github5.com/drawio/doc/base.html'; 
urlParams['sync'] = 'manual';
urlParams['lang'] = 'en';
urlParams['browser'] = 1;
urlParams['gapi'] = 0;
urlParams['db'] = 0;
urlParams['od'] = 0; 
urlParams['tr'] = 0;
urlParams['gh'] =0; 
urlParams['gl'] =0;
urlParams['mode'] = 'browser';

window.DRAWIO_ LIGHTBOX_ The URL cannot be changed. It must be window.DRAWIO_LIGHTBOX_URL =null

Analysis reason:
\SRC \ main \ webapp \ JS \ diagrammatically \ init.js uses this variable

// Uses lightbox mode on viewer domain
if (window.location.hostname == DRAWIO_LIGHTBOX_URL.substring(DRAWIO_LIGHTBOX_URL.indexOf('//') + 2))
{
	urlParams['lightbox'] = '1';
}	

// Lightbox enables chromeless mode
if (urlParams['lightbox'] == '1')
{
	urlParams['chrome'] = '0';
}


Will enter lightbox mode, official explanation:

lightbox=1: Uses the lightbox in chromeless mode (larger zoom, no page visible, chromeless).

So first

urlParams['lightbox'] = '1'; 

Comment out

Deploy Online

Finally online

final Online drawing address

All subfolders of the js directory can be deleted

TODO

Unfinished business

  • Learning of plug-ins and other functions

  • Support server storage

  • Advanced features tutorial

communication

drawio secondary development exchange

Reference documents

drawio official documents

Excellent secondary development project of drawio

drawio encoding and decryption tool

drawio tutorial

drawio draw flow chart

Topics: Javascript node.js SQL drawio