Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #5 from alphagov/cut_0.2.0

Cut 0.2.0
  • Loading branch information...
commit 932646fac82d989147ed24e6d29a766791d85423 2 parents 5d75036 + f525e2f
@abersager abersager authored
View
262 release/lightGate.0.2.0.js
@@ -0,0 +1,262 @@
+/*jslint indent: 2 */
+// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys
+
+if (!Object.keys) {
+ Object.keys = (function () {
+ var hasProperty = Object.prototype.hasOwnProperty,
+ hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
+ dontEnums = [
+ 'toString',
+ 'toLocaleString',
+ 'valueOf',
+ 'hasOwnProperty',
+ 'isPrototypeOf',
+ 'propertyIsEnumerable',
+ 'constructor'
+ ],
+ dontEnumsLength = dontEnums.length;
+
+ return function (obj) {
+ if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) {
+ throw new TypeError('Object.keys called on non-object');
+ }
+
+ var result = [],
+ prop, i;
+
+ for (prop in obj) {
+ if (hasProperty.call(obj, prop)) {
+ result.push(prop);
+ }
+ }
+
+ if (hasDontEnumBug) {
+ for (i = 0; i < dontEnumsLength; (i += 1)) {
+ if (hasProperty.call(obj, dontEnums[i])) {
+ result.push(dontEnums[i]);
+ }
+ }
+ }
+ return result;
+ };
+ }());
+}
+/*jslint indent: 2 */
+var GOVUK = GOVUK || {};
+GOVUK.performance = {};
+
+GOVUK.performance.addToNamespace = function (name, obj) {
+ if (GOVUK.performance[name] === undefined) {
+ GOVUK.performance[name] = obj;
+ }
+ else {
+ throw new Error("There is already a key: '" + name + "' in the namespace.");
+ }
+};
+
+
+GOVUK.performance.close = function () {
+ GOVUK.performance.addToNamespace = undefined;
+ GOVUK.performance.close = undefined;
+};
+
+/*global document:true*/
+/*global GOVUK: true*/
+/*jslint indent: 2 */
+
+GOVUK.performance.addToNamespace("cookieUtils", (function () {
+
+ var cookiesAsKeyValues, getCookieNamed, setSessionCookie, deleteCookieNamed, arrayify;
+
+
+ cookiesAsKeyValues = function () {
+ var bakedCookies = [], rawCookies = document.cookie.split(';'), i = 0, keyValue;
+ for (i = 0; i < rawCookies.length; (i += 1)) {
+ keyValue = rawCookies[i].split('=');
+ bakedCookies.push({
+ key: keyValue[0].trim(),
+ value: keyValue[1] ? keyValue[1].trim() : undefined
+ });
+ }
+ return bakedCookies;
+ };
+
+
+ getCookieNamed = function (name) {
+ var allCookies = cookiesAsKeyValues(), i = 0;
+ for (i = 0; i < allCookies.length; (i += 1)) {
+ if (allCookies[i].key === name) {
+ return allCookies[i];
+ }
+ }
+ };
+
+
+ setSessionCookie = function (cookie) {
+ var path = (cookie.path === undefined) ? "; Path=/" : "; Path=" + cookie.path;
+ document.cookie = cookie.key + "=" + cookie.value + path;
+ };
+
+
+ deleteCookieNamed = function (name) {
+ document.cookie = name.trim() + "=" + "deleted" + ";expires=" + new Date(0).toUTCString() + "; Path=/";
+ };
+
+
+ arrayify = function (obj) {
+ return (Object.prototype.toString.call(obj) !== '[object Array]') ? [obj] : obj;
+ };
+
+
+ return {
+ cookiesAsKeyValues: cookiesAsKeyValues,
+ getCookieNamed: getCookieNamed,
+ setSessionCookie: setSessionCookie,
+ deleteCookieNamed: deleteCookieNamed,
+ arrayify: arrayify
+ };
+
+}()));
+
+/*global document:true*/
+/*global GOVUK: true*/
+/*jslint indent: 2 */
+
+GOVUK.performance.addToNamespace("lightGate", (function () {
+ var nameOfCookie = "journey_events", pathOfCookie, idOfStartingLink, startingEvent,
+ idOfBodyTagAtEnd, endingEvent, sendDataFunction, eventsForInterestingPages = {},
+ cookieUtils = GOVUK.performance.cookieUtils,
+
+ journeyStart, journeyEnd, journeyStage, cookieName, cookiePath, sendFunction, init,
+ privateMethods = {};
+
+
+ journeyStart = function (startDescription) {
+ idOfStartingLink = startDescription.linkId;
+ startingEvent = startDescription.eventObject;
+ return this;
+ };
+
+
+ journeyEnd = function (endDescription) {
+ idOfBodyTagAtEnd = endDescription.bodyId;
+ endingEvent = endDescription.eventObject;
+ return this;
+ };
+
+
+ journeyStage = function (stageDescription) {
+ if (stageDescription.eventObject.stage === undefined) {
+ stageDescription.eventObject.stage = Object.keys(eventsForInterestingPages).length + 1;
+ }
+
+ eventsForInterestingPages[stageDescription.bodyId] = stageDescription.eventObject;
+ return this;
+ };
+
+
+ cookieName = function (name) {
+ nameOfCookie = name;
+ return this;
+ };
+
+
+ cookiePath = function (path) {
+ pathOfCookie = path;
+ return this;
+ };
+
+
+ sendFunction = function (send) {
+ sendDataFunction = send;
+ return this;
+ };
+
+
+ privateMethods.addStartingEventToCookie = function () {
+ var cookie = {key: nameOfCookie, value: JSON.stringify(startingEvent)};
+ if (pathOfCookie !== undefined) {
+ cookie.path = pathOfCookie;
+ }
+ cookieUtils.setSessionCookie(cookie);
+ };
+
+
+ init = function () {
+ privateMethods.bindStartingEvent();
+ privateMethods.sendCookieEvents();
+ privateMethods.doLandOnPageEvents();
+ };
+
+
+ privateMethods.sendCookieEvents = function () {
+ var existingCookie = cookieUtils.getCookieNamed(nameOfCookie), events, i = 0;
+
+ if (existingCookie && existingCookie.value) {
+ events = cookieUtils.arrayify(JSON.parse(existingCookie.value));
+ for (i = 0; i < events.length; (i += 1)) {
+ privateMethods.sendEvent(events[i]);
+ }
+ cookieUtils.deleteCookieNamed(nameOfCookie);
+ }
+ };
+
+
+ privateMethods.bindStartingEvent = function () {
+ var startingLink = document.getElementById(idOfStartingLink);
+ if (startingLink) {
+ startingLink.onclick = privateMethods.addStartingEventToCookie;
+ }
+ };
+
+
+ privateMethods.doLandOnPageEvents = function () {
+ var i = 0, interestingIds = Object.keys(eventsForInterestingPages),
+ id = document.getElementsByTagName("body")[0].getAttribute("id");
+
+ if (id === idOfBodyTagAtEnd) {
+ privateMethods.sendEvent(endingEvent);
+ }
+
+ for (i = 0; i < interestingIds.length; (i += 1)) {
+ if (id === interestingIds[i]) {
+ privateMethods.sendEvent(eventsForInterestingPages[interestingIds[i]]);
+ }
+ }
+ };
+
+
+ privateMethods.jsonEqual = function (a, b) {
+ return JSON.stringify(a) === JSON.stringify(b);
+ };
+
+
+ privateMethods.sendEvent = function (data) {
+ if (data.stage === undefined && data === endingEvent) {
+ data.stage = Object.keys(eventsForInterestingPages).length + 1;
+ }
+
+ if (data.stage === undefined && privateMethods.jsonEqual(data, startingEvent)) {
+ data.stage = 0;
+ }
+
+ sendDataFunction(data);
+ };
+
+
+ return {
+ init: init,
+ cookieName: cookieName,
+ journeyStart: journeyStart,
+ journeyEnd: journeyEnd,
+ journeyStage: journeyStage,
+ sendFunction: sendFunction,
+ cookiePath: cookiePath
+ };
+
+}()));
+// @depend ../script/patch.js
+// @depend ../script/namespace.js
+// @depend ../script/cookieUtils.js
+// @depend ../script/lightGate.js
+
View
7 release/lightGate.0.2.0.min.js
@@ -0,0 +1,7 @@
+Object.keys||(Object.keys=function(){var c=Object.prototype.hasOwnProperty,b=!{toString:null}.propertyIsEnumerable("toString"),g="toString toLocaleString valueOf hasOwnProperty isPrototypeOf propertyIsEnumerable constructor".split(" "),d=g.length;return function(e){if("object"!==typeof e&&"function"!==typeof e||null===e)throw new TypeError("Object.keys called on non-object");var k=[],f;for(f in e)c.call(e,f)&&k.push(f);if(b)for(f=0;f<d;f+=1)c.call(e,g[f])&&k.push(g[f]);return k}}());
+var GOVUK=GOVUK||{};GOVUK.performance={};GOVUK.performance.addToNamespace=function(c,b){if(void 0===GOVUK.performance[c])GOVUK.performance[c]=b;else throw Error("There is already a key: '"+c+"' in the namespace.");};GOVUK.performance.close=function(){GOVUK.performance.addToNamespace=void 0;GOVUK.performance.close=void 0};
+GOVUK.performance.addToNamespace("cookieUtils",function(){var c;c=function(){for(var b=[],c=document.cookie.split(";"),d=0,e,d=0;d<c.length;d+=1)e=c[d].split("="),b.push({key:e[0].trim(),value:e[1]?e[1].trim():void 0});return b};return{cookiesAsKeyValues:c,getCookieNamed:function(b){for(var g=c(),d=0,d=0;d<g.length;d+=1)if(g[d].key===b)return g[d]},setSessionCookie:function(b){document.cookie=b.key+"="+b.value+(void 0===b.path?"; Path=/":"; Path="+b.path)},deleteCookieNamed:function(b){document.cookie=
+b.trim()+"=deleted;expires="+(new Date(0)).toUTCString()+"; Path=/"},arrayify:function(b){return"[object Array]"!==Object.prototype.toString.call(b)?[b]:b}}}());
+GOVUK.performance.addToNamespace("lightGate",function(){var c="journey_events",b,g,d,e,k,f,l={},m=GOVUK.performance.cookieUtils,h={addStartingEventToCookie:function(){var a={key:c,value:JSON.stringify(d)};void 0!==b&&(a.path=b);m.setSessionCookie(a)},sendCookieEvents:function(){var a=m.getCookieNamed(c),b=0;if(a&&a.value){a=m.arrayify(JSON.parse(a.value));for(b=0;b<a.length;b+=1)h.sendEvent(a[b]);m.deleteCookieNamed(c)}},bindStartingEvent:function(){var a=document.getElementById(g);a&&(a.onclick=
+h.addStartingEventToCookie)},doLandOnPageEvents:function(){var a=0,b=Object.keys(l),c=document.getElementsByTagName("body")[0].getAttribute("id");c===e&&h.sendEvent(k);for(a=0;a<b.length;a+=1)c===b[a]&&h.sendEvent(l[b[a]])},jsonEqual:function(a,b){return JSON.stringify(a)===JSON.stringify(b)},sendEvent:function(a){void 0===a.stage&&a===k&&(a.stage=Object.keys(l).length+1);void 0===a.stage&&h.jsonEqual(a,d)&&(a.stage=0);f(a)}};return{init:function(){h.bindStartingEvent();h.sendCookieEvents();h.doLandOnPageEvents()},
+cookieName:function(a){c=a;return this},journeyStart:function(a){g=a.linkId;d=a.eventObject;return this},journeyEnd:function(a){e=a.bodyId;k=a.eventObject;return this},journeyStage:function(a){void 0===a.eventObject.stage&&(a.eventObject.stage=Object.keys(l).length+1);l[a.bodyId]=a.eventObject;return this},sendFunction:function(a){f=a;return this},cookiePath:function(a){b=a;return this}}}());
View
2  release_templates/lightGateTemplate.js
@@ -1,2 +1,4 @@
+// @depend ../script/patch.js
+// @depend ../script/namespace.js
// @depend ../script/cookieUtils.js
// @depend ../script/lightGate.js
View
5 script/cookieUtils.js
@@ -1,7 +1,8 @@
/*global document:true*/
+/*global GOVUK: true*/
/*jslint indent: 2 */
-var cookieUtils = (function () {
+GOVUK.performance.addToNamespace("cookieUtils", (function () {
var cookiesAsKeyValues, getCookieNamed, setSessionCookie, deleteCookieNamed, arrayify;
@@ -53,4 +54,4 @@ var cookieUtils = (function () {
arrayify: arrayify
};
-}());
+}()));
View
13 script/lightGate.js
@@ -1,10 +1,11 @@
-/*global cookieUtils:true, document:true*/
+/*global document:true*/
+/*global GOVUK: true*/
/*jslint indent: 2 */
-var lightGate = (function () {
-
+GOVUK.performance.addToNamespace("lightGate", (function () {
var nameOfCookie = "journey_events", pathOfCookie, idOfStartingLink, startingEvent,
idOfBodyTagAtEnd, endingEvent, sendDataFunction, eventsForInterestingPages = {},
+ cookieUtils = GOVUK.performance.cookieUtils,
journeyStart, journeyEnd, journeyStage, cookieName, cookiePath, sendFunction, init,
privateMethods = {};
@@ -31,7 +32,7 @@ var lightGate = (function () {
eventsForInterestingPages[stageDescription.bodyId] = stageDescription.eventObject;
return this;
- }
+ };
cookieName = function (name) {
@@ -97,7 +98,7 @@ var lightGate = (function () {
privateMethods.sendEvent(endingEvent);
}
- for (i = 0; i < interestingIds.length; i++) {
+ for (i = 0; i < interestingIds.length; (i += 1)) {
if (id === interestingIds[i]) {
privateMethods.sendEvent(eventsForInterestingPages[interestingIds[i]]);
}
@@ -133,4 +134,4 @@ var lightGate = (function () {
cookiePath: cookiePath
};
-}());
+}()));
View
18 script/namespace.js
@@ -0,0 +1,18 @@
+/*jslint indent: 2 */
+var GOVUK = GOVUK || {};
+GOVUK.performance = {};
+
+GOVUK.performance.addToNamespace = function (name, obj) {
+ if (GOVUK.performance[name] === undefined) {
+ GOVUK.performance[name] = obj;
+ }
+ else {
+ throw new Error("There is already a key: '" + name + "' in the namespace.");
+ }
+};
+
+
+GOVUK.performance.close = function () {
+ GOVUK.performance.addToNamespace = undefined;
+ GOVUK.performance.close = undefined;
+};
View
52 script/patch.js
@@ -1,35 +1,43 @@
+/*jslint indent: 2 */
// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys
if (!Object.keys) {
Object.keys = (function () {
- var hasOwnProperty = Object.prototype.hasOwnProperty,
- hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
- dontEnums = [
- 'toString',
- 'toLocaleString',
- 'valueOf',
- 'hasOwnProperty',
- 'isPrototypeOf',
- 'propertyIsEnumerable',
- 'constructor'
- ],
- dontEnumsLength = dontEnums.length;
+ var hasProperty = Object.prototype.hasOwnProperty,
+ hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
+ dontEnums = [
+ 'toString',
+ 'toLocaleString',
+ 'valueOf',
+ 'hasOwnProperty',
+ 'isPrototypeOf',
+ 'propertyIsEnumerable',
+ 'constructor'
+ ],
+ dontEnumsLength = dontEnums.length;
return function (obj) {
- if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');
+ if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) {
+ throw new TypeError('Object.keys called on non-object');
+ }
- var result = [];
+ var result = [],
+ prop, i;
- for (var prop in obj) {
- if (hasOwnProperty.call(obj, prop)) result.push(prop);
+ for (prop in obj) {
+ if (hasProperty.call(obj, prop)) {
+ result.push(prop);
+ }
}
-
+
if (hasDontEnumBug) {
- for (var i=0; i < dontEnumsLength; i++) {
- if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
+ for (i = 0; i < dontEnumsLength; (i += 1)) {
+ if (hasProperty.call(obj, dontEnums[i])) {
+ result.push(dontEnums[i]);
+ }
}
}
return result;
- }
- })()
-};
+ };
+ }());
+}
View
1  tests/journey_tests/journey_end.html
@@ -15,6 +15,7 @@
<script type="text/javascript" src="../lib/jasmine-1.3.1/jasmine-html.js"></script>
<!-- include source files here... -->
+ <script type="text/javascript" src="../../script/namespace.js"></script>
<script type="text/javascript" src="../../script/cookieUtils.js"></script>
<script type="text/javascript" src="../../script/lightGate.js"></script>
<script type="text/javascript" src="../stubAnalyticsService.js"></script>
View
1  tests/journey_tests/journey_middle.html
@@ -15,6 +15,7 @@
<script type="text/javascript" src="../lib/jasmine-1.3.1/jasmine-html.js"></script>
<!-- include source files here... -->
+ <script type="text/javascript" src="../../script/namespace.js"></script>
<script type="text/javascript" src="../../script/cookieUtils.js"></script>
<script type="text/javascript" src="../../script/lightGate.js"></script>
<script type="text/javascript" src="../stubAnalyticsService.js"></script>
View
1  tests/journey_tests/journey_start.html
@@ -15,6 +15,7 @@
<script type="text/javascript" src="../lib/jasmine-1.3.1/jasmine-html.js"></script>
<!-- include source files here... -->
+ <script type="text/javascript" src="../../script/namespace.js"></script>
<script type="text/javascript" src="../../script/cookieUtils.js"></script>
<script type="text/javascript" src="../../script/lightGate.js"></script>
<script type="text/javascript" src="../stubAnalyticsService.js"></script>
View
2  tests/journey_tests/lightGateExampleSetup.js
@@ -1,4 +1,4 @@
-lightGate.cookieName("test_journey")
+GOVUK.performance.lightGate.cookieName("test_journey")
.sendFunction(stubAnalyticsService.post)
.journeyStart({ linkId: "start", eventObject: {message: "hello"} })
.journeyStage({ bodyId: "middle", eventObject: {message: "ping"} })
View
2  tests/unit/cookieUtilsSpec.js
@@ -1,5 +1,7 @@
describe("cookie utils", function () {
+ var cookieUtils = GOVUK.performance.cookieUtils;
+
beforeEach(function () {
document.cookie = 'foo="bar"' + '; Path=/';
document.cookie = ' zap = "pow"' + '; Path=/';
View
4 tests/unit/lightGateSpec.js
@@ -17,7 +17,9 @@ describe("lightGate.js - journey tracking for google analytics", function () {
'action': "something_happened",
"label": "some_label",
"nonInteraction": true
- };
+ },
+ cookieUtils = GOVUK.performance.cookieUtils,
+ lightGate = GOVUK.performance.lightGate;
// BEFORE ALL
View
22 tests/unit/namespaceSpec.js
@@ -0,0 +1,22 @@
+describe("namespacing", function () {
+
+ it("should add to the namespace", function () {
+ GOVUK.performance.addToNamespace("foo", function () { return "bar"; });
+ expect(GOVUK.performance.foo()).toBe("bar");
+ });
+
+
+ it("should throw an exception if the name already exists and not add to the namespace", function () {
+ expect(function () { GOVUK.performance.addToNamespace("foo", "blah blah blah"); })
+ .toThrow(new Error("There is already a key: 'foo' in the namespace."));
+ expect(GOVUK.performance.foo()).toBe("bar");
+ });
+
+
+ it("should remove namespace helpers when closed", function () {
+ GOVUK.performance.close();
+ expect(function () { GOVUK.performance.addToNamespace("test", {}); }).toThrow("Property 'addToNamespace' of object #<Object> is not a function");
+ expect(function () { GOVUK.performance.close(); }).toThrow("Property 'close' of object #<Object> is not a function");
+ });
+
+});
View
4 tests/unit/unit_tests.html
@@ -12,10 +12,12 @@
<script type="text/javascript" src="../lib/jasmine-1.3.1/jasmine-html.js"></script>
<!-- include source files here... -->
- <script type="text/javascript" src="../../script/lightGate.js"></script>
+ <script type="text/javascript" src="../../script/namespace.js"></script>
<script type="text/javascript" src="../../script/cookieUtils.js"></script>
+ <script type="text/javascript" src="../../script/lightGate.js"></script>
<!-- include spec files here... -->
+ <script type="text/javascript" src="namespaceSpec.js"></script>
<script type="text/javascript" src="../stubAnalyticsService.js"></script>
<script type="text/javascript" src="lightGateSpec.js"></script>
<script type="text/javascript" src="cookieUtilsSpec.js"></script>
Please sign in to comment.
Something went wrong with that request. Please try again.