javascript - 使用 Javascript 确定 JSF 库资源

标签 javascript jsf primefaces omnifaces primefaces-extensions

我是 Primefaces Extensions 项目的开发人员,我使用核心 Primefaces JS 函数在 Javascript 中为 DocumentViewer 和 CKEditor 组件获取资源的位置。 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 文件创建 1 个脚本。所以 10 个不同的 JS 文件现在变成了 1 个资源来实现这样的性能......

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

现在这破坏了核心 PrimeFaces 代码,因为它无法查找 core.js,因为页面上不再存在 core.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">

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

最佳答案

我能够重写该方法,使其不假设使用正则表达式在页面上找到了 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;
   },

关于javascript - 使用 Javascript 确定 JSF 库资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51679748/

相关文章:

javascript - JS : Show Pop up box position exactly above tr in table

javascript - 如何通过在 Grails 中选择另一个下拉列表(无需 AJAX)来动态加载一个下拉列表

javascript - 如何在不使用 try/catch(err) 的情况下处理 indexOf 返回 'null' ?

javascript - p :commandButton mull functioning

javascript - 如何在page_load中添加javascript

java - 用户可以设置 JSF 支持 bean 中的哪些属性?

java - 在 Maven 项目中添加 Primefaces 引用?

java - 如何在用户刷新时更新 jsf 列表

java - JSF:我如何将流保存为 webapp 之外的文件以及如何在部署为 war 时访问它

jsf-2 - dataTable 内 JSF 复合组件的唯一 ID