Skip to content
This repository was archived by the owner on Jan 10, 2024. It is now read-only.

Commit 0c1e81f

Browse files
author
Pat Patterson
committed
Remove jQuery dependencies
1 parent f2562ca commit 0c1e81f

File tree

1 file changed

+160
-92
lines changed

1 file changed

+160
-92
lines changed

forcetk.js

Lines changed: 160 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
* console, go to Your Name | Setup | Security Controls | Remote Site Settings
3333
*/
3434

35-
/*jslint browser: true*/
36-
/*global alert, Blob, $, jQuery*/
35+
/*jslint browser: true, plusplus: true*/
36+
/*global alert, Blob*/
3737

3838
var forcetk = window.forcetk;
3939

@@ -96,38 +96,44 @@ if (forcetk.Client === undefined) {
9696
*/
9797
forcetk.Client.prototype.refreshAccessToken = function (callback, error) {
9898
'use strict';
99-
var that = this,
100-
url = this.loginUrl + '/services/oauth2/token';
101-
return $.ajax({
102-
type: 'POST',
103-
url: (this.proxyUrl !== null && !this.visualforce) ? this.proxyUrl : url,
104-
cache: false,
105-
processData: false,
106-
data: 'grant_type=refresh_token&client_id=' + this.clientId + '&refresh_token=' + this.refreshToken,
107-
success: callback,
108-
error: error,
109-
dataType: "json",
110-
beforeSend: function (xhr) {
111-
if (that.proxyUrl !== null && !this.visualforce) {
112-
xhr.setRequestHeader('SalesforceProxy-Endpoint', url);
99+
var xhr = new XMLHttpRequest(),
100+
url = this.loginUrl + '/services/oauth2/token',
101+
payload = 'grant_type=refresh_token&client_id=' + this.clientId + '&refresh_token=' + this.refreshToken;
102+
103+
xhr.onreadystatechange = function () {
104+
if (xhr.readyState === 4) {
105+
if (xhr.status > 199 && xhr.status < 300) {
106+
if (callback) {
107+
callback(xhr.responseText ? JSON.parse(xhr.responseText) : undefined);
108+
}
109+
} else {
110+
console.error(xhr.responseText);
111+
if (error) {
112+
error(xhr);
113+
}
113114
}
114115
}
115-
});
116+
};
117+
118+
xhr.open('POST', url, true);
119+
xhr.setRequestHeader("Accept", "application/json");
120+
xhr.setRequestHeader('X-User-Agent', 'salesforce-toolkit-rest-javascript/' + this.apiVersion);
121+
xhr.send(payload);
116122
};
117123

118124
/**
119125
* Set a session token and the associated metadata in the client.
120126
* @param sessionId a salesforce.com session ID. In a Visualforce page,
121127
* use '{!$Api.sessionId}' to obtain a session ID.
122-
* @param [apiVersion="v29.0"] Force.com API version
128+
* @param [apiVersion="v36.0"] Force.com API version
123129
* @param [instanceUrl] Omit this if running on Visualforce; otherwise
124130
* use the value from the OAuth token.
125131
*/
126132
forcetk.Client.prototype.setSessionToken = function (sessionId, apiVersion, instanceUrl) {
127133
'use strict';
128134
this.sessionId = sessionId;
129135
this.apiVersion = (apiVersion === undefined || apiVersion === null)
130-
? 'v29.0' : apiVersion;
136+
? 'v36.0' : apiVersion;
131137
if (instanceUrl === undefined || instanceUrl === null) {
132138
this.visualforce = true;
133139

@@ -150,49 +156,73 @@ if (forcetk.Client === undefined) {
150156
}
151157
};
152158

159+
var nonce = +(new Date());
160+
var rquery = (/\?/);
161+
153162
/*
154163
* Low level utility function to call the Salesforce endpoint.
155164
* @param path resource path relative to /services/data
156165
* @param callback function to which response will be passed
157166
* @param [error=null] function to which jqXHR will be passed in case of error
158167
* @param [method="GET"] HTTP method for call
159-
* @param [payload=null] payload for POST/PATCH etc
168+
* @param [payload=null] string payload for POST/PATCH etc
160169
*/
161170
forcetk.Client.prototype.ajax = function (path, callback, error, method, payload, retry) {
162171
'use strict';
163-
var that = this,
164-
url = (this.visualforce ? '' : this.instanceUrl) + '/services/data' + path;
165-
166-
return $.ajax({
167-
type: method || "GET",
168-
async: this.asyncAjax,
169-
url: (this.proxyUrl !== null && !this.visualforce) ? this.proxyUrl : url,
170-
contentType: method === "DELETE" ? null : 'application/json',
171-
cache: false,
172-
processData: false,
173-
data: payload,
174-
success: callback,
175-
error: (!this.refreshToken || retry) ? error : function (jqXHR, textStatus, errorThrown) {
176-
if (jqXHR.status === 401) {
177-
that.refreshAccessToken(function (oauthResponse) {
178-
that.setSessionToken(oauthResponse.access_token, null,
179-
oauthResponse.instance_url);
180-
that.ajax(path, callback, error, method, payload, true);
181-
},
182-
error);
183-
} else {
184-
error(jqXHR, textStatus, errorThrown);
185-
}
186-
},
187-
dataType: "json",
188-
beforeSend: function (xhr) {
189-
if (that.proxyUrl !== null && !that.visualforce) {
190-
xhr.setRequestHeader('SalesforceProxy-Endpoint', url);
172+
173+
// dev friendly API: Add leading '/' if missing so url + path concat always works
174+
if (path.charAt(0) !== '/') {
175+
path = '/' + path;
176+
}
177+
178+
var xhr = new XMLHttpRequest(),
179+
url = (this.visualforce ? '' : this.instanceUrl) + '/services/data' + path,
180+
that = this;
181+
182+
method = method || 'GET';
183+
184+
// Cache-busting logic inspired by jQuery
185+
url = url + (rquery.test(url) ? "&" : "?") + "_=" + nonce++;
186+
187+
if (this.asyncAjax) {
188+
xhr.onreadystatechange = function () {
189+
if (xhr.readyState === 4) {
190+
if (xhr.status > 199 && xhr.status < 300) {
191+
if (callback) {
192+
callback(xhr.responseText ? JSON.parse(xhr.responseText) : undefined);
193+
}
194+
} else if (xhr.status === 401 && that.refresh_token) {
195+
if (retry) {
196+
console.error(xhr.responseText);
197+
error(xhr);
198+
} else {
199+
that.refreshAccessToken(function (oauthResponse) {
200+
that.setSessionToken(oauthResponse.access_token, null,
201+
oauthResponse.instance_url);
202+
that.ajax(path, callback, error, method, payload, true);
203+
},
204+
error);
205+
}
206+
} else {
207+
console.error(xhr.responseText);
208+
if (error) {
209+
error(xhr);
210+
}
211+
}
191212
}
192-
xhr.setRequestHeader(that.authzHeader, "Bearer " + that.sessionId);
193-
xhr.setRequestHeader('X-User-Agent', 'salesforce-toolkit-rest-javascript/' + that.apiVersion);
194-
}
195-
});
213+
};
214+
}
215+
216+
xhr.open(method, url, this.asyncAjax);
217+
xhr.setRequestHeader("Accept", "application/json");
218+
xhr.setRequestHeader(this.authzHeader, "Bearer " + this.sessionId);
219+
xhr.setRequestHeader('X-User-Agent', 'salesforce-toolkit-rest-javascript/' + this.apiVersion);
220+
if (method !== "DELETE") {
221+
xhr.setRequestHeader("Content-Type", 'application/json');
222+
}
223+
xhr.send(payload);
224+
225+
return this.asyncAjax ? null : JSON.parse(xhr.responseText);
196226
};
197227

198228
/**
@@ -374,6 +404,19 @@ if (forcetk.Client === undefined) {
374404
'?_HttpMethod=PATCH', fields, filename, payloadField, payload, callback, error, retry);
375405
};
376406

407+
var param = function (data) {
408+
'use strict';
409+
var r20 = /%20/g,
410+
s = [],
411+
key;
412+
for (key in data) {
413+
if (data.hasOwnProperty(key)) {
414+
s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(data[key]);
415+
}
416+
}
417+
return s.join("&").replace(r20, "+");
418+
};
419+
377420
/*
378421
* Low level utility function to call the Salesforce endpoint specific for Apex REST API.
379422
* @param path resource path relative to /services/apexrest
@@ -386,16 +429,24 @@ if (forcetk.Client === undefined) {
386429
*/
387430
forcetk.Client.prototype.apexrest = function (path, callback, error, method, payload, paramMap, retry) {
388431
'use strict';
389-
var that = this,
390-
url = this.instanceUrl + '/services/apexrest' + path;
391432

392-
method = method || "GET";
433+
// dev friendly API: Add leading '/' if missing so url + path concat always works
434+
if (path.charAt(0) !== '/') {
435+
path = '/' + path;
436+
}
437+
438+
var xhr = new XMLHttpRequest(),
439+
that = this,
440+
url = this.instanceUrl + '/services/apexrest' + path,
441+
paramName;
442+
443+
method = method || 'GET';
393444

394445
if (method === "GET") {
395446
// Handle proxied query params correctly
396447
if (this.proxyUrl && payload) {
397448
if (typeof payload !== 'string') {
398-
payload = $.param(payload);
449+
payload = param(payload);
399450
}
400451
url += "?" + payload;
401452
payload = null;
@@ -407,47 +458,64 @@ if (forcetk.Client === undefined) {
407458
}
408459
}
409460

410-
return $.ajax({
411-
type: method,
412-
async: this.asyncAjax,
413-
url: this.proxyUrl || url,
414-
contentType: 'application/json',
415-
cache: false,
416-
processData: false,
417-
data: payload,
418-
success: callback,
419-
error: (!this.refreshToken || retry) ? error : function (jqXHR, textStatus, errorThrown) {
420-
if (jqXHR.status === 401) {
421-
that.refreshAccessToken(function (oauthResponse) {
422-
that.setSessionToken(oauthResponse.access_token, null,
423-
oauthResponse.instance_url);
424-
that.apexrest(path, callback, error, method, payload, paramMap, true);
425-
}, error);
426-
} else {
427-
error(jqXHR, textStatus, errorThrown);
428-
}
429-
},
430-
dataType: "json",
431-
beforeSend: function (xhr) {
432-
var paramName;
433-
if (that.proxyUrl !== null) {
434-
xhr.setRequestHeader('SalesforceProxy-Endpoint', url);
435-
}
436-
//Add any custom headers
437-
if (paramMap === null) {
438-
paramMap = {};
439-
}
440-
for (paramName in paramMap) {
441-
if (paramMap.hasOwnProperty(paramName)) {
442-
xhr.setRequestHeader(paramName, paramMap[paramName]);
461+
// Cache-busting logic inspired by jQuery
462+
url = url + (rquery.test(url) ? "&" : "?") + "_=" + nonce++;
463+
464+
if (this.asyncAjax) {
465+
xhr.onreadystatechange = function () {
466+
if (xhr.readyState === 4) {
467+
if (xhr.status > 199 && xhr.status < 300) {
468+
if (callback) {
469+
callback(xhr.responseText ? JSON.parse(xhr.responseText) : undefined);
470+
}
471+
} else if (xhr.status === 401 && that.refresh_token) {
472+
if (retry) {
473+
console.error(xhr.responseText);
474+
error(xhr);
475+
} else {
476+
that.refreshAccessToken(function (oauthResponse) {
477+
that.setSessionToken(oauthResponse.access_token, null,
478+
oauthResponse.instance_url);
479+
that.apexrest(path, callback, error, method, payload, paramMap, true);
480+
},
481+
error);
482+
}
483+
} else {
484+
console.error(xhr.responseText);
485+
if (error) {
486+
error(xhr);
487+
}
443488
}
444489
}
445-
xhr.setRequestHeader(that.authzHeader, "Bearer " + that.sessionId);
446-
xhr.setRequestHeader('X-User-Agent', 'salesforce-toolkit-rest-javascript/' + that.apiVersion);
490+
};
491+
}
492+
493+
xhr.open(method, this.proxyUrl || url, this.asyncAjax);
494+
xhr.setRequestHeader("Accept", "application/json");
495+
xhr.setRequestHeader(this.authzHeader, "Bearer " + this.sessionId);
496+
xhr.setRequestHeader('X-User-Agent', 'salesforce-toolkit-rest-javascript/' + this.apiVersion);
497+
xhr.setRequestHeader("Content-Type", 'application/json');
498+
499+
//Add any custom headers
500+
if (paramMap === null) {
501+
paramMap = {};
502+
}
503+
for (paramName in paramMap) {
504+
if (paramMap.hasOwnProperty(paramName)) {
505+
xhr.setRequestHeader(paramName, paramMap[paramName]);
447506
}
448-
});
507+
}
508+
509+
if (that.proxyUrl !== null) {
510+
xhr.setRequestHeader('SalesforceProxy-Endpoint', url);
511+
}
512+
513+
xhr.send(payload);
514+
515+
return this.asyncAjax ? null : JSON.parse(xhr.responseText);
449516
};
450517

518+
451519
/*
452520
* Lists summary information about each Salesforce.com version currently
453521
* available, including the version, label, and a link to each version's

0 commit comments

Comments
 (0)