mxGraph源码学习:mxResources

Posted remo0x

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mxGraph源码学习:mxResources相关的知识,希望对你有一定的参考价值。

前面学习mxClient源码的时候,见过这个类的使用,主要是用于加载资源文件用于实现客户端的国际化

1. 资源文件格式

可以使用如下格式命名资源文件,比如graph_zh.txt

文件名:name[_en].properties

如果没有下划线,表示其为默认加载的资源文件。如果客户端使用的语言存在对应的资源文件,则将加载该文件。

资源文件中的项是key=value的格式,值可能会通过get方法获取,没有等号的项会被忽略,以#开头的行是注释行,如下所示:

# 这是注释
alreadyConnected=节点已经连接
这一行将被忽略

值可能包含1 … n形式的占位符,其中每个占位符都替换为传递给mxResources.get的params参数中相应数组元素的值,占位符1映射到数组中的第一个元素(索引0处),占位符使用如下所示:

duplicateIt=副本 1

为了使用Unicode字符,可以使用标准符号,比如\\u8fd1,也可以使用%u作为前缀,比如%u20AC。对于普通的十六进制编码字符串,使用%作为前缀,比如%F6。可以使用resourcesEncoded禁用Unicode,但必须保证资源文件是UTF-8编码。

2. 加载资源文件

资源文件可以直接在resources文件夹中用上述命名格式添加,然后根据客户端语言进行加载,目录结构如下:

resources/
	graph.txt
	graph_de.txt
	graph_zh.txt

也可以通过<source>标签在editor配置文件的UI部分添加(这种方式目前还没见过,后面见到了再补充),下面的元素将会根据客户端语言加载examples/resources/mxWorkflow.properties资源文件:

<mxEditor>
   <ui>
     <resource basename="examples/resources/mxWorkflow"/>

还可以通过mxResources.add方法动态添加资源文件,方法声明如下:

add: function (basename, lan, callback)

默认情况下,客户端在加载时同步添加src/resources下面的两个资源文件。要异步加载这些文件,可以在加载mxClient.js之前将mxLoadResources设置为false,然后使用mxResources.loadResources添加资源文件。

3. 属性

mxResources类中只定义了五个属性:

// 包含资源文件中键值对的map
resources: ,

// 指定资源文件的后缀。默认为mxResourceExtension
extension: mxResourceExtension,

// 指定是否支持Unicode
resourcesEncoded: false,

// 指定是否加载默认资源文件
loadDefaultBundle: true,

// 指定是否加载特定语言的资源文件
loadSpecialBundle: true,

4. 方法

mxResources定义了一些方法用于加载资源文件:

/**
 * 子类的钩子方法用于禁用对给定语言的支持。如果lan在<mxClient.languages>中,则此实现返回true
 * 
 * lan - 给定的语言
 */
isLanguageSupported: function (lan) 
    if (mxClient.languages != null) 
        return mxUtils.indexOf(mxClient.languages, lan) >= 0;
    

    return true;
,

/**
 * 子类的钩子方法返回默认资源文件的URL,此实现返回basename+<extension>,如果
 * <loadDefaultBundle>为false,则返回null
 * 
 * basename - 将加载的文件的基础名
 * lan - 给定的语言
 */
getDefaultBundle: function (basename, lan) 
    if (mxResources.loadDefaultBundle || !mxResources.isLanguageSupported(lan)) 
        return basename + mxResources.extension;
     else 
        return null;
    
,

/**
 * 子类的钩子用于返回特定资源文件的URL,该实现返回basename+'_'+lan+<extension>。
 * 如果<loadSpecialBundle为false>,或lan等于<mxClient.defaultLanguage>,则返回null
 * 
 * 如果<mxResources.languages>不为null且<mxClient.language>包含破折号,则此方法检查
 * <isLanguageSupported>对完整语言(包括破折号)是否返回true。如果返回false,
 * 则语言的第一部分(直到破折号)将作为扩展名进行尝试。
 * 
 * 如果<mxResources.language>为null,则语言的第一部分用于保持向后兼容性。
 *
 * basename - 将加载的文件的基础名
 * lan - 将要加载的资源文件的语言
 */
getSpecialBundle: function (basename, lan) 
    if (mxClient.languages == null || !this.isLanguageSupported(lan)) 
        var dash = lan.indexOf('-');

        if (dash > 0) 
            lan = lan.substring(0, dash);
        
    

    if (mxResources.loadSpecialBundle && mxResources.isLanguageSupported(lan) && lan != mxClient.defaultLanguage) 
        return basename + '_' + lan + mxResources.extension;
     else 
        return null;
    
,

/**
 * 添加指定基本名的默认和当前语言资源文件。添加新文件时会覆盖现有键值对。
 * 如果没有使用回调,则请求是同步的。
 *
 * basename - 将加载的文件的基础名
 * lan - 将要加载的资源文件的语言
 * callback - 可选的回调函数用于异步加载
 */
add: function (basename, lan, callback) 
    lan = (lan != null) ? lan : ((mxClient.language != null) ?
        mxClient.language.toLowerCase() : mxConstants.NONE);

    if (lan != mxConstants.NONE) 
        var defaultBundle = mxResources.getDefaultBundle(basename, lan);
        var specialBundle = mxResources.getSpecialBundle(basename, lan);

        var loadSpecialBundle = function () 
            if (specialBundle != null) 
                if (callback) 
                    mxUtils.get(specialBundle, function (req) 
                        mxResources.parse(req.getText());
                        callback();
                    , function () 
                        callback();
                    );
                 else 
                    try 
                        var req = mxUtils.load(specialBundle);

                        if (req.isReady()) 
                            mxResources.parse(req.getText());
                        
                     catch (e) 
                        // ignore
                    
                
             else if (callback != null) 
                callback();
            
        ;

        if (defaultBundle != null) 
            if (callback) 
                mxUtils.get(defaultBundle, function (req) 
                    mxResources.parse(req.getText());
                    loadSpecialBundle();
                , function () 
                    loadSpecialBundle();
                );
             else 
                try 
                    var req = mxUtils.load(defaultBundle);

                    if (req.isReady()) 
                        mxResources.parse(req.getText());
                    

                    loadSpecialBundle();
                 catch (e) 
                    // ignore
                
            
         else 
            // Overlays the language specific file (_lan-extension)
            loadSpecialBundle();
        
    
,

/**
 * 解析指定文本中的键值对,并将它们存储为本地资源
 */
parse: function (text) 
    if (text != null) 
        var lines = text.split('\\n');

        for (var i = 0; i < lines.length; i++) 
            // 忽略注释
            if (lines[i].charAt(0) !== '#') 
                var index = lines[i].indexOf('=');

                // 忽略没有等号的行
                if (index > 0) 
                    var key = lines[i].substring(0, index);
                    var idx = lines[i].length;

                    if (lines[i].charCodeAt(idx - 1) === 13) 
                        idx--;
                    

                    var value = lines[i].substring(index + 1, idx);

                    if (this.resourcesEncoded) 
                        value = value.replace(/\\\\(?=u[a-fA-F\\d]4)/g, "%");
                        mxResources.resources[key] = decodeURI(value); // unescape()不能用了
                     else 
                        mxResources.resources[key] = value;
                    
                
            
        
    
,

/**
 * 返回指定资源键对应的值
 *
 * key - 表示要返回的资源的键的字符串
 * params - 在结果字符串中替换形式1 ... n的占位符的值的数组
 * defaultValue - 可选字符串,指定默认返回值
 */
get: function (key, params, defaultValue) 
    var value = mxResources.resources[key];

    // 如果未找到资源,则应用默认值
    if (value == null) 
        value = defaultValue;
    

    // 用数组中的值替换占位符
    if (value != null && params != null) 
        value = mxResources.replacePlaceholders(value, params);
    

    return value;
,

/**
 * 用给定的参数替换给定的占位符
 *
 * value - 包含占位符的字符串
 * params - 在结果字符串中替换形式1 ... n的占位符的值的数组
 */
replacePlaceholders: function (value, params) 
    var result = [];
    var index = null;

    for (var i = 0; i < value.length; i++) 
        var c = value.charAt(i);

        if (c == '') 
            index = '';
         else if (index != null && c == '') 
            index = parseInt(index) - 1;

            if (index >= 0 && index < params.length) 
                result.push(params[index]);
            

            index = null;
         else if (index != null) 
            index += c;
         else 
            result.push(c);
        
    

    return result.join('');
,

/**
 * 异步加载所有必需的资源。如果<mxLoadResources>为false,则用此方法加载graph和editor资源文件
 *
 * callback - 异步加载的回调函数
 */
loadResources: function (callback) 
    mxResources.add(mxClient.basePath + '/resources/editor', null, function () 
        mxResources.add(mxClient.basePath + '/resources/graph', null, callback);
    );

以上是关于mxGraph源码学习:mxResources的主要内容,如果未能解决你的问题,请参考以下文章

mxGraph源码学习:mxGraph

mxGraph源码学习:mxGraph

mxGraph源码学习:mxEventSource

mxGraph源码学习:mxClient

mxGraph源码学习:mxCell

mxGraph源码学习:mxCell