mxGraph源码学习:mxClient
Posted remo0x
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mxGraph源码学习:mxClient相关的知识,希望对你有一定的参考价值。
1. mxClient.js文件
mxClient.js
是客户端的引导机制,此文件include了运行mxGraph所需的所有源文件,并加载了其依赖的资源文件,以及配置了客户端的语言。
意思就是只要在需要使用mxGraph的地方用<script>
标签加载mxClient.js
即可使用该库。这是一种非常好的做法,不仅能方便的进行开发,还能提供mxClient的压缩版本以提升加载速度。
mxClient.js
的作用如下:
- 设置加载相关文件的全局变量
- 设置相关路径
- 设置客户端语言
- 加载css文件和js文件
1.1 控制加载相关文件
mxClient.js
定义了一些用于控制加载相关文件的全局变量:
// 用于切换<mxGraph>和<mxEditor>中两个资源文件的加载
// 这两个资源文件在resource文件夹中,如果应用已经提供则置false,参照GraphEditor
if (typeof(mxLoadResources) == 'undefined')
mxLoadResources = true;
// 用于指定资源文件的后缀。默认为.txt
if (typeof(mxResourceExtension) == 'undefined')
mxResourceExtension = '.txt';
// 用于强制在开发模式下加载javascript文件。默认为undefined
if (typeof(mxForceIncludes) == 'undefined')
mxForceIncludes = false;
// 用于在初始化库时切换加载CSS文件
if (typeof(mxLoadStylesheets) == 'undefined')
mxLoadStylesheets = true;
1.2 相关路径
还需要设置一些路径,如果没有指定则使用默认值:
// 所有文件的基本路径,不带斜杠。默认为'.'
// 在加载mxClient库之前覆盖此设置,比如mxBasePath='/path/to/core/directory'
if (typeof(mxBasePath) != 'undefined' && mxBasePath.length > 0)
// 去掉斜杠
if (mxBasePath.substring(mxBasePath.length - 1) === '/')
mxBasePath = mxBasePath.substring(0, mxBasePath.length - 1);
mxClient.basePath = mxBasePath;
else
mxClient.basePath = '.';
// 所有图片的基本路径,不带斜杠。默认为<mxClient.basePath> + '/images'
// 在加载mxClient库之前覆盖此设置,比如mxImageBasePath='/path/to/image/directory'
if (typeof(mxImageBasePath) != 'undefined' && mxImageBasePath.length > 0)
// 去掉斜杠
if (mxImageBasePath.substring(mxImageBasePath.length - 1) === '/')
mxImageBasePath = mxImageBasePath.substring(0, mxImageBasePath.length - 1);
mxClient.imageBasePath = mxImageBasePath;
else
mxClient.imageBasePath = mxClient.basePath + '/images';
1.3 配置语言
还支持主动设置客户端的语言,或者检测浏览器的语言以配置其语言:
// 设置客户端的语言,比如en表示英语,de表示德语。默认是en
// 资源文件的格式是使用下划线表示语言,比如graph_zh.txt
// 在加载mxClient库之前覆盖此设置,比如mxLanguage='en'
if (typeof(mxLanguage) != 'undefined' && mxLanguage != null)
mxClient.language = mxLanguage;
else
// 在GraphEditor中必须设置mxLanguage,界面的语言才更改
mxLanguage = (mxClient.IS_IE) ? navigator.userLanguage : navigator.language;
// 中文分简体和繁体,这里只设置简体
mxLanguage = (mxLanguage === 'zh-CN') ? 'zh' : mxLanguage;
mxClient.language = mxLanguage;
// 设置默认语言加载不带下划线的资源文件。默认为en
// 在加载mxClient库之前覆盖此设置,比如mxDefaultLanguage='zh'
if (typeof(mxDefaultLanguage) != 'undefined' && mxDefaultLanguage != null)
mxClient.defaultLanguage = mxDefaultLanguage;
else
mxClient.defaultLanguage = 'en';
// 设置支持的所有语言。默认语言不用添加到列表中
// 在加载mxClient库之前覆盖此设置,比如mxLanguages=['de','it','fr']
if (typeof(mxLanguages) != 'undefined' && mxLanguages != null)
mxClient.languages = mxLanguages;
1.4 加载cs和js文件
开发环境中,将所有代码分成了不同的包便于开发,还需要将它们集中在同一个文件即mxClient.js
中,这样可以在html通过导入一个文件而导入整个库:
// 导入所有样式和命名空间
if (mxLoadStylesheets)
mxClient.link('stylesheet', mxClient.basePath + '/css/common.css');
// 为旧的IE浏览器添加所需的命名空间,样式表和内存处理
if (mxClient.IS_VML)
// 如果支持SVG则使用SVG
if (mxClient.IS_SVG)
mxClient.IS_VML = false;
else
// 允许支持IE8的standards模式,这需要所有VML属性可以直接赋值,比如node.attr=value
// 不能使用setAttribute
if (document.documentMode == 8)
document.namespaces.add(mxClient.VML_PREFIX, 'urn:schemas-microsoft-com:vml', '#default#VML');
document.namespaces.add(mxClient.OFFICE_PREFIX, 'urn:schemas-microsoft-com:office:office', '#default#VML');
else
document.namespaces.add(mxClient.VML_PREFIX, 'urn:schemas-microsoft-com:vml');
document.namespaces.add(mxClient.OFFICE_PREFIX, 'urn:schemas-microsoft-com:office:office');
// IE中有限数量样式表的解决方法(在标准模式下不起作用)
if (mxClient.IS_QUIRKS && document.styleSheets.length >= 30)
(function ()
var node = document.createElement('style');
node.type = 'text/css';
node.styleSheet.cssText = mxClient.VML_PREFIX + '\\\\:*behavior:url(#default#VML)' +
mxClient.OFFICE_PREFIX + '\\\\:*behavior:url(#default#VML)';
document.getElementsByTagName('head')[0].appendChild(node);
)();
else
document.createStyleSheet().cssText = mxClient.VML_PREFIX + '\\\\:*behavior:url(#default#VML)' +
mxClient.OFFICE_PREFIX + '\\\\:*behavior:url(#default#VML)';
if (mxLoadStylesheets)
mxClient.link('stylesheet', mxClient.basePath + '/css/explorer.css');
// 如果通过CommonJS加载脚本,不要将<script>标记写入页面以获取依赖项。这些已经包含在编译版本中
if (mxForceIncludes || !(typeof module === 'object' && module.exports != null))
// PREPROCESSOR-REMOVE-END
mxClient.include(mxClient.basePath + '/js/util/mxLog.js');
mxClient.include(mxClient.basePath + '/js/util/mxObjectIdentity.js');
mxClient.include(mxClient.basePath + '/js/util/mxDictionary.js');
mxClient.include(mxClient.basePath + '/js/util/mxResources.js');
...
mxClient.include(mxClient.basePath + '/js/io/mxDefaultKeyHandlerCodec.js');
mxClient.include(mxClient.basePath + '/js/io/mxDefaultToolbarCodec.js');
mxClient.include(mxClient.basePath + '/js/io/mxDefaultPopupMenuCodec.js');
mxClient.include(mxClient.basePath + '/js/io/mxEditorCodec.js');
// PREPROCESSOR-REMOVE-START
2. mxClient类
mxClient在mxClient.js
文件中是作为一个类定义的,主要的作用如下:
- 说明当前mxGraph的版本号
- 标识客户端的浏览器和操作系统
- 定义检查浏览器是否支持的函数
- 定义加载css文件、js文件和依赖资源的函数
- 保存一些配置相关的变量,比如语言、路径等
2.1 版本号
版本号说明了mxGraph库的当前版本,格式是主版本.次版本.编译号
,如下所示:
VERSION: '3.9.9'
2.2 标识浏览器
标识浏览器的变量如下表所示:
// IE浏览器
IS_IE: navigator.userAgent.indexOf('MSIE') >= 0,
IS_IE6: navigator.userAgent.indexOf('MSIE 6') >= 0,
IS_IE11: !!navigator.userAgent.match(/Trident\\/7\\./),
// 如果是IE浏览器,标识是否是Quirks模式
IS_QUIRKS: navigator.userAgent.indexOf('MSIE') >= 0 &&
(document.documentMode == null || document.documentMode == 5),
// IE11的enterprise模式(IE8的standards模式)
IS_EM: 'spellcheck' in document.createElement('textarea') &&
document.documentMode == 8,
// Edge浏览器
IS_EDGE: !!navigator.userAgent.match(/Edge\\//),
// VML命名空间中结点的前缀,默认为v
VML_PREFIX: 'v',
// VML office命令空间中结点的前缀,默认为o
OFFICE_PREFIX: 'o',
// Netscape浏览器(包括Firefox浏览器)
IS_NS: navigator.userAgent.indexOf('Mozilla/') >= 0 &&
navigator.userAgent.indexOf('MSIE') < 0 &&
navigator.userAgent.indexOf('Edge/') < 0,
// Opera浏览器
IS_OP: navigator.userAgent.indexOf('Opera/') >= 0 ||
navigator.userAgent.indexOf('OPR/') >= 0,
// 如果-o-transform可用作CSS样式,则为True,即基于具有2.5或更高版本的Presto引擎的Opera浏览器。
IS_OT: 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.') < 0,
// Safari浏览器
IS_SF: navigator.userAgent.indexOf('AppleWebKit/') >= 0 &&
navigator.userAgent.indexOf('Chrome/') < 0 &&
navigator.userAgent.indexOf('Edge/') < 0,
// Google Chrome浏览器
IS_GC: navigator.userAgent.indexOf('Chrome/') >= 0 &&
navigator.userAgent.indexOf('Edge/') < 0,
// Chrome App
IS_CHROMEAPP: window.chrome != null &&
chrome.app != null &&
chrome.app.runtime != null,
// Firefox浏览器
IS_FF: navigator.userAgent.indexOf('Firefox/') >= 0,
// 如果-moz-transform可用作CSS样式,则为True。
// 所有基于Firefox的浏览器都是3或者等于3的情况,例如Camino,Iceweasel,Seamonkey和Iceape。
IS_MT: (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.') < 0),
// 浏览器是否支持SVG
IS_SVG: navigator.userAgent.indexOf('Firefox/') >= 0 || // FF and Camino
navigator.userAgent.indexOf('Iceweasel/') >= 0 || // Firefox on Debian
navigator.userAgent.indexOf('Seamonkey/') >= 0 || // Firefox-based
navigator.userAgent.indexOf('Iceape/') >= 0 || // Seamonkey on Debian
navigator.userAgent.indexOf('Galeon/') >= 0 || // Gnome Browser (old)
navigator.userAgent.indexOf('Epiphany/') >= 0 || // Gnome Browser (new)
navigator.userAgent.indexOf('AppleWebKit/') >= 0 || // Safari/Google Chrome
navigator.userAgent.indexOf('Gecko/') >= 0 || // Netscape/Gecko
navigator.userAgent.indexOf('Opera/') >= 0 || // Opera
(document.documentMode != null && document.documentMode >= 9), // IE9+
// 如果foreignObject支持不可用,则为True。 这是Opera,较旧的基于SVG的浏览器和所有版本的IE的情况。
NO_FO: !document.createElementNS ||
document.createElementNS('http://www.w3.org/2000/svg','foreignObject') !=
'[object SVGForeignObjectElement]' ||
navigator.userAgent.indexOf('Opera/') >= 0,
// 浏览器是否支持VML
IS_VML: navigator.appName.toUpperCase() == 'MICROSOFT INTERNET EXPLORER',
2.3 标识系统
标识系统的变量如下所示:
// iPad、iPhone和iPod平台
IS_ios: (navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? true : false),
// Windows系统
IS_WIN: navigator.appVersion.indexOf('Win') > 0,
// Mac系统
IS_MAC: navigator.appVersion.indexOf('Mac') > 0,
// 如果此设备支持touchstart/-move/-end事件,
// 启用触摸的设备上的Apple iOS,android,Chromebook和Chrome浏览器,则为True。
IS_TOUCH: 'ontouchstart' in document.documentElement,
// 如果此设备支持Microsoft指针事件,则为True(在Mac上始终为false)。
IS_POINTER: window.PointerEvent != null && !(navigator.appVersion.indexOf('Mac') > 0),
// 是否是本地运行(如果文档位置不以http://或https://开头,则为True)。
IS_LOCAL: document.location.href.indexOf('http://') < 0 &&
document.location.href.indexOf('https://') < 0,
2.4 浏览器支持
检查浏览器是否支持VML或者SVG,因为mxGraph的cell可以用VML或者SVG在画出来,所以必须要浏览器支持其中一种语言:
isBrowserSupported: function ()
return mxClient.IS_VML || mxClient.IS_SVG;
,
2.5 加载文件
mxClient类中定义了三个函数用于加载css文件、js文件和资源文件。
加载css文件到HTML的head中,link标签的charset固定为UTF-8
,type固定为text/css
:
/**
* rel:link标签的rel属性
* href:link标签的href属性,相对路径
* doc:可选的link标签所属的document
*/
link: function (rel, href, doc)
// 使用指定的document。如果未指定,则使用当前页面的document
doc = doc || document;
// 如果是IE6则直接在head中添加link标签
if (mxClient.IS_IE6)
doc.write('<link rel="' + rel + '" href="' + href + '" charset="UTF-8" type="text/css"/>');
else
var link = doc.createElement('link');
link.setAttribute('rel', rel);
link.setAttribute('href', href);
link.setAttribute('charset', 'UTF-8');
link.setAttribute('type', 'text/css');
var head = doc.getElementsByTagName('head')[0];
head.appendChild(link);
加载js文件到HTML的head中,这个函数只在开发环境中使用,因为在生成环境中使用的是mxClient.min.js
,如下所示:
/**
* src:script标签的src属性,相对路径
*/
include: function (src)
document.write('<script src="' + src + '"></script>');
如果mxLoadResources
全局变量为false,则使用该函数加载mxClient的依赖资源:
/**
* fn:在所有资源文件加载之后调用的函数
* lan:可选的传递给<mxResources.add>的参数
*/
loadResources: function (fn, lan)
// 待加载的资源以上是关于mxGraph源码学习:mxClient的主要内容,如果未能解决你的问题,请参考以下文章