UNPKG

4.44 kBJavaScriptView Raw
1import window from "window"
2import document from "document"
3import objMap from "./helpers/objMap"
4import dataLayerPush from "./helpers/dataLayerPush"
5import forEach from "lodash-es/forEach"
6import isUndefined from "lodash-es/isUndefined"
7import indexOf from "lodash-es/indexOf"
8import MeasurementFramework from "./MeasurementFramework"
9import merge from "lodash-es/merge"
10
11let actionCount = {}
12
13const createActionIdentifier = function (query, actionIds) {
14 let ident = []
15 forEach(actionIds, function (actionId) {
16 if (!isUndefined(query[actionId])) {
17 ident.push(query[actionId])
18 }
19 })
20 return ident.join(".")
21}
22
23/**
24 *
25 * @param ajaxCompleteCallback
26 * @param actionIds
27 */
28const ajaxComplete = function (ajaxCompleteCallback, actionIds) {
29 'use strict'
30 let jquery
31 let n = 0
32 let allParams = []
33
34 /**
35 * This code would benefit from being run with the domReady module.
36 */
37 const init = function () {
38 // Ensure jQuery is available before anything
39 if (typeof window.jQuery !== 'undefined') {
40 // Define our $ shortcut locally
41 jquery = window.jQuery
42 bindToAjax()
43 // Check for up to 10 seconds
44 } else if (n < 20) {
45 n++
46 setTimeout(init, 500)
47 }
48 }
49
50 MeasurementFramework.register(function () {
51 init()
52 return {
53 "ajaxCompleteLoaded": true
54 }
55 })
56
57 function noop() {}
58
59 function bindToAjax() {
60 jquery(document).bind('ajaxComplete', function (evt, jqXhr, opts) {
61 // Create a fake a element for magically simple URL parsing
62 let fullUrl = document.createElement('a')
63 fullUrl.href = opts.url
64 // Manually remove the leading question mark, if there is one
65 let queryString = fullUrl.search[0] === '?' ? fullUrl.search.slice(1) : fullUrl.search
66 let qs = []
67 if (queryString) {
68 qs.push(queryString)
69 }
70 if (opts.data) {
71 qs.push(opts.data)
72 }
73
74 // Turn our params and headers into objects for easier reference
75 let queryParameters = objMap(qs.join('&'), '&', '=', true)
76
77 forEach(queryParameters, function (val, key) {
78 if (indexOf(allParams, key) === -1) {
79 allParams.push(key)
80 }
81 })
82 forEach(allParams, function (value) {
83 if (isUndefined(queryParameters[value])) {
84 queryParameters[value] = noop()
85 }
86 })
87
88
89 /**
90 * Request Object
91 */
92 let request = {
93 // Return empty strings to prevent accidental inheritance of old data
94 'type': opts.type || noop(),
95 'url': fullUrl.href || noop(),
96 'query': queryParameters,
97 'contentType': opts.contentType || noop()
98 }
99 if (isUndefined(request.query)) {
100 request.query = {}
101 }
102
103 /**
104 * Creating and counting ajax Action
105 */
106 request.actionId = createActionIdentifier(request.query, actionIds)
107 if (actionCount[request.actionId]) {
108 actionCount[request.actionId]++
109 } else {
110 actionCount[request.actionId] = 1
111 }
112 request.actionCount = actionCount[request.actionId]
113
114
115 /**
116 * Response Object
117 */
118 let headers = objMap(jqXhr.getAllResponseHeaders(), '\n', ':')
119 let response = {
120 // Return empty strings to prevent accidental inheritance of old data
121 'statusCode': jqXhr.status || noop(),
122 'statusText': jqXhr.statusText || noop(),
123 'headers': headers,
124 'timestamp': evt.timeStamp || noop(),
125 'body': jqXhr.responseJSON || noop()
126 }
127 if (isUndefined(response.body)) {
128 response.body = {}
129 }
130
131 let dlPush = {
132 'ajax': merge(request, response)
133 }
134
135 let result = ajaxCompleteCallback(request, response)
136 dlPush = merge(result, dlPush)
137 dataLayerPush('Ajax Complete',dlPush)
138 })
139
140 }
141
142}
143
144export default ajaxComplete
\No newline at end of file