From a00eb8c8bf7c2f4ea05e7bd278a4b1933e6bc338 Mon Sep 17 00:00:00 2001 From: Donovan Mikrot Date: Thu, 20 Aug 2015 15:45:55 -0500 Subject: [PATCH 1/4] Add required karma reporter to dev dependencies --- package.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5f1c7b3..6bbc584 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,10 @@ "ie9" ], "author": "saintmac (Martin Saint-Macary, http://vyte.in)", - "contributors": ["Alfred Bratterud "], + "contributors": [ + "Alfred Bratterud ", + "Donovan Mikrot " + ], "license": "MIT", "bugs": { "url": "https://github.com/saintmac/angular-cache-buster/issues" @@ -38,6 +41,7 @@ "requirejs": "~2.1.11", "karma-requirejs": "~0.2.1", "karma-phantomjs-launcher": "~0.1.2", - "karma": "~0.12.15" + "karma": "~0.12.15", + "karma-junit-reporter": "~0.3.3" } } From 2dc37df042ee79fe1cb12b396b7ab4cfc15edeb9 Mon Sep 17 00:00:00 2001 From: Donovan Mikrot Date: Thu, 20 Aug 2015 15:50:37 -0500 Subject: [PATCH 2/4] Normalize whitespace --- angular-cache-buster.js | 109 +++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 56 deletions(-) diff --git a/angular-cache-buster.js b/angular-cache-buster.js index a368a50..20236cd 100644 --- a/angular-cache-buster.js +++ b/angular-cache-buster.js @@ -2,61 +2,58 @@ angular.module('ngCacheBuster', []) .config(['$httpProvider', function($httpProvider) { return $httpProvider.interceptors.push('httpRequestInterceptorCacheBuster'); }]) - .provider('httpRequestInterceptorCacheBuster', function() { - - this.matchlist = [/.*partials.*/, /.*views.*/ ]; - this.logRequests = false; - - //Default to whitelist (i.e. block all except matches) - this.black=false; - - //Select blacklist or whitelist, default to whitelist - this.setMatchlist = function(list,black) { - this.black = typeof black != 'undefined' ? black : false - this.matchlist = list; - }; - - - this.setLogRequests = function(logRequests) { - this.logRequests = logRequests; - }; - - this.$get = ['$q', '$log', function($q, $log) { - var matchlist = this.matchlist; - var logRequests = this.logRequests; - var black = this.black; - if (logRequests) { - $log.log("Blacklist? ",black); - } - return { - 'request': function(config) { - //Blacklist by default, match with whitelist - var busted= !black; - - for(var i=0; i< matchlist.length; i++){ - if(config.url.match(matchlist[i])) { - busted=black; break; - } - } - - //Bust if the URL was on blacklist or not on whitelist - if (busted) { - var d = new Date(); - config.url = config.url.replace(/[?|&]cacheBuster=\d+/,''); - //Some url's allready have '?' attached - config.url+=config.url.indexOf('?') === -1 ? '?' : '&' - config.url += 'cacheBuster=' + d.getTime(); - } - - if (logRequests) { - var log='request.url =' + config.url - busted ? $log.warn(log) : $log.info(log) - } - - return config || $q.when(config); - } - } - }]; - }); + .provider('httpRequestInterceptorCacheBuster', function() { + + this.matchlist = [/.*partials.*/, /.*views.*/ ]; + this.logRequests = false; + + //Default to whitelist (i.e. block all except matches) + this.black=false; + + //Select blacklist or whitelist, default to whitelist + this.setMatchlist = function(list,black) { + this.black = typeof black != 'undefined' ? black : false + this.matchlist = list; + }; + + this.setLogRequests = function(logRequests) { + this.logRequests = logRequests; + }; + this.$get = ['$q', '$log', function($q, $log) { + var matchlist = this.matchlist; + var logRequests = this.logRequests; + var black = this.black; + if (logRequests) { + $log.log("Blacklist? ",black); + } + return { + 'request': function(config) { + //Blacklist by default, match with whitelist + var busted= !black; + for(var i=0; i< matchlist.length; i++){ + if(config.url.match(matchlist[i])) { + busted=black; break; + } + } + + //Bust if the URL was on blacklist or not on whitelist + if (busted) { + var d = new Date(); + config.url = config.url.replace(/[?|&]cacheBuster=\d+/,''); + //Some url's allready have '?' attached + config.url+=config.url.indexOf('?') === -1 ? '?' : '&' + config.url += 'cacheBuster=' + d.getTime(); + } + + if (logRequests) { + var log='request.url =' + config.url + busted ? $log.warn(log) : $log.info(log) + } + + return config || $q.when(config); + } + } + }]; + }); From a7be10f1434395609a485828988ce6236e244499 Mon Sep 17 00:00:00 2001 From: Donovan Mikrot Date: Thu, 20 Aug 2015 16:39:48 -0500 Subject: [PATCH 3/4] Add setMatchFunction support --- angular-cache-buster.js | 32 +++++++++----- test/test.js | 93 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 110 insertions(+), 15 deletions(-) diff --git a/angular-cache-buster.js b/angular-cache-buster.js index 20236cd..cfe1a05 100644 --- a/angular-cache-buster.js +++ b/angular-cache-buster.js @@ -11,44 +11,56 @@ angular.module('ngCacheBuster', []) this.black=false; //Select blacklist or whitelist, default to whitelist - this.setMatchlist = function(list,black) { - this.black = typeof black != 'undefined' ? black : false + this.setMatchlist = function(list, black) { + this.black = typeof black != 'undefined' ? black : false; this.matchlist = list; }; + this.setMatchFunction = function(matchFn, black) { + this.black = typeof black != 'undefined' ? black : false; + this.matchFn = matchFn; + }; + this.setLogRequests = function(logRequests) { this.logRequests = logRequests; }; this.$get = ['$q', '$log', function($q, $log) { var matchlist = this.matchlist; + var matchFn = this.matchFn; var logRequests = this.logRequests; var black = this.black; if (logRequests) { - $log.log("Blacklist? ",black); + $log.log("Blacklist? ", black); } return { 'request': function(config) { //Blacklist by default, match with whitelist - var busted= !black; + var busted = !black; - for(var i=0; i< matchlist.length; i++){ - if(config.url.match(matchlist[i])) { - busted=black; break; + if (typeof matchFn === 'function') { + if (matchFn(config.url)) { + busted = black; + } + } else { + for(var i = 0; i < matchlist.length; i++){ + if (config.url.match(matchlist[i])) { + busted = black; break; + } } } //Bust if the URL was on blacklist or not on whitelist if (busted) { var d = new Date(); - config.url = config.url.replace(/[?|&]cacheBuster=\d+/,''); + config.url = config.url.replace(/[?|&]cacheBuster=\d+/, ''); //Some url's allready have '?' attached - config.url+=config.url.indexOf('?') === -1 ? '?' : '&' + config.url += config.url.indexOf('?') === -1 ? '?' : '&' config.url += 'cacheBuster=' + d.getTime(); } if (logRequests) { - var log='request.url =' + config.url + var log = 'request.url =' + config.url busted ? $log.warn(log) : $log.info(log) } diff --git a/test/test.js b/test/test.js index 1a0d6b6..7cd8839 100644 --- a/test/test.js +++ b/test/test.js @@ -6,7 +6,7 @@ describe('ngCacheBuster', function () { beforeEach(inject(function($injector) { $httpBackend = $injector.get('$httpBackend'); - $http = $injector.get('$http'); + $http = $injector.get('$http'); })); afterEach(function() { @@ -62,7 +62,7 @@ describe('ngCacheBuster', function () { $httpBackend.verifyNoOutstandingExpectation(); $httpBackend.verifyNoOutstandingRequest(); }); - + //Whitelist, views describe('with a views request', function() { it('should add a cache buster', function() { @@ -176,7 +176,7 @@ describe('ngCacheBuster', function () { $httpBackend.flush(); }); }); - + //Blacklist, other describe('with any other request', function() { it('should not add a cache buster', function() { @@ -186,7 +186,90 @@ describe('ngCacheBuster', function () { $httpBackend.flush(); }); }); - - + }); + + //Match function + describe('configuring the provider with a match function', function() { + beforeEach(function() { + var matchlist = [/.*users.*/, /.*orders.*/]; + module('ngCacheBuster'); + module(function(httpRequestInterceptorCacheBusterProvider){ + httpRequestInterceptorCacheBusterProvider.setMatchFunction(function (url) { + for(var i = 0; i < matchlist.length; i++){ + if (url.match(matchlist[i])) { + return true; + } + } + return false; + }, true); + httpRequestInterceptorCacheBusterProvider.setLogRequests(true); + }); + }); + + beforeEach(inject(function($injector) { + $httpBackend = $injector.get('$httpBackend'); + $http = $injector.get('$http'); + })); + + afterEach(function() { + $httpBackend.verifyNoOutstandingExpectation(); + $httpBackend.verifyNoOutstandingRequest(); + }); + + //Match function, users + describe('with an api/users request', function() { + it('should add a cache buster', function() { + var req = '/api/users/654645'; + var regex_friendly_req = req.replace(/\//g, '\\/'); + var expected = new RegExp(regex_friendly_req + '\\?cacheBuster=[0-9]+') + $httpBackend.expectGET(expected).respond(200); + $http.get(req); + $httpBackend.flush(); + }); + }); + + //Match function, api/orders + describe('with an api/orders request', function() { + it('should add a cache buster', function() { + var req = '/api/orders/654645'; + var regex_friendly_req = req.replace(/\//g, '\\/'); + var expected = new RegExp(regex_friendly_req + '\\?cacheBuster=[0-9]+') + $httpBackend.expectGET(expected).respond(200); + $http.get(req); + $httpBackend.flush(); + }); + }); + + //Match function, with existing query params + describe('with an api/orders request with existing query-string parameter', function() { + it('should add a cache buster, but not break existing params', function() { + var req = '/api/orders/654645?orderid=115'; + var regex_friendly_req = req.replace(/\//g, '\\/').replace(/\?/g,'\\?') + var expected = new RegExp(regex_friendly_req + '&cacheBuster=[0-9]+') + $httpBackend.expectGET(expected).respond(200); + $http.get(req); + $httpBackend.flush(); + }); + }); + + //Match function, partials + describe('with a partials request', function() { + it('should not add a cache buster', function() { + var req = '/bower_components/mymodule/partials/home.html'; + $httpBackend.expectGET(req).respond(200); + $http.get(req); + $httpBackend.flush(); + }); + }); + + //Match function, other + describe('with any other request', function() { + it('should not add a cache buster', function() { + var req = '/task/1234'; + $httpBackend.expectGET(req).respond(200); + $http.get(req); + $httpBackend.flush(); + }); + }); }); }); From cb8c35fb60b4fcdd044a7fe7526e2907fc48b6d0 Mon Sep 17 00:00:00 2001 From: Donovan Mikrot Date: Thu, 20 Aug 2015 16:46:54 -0500 Subject: [PATCH 4/4] Update readme with setMatchFunction instructions --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 23cf042..1869273 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,15 @@ If instead you want to allow everything to be cached, except your "/api/users" a httpRequestInterceptorCacheBusterProvider.setMatchlist([/.*orders.*/,/.*users.*/],true); }); +If you need custom logic instead of regular expression matching, you can supply a match function instead of a matchlist. The second boolean argument "blacklist" operates the same. The match function is called with a single url argument. Return a truthy value if the url matches: + + angular.module('yourApp', ['ngCacheBuster']) + .config(function(httpRequestInterceptorCacheBusterProvider){ + httpRequestInterceptorCacheBusterProvider.setMatchFunction(function(url) { + return url.length % 2; + },true); + }); + # use That's it! All your resource calls will have a cache buster added for anything not in the whitelist, or if you specified "blacklist", for everything matching the blacklist,