代码之家  ›  专栏  ›  技术社区  ›  Melloware

使用Javascript确定JSF库资源

  •  4
  • Melloware  · 技术社区  · 7 年前

    我是Primefaces扩展项目的开发人员,我使用一个Primefaces JS核心函数来获取DocumentViewer和CKEditor组件的Javascript资源位置。这个 getFacesResource() 函数位于PrimeFaces core.js中,如下所示。。

       /**
         * Builds a resource URL for given parameters.
         *
         * @param {string} name The name of the resource. For example: primefaces.js
         * @param {string} library The library of the resource. For example: primefaces
         * @param {string} version The version of the library. For example: 5.1
         * @returns {string} The resource URL.
         */
    getFacesResource : function(name, library, version) {
        // just get sure - name shoudln't start with a slash
        if (name.indexOf('/') === 0)
        {
            name = name.substring(1, name.length);
        }
    
        var scriptURI = $('script[src*="/' + PrimeFaces.RESOURCE_IDENTIFIER + '/core.js"]').attr('src');
        // portlet
        if (!scriptURI) {
            scriptURI = $('script[src*="' + PrimeFaces.RESOURCE_IDENTIFIER + '=core.js"]').attr('src');
        }
    
        scriptURI = scriptURI.replace('core.js', name);
    

    它所做的是在DOM中找到“core.js”脚本,然后删除core.js,这样它就有了用于查找资源的新URL的正确位置。

    为什么我们要这么做?

    CKEDitor和DocumentViewer组件是复杂的组件,可以加载许多插件、语言文件等。我们不能修改这些插件每次升级时使用的核心JS文件,我们必须编辑它们的核心源代码。因此,为了让DocumentViewer加载语言包,库值有“DocumentViewer/locale/en-GB.locale.txt”来加载DocumentViewer使用的PDF.js的英语语言包。但这需要成为一种真正的资源 PrimeFaces.getFacesResource('documentviewer/locale/en-GB.locale.txt'); 将URL转换为PDF.JS代码可以找到的适当资源,例如:

    https://www.primefaces.org/showcase-ext/javax.faces.resource/documentviewer/locale/en-GB.locale.txt.jsf?ln=primefaces-extensions&v=6.2.5
    

    它处理知道完整的URL、附加库版本以及知道当前服务器是服务于.jsf还是.xhtml扩展等等。

    问题:

    我在用 OmniFaces CombinedResourceHandler 它获取所有JS文件,并从找到的所有JS文件中创建一个脚本。所以10个不同的JS文件现在变成了1个这样的性能资源。。。

    /javax.faces.resource/XXX.js.xhtml?ln=omnifaces.combined&v=1532916484000
    

    现在,这会破坏核心PrimeFrices代码,因为它不能查找Cy.js,因为Cal.js不再存在于页面上。

    我试着用这个开关排除core.js。。

    <context-param>
        <param-name>org.omnifaces.COMBINED_RESOURCE_HANDLER_EXCLUDED_RESOURCES</param-name>
        <param-value>primefaces:core.js</param-value>
    </context-param>
    

    它在omnifaces.combined.js之后加载PrimeFaces core.js,这会破坏整个页面。要确认输出是。。。

    <script src="/primeext-showcase/javax.faces.resource/XXX.js.jsf?ln=omnifaces.combined&amp;v=1533319992000"></script>
    <script src="/primeext-showcase/javax.faces.resource/core.js.jsf?ln=primefaces&amp;v=6.2">
    

    所以我的问题是如何用纯JavaScript替换/修复PrimeFaces.getFacesResource()JS函数,以确定OmniFaces是否合并了脚本?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Melloware    7 年前

    我可以重写该方法,以避免假定在页面上使用正则表达式找到core.js。它现在在PrimeFaces处于正常模式时工作,如果使用OmniFaces CombinedResourceHandler,它将工作。我会把这个作为补丁提交给PrimeFaces。

    以下是最终的工作方法:

    /**
        * Builds a resource URL for given parameters.
        * 
        * @param {string}
        *        name The name of the resource. For example: primefaces.js
        * @param {string}
        *        library The library of the resource. For example: primefaces
        * @param {string}
        *        version The version of the library. For example: 5.1
        * @returns {string} The resource URL.
        */
       getFacesResource : function(name, library, version) {
          // just get sure - name shoudln't start with a slash
          if (name.indexOf('/') === 0) {
             name = name.substring(1, name.length);
          }
    
          // find any JS served JSF resource
          var scriptURI = $('script[src*="/' + PrimeFaces.RESOURCE_IDENTIFIER + '/"]').first().attr('src');
          // portlet
          if (!scriptURI) {
            scriptURI = $('script[src*="' + PrimeFaces.RESOURCE_IDENTIFIER + '="]').first().attr('src');
          }
    
          // find script...normal is '/core.js' and portlets are '=core.js'
          var scriptRegex = new RegExp('\\/' + PrimeFaces.RESOURCE_IDENTIFIER + '(\\/|=)(.*?)\\.js');
    
          // find script to replace e.g. 'core.js'
          var currentScriptName = scriptRegex.exec(scriptURI)[2] + '.js';
    
          // replace core.js with our custom name
          scriptURI = scriptURI.replace(currentScriptName, name);
    
          // find the library like ln=primefaces
          var libraryRegex = new RegExp('[?&]([^&=]*)ln=(.*?)(&|$)');
    
          // find library to replace e.g. 'ln=primefaces'
          var currentLibraryName = 'ln=' + libraryRegex.exec(scriptURI)[2];
    
          // In a portlet environment, url parameters may be namespaced.
          var namespace = '';
          var urlParametersAreNamespaced = !(scriptURI.indexOf('?' + currentLibraryName) > -1 || scriptURI.indexOf('&'
                + currentLibraryName) > -1);
    
          if (urlParametersAreNamespaced) {
             namespace = new RegExp('[?&]([^&=]+)' + currentLibraryName + '($|&)').exec(scriptURI)[1];
          }
    
          // If the parameters are namespaced, the namespace must be included
          // when replacing parameters.
          scriptURI = scriptURI.replace(namespace + currentLibraryName, namespace + 'ln=' + library);
    
          if (version) {
             var extractedVersion = new RegExp('[?&]' + namespace + 'v=([^&]*)').exec(scriptURI)[1];
             scriptURI = scriptURI.replace(namespace + 'v=' + extractedVersion, namespace + 'v=' + version);
          }
    
          var prefix = window.location.protocol + '//' + window.location.host;
          return scriptURI.indexOf(prefix) >= 0 ? scriptURI : prefix + scriptURI;
       },
    
    推荐文章