Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Base URL Feature #110

Merged
merged 4 commits into from

2 participants

@KenPowers

Added a feature to allow base urls for loading. On the yepnope.js web page there is a sample as follows:

yepnope({
  load: ["https:/­/my-cdn.com/jquery.min.js?v=1.7.1", "https:/­/my-cdn.com/jquery-ui.min.js?v=1.8.16"],
  // ...
});

This can now be expressed as follows:

yepnope({
  base: "https://my-cdn.com/",
  load: ["jquery.min.js?v=1.7.1", "jquery-ui.min.js?v=1.8.16"],
  // ...
});

I have also added several tests to make sure everything is working. I have changed the version of Express.js to 2.5.9 because 2.4.7 wasn't working with my version of node. All tests still pass.

My primary motivation for creating this new feature is because I load files locally during development but use a CDN in production. My traditional approach was as so:

var base = '/';
yepnope({
  load: [base + "jquery.min.js?v=1.7.1", base + "jquery-ui.min.js?v=1.8.16"],
  // ...
});

Then I would just have to change base when going into production.

@SlexAxton
Owner

Hi Ken,

I think this may be better off as an official plugin, rather than a core feature. You can implement it as a filter - via the yepnope.addFilter method.

We try to be religious about adding features into core, so we can keep the file size as small as possible.

Does this sound agreeable? Happy to hear arguments to the contrary. Happy to help out if the docs are lacking. We love pull requests and yours is great. So good when people add tests.

@SlexAxton
Owner

(note, we can still add it in the official repo. We don't have a filters directory, like we have a prefixes directory, but you could create one)

@SlexAxton
Owner

Also, regardless of the direction we go, we have a system for generating the test files that you've created. If you check out the test server app a bit, that logic should be clear. If not, happy to help out.

@KenPowers

That sounds good. I'll get on that tomorrow (time for bed).

@KenPowers KenPowers closed this
@KenPowers KenPowers reopened this
@KenPowers

I'm not seeing any way to make the base url reach the filter without setting a global (ick). I see that there is an attrs property in the passed resourceObj but I don't see a user interface for setting attributes. It could be possible to pull off with a function call before any scripts are loaded but keeping this as a core feature has the benefit of specifying different bases for each test object (one test object could load jquery and jquery-ui from google, another could load all local scripts / other scripts from another CDN, and yet another could load with no base at all).

I have reopened this pull request with a few changes to the test logic.

@SlexAxton
Owner

As far as I can tell, the url param on the resource object should be immediately available to change. I wouldn't change the origUrl - just the url property.

yepnope.addFilter(function( resObj ) {
  resObj.url = yepnope.baseUrl + resObj.url;
  return resObj;
});

Something like that seems like it would work, no?

@KenPowers

Setting yepnope.baseUrl would set the base url for all scripts to be loaded (not all scripts may have the same base url). By putting base as a property of the test object we can still pass in an array of test objects and use different bases for different scripts.

@SlexAxton
Owner

It may be better implemented as a paths type system like in RequireJS.

yepnope.paths = {
  'template' : 'http://something.com/template',
  'js' : 'http://somethingelse.com/scripts'
}

Then any time a resource starts with the path, the path mapped string is put there instead.

@KenPowers

Makes sense. I'll look into that after class.

@SlexAxton
Owner

Best.

@KenPowers

I have created the filter and removed the core functionality. I have also removed two of my tests as they are no longer necessary because my code doesn't touch prefixes.

filters/yepnope.pathfilter.js
((15 lines not shown))
+ * See: http://soledadpenades.com/2007/05/17/arrayindexof-in-internet-explorer/
+ *
+ * Official Yepnope Plugin
+ *
+ * WTFPL License
+ *
+ * by Kenneth Powers | mail@kenpowers.net
+ */
+(function () {
+ var addPathFilter = function (yn) {
+ // add each prefix
+ yn.addFilter(function (resource) {
+ // check each url for path
+ for (path in yn.paths) {
+ if (resource.url.indexOf(path) === 0) {
+ resource.url = resource.url.replace(path, yn.paths[path]);
@SlexAxton Owner

shouldn't that path need to be at the beginning?

That's what indexOf(path) === 0 is for. replace(...) will only replace the first occurrence and we only reach that point if there is a match at the beginning.

@SlexAxton Owner

Ah, yea, I forgot, I normally do RegExp with ig so it replaces everything. Got it.

Couldn't we remove the dependency on indexOf with just

resource.url.replace(new RegExp( '^' + path), yn.paths[path]);

or something?

Sure. I'll get right on that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@KenPowers

Removed dependency on Array.indexOf(...). All tests still pass.

@SlexAxton
Owner

Woah, that worked first try?! I'm a regex master!

@SlexAxton SlexAxton merged commit 1bf25b2 into from
@SlexAxton
Owner

Merged. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
35 filters/yepnope.pathfilter.js
@@ -0,0 +1,35 @@
+/**
+ * YepNope Path Filter
+ *
+ * Usage:
+ * yepnope.paths = {
+ * 'google': '//ajax.googleapis.com/ajax',
+ * 'my-cdn': '//cdn.myawesomesite.com'
+ * };
+ * yepnope({
+ * load: ['google/jquery/1.7.2/jquery.min.js', 'google/jqueryui/1.8.18/jquery-ui.min.js', 'my-cdn/style.css', '/non/path/directory/file.js']
+ * });
+ *
+ * Official Yepnope Plugin
+ *
+ * WTFPL License
+ *
+ * by Kenneth Powers | mail@kenpowers.net
+ */
+(function () {
+ var addPathFilter = function (yn) {
+ // add each prefix
+ yn.addFilter(function (resource) {
+ // check each url for path
+ for (path in yn.paths) {
+ resource.url = resource.url.replace(new RegExp('^' + path), yn.paths[path]);
+ return resource;
+ }
+ // carry on my wayward, son
+ return resource;
+ });
+ };
+ console.log(yepnope);
+ if (yepnope) addPathFilter(yepnope);
+ else if (modernizr.load) addPathFilter(modernizr.load);
+})();
View
6 tests/index.html
@@ -15,6 +15,12 @@
<!-- load the supported plugins so they can be tested as well. Will break them out when it makes sense -->
<script type="text/javascript" src="../prefixes/yepnope.ie-prefix.js"></script>
<script type="text/javascript" src="../prefixes/yepnope.preload.js"></script>
+<script type="text/javascript" src="../filters/yepnope.pathfilter.js"></script>
+<script type="text/javascript">
+ yepnope.paths = {
+ 'jsb': 'js/basetest'
+ };
+</script>
<script type="text/javascript" src="qunit.js"></script>
<script type="text/javascript" src="jquery-1.6.4.min.js"></script>
View
2  tests/package.json
@@ -3,6 +3,6 @@
, "version": "0.0.1"
, "private": true
, "dependencies": {
- "express": "2.4.7"
+ "express": "2.5.9"
}
}
View
19 tests/tests.js
@@ -327,6 +327,25 @@ if ( ! window.console ) {
})
});
+ asyncTest("Yepnope loads several files with a common base", 1, function() {
+ yepnope({
+ load: ['jsb/file3.js', 'jsb/file4.js'],
+ complete: function(){
+ ok( w.file3 && w.file4, 'js/basetest/file3.js and js/basetest/file4.js have loaded.');
+ start();
+ }
+ })
+ });
+
+ asyncTest("Yepnope loads a single file with a given base", 1, function() {
+ yepnope({
+ load: 'jsb/file5.js',
+ complete: function(){
+ ok( w.file5, 'basetest/file5.js has loaded.');
+ start();
+ }
+ })
+ });
/** /
asyncTest("CSS Callback Timing", 4, function() {
View
2  yepnope.js
@@ -397,7 +397,7 @@ var docElement = doc.documentElement,
complete = testObject['complete'] || noop,
needGroupSize,
callbackKey;
-
+
// Reusable function for dealing with the different input types
// NOTE:: relies on closures to keep 'chain' up to date, a bit confusing, but
// much smaller than the functional equivalent in this case.
Something went wrong with that request. Please try again.