[xwiki-devs] [PROPOSAL] Change the webjars URL mapping
Hi, Currently, the webjars URL mapping is the following: http://localhost:8080/xwiki/bin/webjars/resources/path?value= <id>%2F<version>%2F<filePath> Example: $services.webjars.url('codemirror', 'lib/codemirror.js') returns http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5.... The problem with this is that require modules that use relative paths for their dependencies are broken because of the URL mapping we use, more specifically by the "?" character inside the URL we use. A concrete example is the CodeMirror webjar that defines its own modules which express their dependencies relatively: "../../lib/codemirror" Here we have a problem, since if we directly depend on "$services.webjars.url('codemirror', 'mode/css/css.js')", the module will fail to find its relatively defined dependency. One approach would be to define paths, so that requirejs can work its magic: require.config({ paths: { cm : " http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5.... " } }); require(["cm/lib/codemirror", "cm/mode/css/css"], function (CodeMirror) { console.log(CodeMirror); }); This properly finds "/lib/codemirror.js" and "mode/css/css.js" that we explicitly request, however, the internal dependency of css.js fails to be found at the resolved URL " http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5.... ". Requirejs does not add the ".js" extension to the resolved path because the resolved path contains a "?" character so it is considered an absolute URL, not a relative path. The proposal is to stop using this URL mapping, since it is awkward to have paths in parameters and, instead, use a more intuitive one that is both good for clients and for requirejs. The proposed mapping/scheme is: http://localhost:8080/xwiki/bin/webjars/<id>/<version>/<filePath> Any additional parameters that we might need for the webjars action would be appended at the end. There is currently 1 case that I know of, which is "evaluate=true|false". Without this change, I can not find any solution to using a webjar such as CodeMirror that uses relative defined modules. Thanks, Eduard P.S.: Any additional advice on using requirejs to circumvent this limitation is most than welcomed.
See http://jira.xwiki.org/browse/XWIKI-10881 Thanks, Marius On Fri, Apr 3, 2015 at 7:38 PM, Eduard Moraru <enygma2002@gmail.com> wrote:
Hi,
Currently, the webjars URL mapping is the following:
http://localhost:8080/xwiki/bin/webjars/resources/path?value= <id>%2F<version>%2F<filePath>
Example: $services.webjars.url('codemirror', 'lib/codemirror.js') returns http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5....
The problem with this is that require modules that use relative paths for their dependencies are broken because of the URL mapping we use, more specifically by the "?" character inside the URL we use.
A concrete example is the CodeMirror webjar that defines its own modules which express their dependencies relatively: "../../lib/codemirror"
Here we have a problem, since if we directly depend on "$services.webjars.url('codemirror', 'mode/css/css.js')", the module will fail to find its relatively defined dependency.
One approach would be to define paths, so that requirejs can work its magic:
require.config({ paths: { cm : " http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5.... " } });
require(["cm/lib/codemirror", "cm/mode/css/css"], function (CodeMirror) { console.log(CodeMirror); });
This properly finds "/lib/codemirror.js" and "mode/css/css.js" that we explicitly request, however, the internal dependency of css.js fails to be found at the resolved URL " http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5.... ".
Requirejs does not add the ".js" extension to the resolved path because the resolved path contains a "?" character so it is considered an absolute URL, not a relative path.
The proposal is to stop using this URL mapping, since it is awkward to have paths in parameters and, instead, use a more intuitive one that is both good for clients and for requirejs.
The proposed mapping/scheme is:
http://localhost:8080/xwiki/bin/webjars/<id>/<version>/<filePath>
Any additional parameters that we might need for the webjars action would be appended at the end. There is currently 1 case that I know of, which is "evaluate=true|false".
Without this change, I can not find any solution to using a webjar such as CodeMirror that uses relative defined modules.
Thanks, Eduard
P.S.: Any additional advice on using requirejs to circumvent this limitation is most than welcomed. _______________________________________________ devs mailing list devs@xwiki.org http://lists.xwiki.org/mailman/listinfo/devs
+1 requirejs is insane for fishing around in the URL and making decisions about it but webjars is insane for encoding path information in a parameter. XWIKI-10881 is refactoring which is orthogonal to this issue. Thanks, Caleb On 04/03/2015 07:09 PM, Marius Dumitru Florea wrote:
See http://jira.xwiki.org/browse/XWIKI-10881
Thanks, Marius
On Fri, Apr 3, 2015 at 7:38 PM, Eduard Moraru <enygma2002@gmail.com> wrote:
Hi,
Currently, the webjars URL mapping is the following:
http://localhost:8080/xwiki/bin/webjars/resources/path?value= <id>%2F<version>%2F<filePath>
Example: $services.webjars.url('codemirror', 'lib/codemirror.js') returns http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5....
The problem with this is that require modules that use relative paths for their dependencies are broken because of the URL mapping we use, more specifically by the "?" character inside the URL we use.
A concrete example is the CodeMirror webjar that defines its own modules which express their dependencies relatively: "../../lib/codemirror"
Here we have a problem, since if we directly depend on "$services.webjars.url('codemirror', 'mode/css/css.js')", the module will fail to find its relatively defined dependency.
One approach would be to define paths, so that requirejs can work its magic:
require.config({ paths: { cm : " http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5.... " } });
require(["cm/lib/codemirror", "cm/mode/css/css"], function (CodeMirror) { console.log(CodeMirror); });
This properly finds "/lib/codemirror.js" and "mode/css/css.js" that we explicitly request, however, the internal dependency of css.js fails to be found at the resolved URL " http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5.... ".
Requirejs does not add the ".js" extension to the resolved path because the resolved path contains a "?" character so it is considered an absolute URL, not a relative path.
The proposal is to stop using this URL mapping, since it is awkward to have paths in parameters and, instead, use a more intuitive one that is both good for clients and for requirejs.
The proposed mapping/scheme is:
http://localhost:8080/xwiki/bin/webjars/<id>/<version>/<filePath>
Any additional parameters that we might need for the webjars action would be appended at the end. There is currently 1 case that I know of, which is "evaluate=true|false".
Without this change, I can not find any solution to using a webjar such as CodeMirror that uses relative defined modules.
Thanks, Eduard
P.S.: Any additional advice on using requirejs to circumvent this limitation is most than welcomed. _______________________________________________ devs mailing list devs@xwiki.org http://lists.xwiki.org/mailman/listinfo/devs
devs mailing list devs@xwiki.org http://lists.xwiki.org/mailman/listinfo/devs
-- Satire is the escape hatch from the cycle of sorrow, hatred and violence. #JeSuisCharlie
Hi Eduard, AFAIK, Vincent is actively working on a fix that will allow to fix this and support more URL mappings. You should see with him about his work in progress. Regards, On Fri, Apr 3, 2015 at 6:38 PM, Eduard Moraru <enygma2002@gmail.com> wrote:
Hi,
Currently, the webjars URL mapping is the following:
http://localhost:8080/xwiki/bin/webjars/resources/path?value= <id>%2F<version>%2F<filePath>
Example: $services.webjars.url('codemirror', 'lib/codemirror.js') returns
http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5....
The problem with this is that require modules that use relative paths for their dependencies are broken because of the URL mapping we use, more specifically by the "?" character inside the URL we use.
A concrete example is the CodeMirror webjar that defines its own modules which express their dependencies relatively: "../../lib/codemirror"
Here we have a problem, since if we directly depend on "$services.webjars.url('codemirror', 'mode/css/css.js')", the module will fail to find its relatively defined dependency.
One approach would be to define paths, so that requirejs can work its magic:
require.config({ paths: { cm : "
http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5.... " } });
require(["cm/lib/codemirror", "cm/mode/css/css"], function (CodeMirror) { console.log(CodeMirror); });
This properly finds "/lib/codemirror.js" and "mode/css/css.js" that we explicitly request, however, the internal dependency of css.js fails to be found at the resolved URL "
http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5.... ".
Requirejs does not add the ".js" extension to the resolved path because the resolved path contains a "?" character so it is considered an absolute URL, not a relative path.
The proposal is to stop using this URL mapping, since it is awkward to have paths in parameters and, instead, use a more intuitive one that is both good for clients and for requirejs.
The proposed mapping/scheme is:
http://localhost:8080/xwiki/bin/webjars/<id>/<version>/<filePath>
Any additional parameters that we might need for the webjars action would be appended at the end. There is currently 1 case that I know of, which is "evaluate=true|false".
Without this change, I can not find any solution to using a webjar such as CodeMirror that uses relative defined modules.
Thanks, Eduard
P.S.: Any additional advice on using requirejs to circumvent this limitation is most than welcomed. _______________________________________________ devs mailing list devs@xwiki.org http://lists.xwiki.org/mailman/listinfo/devs
-- Denis Gervalle SOFTEC sa - CEO
Hi, On 3 Apr 2015 at 19:27:14, Denis Gervalle (dgl@softec.lu(mailto:dgl@softec.lu)) wrote:
Hi Eduard,
AFAIK, Vincent is actively working on a fix that will allow to fix this and support more URL mappings. You should see with him about his work in progress.
Actually we talked about it on IRC. I’m working on adding the ability to register new resource types (the “bin”, “rest”, “xmlrpc”, etc part of the URL). The WebJar URL format is independent of my work actually (the only consequence of my work on webjar urls is the start of the URL, i.e. http://<server>/<context path>/webjars/[rest of URL]). Thanks -Vincent
Regards,
On Fri, Apr 3, 2015 at 6:38 PM, Eduard Moraru wrote:
Hi,
Currently, the webjars URL mapping is the following:
http://localhost:8080/xwiki/bin/webjars/resources/path?value= %2F%2F
Example: $services.webjars.url('codemirror', 'lib/codemirror.js') returns
http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5....
The problem with this is that require modules that use relative paths for their dependencies are broken because of the URL mapping we use, more specifically by the "?" character inside the URL we use.
A concrete example is the CodeMirror webjar that defines its own modules which express their dependencies relatively: "../../lib/codemirror"
Here we have a problem, since if we directly depend on "$services.webjars.url('codemirror', 'mode/css/css.js')", the module will fail to find its relatively defined dependency.
One approach would be to define paths, so that requirejs can work its magic:
require.config({ paths: { cm : "
http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5.... " } });
require(["cm/lib/codemirror", "cm/mode/css/css"], function (CodeMirror) { console.log(CodeMirror); });
This properly finds "/lib/codemirror.js" and "mode/css/css.js" that we explicitly request, however, the internal dependency of css.js fails to be found at the resolved URL "
http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5.... ".
Requirejs does not add the ".js" extension to the resolved path because the resolved path contains a "?" character so it is considered an absolute URL, not a relative path.
The proposal is to stop using this URL mapping, since it is awkward to have paths in parameters and, instead, use a more intuitive one that is both good for clients and for requirejs.
The proposed mapping/scheme is:
http://localhost:8080/xwiki/bin/webjars///
Any additional parameters that we might need for the webjars action would be appended at the end. There is currently 1 case that I know of, which is "evaluate=true|false".
Without this change, I can not find any solution to using a webjar such as CodeMirror that uses relative defined modules.
Thanks, Eduard
P.S.: Any additional advice on using requirejs to circumvent this limitation is most than welcomed. _______________________________________________ devs mailing list devs@xwiki.org http://lists.xwiki.org/mailman/listinfo/devs
-- Denis Gervalle SOFTEC sa - CEO _______________________________________________ devs mailing list devs@xwiki.org http://lists.xwiki.org/mailman/listinfo/devs
Hi Edy, I don’t enough about requirejs to make an educated answer on this part so my answer is only about the new proposed format. PROs: * possibly a bit better for end users CONs: * not restful (I think) * we mix the resource name with the rest of the URL (semantic mixing) * by mixing the resource name with the rest of the URL we need to reparse the URL to reconstruct the resource name Let me give more information by what I mean on these last 2 points. Right now when we have a URL our ExtendedURL class parses the URL by parsing the path portions and storing them into a List. So if we have http:////path1/path2/path3, we get [“path1”, “path2”, “path3]. If we wish to get the resource name we need to [“path1”, “path2”, “path3].join(“/“). In addition I also find it more logical that the resourcename be a BLOB for which we don’t know the structure (whether it’s separated by “/“ or “.” or anything else, we shouldn’t care about). The way we load the resource is by doing a ClassLoader.getResourceAsStream(resourceName). Said differently it’s by pure chance that we have both “/“ for loading a classloader resource and as a separator for a URL! So I don’t want to block your proposal but it’s seems we’re mixing apples and oranges and I’m not sure it’s a good thing. I’m curious to know what others think. Thanks -Vincent On 3 Apr 2015 at 18:39:09, Eduard Moraru (enygma2002@gmail.com(mailto:enygma2002@gmail.com)) wrote:
Hi,
Currently, the webjars URL mapping is the following:
http://localhost:8080/xwiki/bin/webjars/resources/path?value= %2F%2F
Example: $services.webjars.url('codemirror', 'lib/codemirror.js') returns http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5....
The problem with this is that require modules that use relative paths for their dependencies are broken because of the URL mapping we use, more specifically by the "?" character inside the URL we use.
A concrete example is the CodeMirror webjar that defines its own modules which express their dependencies relatively: "../../lib/codemirror"
Here we have a problem, since if we directly depend on "$services.webjars.url('codemirror', 'mode/css/css.js')", the module will fail to find its relatively defined dependency.
One approach would be to define paths, so that requirejs can work its magic:
require.config({ paths: { cm : " http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5.... " } });
require(["cm/lib/codemirror", "cm/mode/css/css"], function (CodeMirror) { console.log(CodeMirror); });
This properly finds "/lib/codemirror.js" and "mode/css/css.js" that we explicitly request, however, the internal dependency of css.js fails to be found at the resolved URL " http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5.... ".
Requirejs does not add the ".js" extension to the resolved path because the resolved path contains a "?" character so it is considered an absolute URL, not a relative path.
The proposal is to stop using this URL mapping, since it is awkward to have paths in parameters and, instead, use a more intuitive one that is both good for clients and for requirejs.
The proposed mapping/scheme is:
http://localhost:8080/xwiki/bin/webjars///
Any additional parameters that we might need for the webjars action would be appended at the end. There is currently 1 case that I know of, which is "evaluate=true|false".
Without this change, I can not find any solution to using a webjar such as CodeMirror that uses relative defined modules.
Thanks, Eduard
P.S.: Any additional advice on using requirejs to circumvent this limitation is most than welcomed.
Hi Vincent, On Fri, Apr 3, 2015 at 11:18 PM, vincent@massol.net <vincent@massol.net> wrote:
Hi Edy,
I don’t enough about requirejs to make an educated answer on this part so my answer is only about the new proposed format.
PROs: * possibly a bit better for end users
CONs: * not restful (I think)
But isn't it much more restful than the current http://localhost:8080/xwiki/bin/webjars/resources/path?value=<id>%2F<version>%2F<filePath> ?
* we mix the resource name with the rest of the URL (semantic mixing)
IMO, the ID (if this is what you refer to as resource name) should always be between 2 "/"es. If the resource name contains a "/" itself, then it should be URL escaped by the caller. If by resource name you mean the entire "value=<id>%2F<version>%2F<filePath>" part, see below.
* by mixing the resource name with the rest of the URL we need to reparse the URL to reconstruct the resource name
Let me give more information by what I mean on these last 2 points. Right now when we have a URL our ExtendedURL class parses the URL by parsing the path portions and storing them into a List. So if we have http:////path1/path2/path3, we get [“path1”, “path2”, “path3]. If we wish to get the resource name we need to [“path1”, “path2”, “path3].join(“/“).
In addition I also find it more logical that the resourcename be a BLOB for which we don’t know the structure (whether it’s separated by “/“ or “.” or anything else, we shouldn’t care about). The way we load the resource is by doing a ClassLoader.getResourceAsStream(resourceName). Said differently it’s by pure chance that we have both “/“ for loading a classloader resource and as a separator for a URL!
So I don’t want to block your proposal but it’s seems we’re mixing apples and oranges and I’m not sure it’s a good thing.
I am having a hard time understanding if you are talking about URL management in XWiki in general (i.e. determining what is the action that the current URL is trying to reach; is it webjars, is it view, is it bin, is it rest, etc...), or if you are talking about the actual webjar resource that the client is trying to reach (i.e. files inside the webjar). If you are talking about webjars in specific, don`t forget that they are basically zipped directories and that will not really change AFAIK. Any resource inside a webjar is basically a file in a directory. Webaps will still want to handle them as files inside directories inside the web application, not as parameters inside a URL request to some service that returns files. This is actually where the problem comes when a library such as requirejs uses and enforces this assumption. Thanks, Eduard
I’m curious to know what others think.
Thanks -Vincent
On 3 Apr 2015 at 18:39:09, Eduard Moraru (enygma2002@gmail.com(mailto: enygma2002@gmail.com)) wrote:
Hi,
Currently, the webjars URL mapping is the following:
http://localhost:8080/xwiki/bin/webjars/resources/path?value= %2F%2F
Example: $services.webjars.url('codemirror', 'lib/codemirror.js') returns
http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5....
The problem with this is that require modules that use relative paths for their dependencies are broken because of the URL mapping we use, more specifically by the "?" character inside the URL we use.
A concrete example is the CodeMirror webjar that defines its own modules which express their dependencies relatively: "../../lib/codemirror"
Here we have a problem, since if we directly depend on "$services.webjars.url('codemirror', 'mode/css/css.js')", the module will fail to find its relatively defined dependency.
One approach would be to define paths, so that requirejs can work its
magic:
require.config({ paths: { cm : "
http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5....
" } });
require(["cm/lib/codemirror", "cm/mode/css/css"], function (CodeMirror) { console.log(CodeMirror); });
This properly finds "/lib/codemirror.js" and "mode/css/css.js" that we explicitly request, however, the internal dependency of css.js fails to be found at the resolved URL "
http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5....
".
Requirejs does not add the ".js" extension to the resolved path because the resolved path contains a "?" character so it is considered an absolute URL, not a relative path.
The proposal is to stop using this URL mapping, since it is awkward to have paths in parameters and, instead, use a more intuitive one that is both good for clients and for requirejs.
The proposed mapping/scheme is:
http://localhost:8080/xwiki/bin/webjars///
Any additional parameters that we might need for the webjars action would be appended at the end. There is currently 1 case that I know of, which is "evaluate=true|false".
Without this change, I can not find any solution to using a webjar such as CodeMirror that uses relative defined modules.
Thanks, Eduard
P.S.: Any additional advice on using requirejs to circumvent this limitation is most than welcomed.
_______________________________________________ devs mailing list devs@xwiki.org http://lists.xwiki.org/mailman/listinfo/devs
Hi Edy, On 4 Apr 2015 at 07:47:04, Eduard Moraru (enygma2002@gmail.com(mailto:enygma2002@gmail.com)) wrote:
Hi Vincent,
On Fri, Apr 3, 2015 at 11:18 PM, vincent@massol.net wrote:
Hi Edy,
I don’t enough about requirejs to make an educated answer on this part so my answer is only about the new proposed format.
PROs: * possibly a bit better for end users
CONs: * not restful (I think)
But isn't it much more restful than the current http://localhost:8080/xwiki/bin/webjars/resources/path?value=%2F%2F ?
Yes it’s very possible, I honestly don’t know if having some data separated by the URL path separator is RESTful or not. I mean something like /key/value1/value2/value3. In which case it goes in the PROs list if it is RESTful.
* we mix the resource name with the rest of the URL (semantic mixing)
IMO, the ID (if this is what you refer to as resource name) should always be between 2 "/"es. If the resource name contains a "/" itself, then it should be URL escaped by the caller.
If by resource name you mean the entire "value=%2F%2F" part, see below.
What I call resource name is for example: "angularjs/1.1.5/angular.js”
* by mixing the resource name with the rest of the URL we need to reparse the URL to reconstruct the resource name
Let me give more information by what I mean on these last 2 points. Right now when we have a URL our ExtendedURL class parses the URL by parsing the path portions and storing them into a List. So if we have http:////path1/path2/path3, we get [“path1”, “path2”, “path3]. If we wish to get the resource name we need to [“path1”, “path2”, “path3].join(“/“).
In addition I also find it more logical that the resourcename be a BLOB for which we don’t know the structure (whether it’s separated by “/“ or “.” or anything else, we shouldn’t care about). The way we load the resource is by doing a ClassLoader.getResourceAsStream(resourceName). Said differently it’s by pure chance that we have both “/“ for loading a classloader resource and as a separator for a URL!
So I don’t want to block your proposal but it’s seems we’re mixing apples and oranges and I’m not sure it’s a good thing.
I am having a hard time understanding if you are talking about URL management in XWiki in general (i.e. determining what is the action that the current URL is trying to reach; is it webjars, is it view, is it bin, is it rest, etc...), or if you are talking about the actual webjar resource that the client is trying to reach (i.e. files inside the webjar).
If you are talking about webjars in specific, don`t forget that they are basically zipped directories and that will not really change AFAIK. Any resource inside a webjar is basically a file in a directory. Webaps will still want to handle them as files inside directories inside the web application, not as parameters inside a URL request to some service that returns files. This is actually where the problem comes when a library such as requirejs uses and enforces this assumption.
Yes this was exactly my issue: webjars resource names are directories. When you have "angularjs/1.1.5/angular.js” the “/“ represent a directory separator. Whereas the “/“ in URLs don’t represent directory separators. They just happen to be the same. Now I’ve thought more about it and it’s not a showstopper at all since I believe the correct algorithm is actually: 1) Parse the URL and extract all path segments. For example when you have "angularjs/1.1.5/angular.js” you extract segments = [“angularjs”, “1.1.5”, “angular.js”] 2) To construct the resource name you simply do: segments.join(PATHSEPARATORCHAR) and if PATHSEPARATORCHAR is “/“ you‘ll get "angularjs/1.1.5/angular.js” As I mentioned in my previous mail, we do 1) anyway in the XWiki URL management so it’s fine. So, after more thinking I’m +0 about using the following WebJar URL format: http://<server>/xwiki/webjars/angularjs/1.1.5/angular.js?evaluate=true|false It still feels a bit magical and as a user you need to infer that the resource you’re accessing is the one after the “webjars” segment (you must have this knowledge), whereas when you have the following you make it explicit and remove the magic (anyone can understand it without having to read any documentation): http://<server>/xwiki/webjars?resource=angularjs/1.1.5/angular.js&evaluate=true|false However, since I understand the need I’m +0. Thanks -Vincent
Thanks, Eduard
I’m curious to know what others think.
Thanks -Vincent
On 3 Apr 2015 at 18:39:09, Eduard Moraru (enygma2002@gmail.com(mailto: enygma2002@gmail.com)) wrote:
Hi,
Currently, the webjars URL mapping is the following:
http://localhost:8080/xwiki/bin/webjars/resources/path?value= %2F%2F
Example: $services.webjars.url('codemirror', 'lib/codemirror.js') returns
http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5....
The problem with this is that require modules that use relative paths for their dependencies are broken because of the URL mapping we use, more specifically by the "?" character inside the URL we use.
A concrete example is the CodeMirror webjar that defines its own modules which express their dependencies relatively: "../../lib/codemirror"
Here we have a problem, since if we directly depend on "$services.webjars.url('codemirror', 'mode/css/css.js')", the module will fail to find its relatively defined dependency.
One approach would be to define paths, so that requirejs can work its
magic:
require.config({ paths: { cm : "
http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5....
" } });
require(["cm/lib/codemirror", "cm/mode/css/css"], function (CodeMirror) { console.log(CodeMirror); });
This properly finds "/lib/codemirror.js" and "mode/css/css.js" that we explicitly request, however, the internal dependency of css.js fails to be found at the resolved URL "
http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5....
".
Requirejs does not add the ".js" extension to the resolved path because the resolved path contains a "?" character so it is considered an absolute URL, not a relative path.
The proposal is to stop using this URL mapping, since it is awkward to have paths in parameters and, instead, use a more intuitive one that is both good for clients and for requirejs.
The proposed mapping/scheme is:
http://localhost:8080/xwiki/bin/webjars///
Any additional parameters that we might need for the webjars action would be appended at the end. There is currently 1 case that I know of, which is "evaluate=true|false".
Without this change, I can not find any solution to using a webjar such as CodeMirror that uses relative defined modules.
Thanks, Eduard
P.S.: Any additional advice on using requirejs to circumvent this limitation is most than welcomed.
Hi, On Sun, Apr 5, 2015 at 10:52 AM, vincent@massol.net <vincent@massol.net> wrote:
Hi Edy,
On 4 Apr 2015 at 07:47:04, Eduard Moraru (enygma2002@gmail.com(mailto: enygma2002@gmail.com)) wrote:
Hi Vincent,
On Fri, Apr 3, 2015 at 11:18 PM, vincent@massol.net wrote:
Hi Edy,
I don’t enough about requirejs to make an educated answer on this part so my answer is only about the new proposed format.
PROs: * possibly a bit better for end users
CONs: * not restful (I think)
But isn't it much more restful than the current http://localhost:8080/xwiki/bin/webjars/resources/path?value=%2F%2F ?
Yes it’s very possible, I honestly don’t know if having some data separated by the URL path separator is RESTful or not. I mean something like /key/value1/value2/value3.
In which case it goes in the PROs list if it is RESTful.
* we mix the resource name with the rest of the URL (semantic mixing)
IMO, the ID (if this is what you refer to as resource name) should always be between 2 "/"es. If the resource name contains a "/" itself, then it should be URL escaped by the caller.
If by resource name you mean the entire "value=%2F%2F" part, see below.
What I call resource name is for example: "angularjs/1.1.5/angular.js”
* by mixing the resource name with the rest of the URL we need to reparse the URL to reconstruct the resource name
Let me give more information by what I mean on these last 2 points. Right now when we have a URL our ExtendedURL class parses the URL by parsing the path portions and storing them into a List. So if we have http:////path1/path2/path3, we get [“path1”, “path2”, “path3]. If we wish to get the resource name we need to [“path1”, “path2”, “path3].join(“/“).
In addition I also find it more logical that the resourcename be a BLOB for which we don’t know the structure (whether it’s separated by “/“ or “.” or anything else, we shouldn’t care about). The way we load the resource is by doing a ClassLoader.getResourceAsStream(resourceName). Said differently it’s by pure chance that we have both “/“ for loading a classloader resource and as a separator for a URL!
So I don’t want to block your proposal but it’s seems we’re mixing apples and oranges and I’m not sure it’s a good thing.
I am having a hard time understanding if you are talking about URL management in XWiki in general (i.e. determining what is the action that the current URL is trying to reach; is it webjars, is it view, is it bin, is it rest, etc...), or if you are talking about the actual webjar resource that the client is trying to reach (i.e. files inside the webjar).
If you are talking about webjars in specific, don`t forget that they are basically zipped directories and that will not really change AFAIK. Any resource inside a webjar is basically a file in a directory. Webaps will still want to handle them as files inside directories inside the web application, not as parameters inside a URL request to some service that returns files. This is actually where the problem comes when a library such as requirejs uses and enforces this assumption.
Yes this was exactly my issue: webjars resource names are directories. When you have "angularjs/1.1.5/angular.js” the “/“ represent a directory separator.
Whereas the “/“ in URLs don’t represent directory separators. They just happen to be the same.
Now I’ve thought more about it and it’s not a showstopper at all since I believe the correct algorithm is actually:
1) Parse the URL and extract all path segments. For example when you have "angularjs/1.1.5/angular.js” you extract segments = [“angularjs”, “1.1.5”, “angular.js”] 2) To construct the resource name you simply do: segments.join(PATHSEPARATORCHAR) and if PATHSEPARATORCHAR is “/“ you‘ll get "angularjs/1.1.5/angular.js”
As I mentioned in my previous mail, we do 1) anyway in the XWiki URL management so it’s fine.
So, after more thinking I’m +0 about using the following WebJar URL format:
http:// <server>/xwiki/webjars/angularjs/1.1.5/angular.js?evaluate=true|false
It still feels a bit magical and as a user you need to infer that the resource you’re accessing is the one after the “webjars” segment (you must have this knowledge), whereas when you have the following you make it explicit and remove the magic (anyone can understand it without having to read any documentation): http:// <server>/xwiki/webjars?resource=angularjs/1.1.5/angular.js&evaluate=true|false
I guess the same can be said about "http://<server>/xwiki/rest/<resourceURIPart>". You have to know the *endpoint* of the API you are accessing, whether it's a REST resource, a webjar resource or anything else, depending on the resource type, there is a particular endpoint associated with it that you need to know. I find that perfectly acceptable :) The same mention about "/" path separator probably applies for the REST API again. Thanks, Eduard
However, since I understand the need I’m +0.
Thanks -Vincent
Thanks, Eduard
I’m curious to know what others think.
Thanks -Vincent
On 3 Apr 2015 at 18:39:09, Eduard Moraru (enygma2002@gmail.com(mailto: enygma2002@gmail.com)) wrote:
Hi,
Currently, the webjars URL mapping is the following:
http://localhost:8080/xwiki/bin/webjars/resources/path?value= %2F%2F
Example: $services.webjars.url('codemirror', 'lib/codemirror.js') returns
http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5....
The problem with this is that require modules that use relative
paths for
their dependencies are broken because of the URL mapping we use, more specifically by the "?" character inside the URL we use.
A concrete example is the CodeMirror webjar that defines its own modules which express their dependencies relatively: "../../lib/codemirror"
Here we have a problem, since if we directly depend on "$services.webjars.url('codemirror', 'mode/css/css.js')", the module will fail to find its relatively defined dependency.
One approach would be to define paths, so that requirejs can work its magic:
require.config({ paths: { cm : "
http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5....
" } });
require(["cm/lib/codemirror", "cm/mode/css/css"], function (CodeMirror) { console.log(CodeMirror); });
This properly finds "/lib/codemirror.js" and "mode/css/css.js" that we explicitly request, however, the internal dependency of css.js fails to be found at the resolved URL "
http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5....
".
Requirejs does not add the ".js" extension to the resolved path because the resolved path contains a "?" character so it is considered an absolute URL, not a relative path.
The proposal is to stop using this URL mapping, since it is awkward to have paths in parameters and, instead, use a more intuitive one that is both good for clients and for requirejs.
The proposed mapping/scheme is:
http://localhost:8080/xwiki/bin/webjars///
Any additional parameters that we might need for the webjars action would be appended at the end. There is currently 1 case that I know of, which is "evaluate=true|false".
Without this change, I can not find any solution to using a webjar such as CodeMirror that uses relative defined modules.
Thanks, Eduard
P.S.: Any additional advice on using requirejs to circumvent this limitation is most than welcomed.
Hi, After a weekend`s rest, I`ve managed to come up with a solution/workaround/hack for the requirejs relative path dependency issue until we get to refactor the current webjars URL. I`ve posted the details on http://extensions.xwiki.org/xwiki/bin/view/Extension/Requirejs+and+Webjars+w... in case anyone else is in the same situation. Thanks, Eduard On Sun, Apr 5, 2015 at 1:24 PM, Eduard Moraru <enygma2002@gmail.com> wrote:
Hi,
On Sun, Apr 5, 2015 at 10:52 AM, vincent@massol.net <vincent@massol.net> wrote:
Hi Edy,
On 4 Apr 2015 at 07:47:04, Eduard Moraru (enygma2002@gmail.com(mailto: enygma2002@gmail.com)) wrote:
Hi Vincent,
On Fri, Apr 3, 2015 at 11:18 PM, vincent@massol.net wrote:
Hi Edy,
I don’t enough about requirejs to make an educated answer on this part so my answer is only about the new proposed format.
PROs: * possibly a bit better for end users
CONs: * not restful (I think)
But isn't it much more restful than the current http://localhost:8080/xwiki/bin/webjars/resources/path?value=%2F%2F ?
Yes it’s very possible, I honestly don’t know if having some data separated by the URL path separator is RESTful or not. I mean something like /key/value1/value2/value3.
In which case it goes in the PROs list if it is RESTful.
* we mix the resource name with the rest of the URL (semantic mixing)
IMO, the ID (if this is what you refer to as resource name) should always be between 2 "/"es. If the resource name contains a "/" itself, then it should be URL escaped by the caller.
If by resource name you mean the entire "value=%2F%2F" part, see below.
What I call resource name is for example: "angularjs/1.1.5/angular.js”
* by mixing the resource name with the rest of the URL we need to reparse the URL to reconstruct the resource name
Let me give more information by what I mean on these last 2 points. Right now when we have a URL our ExtendedURL class parses the URL by parsing the path portions and storing them into a List. So if we have http:////path1/path2/path3, we get [“path1”, “path2”, “path3]. If we wish to get the resource name we need to [“path1”, “path2”, “path3].join(“/“).
In addition I also find it more logical that the resourcename be a BLOB for which we don’t know the structure (whether it’s separated by “/“ or “.” or anything else, we shouldn’t care about). The way we load the resource is by doing a ClassLoader.getResourceAsStream(resourceName). Said differently it’s by pure chance that we have both “/“ for loading a classloader resource and as a separator for a URL!
So I don’t want to block your proposal but it’s seems we’re mixing apples and oranges and I’m not sure it’s a good thing.
I am having a hard time understanding if you are talking about URL management in XWiki in general (i.e. determining what is the action that the current URL is trying to reach; is it webjars, is it view, is it bin, is it rest, etc...), or if you are talking about the actual webjar resource that the client is trying to reach (i.e. files inside the webjar).
If you are talking about webjars in specific, don`t forget that they are basically zipped directories and that will not really change AFAIK. Any resource inside a webjar is basically a file in a directory. Webaps will still want to handle them as files inside directories inside the web application, not as parameters inside a URL request to some service that returns files. This is actually where the problem comes when a library such as requirejs uses and enforces this assumption.
Yes this was exactly my issue: webjars resource names are directories. When you have "angularjs/1.1.5/angular.js” the “/“ represent a directory separator.
Whereas the “/“ in URLs don’t represent directory separators. They just happen to be the same.
Now I’ve thought more about it and it’s not a showstopper at all since I believe the correct algorithm is actually:
1) Parse the URL and extract all path segments. For example when you have "angularjs/1.1.5/angular.js” you extract segments = [“angularjs”, “1.1.5”, “angular.js”] 2) To construct the resource name you simply do: segments.join(PATHSEPARATORCHAR) and if PATHSEPARATORCHAR is “/“ you‘ll get "angularjs/1.1.5/angular.js”
As I mentioned in my previous mail, we do 1) anyway in the XWiki URL management so it’s fine.
So, after more thinking I’m +0 about using the following WebJar URL format:
http:// <server>/xwiki/webjars/angularjs/1.1.5/angular.js?evaluate=true|false
It still feels a bit magical and as a user you need to infer that the resource you’re accessing is the one after the “webjars” segment (you must have this knowledge), whereas when you have the following you make it explicit and remove the magic (anyone can understand it without having to read any documentation): http:// <server>/xwiki/webjars?resource=angularjs/1.1.5/angular.js&evaluate=true|false
I guess the same can be said about "http://<server>/xwiki/rest/<resourceURIPart>". You have to know the *endpoint* of the API you are accessing, whether it's a REST resource, a webjar resource or anything else, depending on the resource type, there is a particular endpoint associated with it that you need to know. I find that perfectly acceptable :)
The same mention about "/" path separator probably applies for the REST API again.
Thanks, Eduard
However, since I understand the need I’m +0.
Thanks -Vincent
Thanks, Eduard
I’m curious to know what others think.
Thanks -Vincent
On 3 Apr 2015 at 18:39:09, Eduard Moraru (enygma2002@gmail.com (mailto: enygma2002@gmail.com)) wrote:
Hi,
Currently, the webjars URL mapping is the following:
http://localhost:8080/xwiki/bin/webjars/resources/path?value= %2F%2F
Example: $services.webjars.url('codemirror', 'lib/codemirror.js') returns
http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5....
The problem with this is that require modules that use relative
paths for
their dependencies are broken because of the URL mapping we use, more specifically by the "?" character inside the URL we use.
A concrete example is the CodeMirror webjar that defines its own modules which express their dependencies relatively: "../../lib/codemirror"
Here we have a problem, since if we directly depend on "$services.webjars.url('codemirror', 'mode/css/css.js')", the module will fail to find its relatively defined dependency.
One approach would be to define paths, so that requirejs can work its magic:
require.config({ paths: { cm : "
http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5....
" } });
require(["cm/lib/codemirror", "cm/mode/css/css"], function (CodeMirror) { console.log(CodeMirror); });
This properly finds "/lib/codemirror.js" and "mode/css/css.js" that we explicitly request, however, the internal dependency of css.js fails to be found at the resolved URL "
http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5....
".
Requirejs does not add the ".js" extension to the resolved path because the resolved path contains a "?" character so it is considered an absolute URL, not a relative path.
The proposal is to stop using this URL mapping, since it is awkward to have paths in parameters and, instead, use a more intuitive one that is both good for clients and for requirejs.
The proposed mapping/scheme is:
http://localhost:8080/xwiki/bin/webjars///
Any additional parameters that we might need for the webjars action would be appended at the end. There is currently 1 case that I know of, which is "evaluate=true|false".
Without this change, I can not find any solution to using a webjar such as CodeMirror that uses relative defined modules.
Thanks, Eduard
P.S.: Any additional advice on using requirejs to circumvent this limitation is most than welcomed.
On 04/04/2015 01:46 AM, Eduard Moraru wrote:
IMO, the ID (if this is what you refer to as resource name) should always be between 2 "/"es. If the resource name contains a "/" itself, then it should be URL escaped by the caller.
Don't forget that escaped / is not allowed in URLs by default by both HTTPD and Tomcat. -- Sergiu Dumitriu http://purl.org/net/sergiu
Hi, 2015-04-21 5:29 GMT+02:00 Sergiu Dumitriu <sergiu@xwiki.com>:
On 04/04/2015 01:46 AM, Eduard Moraru wrote:
IMO, the ID (if this is what you refer to as resource name) should always be between 2 "/"es. If the resource name contains a "/" itself, then it should be URL escaped by the caller.
Don't forget that escaped / is not allowed in URLs by default by both HTTPD and Tomcat.
As there can be both / and \ in the page name, this security feature has to be always disabled (for Tomcat it's -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true), so this shouldn't matter anyway. -- Best Regards Lukáš Raška
On Fri, Apr 3, 2015 at 7:38 PM, Eduard Moraru <enygma2002@gmail.com> wrote:
Hi,
Currently, the webjars URL mapping is the following:
http://localhost:8080/xwiki/bin/webjars/resources/path?value= <id>%2F<version>%2F<filePath>
Example: $services.webjars.url('codemirror', 'lib/codemirror.js') returns http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5....
The problem with this is that require modules that use relative paths for their dependencies are broken because of the URL mapping we use, more specifically by the "?" character inside the URL we use.
A concrete example is the CodeMirror webjar that defines its own modules which express their dependencies relatively: "../../lib/codemirror"
Here we have a problem, since if we directly depend on "$services.webjars.url('codemirror', 'mode/css/css.js')", the module will fail to find its relatively defined dependency.
One approach would be to define paths, so that requirejs can work its magic:
require.config({ paths: { cm : " http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5.... " } });
require(["cm/lib/codemirror", "cm/mode/css/css"], function (CodeMirror) { console.log(CodeMirror); });
This properly finds "/lib/codemirror.js" and "mode/css/css.js" that we explicitly request, however, the internal dependency of css.js fails to be found at the resolved URL " http://localhost:8080/xwiki/bin/webjars/resources/path?value=codemirror%2F5.... ".
Requirejs does not add the ".js" extension to the resolved path because the resolved path contains a "?" character so it is considered an absolute URL, not a relative path.
The proposal is to stop using this URL mapping, since it is awkward to have paths in parameters and, instead, use a more intuitive one that is both good for clients and for requirejs.
The proposed mapping/scheme is:
http://localhost:8080/xwiki/bin/webjars/<id>/<version>/<filePath>
Any additional parameters that we might need for the webjars action would be appended at the end. There is currently 1 case that I know of, which is "evaluate=true|false".
+1, I don't think we have a choice if we want to support relative paths in the WebJar resources, as pointed in http://jira.xwiki.org/browse/XWIKI-11996 . Thanks, Marius
Without this change, I can not find any solution to using a webjar such as CodeMirror that uses relative defined modules.
Thanks, Eduard
P.S.: Any additional advice on using requirejs to circumvent this limitation is most than welcomed. _______________________________________________ devs mailing list devs@xwiki.org http://lists.xwiki.org/mailman/listinfo/devs
+1 for this proposal. Thanks, -- Guillaume Delhumeau (gdelhumeau@xwiki.com) Research & Development Engineer at XWiki SAS Committer on the XWiki.org project
participants (8)
-
Caleb James DeLisle -
Denis Gervalle -
Eduard Moraru -
Guillaume "Louis-Marie" Delhumeau -
Lukáš Raška -
Marius Dumitru Florea -
Sergiu Dumitriu -
vincent@massol.net