使用Javascript确定JSF库资源
我是Primefaces Extensions项目的开发人员,我使用Primefaces JS核心函数获取DocumentViewer和CKEditor组件的Javascript资源位置。该函数位于PrimeFaces core.js中,如下所示使用Javascript确定JSF库资源,javascript,jsf,primefaces,omnifaces,primefaces-extensions,Javascript,Jsf,Primefaces,Omnifaces,Primefaces Extensions,我是Primefaces Extensions项目的开发人员,我使用Primefaces JS核心函数获取DocumentViewer和CKEditor组件的Javascript资源位置。该函数位于PrimeFaces core.js中,如下所示 /** * Builds a resource URL for given parameters. * * @param {string} name The name of the resource. For exa
/**
* 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扩展名等
问题:
/**
* 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;
},
我正在使用它获取所有JS文件,并从找到的所有JS文件中创建一个脚本。所以10个不同的JS文件现在就成了这样性能的一个资源
/javax.faces.resource/XXX.js.xhtml?ln=omnifaces.combined&v=1532916484000
现在这破坏了core 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>
org.omnifaces.composed\u RESOURCE\u HANDLER\u EXCLUDED\u RESOURCES
primefaces:core.js
在omnifaces.combined.js之后加载PrimeFaces core.js,这会破坏整个页面。要确认输出是否正确,请执行以下操作
<script src="/primeext-showcase/javax.faces.resource/XXX.js.jsf?ln=omnifaces.combined&v=1533319992000"></script>
<script src="/primeext-showcase/javax.faces.resource/core.js.jsf?ln=primefaces&v=6.2">
因此,我的问题是如何使用纯JavaScript替换/修复PrimeFaces.getFacesResource()JS函数,以确定OmniFaces是否合并了脚本?我能够重写该方法,以避免使用正则表达式在页面上找到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;
},
你认为需要“重新定位”core.js的原因是什么?@Kukeltje我在上面添加了“为什么我们需要这个?”一节,以澄清正在做什么以及为什么我们需要它。我仍然不明白为什么需要将core.js分离以加载语言文件。如果将一个参数传递给函数,则其他参数显式为空。也许只是通过一个额外的/显式的库?谢谢伙计们,我能够通过使用更好的正则表达式重写方法来解决这个问题,并在两种情况下对它进行了测试,现在一切都很好。