├── .gitignore ├── CODEOWNERS ├── CODE_OF_CONDUCT.md ├── LICENSE.txt ├── README.md ├── SECURITY.md ├── callback.html ├── css └── canvas.css ├── docs ├── files.html ├── index.html └── symbols │ ├── Sfdc.canvas.client.html │ ├── Sfdc.canvas.html │ ├── Sfdc.canvas.oauth.html │ ├── _global_.html │ └── src │ ├── SalesforceCanvasJavascriptSDK_js_canvas-all.js.html │ ├── SalesforceCanvasJavascriptSDK_js_canvas.js.html │ ├── SalesforceCanvasJavascriptSDK_js_client.js.html │ ├── SalesforceCanvasJavascriptSDK_js_client.js.html.orig │ ├── SalesforceCanvasJavascriptSDK_js_cookies.js.html │ ├── SalesforceCanvasJavascriptSDK_js_oauth.js.html │ └── SalesforceCanvasJavascriptSDK_js_xd.js.html ├── js ├── canvas-all.js ├── canvas.js ├── client.js ├── cookies.js ├── oauth.js └── xd.js ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /node_modules/ 3 | /.vscode/ 4 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Comment line immediately above ownership line is reserved for related gus information. Please be careful while editing. 2 | #ECCN:Open Source 3 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Salesforce Open Source Community Code of Conduct 2 | 3 | ## About the Code of Conduct 4 | 5 | Equality is a core value at Salesforce. We believe a diverse and inclusive 6 | community fosters innovation and creativity, and are committed to building a 7 | culture where everyone feels included. 8 | 9 | Salesforce open-source projects are committed to providing a friendly, safe, and 10 | welcoming environment for all, regardless of gender identity and expression, 11 | sexual orientation, disability, physical appearance, body size, ethnicity, nationality, 12 | race, age, religion, level of experience, education, socioeconomic status, or 13 | other similar personal characteristics. 14 | 15 | The goal of this code of conduct is to specify a baseline standard of behavior so 16 | that people with different social values and communication styles can work 17 | together effectively, productively, and respectfully in our open source community. 18 | It also establishes a mechanism for reporting issues and resolving conflicts. 19 | 20 | All questions and reports of abusive, harassing, or otherwise unacceptable behavior 21 | in a Salesforce open-source project may be reported by contacting the Salesforce 22 | Open Source Conduct Committee at ossconduct@salesforce.com. 23 | 24 | ## Our Pledge 25 | 26 | In the interest of fostering an open and welcoming environment, we as 27 | contributors and maintainers pledge to making participation in our project and 28 | our community a harassment-free experience for everyone, regardless of gender 29 | identity and expression, sexual orientation, disability, physical appearance, 30 | body size, ethnicity, nationality, race, age, religion, level of experience, education, 31 | socioeconomic status, or other similar personal characteristics. 32 | 33 | ## Our Standards 34 | 35 | Examples of behavior that contributes to creating a positive environment 36 | include: 37 | 38 | * Using welcoming and inclusive language 39 | * Being respectful of differing viewpoints and experiences 40 | * Gracefully accepting constructive criticism 41 | * Focusing on what is best for the community 42 | * Showing empathy toward other community members 43 | 44 | Examples of unacceptable behavior by participants include: 45 | 46 | * The use of sexualized language or imagery and unwelcome sexual attention or 47 | advances 48 | * Personal attacks, insulting/derogatory comments, or trolling 49 | * Public or private harassment 50 | * Publishing, or threatening to publish, others' private information—such as 51 | a physical or electronic address—without explicit permission 52 | * Other conduct which could reasonably be considered inappropriate in a 53 | professional setting 54 | * Advocating for or encouraging any of the above behaviors 55 | 56 | ## Our Responsibilities 57 | 58 | Project maintainers are responsible for clarifying the standards of acceptable 59 | behavior and are expected to take appropriate and fair corrective action in 60 | response to any instances of unacceptable behavior. 61 | 62 | Project maintainers have the right and responsibility to remove, edit, or 63 | reject comments, commits, code, wiki edits, issues, and other contributions 64 | that are not aligned with this Code of Conduct, or to ban temporarily or 65 | permanently any contributor for other behaviors that they deem inappropriate, 66 | threatening, offensive, or harmful. 67 | 68 | ## Scope 69 | 70 | This Code of Conduct applies both within project spaces and in public spaces 71 | when an individual is representing the project or its community. Examples of 72 | representing a project or community include using an official project email 73 | address, posting via an official social media account, or acting as an appointed 74 | representative at an online or offline event. Representation of a project may be 75 | further defined and clarified by project maintainers. 76 | 77 | ## Enforcement 78 | 79 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 80 | reported by contacting the Salesforce Open Source Conduct Committee 81 | at ossconduct@salesforce.com. All complaints will be reviewed and investigated 82 | and will result in a response that is deemed necessary and appropriate to the 83 | circumstances. The committee is obligated to maintain confidentiality with 84 | regard to the reporter of an incident. Further details of specific enforcement 85 | policies may be posted separately. 86 | 87 | Project maintainers who do not follow or enforce the Code of Conduct in good 88 | faith may face temporary or permanent repercussions as determined by other 89 | members of the project's leadership and the Salesforce Open Source Conduct 90 | Committee. 91 | 92 | ## Attribution 93 | 94 | This Code of Conduct is adapted from the [Contributor Covenant][contributor-covenant-home], 95 | version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html. 96 | It includes adaptions and additions from [Go Community Code of Conduct][golang-coc], 97 | [CNCF Code of Conduct][cncf-coc], and [Microsoft Open Source Code of Conduct][microsoft-coc]. 98 | 99 | This Code of Conduct is licensed under the [Creative Commons Attribution 3.0 License][cc-by-3-us]. 100 | 101 | [contributor-covenant-home]: https://www.contributor-covenant.org (https://www.contributor-covenant.org/) 102 | [golang-coc]: https://golang.org/conduct 103 | [cncf-coc]: https://github.com/cncf/foundation/blob/master/code-of-conduct.md 104 | [microsoft-coc]: https://opensource.microsoft.com/codeofconduct/ 105 | [cc-by-3-us]: https://creativecommons.org/licenses/by/3.0/us/ 106 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Salesforce.com, Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 9 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SalesforceCanvasJavascriptSDK 2 | 3 | A JavaScript SDK used to integrate applications with the Force.com Canvas framework 4 | 5 | ### Introduction 6 | 7 | Force.com Canvas is a mechanism for consuming third-party applications within Salesforce. Its goal is to connect applications at a UI level instead of just an API level. The purpose of this GitHub repository is to provide third-party applications with a JavaScript SDK so you can easily integrate canvas-style applications into Salesforce, while developing in the technology and platform of your choice. 8 | 9 | The best place to get started building canvas applications is the [online developer's guide](https://developer.salesforce.com/docs/atlas.en-us.platform_connect.meta/platform_connect/canvas_framework_intro.htm). 10 | 11 | Currently, we provide Java and Ruby examples, but you can develop in whatever language you prefer. Most of the integration with Salesforce is through JavaScript and REST. You can also run and test your application locally from your own host, or from [Heroku](http://www.heroku.com/). For a quick example of how to create a Java Canvas application, please see the [SalesforceCanvasFrameworkSDK GitHub project](https://github.com/forcedotcom/SalesforceCanvasFrameworkSDK). 12 | 13 | ### How to install the SDK (using _npm_) 14 | 15 | npm install @salesforce/canvas-js-sdk 16 | 17 | Then add a ` 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /css/canvas.css: -------------------------------------------------------------------------------- 1 | /** * Copyright (c) 2011, salesforce.com, inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and * the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or * promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ 2 | body { 3 | margin: 0; 4 | margin-bottom: 0; 5 | margin-top: 0; 6 | padding: 10px; 7 | background-color: #FFFFFF; 8 | font-family: "Arial", "Helvetica", "sans-serif"; 9 | font-size: 75%; 10 | color: #222222 11 | } 12 | 13 | h1 { 14 | font-size: 28px; 15 | color: #000 16 | } 17 | 18 | a { 19 | color: #015BA7 20 | } 21 | 22 | a:hover { 23 | background-color: #015BA7; 24 | color: white; 25 | text-decoration: none 26 | } 27 | 28 | #page { 29 | background-color: #FFFFFF; 30 | width: 800px; 31 | margin: 0; 32 | margin-left: 0; 33 | margin-right: 0 34 | } 35 | 36 | #content { 37 | float: left; 38 | background-color: white; 39 | border: 3px solid #aaa; 40 | padding: 25px; 41 | width: 700px 42 | } 43 | 44 | #footer { 45 | clear: both 46 | } 47 | 48 | #header { 49 | padding-left: 75px; 50 | padding-right: 30px 51 | } 52 | 53 | #canvas-content { 54 | padding-top: 25px; 55 | padding-left: 0px; 56 | padding-right: 30px 57 | } 58 | 59 | #header { 60 | background-image: url("/logo.png"); 61 | background-repeat: no-repeat; 62 | background-position: top left; 63 | height: 64px 64 | } 65 | 66 | #header h1, #header h2 { 67 | margin: 0 68 | } 69 | 70 | #header h2 { 71 | color: #888; 72 | font-weight: normal; 73 | font-size: 16px 74 | } 75 | 76 | #canvas-content { 77 | border-top: 1px solid #ccc; 78 | margin-top: 20px; 79 | padding-top: 0 80 | } 81 | 82 | #canvas-content h1 { 83 | margin: 0; 84 | font-size: 20px 85 | } 86 | 87 | #canvas-content h2 { 88 | margin: 0; 89 | font-size: 14px; 90 | font-weight: normal; 91 | color: #333; 92 | margin-bottom: 25px 93 | } 94 | 95 | #canvas-content ol { 96 | margin-left: 0; 97 | padding-left: 0 98 | } 99 | 100 | #canvas-content li { 101 | font-size: 18px; 102 | color: #888; 103 | margin-bottom: 25px 104 | } 105 | 106 | #canvas-content li h2 { 107 | margin: 0; 108 | font-weight: normal; 109 | font-size: 18px; 110 | color: #333 111 | } 112 | 113 | #canvas-content li p { 114 | color: #555; 115 | font-size: 13px 116 | } 117 | 118 | #canvas-chatter { 119 | border-top: 1px solid #ccc; 120 | margin-top: 20px; 121 | padding-top: 0 122 | } 123 | 124 | #speech-input-field { 125 | width: 400px; 126 | height: 14px; 127 | padding: 6px 15px; 128 | border-radius: 10px; 129 | border: 1px solid #ccc; 130 | outline: 0; 131 | } 132 | 133 | button { 134 | clear: both; 135 | width: 48px; 136 | height:24px; 137 | background: #666666 url(/images/share.png) no-repeat; 138 | } 139 | 140 | #footercont 141 | { 142 | float: left; 143 | width: 700px; 144 | height: 50px; 145 | color: #999; 146 | } 147 | 148 | #footercont p 149 | { 150 | margin: 0; 151 | padding: 15px; 152 | } 153 | 154 | #footercont a 155 | { 156 | color: #999; 157 | text-decoration: none; 158 | } 159 | 160 | #footercont a:hover 161 | { 162 | color: #199BD2; 163 | text-decoration: none; 164 | } 165 | 166 | #footerleft 167 | { 168 | float: left; 169 | width: 400px; 170 | height: 50px; 171 | } 172 | 173 | #footerright 174 | { 175 | float: left; 176 | width: 300px; 177 | height: 50px; 178 | text-align: right; 179 | } 180 | -------------------------------------------------------------------------------- /docs/files.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | JsDoc Reference - File Index 8 | 9 | 10 | 174 | 175 | 176 | 177 | 179 | 180 |
181 |
Class Index 182 | | File Index
183 |
184 |

Classes

185 | 196 |
197 |
198 | 199 |
200 |

File Index

201 | 202 | 203 |
204 |

../SalesforceCanvasJavascriptSDK/js/canvas-all.js

205 | 206 |
207 | 208 | 209 | 210 | 211 |
212 |
213 |
214 | 215 |
216 |

../SalesforceCanvasJavascriptSDK/js/canvas.js

217 | 218 |
219 | 220 | 221 | 222 | 223 |
224 |
225 |
226 | 227 |
228 |

../SalesforceCanvasJavascriptSDK/js/client.js

229 | 230 |
231 | 232 | 233 | 234 | 235 |
236 |
237 |
238 | 239 |
240 |

../SalesforceCanvasJavascriptSDK/js/cookies.js

241 | 242 |
243 | 244 | 245 | 246 | 247 |
248 |
249 |
250 | 251 |
252 |

../SalesforceCanvasJavascriptSDK/js/oauth.js

253 | 254 |
255 | 256 | 257 | 258 | 259 |
260 |
261 |
262 | 263 |
264 |

../SalesforceCanvasJavascriptSDK/js/xd.js

265 | 266 |
267 | 268 | 269 | 270 | 271 |
272 |
273 |
274 | 275 | 276 |
277 |
278 | 279 | Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 15 2014 13:44:12 GMT-0700 (PDT) 280 |
281 | 282 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | JsDoc Reference - Index 8 | 9 | 10 | 174 | 175 | 176 | 177 | 179 | 180 |
181 |
Class Index 182 | | File Index
183 |
184 |

Classes

185 | 196 |
197 |
198 | 199 |
200 |

Class Index

201 | 202 | 203 |
204 |

_global_

205 | 206 |
207 |
208 | 209 |
210 |

Sfdc.canvas

211 | Canvas 212 |
213 |
214 | 215 |
216 |

Sfdc.canvas.client

217 | Sfdc.canvas.client 218 |
219 |
220 | 221 |
222 |

Sfdc.canvas.oauth

223 | Sfdc.canvas.oauth 224 |
225 |
226 | 227 | 228 |
229 |
230 | 231 | Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 15 2014 13:44:12 GMT-0700 (PDT) 232 |
233 | 234 | -------------------------------------------------------------------------------- /docs/symbols/Sfdc.canvas.client.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | JsDoc Reference - Sfdc.canvas.client 9 | 10 | 174 | 175 | 176 | 177 | 178 | 179 | 181 | 182 | 183 | 184 |
185 | 186 |
Class Index 187 | | File Index
188 |
189 |

Classes

190 | 201 |
202 | 203 |
204 | 205 |
206 | 207 |

208 | 209 | Namespace Sfdc.canvas.client 210 |

211 | 212 | 213 |

214 | 215 | 216 | 217 | Sfdc.canvas.client 218 | 219 | 220 |
Defined in: client.js. 221 | 222 |

223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 243 | 244 | 245 |
Namespace Summary
Constructor AttributesConstructor Name and Description
  238 |
239 | Sfdc.canvas.client 240 |
241 |
242 |
246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 272 | 273 | 274 | 275 | 276 | 282 | 283 | 284 | 285 | 286 | 291 | 292 | 293 | 294 | 295 | 300 | 301 | 302 | 303 | 304 | 309 | 310 | 311 | 312 | 313 | 318 | 319 | 320 | 321 | 322 | 327 | 328 | 329 | 330 | 331 | 336 | 337 | 338 | 339 | 340 | 345 | 346 | 347 | 348 | 349 | 354 | 355 | 356 | 357 | 358 | 363 | 364 | 365 | 366 | 367 | 372 | 373 | 374 | 375 | 376 | 381 | 382 | 383 | 384 |
Method Summary
Method AttributesMethod Name and Description
  268 |
ajax(url, settings) 269 |
270 |
Performs a cross-domain, asynchronous HTTP request.
271 |
  277 |
autogrow(client, b, interval) 278 |
279 |
Starts or stops a timer which checks the content size of the iFrame and 280 | adjusts the frame accordingly.
281 |
  287 |
ctx(clientscb, client) 288 |
289 |
Returns the context for the current user and organization.
290 |
  296 |
publish(client, e) 297 |
298 |
Publishes a custom event.
299 |
  305 |
refreshSignedRequest(clientscb) 306 |
307 |
Refresh the signed request.
308 |
  314 |
repost(refresh) 315 |
316 |
Repost the signed request.
317 |
  323 |
resize(client, size) 324 |
325 |
Informs the parent window to resize the canvas iFrame.
326 |
  332 |
signedrequest(s) 333 |
334 |
Temporary storage for the signed request.
335 |
  341 |
size() 342 |
343 |
Returns the current size of the iFrame.
344 |
  350 |
subscribe(client, s) 351 |
352 |
Subscribes to parent or custom events.
353 |
  359 |
token(t) 360 |
361 |
Stores or gets the oauth token in a local javascript variable.
362 |
  368 |
unsubscribe(client, s) 369 |
370 |
Unsubscribes from parent or custom events.
371 |
  377 |
version() 378 |
379 |
Returns the current version of the client.
380 |
385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 |
395 |
396 | Namespace Detail 397 |
398 | 399 |
400 | Sfdc.canvas.client 401 |
402 | 403 |
404 | 405 | 406 |
407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 |
420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 |
428 | Method Detail 429 |
430 | 431 | 432 |
433 | 434 | 435 | ajax(url, settings) 436 | 437 |
438 |
439 | Performs a cross-domain, asynchronous HTTP request. 440 |
Note: this method shouldn't be used for same domain requests. 441 | 442 | 443 |
444 | 445 | 446 | 447 |
//Posting to a Chatter feed:
 448 | var sr = JSON.parse('<%=signedRequestJson%>');
 449 | var url = sr.context.links.chatterFeedsUrl+"/news/"
 450 |                                   +sr.context.user.userId+"/feed-items";
 451 | var body = {body : {messageSegments : [{type: "Text", text: "Some Chatter Post"}]}};
 452 | Sfdc.canvas.client.ajax(url,
 453 |   {client : sr.client,
 454 |     method: 'POST',
 455 |     contentType: "application/json",
 456 |     data: JSON.stringify(body),
 457 |     success : function(data) {
 458 |     if (201 === data.status) {
 459 |          alert("Success"
 460 |          }
 461 |     }
 462 |   });
463 | 464 |
// Gets a list of Chatter users:
 465 | // Paste the signed request string into a JavaScript object for easy access.
 466 | var sr = JSON.parse('<%=signedRequestJson%>');
 467 | // Reference the Chatter user's URL from Context.Links object.
 468 | var chatterUsersUrl = sr.context.links.chatterUsersUrl;
 469 | 
 470 | // Make an XHR call back to Salesforce through the supplied browser proxy.
 471 | Sfdc.canvas.client.ajax(chatterUsersUrl,
 472 |   {client : sr.client,
 473 |   success : function(data){
 474 |   // Make sure the status code is OK.
 475 |   if (data.status === 200) {
 476 |     // Alert with how many Chatter users were returned.
 477 |     alert("Got back "  + data.payload.users.length +
 478 |     " users"); // Returned 2 users
 479 |    }
 480 | })};
481 | 482 | 483 | 484 | 485 |
486 |
Parameters:
487 | 488 |
489 | {String} url 490 | 491 |
492 |
The URL to which the request is sent
493 | 494 |
495 | {Object} settings 496 | 497 |
498 |
A set of key/value pairs to configure the request 499 |
The success setting is required at minimum and should be a callback function
500 | 501 |
502 | {String} settings.client 503 | Optional 504 |
505 |
The required client context {oauthToken: "", targetOrigin : "", instanceId : ""}
506 | 507 |
508 | {String} settings.contentType 509 | Optional 510 |
511 |
"application/json"
512 | 513 |
514 | {String} settings.data 515 | Optional 516 |
517 |
The request body
518 | 519 |
520 | {String} settings.headers 521 | Optional 522 |
523 |
request headers
524 | 525 |
526 | {String} settings.method 527 | Optional, Default: "GET" 528 |
529 |
The type of AJAX request to make
530 | 531 |
532 | {Function} settings.success 533 | Optional 534 |
535 |
Callback for all responses from the server (failure and success). Signature: success(response); interesting fields: [response.data, response.responseHeaders, response.status, response.statusText}
536 | 537 |
538 | {Boolean} settings.async 539 | Optional, Default: true 540 |
541 |
Asynchronous: only true is supported.
542 | 543 |
544 | 545 | 546 | 547 | 548 |
549 |
Throws:
550 | 551 |
552 | 553 |
554 |
An error if the URL is missing or the settings object doesn't contain a success callback function.
555 | 556 |
557 | 558 | 559 | 560 | 561 | 562 |
563 | 564 | 565 |
566 | 567 | 568 | autogrow(client, b, interval) 569 | 570 |
571 |
572 | Starts or stops a timer which checks the content size of the iFrame and 573 | adjusts the frame accordingly. 574 | Use this function when you know your content is changing size, but you're not sure when. There's a delay as 575 | the resizing is done asynchronously. Therfore, if you know when your content changes size, you should 576 | explicitly call the resize() method and save browser CPU cycles. 577 | Note: you should turn off scrolling before this call, otherwise you might get a flicker. 578 | 579 | 580 |
581 | 582 | 583 | 584 |
 585 | // Turn on auto grow with default settings.
 586 | Sfdc.canvas(function() {
 587 |     sr = JSON.parse('<%=signedRequestJson%>');
 588 |     Sfdc.canvas.client.autogrow(sr.client);
 589 | });
 590 | 
 591 | // Turn on auto grow with a polling interval of 100ms (milliseconds).
 592 | Sfdc.canvas(function() {
 593 |     sr = JSON.parse('<%=signedRequestJson%>');
 594 |     Sfdc.canvas.client.autogrow(sr.client, true, 100);
 595 | });
 596 | 
 597 | // Turn off auto grow.
 598 | Sfdc.canvas(function() {
 599 |     sr = JSON.parse('<%=signedRequestJson%>');
 600 |     Sfdc.canvas.client.autogrow(sr.client, false);
 601 | });
602 | 603 | 604 | 605 | 606 |
607 |
Parameters:
608 | 609 |
610 | {client} client 611 | 612 |
613 |
The object from the signed request
614 | 615 |
616 | {boolean} b 617 | 618 |
619 |
Whether it's turned on or off; defaults to true
620 | 621 |
622 | {Integer} interval 623 | 624 |
625 |
The interval used to check content size; default timeout is 300ms.
626 | 627 |
628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 |
637 | 638 | 639 |
640 | 641 | 642 | ctx(clientscb, client) 643 | 644 |
645 |
646 | Returns the context for the current user and organization. 647 | 648 | 649 |
650 | 651 | 652 | 653 |
// Gets context in the canvas app.
 654 | 
 655 | function callback(msg) {
 656 |   if (msg.status !== 200) {
 657 |     alert("Error: " + msg.status);
 658 |     return;
 659 |   }
 660 |   alert("Payload: ", msg.payload);
 661 | }
 662 | var ctxlink = Sfdc.canvas.byId("ctxlink");
 663 | var client = Sfdc.canvas.oauth.client();
 664 | ctxlink.onclick=function() {
 665 |   Sfdc.canvas.client.ctx(callback, client)};
 666 | }
667 | 668 | 669 | 670 | 671 |
672 |
Parameters:
673 | 674 |
675 | {Function} clientscb 676 | 677 |
678 |
The callback function to run when the call to ctx completes
679 | 680 |
681 | {Object} client 682 | 683 |
684 |
The signedRequest.client.
685 | 686 |
687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 |
696 | 697 | 698 |
699 | 700 | 701 | publish(client, e) 702 | 703 |
704 |
705 | Publishes a custom event. Events are published to all subscribing canvas applications 706 | on the same page, regardless of domain. Choose a unique namespace so the event doesn't collide with other 707 | application events. Events can have payloads of arbitrary JSON objects. 708 | 709 | 710 |
711 | 712 | 713 | 714 |
// Publish the foo.bar event with the specified payload.
 715 | Sfdc.canvas(function() {
 716 |     sr = JSON.parse('<%=signedRequestJson%>');
 717 |     Sfdc.canvas.client.publish(sr.client,
 718 |         {name : "foo.bar", payload : {some : 'stuff'}});
 719 | });
720 | 721 | 722 | 723 | 724 |
725 |
Parameters:
726 | 727 |
728 | {client} client 729 | 730 |
731 |
The object from the signed request
732 | 733 |
734 | {Object} e 735 | 736 |
737 |
The event to publish
738 | 739 |
740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 |
749 | 750 | 751 |
752 | 753 | 754 | refreshSignedRequest(clientscb) 755 | 756 |
757 |
758 | Refresh the signed request. Obtain a new signed request on demand. Note the 759 | authentication mechanism of the canvas app must be set to SignedRequest and not OAuth. 760 | 761 | 762 |
763 | 764 | 765 | 766 |
// Gets a signed request on demand.
 767 |  Sfdc.canvas.client.refreshSignedRequest(function(data) {
 768 |      if (data.status === 200) {
 769 |          var signedRequest =  data.payload.response;
 770 |          var part = signedRequest.split('.')[1];
 771 |          var obj = JSON.parse(Sfdc.canvas.decode(part));
 772 |      }
 773 |   }
774 | 775 | 776 | 777 | 778 |
779 |
Parameters:
780 | 781 |
782 | {Function} clientscb 783 | 784 |
785 |
The client's callback function to receive the base64 encoded signed request.
786 | 787 |
788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 |
797 | 798 | 799 |
800 | 801 | 802 | repost(refresh) 803 | 804 |
805 |
806 | Repost the signed request. Instruct the parent window to initiate a new post to the 807 | canvas url. Note the authentication mechanism of the canvas app must be set to SignedRequest and not OAuth. 808 | 809 | 810 |
811 | 812 | 813 | 814 |
// Gets a signed request on demand, without refreshing the signed request.
 815 |  Sfdc.canvas.client.repost();
 816 | // Gets a signed request on demand, first by refreshing the signed request.
 817 |  Sfdc.canvas.client.repost({refresh : true});
818 | 819 | 820 | 821 | 822 |
823 |
Parameters:
824 | 825 |
826 | {Boolean} refresh 827 | Optional, Default: false 828 |
829 |
Refreshes the signed request when set to true.
830 | 831 |
832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 |
841 | 842 | 843 |
844 | 845 | 846 | resize(client, size) 847 | 848 |
849 |
850 | Informs the parent window to resize the canvas iFrame. If no parameters are specified, 851 | the parent window attempts to determine the height of the canvas app based on the 852 | content and then sets the iFrame width and height accordingly. To explicitly set the dimensions, 853 | pass in an object with height and/or width properties. 854 | 855 | 856 |
857 | 858 | 859 | 860 |
//Automatically determine the size
 861 | Sfdc.canvas(function() {
 862 |     sr = JSON.parse('<%=signedRequestJson%>');
 863 |     Sfdc.canvas.client.resize(sr.client);
 864 | });
865 | 866 |
//Set the height and width explicitly
 867 | Sfdc.canvas(function() {
 868 |     sr = JSON.parse('<%=signedRequestJson%>');
 869 |     Sfdc.canvas.client.resize(sr.client, {height : "1000px", width : "900px"});
 870 | });
871 | 872 |
//Set only the height
 873 | Sfdc.canvas(function() {
 874 |     sr = JSON.parse('<%=signedRequestJson%>');
 875 |     Sfdc.canvas.client.resize(sr.client, {height : "1000px"});
 876 | });
877 | 878 | 879 | 880 | 881 |
882 |
Parameters:
883 | 884 |
885 | {Client} client 886 | 887 |
888 |
The object from the signed request
889 | 890 |
891 | {size} size 892 | 893 |
894 |
The optional height and width information
895 | 896 |
897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 |
906 | 907 | 908 |
909 | 910 | {Object} 911 | signedrequest(s) 912 | 913 |
914 |
915 | Temporary storage for the signed request. An alternative for users storing SR in 916 | a global variable. Note: if you would like a new signed request take a look at refreshSignedRequest(). 917 | 918 | 919 |
920 | 921 | 922 | 923 | 924 |
925 |
Parameters:
926 | 927 |
928 | {Object} s 929 | 930 |
931 |
signedrequest to be temporarily stored in Sfdc.canvas.client object.
932 | 933 |
934 | 935 | 936 | 937 | 938 | 939 |
940 |
Returns:
941 | 942 |
{Object} the value previously stored
943 | 944 |
945 | 946 | 947 | 948 | 949 |
950 | 951 | 952 |
953 | 954 | {Object} 955 | size() 956 | 957 |
958 |
959 | Returns the current size of the iFrame. 960 | 961 | 962 |
963 | 964 | 965 | 966 |
//get the size of the iFrame and print out each component.
 967 | var sizes = Sfdc.canvas.client.size();
 968 | console.log("contentHeight; " + sizes.heights.contentHeight);
 969 | console.log("pageHeight; " + sizes.heights.pageHeight);
 970 | console.log("scrollTop; " + sizes.heights.scrollTop);
 971 | console.log("contentWidth; " + sizes.widths.contentWidth);
 972 | console.log("pageWidth; " + sizes.widths.pageWidth);
 973 | console.log("scrollLeft; " + sizes.widths.scrollLeft);
974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | 982 |
983 |
Returns:
984 | 985 |
{Object}
986 | heights.contentHeight: the height of the virtual iFrame, all content, not just visible content.
987 | heights.pageHeight: the height of the visible iFrame in the browser.
988 | heights.scrollTop: the position of the scroll bar measured from the top.
989 | widths.contentWidth: the width of the virtual iFrame, all content, not just visible content.
990 | widths.pageWidth: the width of the visible iFrame in the browser.
991 | widths.scrollLeft: the position of the scroll bar measured from the left.
992 | 993 |
994 | 995 | 996 | 997 | 998 |
999 | 1000 | 1001 |
1002 | 1003 | 1004 | subscribe(client, s) 1005 | 1006 |
1007 |
1008 | Subscribes to parent or custom events. Events 1009 | with the namespaces 'canvas', 'sfdc', 'force', 'salesforce', and 'chatter' are reserved by Salesforce. 1010 | Developers can choose their own namespace and event names. 1011 | Event names must be in the form namespace.eventname. 1012 | 1013 | 1014 |
1015 | 1016 | 1017 | 1018 |
// Subscribe to the parent window onscroll event.
1019 | Sfdc.canvas(function() {
1020 |     sr = JSON.parse('<%=signedRequestJson%>');
1021 |     // Capture the onScrolling event of the parent window.
1022 |     Sfdc.canvas.client.subscribe(sr.client,
1023 |          {name : 'canvas.scroll', onData : function (event) {
1024 |              console.log("Parent's contentHeight; " + event.heights.contentHeight);
1025 |              console.log("Parent's pageHeight; " + event.heights.pageHeight);
1026 |              console.log("Parent's scrollTop; " + event.heights.scrollTop);
1027 |              console.log("Parent's contentWidth; " + event.widths.contentWidth);
1028 |              console.log("Parent's pageWidth; " + event.widths.pageWidth);
1029 |              console.log("Parent's scrollLeft; " + event.widths.scrollLeft);
1030 |          }}
1031 |     );
1032 | });
1033 | 1034 |
// Subscribe to a custom event.
1035 | Sfdc.canvas(function() {
1036 |     sr = JSON.parse('<%=signedRequestJson%>');
1037 |     Sfdc.canvas.client.subscribe(sr.client,
1038 |         {name : 'mynamespace.someevent', onData : function (event) {
1039 |             console.log("Got custom event ",  event);
1040 |         }}
1041 |     );
1042 | });
1043 | 1044 |
// Subscribe to multiple events
1045 | Sfdc.canvas(function() {
1046 |     sr = JSON.parse('<%=signedRequestJson%>');
1047 |     Sfdc.canvas.client.subscribe(sr.client, [
1048 |         {name : 'mynamespace.someevent1', onData : handler1},
1049 |         {name : 'mynamespace.someevent2', onData : handler2},
1050 |     ]);
1051 | });
1052 | 1053 |
//Subscribe to Streaming API events.  
1054 | //The PushTopic to subscribe to must be passed in.
1055 | //The 'onComplete' method may be defined,
1056 | //and will fire when the subscription is complete.
1057 | Sfdc.canvas(function() {
1058 |     sr = JSON.parse('<%=signedRequestJson%>');
1059 |     var handler1 = function(){ console.log("onData done");},
1060 |     handler2 = function(){ console.log("onComplete done");};
1061 |     Sfdc.canvas.client.subscribe(sr.client,
1062 |         {name : 'sfdc.streamingapi', params:{topic:"/topic/InvoiceStatements"}},
1063 |          onData : handler1, onComplete : handler2}
1064 |     );
1065 | });
1066 | 1067 | 1068 | 1069 | 1070 |
1071 |
Parameters:
1072 | 1073 |
1074 | {client} client 1075 | 1076 |
1077 |
The object from the signed request
1078 | 1079 |
1080 | {Object} s 1081 | 1082 |
1083 |
The subscriber object or array of objects with name and callback functions
1084 | 1085 |
1086 | 1087 | 1088 | 1089 | 1090 | 1091 | 1092 | 1093 | 1094 |
1095 | 1096 | 1097 |
1098 | 1099 | {Object} 1100 | token(t) 1101 | 1102 |
1103 |
1104 | Stores or gets the oauth token in a local javascript variable. Note, if longer term 1105 | (survive page refresh) storage is needed store the oauth token on the server side. 1106 | 1107 | 1108 |
1109 | 1110 | 1111 | 1112 | 1113 |
1114 |
Parameters:
1115 | 1116 |
1117 | {String} t 1118 | 1119 |
1120 |
oauth token, if supplied it will be stored in a volatile local JS variable.
1121 | 1122 |
1123 | 1124 | 1125 | 1126 | 1127 | 1128 |
1129 |
Returns:
1130 | 1131 |
{Object} the oauth token.
1132 | 1133 |
1134 | 1135 | 1136 | 1137 | 1138 |
1139 | 1140 | 1141 |
1142 | 1143 | 1144 | unsubscribe(client, s) 1145 | 1146 |
1147 |
1148 | Unsubscribes from parent or custom events. 1149 | 1150 | 1151 |
1152 | 1153 | 1154 | 1155 |
//Unsubscribe from the canvas.scroll method.
1156 | Sfdc.canvas(function() {
1157 |     sr = JSON.parse('<%=signedRequestJson%>');
1158 |     Sfdc.canvas.client.unsubscribe(sr.client, "canvas.scroll");
1159 | });
1160 | 1161 |
//Unsubscribe from the canvas.scroll method by specifying the object name.
1162 | Sfdc.canvas(function() {
1163 |     sr = JSON.parse('<%=signedRequestJson%>');
1164 |     Sfdc.canvas.client.unsubscribe(sr.client, {name : "canvas.scroll"});
1165 | });
1166 | 1167 |
//Unsubscribe from multiple events.
1168 | Sfdc.canvas(function() {
1169 |     sr = JSON.parse('<%=signedRequestJson%>');
1170 |     Sfdc.canvas.client.unsubscribe(sr.client, ['canvas.scroll', 'foo.bar']);
1171 | });
1172 | 1173 |
//Unsubscribe from Streaming API events.
1174 | //The PushTopic to unsubscribe from  must be passed in.
1175 | Sfdc.canvas(function() {
1176 |     sr = JSON.parse('<%=signedRequestJson%>');
1177 |     Sfdc.canvas.client.unsubscribe(sr.client, {name : 'sfdc.streamingapi',
1178 |               params:{topic:"/topic/InvoiceStatements"}});
1179 | });
1180 | 1181 | 1182 | 1183 | 1184 |
1185 |
Parameters:
1186 | 1187 |
1188 | {client} client 1189 | 1190 |
1191 |
The object from the signed request
1192 | 1193 |
1194 | {Object} s 1195 | 1196 |
1197 |
The events to unsubscribe from
1198 | 1199 |
1200 | 1201 | 1202 | 1203 | 1204 | 1205 | 1206 | 1207 | 1208 |
1209 | 1210 | 1211 |
1212 | 1213 | {Object} 1214 | version() 1215 | 1216 |
1217 |
1218 | Returns the current version of the client. 1219 | 1220 | 1221 |
1222 | 1223 | 1224 | 1225 | 1226 | 1227 | 1228 | 1229 | 1230 |
1231 |
Returns:
1232 | 1233 |
{Object} {clientVersion : "29.0", parentVersion : "29.0"}.
1234 | 1235 |
1236 | 1237 | 1238 | 1239 | 1240 | 1241 | 1242 | 1243 | 1244 | 1245 | 1246 | 1247 |
1248 |
1249 | 1250 | 1251 | 1252 |
1253 | 1254 | Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 15 2014 13:44:12 GMT-0700 (PDT) 1255 |
1256 | 1257 | 1258 | -------------------------------------------------------------------------------- /docs/symbols/Sfdc.canvas.oauth.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | JsDoc Reference - Sfdc.canvas.oauth 9 | 10 | 174 | 175 | 176 | 177 | 178 | 179 | 181 | 182 | 183 | 184 |
185 | 186 |
Class Index 187 | | File Index
188 |
189 |

Classes

190 | 201 |
202 | 203 |
204 | 205 |
206 | 207 |

208 | 209 | Namespace Sfdc.canvas.oauth 210 |

211 | 212 | 213 |

214 | 215 | 216 | 217 | Sfdc.canvas.oauth 218 | 219 | 220 |
Defined in: oauth.js. 221 | 222 |

223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 243 | 244 | 245 |
Namespace Summary
Constructor AttributesConstructor Name and Description
  238 |
239 | Sfdc.canvas.oauth 240 |
241 |
242 |
246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 272 | 273 | 274 | 275 | 276 | 282 | 283 | 284 | 285 | 286 | 291 | 292 | 293 | 294 | 295 | 300 | 301 | 302 | 303 | 304 | 309 | 310 | 311 | 312 | 313 | 318 | 319 | 320 | 321 | 322 | 327 | 328 | 329 | 330 | 331 | 336 | 337 | 338 | 339 |
Method Summary
Method AttributesMethod Name and Description
  268 | 270 |
Refreshes the parent window only if the child window is closed.
271 |
  277 | 279 |
Parses the hash value that is passed in and sets the 280 | access_token and instance_url cookies if they exist.
281 |
  287 |
instance(i) 288 |
289 |
Sets, gets, or removes the instance_url cookie.
290 |
  296 |
loggedin() 297 |
298 |
Returns the login state.
299 |
  305 |
login(ctx) 306 |
307 |
Opens the OAuth popup window to retrieve an OAuth token.
308 |
  314 |
loginUrl() 315 |
316 |
Returns the URL for the OAuth authorization service.
317 |
  323 |
logout() 324 |
325 |
Removes the access_token OAuth token from this object.
326 |
  332 |
token(t) 333 |
334 |
Sets, gets, or removes the access_token from this JavaScript object.
335 |
340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 |
350 |
351 | Namespace Detail 352 |
353 | 354 |
355 | Sfdc.canvas.oauth 356 |
357 | 358 |
359 | 360 | 361 |
362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 |
375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 |
383 | Method Detail 384 |
385 | 386 | 387 |
388 | 389 | 390 | checkChildWindowStatus() 391 | 392 |
393 |
394 | Refreshes the parent window only if the child window is closed. This 395 | method is no longer used. Leaving in for backwards compatability. 396 | 397 | 398 |
399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 |
411 | 412 | 413 |
414 | 415 | 416 | childWindowUnloadNotification(hash) 417 | 418 |
419 |
420 | Parses the hash value that is passed in and sets the 421 | access_token and instance_url cookies if they exist. Use this method during 422 | User-Agent OAuth Authentication Flow to pass the OAuth token. 423 | 424 | 425 |
426 | 427 | 428 | 429 |
Sfdc.canvas.oauth.childWindowUnloadNotification(self.location.hash);
430 | 431 | 432 | 433 | 434 |
435 |
Parameters:
436 | 437 |
438 | {String} hash 439 | 440 |
441 |
A string of key-value pairs delimited by 442 | the ampersand character.
443 | 444 |
445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 |
454 | 455 | 456 |
457 | 458 | {String} 459 | instance(i) 460 | 461 |
462 |
463 | Sets, gets, or removes the instance_url cookie.
464 |

This function does one of three things:
465 | 1) If the 'i' parameter is not passed in, the current value for the instance_url cookie is returned.
466 | 2) If the 'i' parameter is null, the instance_url cookie is removed.
467 | 3) Otherwise, the instance_url cookie value is set to the 'i' parameter and then returned. 468 | 469 | 470 |

471 | 472 | 473 | 474 | 475 |
476 |
Parameters:
477 | 478 |
479 | {String} i 480 | Optional 481 |
482 |
The value to set as the instance_url cookie
483 | 484 |
485 | 486 | 487 | 488 | 489 | 490 |
491 |
Returns:
492 | 493 |
{String} The resulting instance_url cookie value if set; otherwise null
494 | 495 |
496 | 497 | 498 | 499 | 500 |
501 | 502 | 503 |
504 | 505 | {Boolean} 506 | loggedin() 507 | 508 |
509 |
510 | Returns the login state. 511 | 512 | 513 |
514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 |
523 |
Returns:
524 | 525 |
{Boolean} true if the access_token is available in this JS object. 526 | Note: access tokens (for example, OAuth tokens) should be stored server-side for more durability. 527 | Never store OAuth tokens in cookies as this can lead to a security risk.
528 | 529 |
530 | 531 | 532 | 533 | 534 |
535 | 536 | 537 |
538 | 539 | 540 | login(ctx) 541 | 542 |
543 |
544 | Opens the OAuth popup window to retrieve an OAuth token. 545 | 546 | 547 |
548 | 549 | 550 | 551 |
function clickHandler(e)
552 | {
553 |  var uri;
554 |  if (! connect.oauth.loggedin())
555 |  {
556 |   uri = connect.oauth.loginUrl();
557 |   connect.oauth.login(
558 |    {uri : uri,
559 |     params: {
560 |      response_type : "token",
561 |      client_id :  "<%=consumerKey%>",
562 |      redirect_uri : encodeURIComponent("/sdk/callback.html")
563 |      }});
564 |  } else {
565 |     connect.oauth.logout();
566 |  }
567 |  return false;
568 | }
569 | 570 | 571 | 572 | 573 |
574 |
Parameters:
575 | 576 |
577 | {Object} ctx 578 | 579 |
580 |
The context object that contains the URL, the response type, the client ID, and the callback URL
581 | 582 |
583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 |
592 | 593 | 594 |
595 | 596 | {String} 597 | loginUrl() 598 | 599 |
600 |
601 | Returns the URL for the OAuth authorization service. 602 | 603 | 604 |
605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 |
614 |
Returns:
615 | 616 |
{String} The URL for the OAuth authorization service or default if there's 617 | no value for loginUrl in the current URL's query string
618 | 619 |
620 | 621 | 622 | 623 | 624 |
625 | 626 | 627 |
628 | 629 | 630 | logout() 631 | 632 |
633 |
634 | Removes the access_token OAuth token from this object. 635 | 636 | 637 |
638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 |
650 | 651 | 652 |
653 | 654 | {String} 655 | token(t) 656 | 657 |
658 |
659 | Sets, gets, or removes the access_token from this JavaScript object.
660 |

This function does one of three things:
661 | 1) If the 't' parameter isn't passed in, the current value for the access_token value is returned.
662 | 2) If the the 't' parameter is null, the access_token value is removed.
663 | 3) Otherwise the access_token value is set to the 't' parameter and then returned.

664 | Note: for longer-term storage of the OAuth token, store it server-side in the session. Access tokens 665 | should never be stored in cookies. 666 | 667 | 668 |

669 | 670 | 671 | 672 | 673 |
674 |
Parameters:
675 | 676 |
677 | {String} t 678 | Optional 679 |
680 |
The OAuth token to set as the access_token value
681 | 682 |
683 | 684 | 685 | 686 | 687 | 688 |
689 |
Returns:
690 | 691 |
{String} The resulting access_token value if set; otherwise null
692 | 693 |
694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 |
706 |
707 | 708 | 709 | 710 |
711 | 712 | Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 15 2014 13:44:12 GMT-0700 (PDT) 713 |
714 | 715 | 716 | -------------------------------------------------------------------------------- /docs/symbols/_global_.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | JsDoc Reference - _global_ 9 | 10 | 174 | 175 | 176 | 177 | 178 | 179 | 181 | 182 | 183 | 184 |
185 | 186 |
Class Index 187 | | File Index
188 |
189 |

Classes

190 | 201 |
202 | 203 |
204 | 205 |
206 | 207 |

208 | 209 | Built-In Namespace _global_ 210 |

211 | 212 | 213 |

214 | 215 | 216 | 217 | 218 | 219 | 220 |

221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 249 | 250 | 251 | 252 | 253 | 258 | 259 | 260 | 261 | 262 | 267 | 268 | 269 | 270 |
Method Summary
Method AttributesMethod Name and Description
  245 |
canvas(cb) 246 |
247 |
248 |
  254 |
error() 255 |
256 |
257 |
  263 |
log() 264 |
265 |
266 |
271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 |
287 | Method Detail 288 |
289 | 290 | 291 |
292 | 293 | 294 | canvas(cb) 295 | 296 |
297 |
298 | 299 | 300 |
301 | Defined in: canvas.js. 302 | 303 | 304 |
305 | 306 | 307 | 308 | 309 |
310 |
Parameters:
311 | 312 |
313 | {Function} cb 314 | 315 |
316 |
The function to run when ready.
317 | 318 |
319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 |
328 | 329 | 330 |
331 | 332 | 333 | error() 334 | 335 |
336 |
337 | 338 | 339 |
340 | Defined in: canvas.js. 341 | 342 | 343 |
344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 |
356 | 357 | 358 |
359 | 360 | 361 | log() 362 | 363 |
364 |
365 | 366 | 367 |
368 | Defined in: canvas.js. 369 | 370 | 371 |
372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 |
391 |
392 | 393 | 394 | 395 |
396 | 397 | Documentation generated by JsDoc Toolkit 2.4.0 on Tue Jul 15 2014 13:44:12 GMT-0700 (PDT) 398 |
399 | 400 | 401 | -------------------------------------------------------------------------------- /docs/symbols/src/SalesforceCanvasJavascriptSDK_js_cookies.js.html: -------------------------------------------------------------------------------- 1 |
  1 /**
  9 |   2 * Copyright (c) 2014, salesforce.com, inc.
 10 |   3 * All rights reserved.
 11 |   4 *
 12 |   5 * Redistribution and use in source and binary forms, with or without modification, are permitted provided
 13 |   6 * that the following conditions are met:
 14 |   7 *
 15 |   8 * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 16 |   9 * following disclaimer.
 17 |  10 *
 18 |  11 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
 19 |  12 * the following disclaimer in the documentation and/or other materials provided with the distribution.
 20 |  13 *
 21 |  14 * Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or
 22 |  15 * promote products derived from this software without specific prior written permission.
 23 |  16 *
 24 |  17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 25 |  18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 26 |  19 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 27 |  20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 28 |  21 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 29 |  22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 30 |  23 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 31 |  24 * POSSIBILITY OF SUCH DAMAGE.
 32 |  25 */
 33 |  26 
 34 |  27 
 35 |  28 (function ($$) {
 36 |  29 
 37 |  30     "use strict";
 38 |  31 
 39 |  32     var module =  (function() {
 40 |  33 
 41 |  34         function isSecure()
 42 |  35         {
 43 |  36             return window.location.protocol === 'https:';
 44 |  37         }
 45 |  38 
 46 |  39         /**
 47 |  40        * @description Create a cookie
 48 |  41        * @param {String} name Cookie name
 49 |  42        * @param {String} value Cookie value
 50 |  43        * @param {Integer} [days] Number of days for the cookie to remain active.
 51 |  44                 If not provided, the cookie never expires
 52 |  45        */
 53 |  46        function set(name, value, days) {
 54 |  47            var expires = "", date;
 55 |  48            if (days) {
 56 |  49                date = new Date();
 57 |  50                date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
 58 |  51                expires = "; expires=" + date.toGMTString();
 59 |  52            }
 60 |  53            else {
 61 |  54                expires = "";
 62 |  55            }
 63 |  56            document.cookie = name + "=" + value + expires + "; path=/" +  ((isSecure() === true) ? "; secure" : "");
 64 |  57        }
 65 |  58        
 66 |  59        /**
 67 |  60        * @description Get the cookie with the specified name
 68 |  61        * @param {String} name The name of the cookie to retrieve
 69 |  62        * @returns The value of the cookie if the name is found, otherwise null
 70 |  63        */
 71 |  64        function get(name) {
 72 |  65            var nameEQ, ca, c, i;
 73 |  66 
 74 |  67            if ($$.isUndefined(name)) {
 75 |  68                return document.cookie.split(';');
 76 |  69            }
 77 |  70 
 78 |  71            nameEQ = name + "=";
 79 |  72            ca = document.cookie.split(';');
 80 |  73            for (i = 0; i < ca.length; i += 1) {
 81 |  74                c = ca[i];
 82 |  75                while (c.charAt(0) === ' ') {c = c.substring(1, c.length);}
 83 |  76                if (c.indexOf(nameEQ) === 0) {
 84 |  77                    return c.substring(nameEQ.length, c.length);
 85 |  78                }
 86 |  79            }
 87 |  80            return null;
 88 |  81        }
 89 |  82        
 90 |  83        /**
 91 |  84        * @description Remove the specified cookie by setting the expiry date to one day ago
 92 |  85        * @param {String} name The name of the cookie to remove.
 93 |  86        */
 94 |  87        function remove(name) {
 95 |  88            set(name, "", -1);
 96 |  89        }
 97 |  90 
 98 |  91        return {
 99 |  92             set : set,
100 |  93             get : get,
101 |  94             remove : remove
102 |  95         };
103 |  96     }());
104 |  97 
105 |  98 
106 |  99     $$.module('Sfdc.canvas.cookies', module);
107 | 100 
108 | 101 }(Sfdc.canvas));
-------------------------------------------------------------------------------- /docs/symbols/src/SalesforceCanvasJavascriptSDK_js_xd.js.html: -------------------------------------------------------------------------------- 1 |
  1 /**
  9 |   2 * Copyright (c) 2014, salesforce.com, inc.
 10 |   3 * All rights reserved.
 11 |   4 *
 12 |   5 * Redistribution and use in source and binary forms, with or without modification, are permitted provided
 13 |   6 * that the following conditions are met:
 14 |   7 *
 15 |   8 * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 16 |   9 * following disclaimer.
 17 |  10 *
 18 |  11 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
 19 |  12 * the following disclaimer in the documentation and/or other materials provided with the distribution.
 20 |  13 *
 21 |  14 * Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or
 22 |  15 * promote products derived from this software without specific prior written permission.
 23 |  16 *
 24 |  17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 25 |  18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 26 |  19 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 27 |  20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 28 |  21 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 29 |  22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 30 |  23 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 31 |  24 * POSSIBILITY OF SUCH DAMAGE.
 32 |  25 */
 33 |  26 
 34 |  27 
 35 |  28 (function ($$, window) {
 36 |  29 
 37 |  30     "use strict";
 38 |  31 
 39 |  32     var module =   (function() {
 40 |  33 
 41 |  34         var internalCallback;
 42 |  35 
 43 |  36         /**
 44 |  37         * @description Pass a message to the target url
 45 |  38         * @param {String} message The message to send
 46 |  39         * @param {String} target_url Specifies what the origin of the target must be for the event to be dispatched.
 47 |  40         * @param {String} [target] The window that is the message's target. Defaults to the parent of the current window.
 48 |  41         */
 49 |  42         function postMessage(message, target_url, target) {
 50 |  43 			var sfdcJson = Sfdc.JSON || JSON;
 51 |  44 
 52 |  45             // If target url was not supplied (client may have lost it), we could default to '*',
 53 |  46             // However there are security implications here as other canvas apps could receive this
 54 |  47             // canvas apps oauth token.
 55 |  48             if ($$.isNil(target_url)) {
 56 |  49                 throw "ERROR: target_url was not supplied on postMessage";
 57 |  50             }
 58 |  51             var otherWindow = $$.stripUrl(target_url);
 59 |  52 
 60 |  53             target = target || parent;  // default to parent
 61 |  54             if (window.postMessage) {
 62 |  55                 // the browser supports window.postMessage, so call it with a targetOrigin
 63 |  56                 // set appropriately, based on the target_url parameter.
 64 |  57 
 65 |  58                 // Add the targetModule as Canvas so we are the only ones interested in these events
 66 |  59                 if ($$.isObject(message)) {message.targetModule = "Canvas";}
 67 |  60                 message = sfdcJson.stringify(message);
 68 |  61                 $$.console.log("Sending Post Message ", message);
 69 |  62                 target.postMessage(message, otherWindow);
 70 |  63             }
 71 |  64         }
 72 |  65         
 73 |  66         /**
 74 |  67         * @name Sfdc.canvas.xd#receive
 75 |  68         * @description Runs the callback function when the message event is received.
 76 |  69         * @param {Function} callback Function to run when the message event is received 
 77 |  70             if the event origin is acceptable.
 78 |  71         * @param {String} source_origin The origin of the desired events
 79 |  72         */
 80 |  73         function receiveMessage(callback, source_origin) {
 81 |  74 
 82 |  75             // browser supports window.postMessage (if not not supported for pilot - removed per securities request)
 83 |  76             if (window.postMessage) {
 84 |  77                 // bind the callback to the actual event associated with window.postMessage
 85 |  78                 if (callback) {
 86 |  79                     internalCallback = function(e) {
 87 |  80 
 88 |  81                         var data, r;
 89 |  82 						var sfdcJson = Sfdc.JSON || JSON;
 90 |  83 
 91 |  84                         $$.console.log("Post Message Got callback", e);
 92 |  85 
 93 |  86                         if (!$$.isNil(e)) {
 94 |  87                             if (typeof source_origin === 'string' && e.origin !== source_origin) {
 95 |  88                                 $$.console.log("source origin's don't match", e.origin, source_origin);
 96 |  89                                 return false;
 97 |  90                             }
 98 |  91                             if ($$.isFunction(source_origin)) {
 99 |  92                                 r = source_origin(e.origin, e.data);
100 |  93                                 if (r === false) {
101 |  94                                     $$.console.log("source origin's function returning false", e.origin, e.data);
102 |  95                                     return false;
103 |  96                                 }
104 |  97                             }
105 |  98                             if ($$.appearsJson(e.data))  {
106 |  99                                 try {
107 | 100                                     data = sfdcJson.parse(e.data);
108 | 101                                 } catch (ignore) {
109 | 102                                     // Ignore parsing errors of any non json objects sent from other frames
110 | 103                                 }
111 | 104                                 // If we could parse the data and there is a targetModule make sure it is for us
112 | 105                                 if (!$$.isNil(data) && ($$.isNil(data.targetModule) || data.targetModule === "Canvas")) {
113 | 106                                     $$.console.log("Invoking callback");
114 | 107                                     callback(data, r);
115 | 108                                 }
116 | 109                             }
117 | 110                         }
118 | 111                     };
119 | 112                 }
120 | 113                 if (window.addEventListener) {
121 | 114                     window.addEventListener('message', internalCallback, false);
122 | 115                 } else {
123 | 116                     window.attachEvent('onmessage', internalCallback);
124 | 117                 }
125 | 118             }
126 | 119         }
127 | 120         
128 | 121         /**
129 | 122         * @description Removes the message event listener
130 | 123         * @public     
131 | 124         */
132 | 125         function removeListener() {
133 | 126 
134 | 127             // browser supports window.postMessage
135 | 128             if (window.postMessage) {
136 | 129                 if (window.removeEventListener) {
137 | 130                     window.removeEventListener('message', internalCallback, false);
138 | 131                 } else {
139 | 132                     window.detachEvent('onmessage', internalCallback);
140 | 133                 }
141 | 134             }
142 | 135         }
143 | 136 
144 | 137         return {
145 | 138             post : postMessage,
146 | 139             receive : receiveMessage,
147 | 140             remove : removeListener
148 | 141         };
149 | 142     }());
150 | 143 
151 | 144     $$.module('Sfdc.canvas.xd', module);
152 | 145 
153 | 146 }(Sfdc.canvas, this));
-------------------------------------------------------------------------------- /js/canvas-all.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | if(global.Sfdc && global.Sfdc.canvas && global.Sfdc.canvas.module) { 3 | return 4 | } 5 | var extmodules = {}; 6 | if(global.Sfdc && global.Sfdc.canvas) { 7 | for(var key in global.Sfdc.canvas) { 8 | if(global.Sfdc.canvas.hasOwnProperty(key)) { 9 | extmodules[key] = global.Sfdc.canvas[key] 10 | } 11 | } 12 | } 13 | var oproto = Object.prototype, aproto = Array.prototype, doc = global.document, keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", $ = {hasOwn:function(obj, prop) { 14 | return oproto.hasOwnProperty.call(obj, prop) 15 | }, isUndefined:function(value) { 16 | var undef; 17 | return value === undef 18 | }, isNil:function(value) { 19 | return $.isUndefined(value) || value === null || value === "" 20 | }, isNumber:function(value) { 21 | return!!(value === 0 || value && value.toExponential && value.toFixed) 22 | }, isFunction:function(value) { 23 | return!!(value && value.constructor && value.call && value.apply) 24 | }, isArray:Array.isArray || function(value) { 25 | return oproto.toString.call(value) === "[object Array]" 26 | }, isArguments:function(value) { 27 | return!!(value && $.hasOwn(value, "callee")) 28 | }, isObject:function(value) { 29 | return value !== null && typeof value === "object" 30 | }, isString:function(value) { 31 | return value !== null && typeof value == "string" 32 | }, appearsJson:function(value) { 33 | return/^\{.*\}$/.test(value) 34 | }, nop:function() { 35 | }, invoker:function(fn) { 36 | if($.isFunction(fn)) { 37 | fn() 38 | } 39 | }, identity:function(obj) { 40 | return obj 41 | }, each:function(obj, it, ctx) { 42 | if($.isNil(obj)) { 43 | return 44 | } 45 | var nativ = aproto.forEach, i = 0, l, key; 46 | l = obj.length; 47 | ctx = ctx || obj; 48 | if(nativ && nativ === obj.forEach) { 49 | obj.forEach(it, ctx) 50 | }else { 51 | if($.isNumber(l)) { 52 | while(i < l) { 53 | if(it.call(ctx, obj[i], i, obj) === false) { 54 | return 55 | } 56 | i += 1 57 | } 58 | }else { 59 | for(key in obj) { 60 | if($.hasOwn(obj, key) && it.call(ctx, obj[key], key, obj) === false) { 61 | return 62 | } 63 | } 64 | } 65 | } 66 | }, startsWithHttp:function(orig, newUrl) { 67 | return!$.isString(orig) ? orig : orig.substring(0, 4) === "http" ? orig : newUrl 68 | }, map:function(obj, it, ctx) { 69 | var results = [], nativ = aproto.map; 70 | if($.isNil(obj)) { 71 | return results 72 | } 73 | if(nativ && obj.map === nativ) { 74 | return obj.map(it, ctx) 75 | } 76 | ctx = ctx || obj; 77 | $.each(obj, function(value, i, list) { 78 | results.push(it.call(ctx, value, i, list)) 79 | }); 80 | return results 81 | }, values:function(obj) { 82 | return $.map(obj, $.identity) 83 | }, slice:function(array, begin, end) { 84 | return aproto.slice.call(array, $.isUndefined(begin) ? 0 : begin, $.isUndefined(end) ? array.length : end) 85 | }, toArray:function(iterable) { 86 | if(!iterable) { 87 | return[] 88 | } 89 | if(iterable.toArray) { 90 | return iterable.toArray 91 | } 92 | if($.isArray(iterable)) { 93 | return iterable 94 | } 95 | if($.isArguments(iterable)) { 96 | return $.slice(iterable) 97 | } 98 | return $.values(iterable) 99 | }, size:function(obj) { 100 | return $.toArray(obj).length 101 | }, indexOf:function(array, item) { 102 | var nativ = aproto.indexOf, i, l; 103 | if(!array) { 104 | return-1 105 | } 106 | if(nativ && array.indexOf === nativ) { 107 | return array.indexOf(item) 108 | } 109 | for(i = 0, l = array.length;i < l;i += 1) { 110 | if(array[i] === item) { 111 | return i 112 | } 113 | } 114 | return-1 115 | }, isEmpty:function(obj) { 116 | if(obj === null) { 117 | return true 118 | } 119 | if($.isArray(obj) || $.isString(obj)) { 120 | return obj.length === 0 121 | } 122 | for(var key in obj) { 123 | if($.hasOwn(obj, key)) { 124 | return false 125 | } 126 | } 127 | return true 128 | }, remove:function(array, item) { 129 | var i = $.indexOf(array, item); 130 | if(i >= 0) { 131 | array.splice(i, 1) 132 | } 133 | }, param:function(a, encode) { 134 | var s = []; 135 | encode = encode || false; 136 | function add(key, value) { 137 | if($.isNil(value)) { 138 | return 139 | } 140 | value = $.isFunction(value) ? value() : value; 141 | if($.isArray(value)) { 142 | $.each(value, function(v, n) { 143 | add(key, v) 144 | }) 145 | }else { 146 | if(encode) { 147 | s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value) 148 | }else { 149 | s[s.length] = key + "=" + value 150 | } 151 | } 152 | } 153 | if($.isArray(a)) { 154 | $.each(a, function(v, n) { 155 | add(n, v) 156 | }) 157 | }else { 158 | for(var p in a) { 159 | if($.hasOwn(a, p)) { 160 | add(p, a[p]) 161 | } 162 | } 163 | } 164 | return s.join("&").replace(/%20/g, "+") 165 | }, objectify:function(q) { 166 | var arr, obj = {}, i, p, n, v, e; 167 | if($.isNil(q)) { 168 | return obj 169 | } 170 | if(q.substring(0, 1) == "?") { 171 | q = q.substring(1) 172 | } 173 | arr = q.split("&"); 174 | for(i = 0;i < arr.length;i += 1) { 175 | p = arr[i].split("="); 176 | n = p[0]; 177 | v = p[1]; 178 | e = obj[n]; 179 | if(!$.isNil(e)) { 180 | if($.isArray(e)) { 181 | e[e.length] = v 182 | }else { 183 | obj[n] = []; 184 | obj[n][0] = e; 185 | obj[n][1] = v 186 | } 187 | }else { 188 | obj[n] = v 189 | } 190 | } 191 | return obj 192 | }, stripUrl:function(url) { 193 | return $.isNil(url) ? null : url.replace(/([^:]+:\/\/[^\/\?#]+).*/, "$1") 194 | }, query:function(url, q) { 195 | if($.isNil(q)) { 196 | return url 197 | } 198 | url = url.replace(/#.*$/, ""); 199 | url += /^\#/.test(q) ? q : (/\?/.test(url) ? "&" : "?") + q; 200 | return url 201 | }, extend:function(dest) { 202 | $.each($.slice(arguments, 1), function(mixin, i) { 203 | $.each(mixin, function(value, key) { 204 | dest[key] = value 205 | }) 206 | }); 207 | return dest 208 | }, endsWith:function(str, suffix) { 209 | return str.indexOf(suffix, str.length - suffix.length) !== -1 210 | }, capitalize:function(str) { 211 | return str.charAt(0).toUpperCase() + str.slice(1) 212 | }, uncapitalize:function(str) { 213 | return str.charAt(0).toLowerCase() + str.slice(1) 214 | }, decode:function(str) { 215 | var output = [], chr1, chr2, chr3 = "", enc1, enc2, enc3, enc4 = "", i = 0; 216 | str = str.replace(/[^A-Za-z0-9\+\/\=]/g, ""); 217 | do { 218 | enc1 = keyStr.indexOf(str.charAt(i++)); 219 | enc2 = keyStr.indexOf(str.charAt(i++)); 220 | enc3 = keyStr.indexOf(str.charAt(i++)); 221 | enc4 = keyStr.indexOf(str.charAt(i++)); 222 | chr1 = enc1 << 2 | enc2 >> 4; 223 | chr2 = (enc2 & 15) << 4 | enc3 >> 2; 224 | chr3 = (enc3 & 3) << 6 | enc4; 225 | output.push(String.fromCharCode(chr1)); 226 | if(enc3 !== 64) { 227 | output.push(String.fromCharCode(chr2)) 228 | } 229 | if(enc4 !== 64) { 230 | output.push(String.fromCharCode(chr3)) 231 | } 232 | chr1 = chr2 = chr3 = ""; 233 | enc1 = enc2 = enc3 = enc4 = "" 234 | }while(i < str.length); 235 | return $.escapeToUTF8(output.join("")) 236 | }, escapeToUTF8:function(str) { 237 | var outStr = ""; 238 | var i = 0; 239 | while(i < str.length) { 240 | var c = str.charCodeAt(i++); 241 | var c1; 242 | if(c < 128) { 243 | outStr += String.fromCharCode(c) 244 | }else { 245 | if(c > 191 && c < 224) { 246 | c1 = str.charCodeAt(i++); 247 | outStr += String.fromCharCode((c & 31) << 6 | c1 & 63) 248 | }else { 249 | c1 = str.charCodeAt(i++); 250 | var c2 = str.charCodeAt(i++); 251 | outStr += String.fromCharCode((c & 15) << 12 | (c1 & 63) << 6 | c2 & 63) 252 | } 253 | } 254 | } 255 | return outStr 256 | }, validEventName:function(name, res) { 257 | var ns, parts = name.split(/\./), regex = /^[$A-Z_][0-9A-Z_$]*$/i, reserved = {"sfdc":true, "canvas":true, "force":true, "salesforce":true, "chatter":true, "s1":true}; 258 | $.each($.isArray(res) ? res : [res], function(v) { 259 | reserved[v] = false 260 | }); 261 | if(parts.length > 2) { 262 | return 1 263 | } 264 | if(parts.length === 2) { 265 | ns = parts[0].toLowerCase(); 266 | if(reserved[ns]) { 267 | return 2 268 | } 269 | } 270 | if(!regex.test(parts[0]) || !regex.test(parts[1])) { 271 | return 3 272 | } 273 | return 0 274 | }, prototypeOf:function(obj) { 275 | var nativ = Object.getPrototypeOf, proto = "__proto__"; 276 | if($.isFunction(nativ)) { 277 | return nativ.call(Object, obj) 278 | }else { 279 | if(typeof{}[proto] === "object") { 280 | return obj[proto] 281 | }else { 282 | return obj.constructor.prototype 283 | } 284 | } 285 | }, module:function(ns, decl) { 286 | var parts = ns.split("."), parent = global.Sfdc.canvas, i, length; 287 | if(parts[1] === "canvas") { 288 | parts = parts.slice(2) 289 | } 290 | length = parts.length; 291 | for(i = 0;i < length;i += 1) { 292 | if($.isUndefined(parent[parts[i]])) { 293 | parent[parts[i]] = {} 294 | } 295 | parent = parent[parts[i]] 296 | } 297 | if($.isFunction(decl)) { 298 | decl = decl() 299 | } 300 | return $.extend(parent, decl) 301 | }, document:function() { 302 | return doc 303 | }, byId:function(id) { 304 | return doc.getElementById(id) 305 | }, byClass:function(clazz) { 306 | return doc.getElementsByClassName(clazz) 307 | }, attr:function(el, name) { 308 | var a = el.attributes, i; 309 | for(i = 0;i < a.length;i += 1) { 310 | if(name === a[i].name) { 311 | return a[i].value 312 | } 313 | } 314 | }, onReady:function(cb) { 315 | if($.isFunction(cb)) { 316 | readyHandlers.push(cb) 317 | } 318 | }, console:function() { 319 | var enabled = false; 320 | if(window && !window.console) { 321 | window.console = {} 322 | } 323 | if(window && !window.console.log) { 324 | window.console.log = function() { 325 | } 326 | } 327 | if(window && !window.console.error) { 328 | window.console.error = function() { 329 | } 330 | } 331 | function isSessionStorage() { 332 | try { 333 | return"sessionStorage" in window && window.sessionStorage !== null 334 | }catch(e) { 335 | return false 336 | } 337 | } 338 | function log() { 339 | } 340 | function error() { 341 | } 342 | function activate() { 343 | if(Function.prototype.bind) { 344 | log = Function.prototype.bind.call(console.log, console) 345 | }else { 346 | log = function() { 347 | Function.prototype.apply.call(console.log, console, arguments) 348 | } 349 | } 350 | } 351 | function deactivate() { 352 | log = function() { 353 | } 354 | } 355 | function enable() { 356 | enabled = true; 357 | if(isSessionStorage()) { 358 | sessionStorage.setItem("canvas_console", "true") 359 | } 360 | activate() 361 | } 362 | function disable() { 363 | enabled = false; 364 | if(isSessionStorage()) { 365 | sessionStorage.setItem("canvas_console", "false") 366 | } 367 | deactivate() 368 | } 369 | enabled = isSessionStorage() && sessionStorage.getItem("canvas_console") === "true"; 370 | if(enabled) { 371 | activate() 372 | }else { 373 | deactivate() 374 | } 375 | if(Function.prototype.bind) { 376 | error = Function.prototype.bind.call(console.error, console) 377 | }else { 378 | error = function() { 379 | Function.prototype.apply.call(console.error, console, arguments) 380 | } 381 | } 382 | return{enable:enable, disable:disable, log:log, error:error} 383 | }()}, readyHandlers = [], canvas = function(cb) { 384 | if($.isFunction(cb)) { 385 | readyHandlers.push(cb) 386 | } 387 | }; 388 | (function() { 389 | var called = false, isFrame, fn; 390 | function ready() { 391 | if(called) { 392 | return 393 | } 394 | called = true; 395 | ready = $.nop; 396 | $.each(readyHandlers, $.invoker); 397 | readyHandlers = [] 398 | } 399 | function tryScroll() { 400 | if(called) { 401 | return 402 | } 403 | try { 404 | document.documentElement.doScroll("left"); 405 | ready() 406 | }catch(e) { 407 | setTimeout(tryScroll, 30) 408 | } 409 | } 410 | if(document.addEventListener) { 411 | document.addEventListener("DOMContentLoaded", ready, false) 412 | }else { 413 | if(document.attachEvent) { 414 | try { 415 | isFrame = self !== top 416 | }catch(e) { 417 | } 418 | if(document.documentElement.doScroll && !isFrame) { 419 | tryScroll() 420 | } 421 | document.attachEvent("onreadystatechange", function() { 422 | if(document.readyState === "complete") { 423 | ready() 424 | } 425 | }) 426 | } 427 | } 428 | if(window.addEventListener) { 429 | window.addEventListener("load", ready, false) 430 | }else { 431 | if(window.attachEvent) { 432 | window.attachEvent("onload", ready) 433 | }else { 434 | fn = window.onload; 435 | window.onload = function() { 436 | if(fn) { 437 | fn() 438 | } 439 | ready() 440 | } 441 | } 442 | } 443 | })(); 444 | $.each($, function(fn, name) { 445 | canvas[name] = fn 446 | }); 447 | $.each(extmodules, function(fn, name) { 448 | canvas[name] = fn 449 | }); 450 | (function() { 451 | var method; 452 | var noop = function() { 453 | }; 454 | var methods = ["assert", "clear", "count", "debug", "dir", "dirxml", "error", "exception", "group", "groupCollapsed", "groupEnd", "info", "log", "markTimeline", "profile", "profileEnd", "table", "time", "timeEnd", "timeStamp", "trace", "warn"]; 455 | var length = methods.length; 456 | var console = typeof window !== "undefined" && window.console ? window.console : {}; 457 | while(length--) { 458 | method = methods[length]; 459 | if(!console[method]) { 460 | console[method] = noop 461 | } 462 | } 463 | })(); 464 | if(!global.Sfdc) { 465 | global.Sfdc = {} 466 | } 467 | global.Sfdc.canvas = canvas 468 | })(window); 469 | (function($$) { 470 | var module = function() { 471 | function isSecure() { 472 | return window.location.protocol === "https:" 473 | } 474 | function set(name, value, days) { 475 | var expires = "", date; 476 | if(days) { 477 | date = new Date; 478 | date.setTime(date.getTime() + days * 24 * 60 * 60 * 1E3); 479 | expires = "; expires=" + date.toGMTString() 480 | }else { 481 | expires = "" 482 | } 483 | document.cookie = name + "=" + value + expires + "; path=/" + (isSecure() === true ? "; secure" : "") 484 | } 485 | function get(name) { 486 | var nameEQ, ca, c, i; 487 | if($$.isUndefined(name)) { 488 | return document.cookie.split(";") 489 | } 490 | nameEQ = name + "="; 491 | ca = document.cookie.split(";"); 492 | for(i = 0;i < ca.length;i += 1) { 493 | c = ca[i]; 494 | while(c.charAt(0) === " ") { 495 | c = c.substring(1, c.length) 496 | } 497 | if(c.indexOf(nameEQ) === 0) { 498 | return c.substring(nameEQ.length, c.length) 499 | } 500 | } 501 | return null 502 | } 503 | function remove(name) { 504 | set(name, "", -1) 505 | } 506 | return{set:set, get:get, remove:remove} 507 | }(); 508 | $$.module("Sfdc.canvas.cookies", module) 509 | })(Sfdc.canvas); 510 | (function($$) { 511 | var storage = function() { 512 | function isLocalStorage() { 513 | try { 514 | return"sessionStorage" in window && window.sessionStorage !== null 515 | }catch(e) { 516 | return false 517 | } 518 | } 519 | return{get:function get(key) { 520 | if(isLocalStorage()) { 521 | return sessionStorage.getItem(key) 522 | } 523 | return $$.cookies.get(key) 524 | }, set:function set(key, value) { 525 | if(isLocalStorage()) { 526 | return sessionStorage.setItem(key, value) 527 | } 528 | return $$.cookies.set(key, value) 529 | }, remove:function remove(key) { 530 | if(isLocalStorage()) { 531 | return sessionStorage.removeItem(key) 532 | } 533 | return $$.cookies.remove(key) 534 | }} 535 | }(); 536 | var module = function() { 537 | var accessToken, instUrl, instId, tOrigin, childWindow; 538 | function init() { 539 | accessToken = storage.get("access_token"); 540 | storage.remove("access_token") 541 | } 542 | function query(params) { 543 | var r = [], n; 544 | if(!$$.isUndefined(params)) { 545 | for(n in params) { 546 | if(params.hasOwnProperty(n)) { 547 | r.push(n + "=" + params[n]) 548 | } 549 | } 550 | return"?" + r.join("&") 551 | } 552 | return"" 553 | } 554 | function refresh() { 555 | storage.set("access_token", accessToken); 556 | self.location.reload() 557 | } 558 | function login(ctx) { 559 | var uri; 560 | ctx = ctx || {}; 561 | uri = ctx.uri || "/rest/oauth2"; 562 | ctx.params = ctx.params || {state:""}; 563 | ctx.params.state = ctx.params.state || ctx.callback || window.location.pathname; 564 | ctx.params.display = ctx.params.display || "popup"; 565 | ctx.params.redirect_uri = $$.startsWithHttp(ctx.params.redirect_uri, encodeURIComponent(window.location.protocol + "//" + window.location.hostname + ":" + window.location.port) + ctx.params.redirect_uri); 566 | uri = uri + query(ctx.params); 567 | childWindow = window.open(uri, "OAuth", "status=0,toolbar=0,menubar=0,resizable=0,scrollbars=1,top=50,left=50,height=500,width=680") 568 | } 569 | function token(t) { 570 | if(arguments.length === 0) { 571 | if(!$$.isNil(accessToken)) { 572 | return accessToken 573 | } 574 | }else { 575 | accessToken = t 576 | } 577 | return accessToken 578 | } 579 | function instanceUrl(i) { 580 | if(arguments.length === 0) { 581 | if(!$$.isNil(instUrl)) { 582 | return instUrl 583 | } 584 | instUrl = storage.get("instance_url") 585 | }else { 586 | if(i === null) { 587 | storage.remove("instance_url"); 588 | instUrl = null 589 | }else { 590 | storage.set("instance_url", i); 591 | instUrl = i 592 | } 593 | } 594 | return instUrl 595 | } 596 | function parseHash(hash) { 597 | var i, nv, nvp, n, v; 598 | if(!$$.isNil(hash)) { 599 | if(hash.indexOf("#") === 0) { 600 | hash = hash.substr(1) 601 | } 602 | nvp = hash.split("&"); 603 | for(i = 0;i < nvp.length;i += 1) { 604 | nv = nvp[i].split("="); 605 | n = nv[0]; 606 | v = decodeURIComponent(nv[1]); 607 | if("access_token" === n) { 608 | token(v) 609 | }else { 610 | if("instance_url" === n) { 611 | instanceUrl(v) 612 | }else { 613 | if("target_origin" === n) { 614 | tOrigin = decodeURIComponent(v) 615 | }else { 616 | if("instance_id" === n) { 617 | instId = v 618 | } 619 | } 620 | } 621 | } 622 | } 623 | } 624 | } 625 | function checkChildWindowStatus() { 626 | if(!childWindow || childWindow.closed) { 627 | refresh() 628 | } 629 | } 630 | function childWindowUnloadNotification(hash) { 631 | var retry = 0, maxretries = 10; 632 | function cws() { 633 | retry++; 634 | if(!childWindow || childWindow.closed) { 635 | refresh() 636 | }else { 637 | if(retry < maxretries) { 638 | setTimeout(cws, 50) 639 | } 640 | } 641 | } 642 | parseHash(hash); 643 | setTimeout(cws, 50) 644 | } 645 | function logout() { 646 | token(null) 647 | } 648 | function loggedin() { 649 | return!$$.isNil(token()) 650 | } 651 | function loginUrl() { 652 | var i, nvs, nv, q = self.location.search; 653 | if(q) { 654 | q = q.substring(1); 655 | nvs = q.split("&"); 656 | for(i = 0;i < nvs.length;i += 1) { 657 | nv = nvs[i].split("="); 658 | if("loginUrl" === nv[0]) { 659 | return decodeURIComponent(nv[1]) + "/services/oauth2/authorize" 660 | } 661 | } 662 | } 663 | return"https://login.salesforce.com/services/oauth2/authorize" 664 | } 665 | function targetOrigin(to) { 666 | if(!$$.isNil(to)) { 667 | tOrigin = to; 668 | return to 669 | } 670 | if(!$$.isNil(tOrigin)) { 671 | return tOrigin 672 | } 673 | parseHash(document.location.hash); 674 | return tOrigin 675 | } 676 | function instanceId(id) { 677 | if(!$$.isNil(id)) { 678 | instId = id; 679 | return id 680 | } 681 | if(!$$.isNil(instId)) { 682 | return instId 683 | } 684 | parseHash(document.location.hash); 685 | return instId 686 | } 687 | function client() { 688 | return{oauthToken:token(), instanceId:instanceId(), targetOrigin:targetOrigin()} 689 | } 690 | return{init:init, login:login, logout:logout, loggedin:loggedin, loginUrl:loginUrl, token:token, instance:instanceUrl, client:client, checkChildWindowStatus:checkChildWindowStatus, childWindowUnloadNotification:childWindowUnloadNotification} 691 | }(); 692 | $$.module("Sfdc.canvas.oauth", module); 693 | $$.oauth.init() 694 | })(Sfdc.canvas); 695 | (function($$, window) { 696 | var module = function() { 697 | var internalCallback; 698 | function postMessage(message, target_url, target) { 699 | var sfdcJson = Sfdc.JSON || JSON; 700 | if($$.isNil(target_url)) { 701 | throw"ERROR: target_url was not supplied on postMessage"; 702 | } 703 | var otherWindow = $$.stripUrl(target_url); 704 | target = target || parent; 705 | if(window.postMessage) { 706 | if($$.isObject(message)) { 707 | message.targetModule = "Canvas" 708 | } 709 | message = sfdcJson.stringify(message); 710 | $$.console.log("Sending Post Message ", message); 711 | target.postMessage(message, otherWindow) 712 | } 713 | } 714 | function receiveMessage(callback, source_origin) { 715 | if(window.postMessage) { 716 | if(callback) { 717 | internalCallback = function(e) { 718 | var data, r; 719 | var sfdcJson = Sfdc.JSON || JSON; 720 | $$.console.log("Post Message Got callback", e); 721 | if(!$$.isNil(e)) { 722 | if(typeof source_origin === "string" && e.origin !== source_origin) { 723 | $$.console.log("source origin's don't match", e.origin, source_origin); 724 | return false 725 | } 726 | if($$.isFunction(source_origin)) { 727 | r = source_origin(e.origin, e.data); 728 | if(r === false) { 729 | $$.console.log("source origin's function returning false", e.origin, e.data); 730 | return false 731 | } 732 | } 733 | if($$.appearsJson(e.data)) { 734 | try { 735 | data = sfdcJson.parse(e.data) 736 | }catch(ignore) { 737 | } 738 | if(!$$.isNil(data) && ($$.isNil(data.targetModule) || data.targetModule === "Canvas")) { 739 | $$.console.log("Invoking callback"); 740 | callback(data, r) 741 | } 742 | } 743 | } 744 | } 745 | } 746 | if(window.addEventListener) { 747 | window.addEventListener("message", internalCallback, false) 748 | }else { 749 | window.attachEvent("onmessage", internalCallback) 750 | } 751 | } 752 | } 753 | function removeListener() { 754 | if(window.postMessage) { 755 | if(window.removeEventListener) { 756 | window.removeEventListener("message", internalCallback, false) 757 | }else { 758 | window.detachEvent("onmessage", internalCallback) 759 | } 760 | } 761 | } 762 | return{post:postMessage, receive:receiveMessage, remove:removeListener} 763 | }(); 764 | $$.module("Sfdc.canvas.xd", module) 765 | })(Sfdc.canvas, window); 766 | (function($$) { 767 | var pversion, cversion = "41.0"; 768 | var module = function() { 769 | var purl; 770 | function getTargetOrigin(to) { 771 | var h; 772 | if(to === "*") { 773 | return to 774 | } 775 | if(!$$.isNil(to)) { 776 | h = $$.stripUrl(to); 777 | purl = $$.startsWithHttp(h, purl); 778 | if(purl) { 779 | return purl 780 | } 781 | } 782 | h = $$.document().location.hash; 783 | if(h) { 784 | h = decodeURIComponent(h.replace(/^#/, "")); 785 | purl = $$.startsWithHttp(h, purl) 786 | } 787 | return purl 788 | } 789 | function xdCallback(data) { 790 | if(data) { 791 | if(submodules[data.type]) { 792 | submodules[data.type].callback(data) 793 | } 794 | } 795 | } 796 | var submodules = function() { 797 | var cbs = [], seq = 0, autog = true; 798 | function postit(clientscb, message) { 799 | var wrapped, to, c; 800 | seq = seq > 100 ? 0 : seq + 1; 801 | cbs[seq] = clientscb; 802 | wrapped = {seq:seq, src:"client", clientVersion:cversion, parentVersion:pversion, body:message}; 803 | c = message && message.config && message.config.client; 804 | to = getTargetOrigin($$.isNil(c) ? null : c.targetOrigin); 805 | if($$.isNil(to)) { 806 | throw"ERROR: targetOrigin was not supplied and was not found on the hash tag, this can result from a redirect or link to another page."; 807 | } 808 | $$.console.log("posting message ", {message:wrapped, to:to}); 809 | $$.xd.post(wrapped, to, parent) 810 | } 811 | function validateClient(client, cb) { 812 | var msg; 813 | client = client || $$.oauth && $$.oauth.client(); 814 | if($$.isNil(client) || $$.isNil(client.oauthToken)) { 815 | msg = {status:401, statusText:"Unauthorized", parentVersion:pversion, payload:"client or client.oauthToken not supplied"} 816 | } 817 | if($$.isNil(client.instanceId) || $$.isNil(client.targetOrigin)) { 818 | msg = {status:400, statusText:"Bad Request", parentVersion:pversion, payload:"client.instanceId or client.targetOrigin not supplied"} 819 | } 820 | if(!$$.isNil(msg)) { 821 | if($$.isFunction(cb)) { 822 | cb(msg); 823 | return false 824 | }else { 825 | throw msg; 826 | } 827 | } 828 | return true 829 | } 830 | var event = function() { 831 | var subscriptions = {}, STR_EVT = "sfdc.streamingapi"; 832 | function validName(name, res) { 833 | var msg, r = $$.validEventName(name, res); 834 | if(r !== 0) { 835 | msg = {1:"Event names can only contain one namespace", 2:"Namespace has already been reserved", 3:"Event name contains invalid characters"}; 836 | throw msg[r]; 837 | } 838 | } 839 | function findSubscription(event) { 840 | var s, name = event.name; 841 | if(name === STR_EVT) { 842 | if(!$$.isNil(subscriptions[name])) { 843 | s = subscriptions[name][event.params.topic] 844 | } 845 | }else { 846 | s = subscriptions[name] 847 | } 848 | if(!$$.isNil(s) && ($$.isFunction(s.onData) || $$.isFunction(s.onComplete))) { 849 | return s 850 | } 851 | return null 852 | } 853 | return{callback:function(data) { 854 | var event = data.payload, subscription = findSubscription(event), func; 855 | if(!$$.isNil(subscription)) { 856 | if(event.method === "onData") { 857 | func = subscription.onData 858 | }else { 859 | if(event.method === "onComplete") { 860 | func = subscription.onComplete 861 | } 862 | } 863 | if(!$$.isNil(func) && $$.isFunction(func)) { 864 | func(event.payload) 865 | } 866 | } 867 | }, subscribe:function(client, s) { 868 | var subs = {}; 869 | if($$.isNil(s) || !validateClient(client)) { 870 | throw"precondition fail"; 871 | } 872 | $$.each($$.isArray(s) ? s : [s], function(v) { 873 | if(!$$.isNil(v.name)) { 874 | validName(v.name, ["canvas", "sfdc"]); 875 | if(v.name === STR_EVT) { 876 | if(!$$.isNil(v.params) && !$$.isNil(v.params.topic)) { 877 | if($$.isNil(subscriptions[v.name])) { 878 | subscriptions[v.name] = {} 879 | } 880 | subscriptions[v.name][v.params.topic] = v 881 | }else { 882 | throw"[" + STR_EVT + "] topic is missing"; 883 | } 884 | }else { 885 | subscriptions[v.name] = v 886 | } 887 | subs[v.name] = {params:v.params} 888 | }else { 889 | throw"subscription does not have a 'name'"; 890 | } 891 | }); 892 | if(!client.isVF) { 893 | postit(null, {type:"subscribe", config:{client:client}, subscriptions:subs}) 894 | } 895 | }, unsubscribe:function(client, s) { 896 | var subs = {}; 897 | if($$.isNil(s) || !validateClient(client)) { 898 | throw"PRECONDITION FAIL: need fo supply client and event name"; 899 | } 900 | if($$.isString(s)) { 901 | subs[s] = {}; 902 | delete subscriptions[s] 903 | }else { 904 | $$.each($$.isArray(s) ? s : [s], function(v) { 905 | var name = v.name ? v.name : v; 906 | validName(name, ["canvas", "sfdc"]); 907 | subs[name] = {params:v.params}; 908 | if(name === STR_EVT) { 909 | if(!$$.isNil(subscriptions[name])) { 910 | if(!$$.isNil(subscriptions[name][v.params.topic])) { 911 | delete subscriptions[name][v.params.topic] 912 | } 913 | if($$.size(subscriptions[name]) <= 0) { 914 | delete subscriptions[name] 915 | } 916 | } 917 | }else { 918 | delete subscriptions[name] 919 | } 920 | }) 921 | } 922 | if(!client.isVF) { 923 | postit(null, {type:"unsubscribe", config:{client:client}, subscriptions:subs}) 924 | } 925 | }, publish:function(client, e) { 926 | if(!$$.isNil(e) && !$$.isNil(e.name)) { 927 | validName(e.name, ["s1"]); 928 | if(validateClient(client)) { 929 | postit(null, {type:"publish", config:{client:client}, event:e}) 930 | } 931 | } 932 | }} 933 | }(); 934 | var callback = function() { 935 | return{callback:function(data) { 936 | if(data.status === 401 && $$.isArray(data.payload) && data.payload[0].errorCode && data.payload[0].errorCode === "INVALID_SESSION_ID") { 937 | if($$.oauth) { 938 | $$.oauth.logout() 939 | } 940 | } 941 | if($$.isFunction(cbs[data.seq])) { 942 | if(!$$.isFunction(cbs[data.seq])) { 943 | alert("not function") 944 | } 945 | cbs[data.seq](data) 946 | }else { 947 | } 948 | }} 949 | }(); 950 | var services = function() { 951 | var sr; 952 | return{ajax:function(url, settings) { 953 | var ccb, config, defaults; 954 | if(!url) { 955 | throw"PRECONDITION ERROR: url required with AJAX call"; 956 | } 957 | if(!settings || !$$.isFunction(settings.success)) { 958 | throw"PRECONDITION ERROR: function: 'settings.success' missing."; 959 | } 960 | if(!validateClient(settings.client, settings.success)) { 961 | return 962 | } 963 | ccb = settings.success; 964 | defaults = {method:"GET", async:true, contentType:"application/json", headers:{"Authorization":"OAuth " + settings.client.oauthToken, "Accept":"application/json"}, data:null}; 965 | config = $$.extend(defaults, settings || {}); 966 | config.success = undefined; 967 | config.failure = undefined; 968 | if(config.client.targetOrigin === "*") { 969 | config.client.targetOrigin = null 970 | }else { 971 | purl = $$.startsWithHttp(config.targetOrigin, purl) 972 | } 973 | postit(ccb, {type:"ajax", url:url, config:config}) 974 | }, ctx:function(clientscb, client) { 975 | if(validateClient(client, clientscb)) { 976 | postit(clientscb, {type:"ctx", accessToken:client.oauthToken, config:{client:client}}) 977 | } 978 | }, token:function(t) { 979 | return $$.oauth && $$.oauth.token(t) 980 | }, version:function() { 981 | return{clientVersion:cversion, parentVersion:pversion} 982 | }, signedrequest:function(s) { 983 | if(arguments.length > 0) { 984 | sr = s 985 | } 986 | return sr 987 | }, refreshSignedRequest:function(clientscb) { 988 | var id = window.name.substring("canvas-frame-".length), client = {oauthToken:"null", instanceId:id, targetOrigin:"*"}; 989 | postit(clientscb, {type:"refresh", accessToken:client.oauthToken, config:{client:client}}) 990 | }, repost:function(refresh) { 991 | var id = window.name.substring("canvas-frame-".length), client = {oauthToken:"null", instanceId:id, targetOrigin:"*"}, r = refresh || false; 992 | postit(null, {type:"repost", accessToken:client.oauthToken, config:{client:client}, refresh:r}) 993 | }} 994 | }(); 995 | var frame = function() { 996 | return{size:function() { 997 | var docElement = $$.document().documentElement; 998 | var contentHeight = docElement.scrollHeight, pageHeight = docElement.clientHeight, scrollTop = docElement && docElement.scrollTop || $$.document().body.scrollTop, contentWidth = docElement.scrollWidth, pageWidth = docElement.clientWidth, scrollLeft = docElement && docElement.scrollLeft || $$.document().body.scrollLeft; 999 | return{heights:{contentHeight:contentHeight, pageHeight:pageHeight, scrollTop:scrollTop}, widths:{contentWidth:contentWidth, pageWidth:pageWidth, scrollLeft:scrollLeft}} 1000 | }, resize:function(client, size) { 1001 | var sh, ch, sw, cw, s = {height:"", width:""}, docElement = $$.document().documentElement; 1002 | if($$.isNil(size)) { 1003 | sh = docElement.scrollHeight; 1004 | ch = docElement.clientHeight; 1005 | if(ch !== sh) { 1006 | s.height = sh + "px" 1007 | } 1008 | sw = docElement.scrollWidth; 1009 | cw = docElement.clientWidth; 1010 | if(sw !== cw) { 1011 | s.width = sw + "px" 1012 | } 1013 | }else { 1014 | if(!$$.isNil(size.height)) { 1015 | s.height = size.height 1016 | } 1017 | if(!$$.isNil(size.width)) { 1018 | s.width = size.width 1019 | } 1020 | } 1021 | if(!$$.isNil(s.height) || !$$.isNil(s.width)) { 1022 | postit(null, {type:"resize", config:{client:client}, size:s}) 1023 | } 1024 | }, autogrow:function(client, b, interval) { 1025 | var ival = $$.isNil(interval) ? 300 : interval; 1026 | autog = $$.isNil(b) ? true : b; 1027 | if(autog === false) { 1028 | return 1029 | } 1030 | setTimeout(function() { 1031 | submodules.frame.resize(client); 1032 | submodules.frame.autogrow(client, autog) 1033 | }, ival) 1034 | }} 1035 | }(); 1036 | return{services:services, frame:frame, event:event, callback:callback} 1037 | }(); 1038 | $$.xd.receive(xdCallback, getTargetOrigin); 1039 | return{ctx:submodules.services.ctx, ajax:submodules.services.ajax, token:submodules.services.token, version:submodules.services.version, resize:submodules.frame.resize, size:submodules.frame.size, autogrow:submodules.frame.autogrow, subscribe:submodules.event.subscribe, unsubscribe:submodules.event.unsubscribe, publish:submodules.event.publish, signedrequest:submodules.services.signedrequest, refreshSignedRequest:submodules.services.refreshSignedRequest, repost:submodules.services.repost} 1040 | }(); 1041 | $$.module("Sfdc.canvas.client", module) 1042 | })(Sfdc.canvas); 1043 | 1044 | -------------------------------------------------------------------------------- /js/cookies.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014, salesforce.com, inc. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided 6 | * that the following conditions are met: 7 | * 8 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the 9 | * following disclaimer. 10 | * 11 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 12 | * the following disclaimer in the documentation and/or other materials provided with the distribution. 13 | * 14 | * Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or 15 | * promote products derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 19 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 23 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | * POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | 28 | (function ($$) { 29 | 30 | "use strict"; 31 | 32 | var module = (function() { 33 | 34 | function isSecure() 35 | { 36 | return window.location.protocol === 'https:'; 37 | } 38 | 39 | /** 40 | * @description Create a cookie 41 | * @param {String} name Cookie name 42 | * @param {String} value Cookie value 43 | * @param {Integer} [days] Number of days for the cookie to remain active. 44 | If not provided, the cookie never expires 45 | */ 46 | function set(name, value, days) { 47 | var expires = "", date; 48 | if (days) { 49 | date = new Date(); 50 | date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); 51 | expires = "; expires=" + date.toGMTString(); 52 | } 53 | else { 54 | expires = ""; 55 | } 56 | document.cookie = name + "=" + value + expires + "; path=/" + ((isSecure() === true) ? "; secure" : ""); 57 | } 58 | 59 | /** 60 | * @description Get the cookie with the specified name 61 | * @param {String} name The name of the cookie to retrieve 62 | * @returns The value of the cookie if the name is found, otherwise null 63 | */ 64 | function get(name) { 65 | var nameEQ, ca, c, i; 66 | 67 | if ($$.isUndefined(name)) { 68 | return document.cookie.split(';'); 69 | } 70 | 71 | nameEQ = name + "="; 72 | ca = document.cookie.split(';'); 73 | for (i = 0; i < ca.length; i += 1) { 74 | c = ca[i]; 75 | while (c.charAt(0) === ' ') {c = c.substring(1, c.length);} 76 | if (c.indexOf(nameEQ) === 0) { 77 | return c.substring(nameEQ.length, c.length); 78 | } 79 | } 80 | return null; 81 | } 82 | 83 | /** 84 | * @description Remove the specified cookie by setting the expiry date to one day ago 85 | * @param {String} name The name of the cookie to remove. 86 | */ 87 | function remove(name) { 88 | set(name, "", -1); 89 | } 90 | 91 | return { 92 | set : set, 93 | get : get, 94 | remove : remove 95 | }; 96 | }()); 97 | 98 | 99 | $$.module('Sfdc.canvas.cookies', module); 100 | 101 | }(Sfdc.canvas)); -------------------------------------------------------------------------------- /js/oauth.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014, salesforce.com, inc. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided 6 | * that the following conditions are met: 7 | * 8 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the 9 | * following disclaimer. 10 | * 11 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 12 | * the following disclaimer in the documentation and/or other materials provided with the distribution. 13 | * 14 | * Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or 15 | * promote products derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 19 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 23 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | * POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | 28 | /** 29 | *@namespace Sfdc.canvas.oauth 30 | *@name Sfdc.canvas.oauth 31 | */ 32 | (function ($$) { 33 | 34 | "use strict"; 35 | 36 | var storage = (function() { 37 | 38 | function isLocalStorage() { 39 | try { 40 | return 'sessionStorage' in window && window.sessionStorage !== null; 41 | } catch (e) { 42 | return false; 43 | } 44 | } 45 | 46 | return { 47 | get : function get(key) { 48 | if (isLocalStorage()) { 49 | return sessionStorage.getItem(key); 50 | } 51 | return $$.cookies.get(key); 52 | }, 53 | set : function set(key, value) { 54 | if (isLocalStorage()) { 55 | return sessionStorage.setItem(key, value); 56 | } 57 | return $$.cookies.set(key, value); 58 | }, 59 | remove : function remove(key) { 60 | if (isLocalStorage()) { 61 | return sessionStorage.removeItem(key); 62 | } 63 | return $$.cookies.remove(key); 64 | } 65 | }; 66 | 67 | }()); 68 | 69 | var module = (function() { 70 | 71 | var accessToken, 72 | instUrl, 73 | instId, 74 | tOrigin, 75 | childWindow; 76 | 77 | function init() { 78 | // Get the access token from the sessionStorage or cookie (needed to survive refresh), 79 | // and then remove the cookie per security's request. 80 | accessToken = storage.get("access_token"); 81 | storage.remove("access_token"); 82 | } 83 | 84 | function query(params) { 85 | var r = [], n; 86 | if (!$$.isUndefined(params)) { 87 | for (n in params) { 88 | if (params.hasOwnProperty(n)) { 89 | // probably should encode these 90 | r.push(n + "=" + params[n]); 91 | } 92 | } 93 | return "?" + r.join('&'); 94 | } 95 | return ''; 96 | } 97 | /** 98 | *@private 99 | */ 100 | function refresh() { 101 | // Temporarily set the oauth token in a sessionStorage or cookie and then remove it 102 | // after the refresh. 103 | storage.set("access_token", accessToken); 104 | self.location.reload(); 105 | } 106 | /** 107 | * @name Sfdc.canvas.oauth#login 108 | * @function 109 | * @description Opens the OAuth popup window to retrieve an OAuth token. 110 | * @param {Object} ctx The context object that contains the URL, the response type, the client ID, and the callback URL 111 | * @docneedsimprovement 112 | * @example 113 | * function clickHandler(e) 114 | * { 115 | * var uri; 116 | * if (! connect.oauth.loggedin()) 117 | * { 118 | * uri = connect.oauth.loginUrl(); 119 | * connect.oauth.login( 120 | * {uri : uri, 121 | * params: { 122 | * response_type : "token", 123 | * client_id : "<%=consumerKey%>", 124 | * redirect_uri : encodeURIComponent("/sdk/callback.html") 125 | * }}); 126 | * } else { 127 | * connect.oauth.logout(); 128 | * } 129 | * return false; 130 | * } 131 | */ 132 | function login(ctx) { 133 | var uri; 134 | 135 | ctx = ctx || {}; 136 | uri = ctx.uri || "/rest/oauth2"; 137 | ctx.params = ctx.params || {state : ""}; 138 | ctx.params.state = ctx.params.state || ctx.callback || window.location.pathname; // @TODO REVIEW THIS 139 | ctx.params.display= ctx.params.display || 'popup'; 140 | ctx.params.redirect_uri = $$.startsWithHttp(ctx.params.redirect_uri, 141 | encodeURIComponent(window.location.protocol + "//" + window.location.hostname + ":" + window.location.port) + ctx.params.redirect_uri); 142 | uri = uri + query(ctx.params); 143 | childWindow = window.open(uri, 'OAuth', 'status=0,toolbar=0,menubar=0,resizable=0,scrollbars=1,top=50,left=50,height=500,width=680'); 144 | } 145 | 146 | /** 147 | * @name Sfdc.canvas.oauth#token 148 | * @function 149 | * @description Sets, gets, or removes the access_token from this JavaScript object.
150 |

This function does one of three things:
151 | 1) If the 't' parameter isn't passed in, the current value for the access_token value is returned.
152 | 2) If the the 't' parameter is null, the access_token value is removed.
153 | 3) Otherwise the access_token value is set to the 't' parameter and then returned.

154 | Note: for longer-term storage of the OAuth token, store it server-side in the session. Access tokens 155 | should never be stored in cookies. 156 | * @param {String} [t] The OAuth token to set as the access_token value 157 | * @returns {String} The resulting access_token value if set; otherwise null 158 | */ 159 | function token(t) { 160 | if (arguments.length === 0) { 161 | if (!$$.isNil(accessToken)) {return accessToken;} 162 | } 163 | else { 164 | accessToken = t; 165 | } 166 | 167 | return accessToken; 168 | } 169 | 170 | /** 171 | * @name Sfdc.canvas.oauth#instance 172 | * @function 173 | * @description Sets, gets, or removes the instance_url cookie.
174 |

This function does one of three things:
175 | 1) If the 'i' parameter is not passed in, the current value for the instance_url cookie is returned.
176 | 2) If the 'i' parameter is null, the instance_url cookie is removed.
177 | 3) Otherwise, the instance_url cookie value is set to the 'i' parameter and then returned. 178 | * @param {String} [i] The value to set as the instance_url cookie 179 | * @returns {String} The resulting instance_url cookie value if set; otherwise null 180 | */ 181 | function instanceUrl(i) { 182 | if (arguments.length === 0) { 183 | if (!$$.isNil(instUrl)) {return instUrl;} 184 | instUrl = storage.get("instance_url"); 185 | } 186 | else if (i === null) { 187 | storage.remove("instance_url"); 188 | instUrl = null; 189 | } 190 | else { 191 | storage.set("instance_url", i); 192 | instUrl = i; 193 | } 194 | return instUrl; 195 | } 196 | 197 | /** 198 | *@private 199 | */ 200 | // Example Results of tha hash.... 201 | // Name [access_token] Value [00DU0000000Xthw!ARUAQMdYg9ScuUXB5zPLpVyfYQr9qXFO7RPbKf5HyU6kAmbeKlO3jJ93gETlJxvpUDsz3mqMRL51N1E.eYFykHpoda8dPg_z] 202 | // Name [instance_url] Value [https://na12.salesforce.com] 203 | // Name [id] Value [https://login.salesforce.com/id/00DU0000000XthwMAC/005U0000000e6PoIAI] 204 | // Name [issued_at] Value [1331000888967] 205 | // Name [signature] Value [LOSzVZIF9dpKvPU07icIDOf8glCFeyd4vNGdj1dhW50] 206 | // Name [state] Value [/crazyrefresh.html] 207 | function parseHash(hash) { 208 | var i, nv, nvp, n, v; 209 | 210 | if (! $$.isNil(hash)) { 211 | if (hash.indexOf('#') === 0) { 212 | hash = hash.substr(1); 213 | } 214 | nvp = hash.split("&"); 215 | 216 | for (i = 0; i < nvp.length; i += 1) { 217 | nv = nvp[i].split("="); 218 | n = nv[0]; 219 | v = decodeURIComponent(nv[1]); 220 | if ("access_token" === n) { 221 | token(v); 222 | } 223 | else if ("instance_url" === n) { 224 | instanceUrl(v); 225 | } 226 | else if ("target_origin" === n) { 227 | tOrigin = decodeURIComponent(v); 228 | } 229 | else if ("instance_id" === n) { 230 | instId = v; 231 | } 232 | } 233 | } 234 | } 235 | 236 | /** 237 | * @name Sfdc.canvas.oauth#checkChildWindowStatus 238 | * @function 239 | * @description Refreshes the parent window only if the child window is closed. This 240 | * method is no longer used. Leaving in for backwards compatability. 241 | */ 242 | function checkChildWindowStatus() { 243 | if (!childWindow || childWindow.closed) { 244 | refresh(); 245 | } 246 | } 247 | 248 | /** 249 | * @name Sfdc.canvas.oauth#childWindowUnloadNotification 250 | * @function 251 | * @description Parses the hash value that is passed in and sets the 252 | access_token and instance_url cookies if they exist. Use this method during 253 | User-Agent OAuth Authentication Flow to pass the OAuth token. 254 | * @param {String} hash A string of key-value pairs delimited by 255 | the ampersand character. 256 | * @example 257 | * Sfdc.canvas.oauth.childWindowUnloadNotification(self.location.hash); 258 | */ 259 | function childWindowUnloadNotification(hash) { 260 | // Here we get notification from child window. Here we can decide if such notification is 261 | // raised because user closed child window, or because user is playing with F5 key. 262 | // NOTE: We can not trust on "onUnload" event of child window, because if user reload or refresh 263 | // such window in fact he is not closing child. (However "onUnload" event is raised!) 264 | 265 | var retry = 0, maxretries = 10; 266 | 267 | // Internal check child window status with max retry logic 268 | function cws() { 269 | 270 | retry++; 271 | if (!childWindow || childWindow.closed) { 272 | refresh(); 273 | } 274 | else if (retry < maxretries) { 275 | setTimeout(cws, 50); 276 | } 277 | } 278 | 279 | parseHash(hash); 280 | setTimeout(cws, 50); 281 | } 282 | 283 | /** 284 | * @name Sfdc.canvas.oauth#logout 285 | * @function 286 | * @description Removes the access_token OAuth token from this object. 287 | */ 288 | function logout() { 289 | // Remove the oauth token and refresh the browser 290 | token(null); 291 | } 292 | 293 | /** 294 | * @name Sfdc.canvas.oauth#loggedin 295 | * @function 296 | * @description Returns the login state. 297 | * @returns {Boolean} true if the access_token is available in this JS object. 298 | * Note: access tokens (for example, OAuth tokens) should be stored server-side for more durability. 299 | * Never store OAuth tokens in cookies as this can lead to a security risk. 300 | */ 301 | function loggedin() { 302 | return !$$.isNil(token()); 303 | } 304 | 305 | /** 306 | * @name Sfdc.canvas.oauth#loginUrl 307 | * @function 308 | * @description Returns the URL for the OAuth authorization service. 309 | * @returns {String} The URL for the OAuth authorization service or default if there's 310 | * no value for loginUrl in the current URL's query string 311 | */ 312 | function loginUrl() { 313 | var i, nvs, nv, q = self.location.search; 314 | 315 | if (q) { 316 | q = q.substring(1); 317 | nvs = q.split("&"); 318 | for (i = 0; i < nvs.length; i += 1) 319 | { 320 | nv = nvs[i].split("="); 321 | if ("loginUrl" === nv[0]) { 322 | return decodeURIComponent(nv[1]) + "/services/oauth2/authorize"; 323 | } 324 | } 325 | } 326 | return "https://login.salesforce.com/services/oauth2/authorize"; 327 | } 328 | 329 | function targetOrigin(to) { 330 | 331 | if (!$$.isNil(to)) { 332 | tOrigin = to; 333 | return to; 334 | } 335 | 336 | if (!$$.isNil(tOrigin)) {return tOrigin;} 337 | 338 | // This relies on the parent passing it in. This may not be there as the client can do a 339 | // redirect or link to another page 340 | parseHash(document.location.hash); 341 | return tOrigin; 342 | } 343 | 344 | function instanceId(id) { 345 | 346 | if (!$$.isNil(id)) { 347 | instId = id; 348 | return id; 349 | } 350 | 351 | if (!$$.isNil(instId)) {return instId;} 352 | 353 | // This relies on the parent passing it in. This may not be there as the client can do a 354 | // redirect or link to another page 355 | parseHash(document.location.hash); 356 | return instId; 357 | } 358 | 359 | function client() { 360 | return {oauthToken : token(), instanceId : instanceId(), targetOrigin : targetOrigin()}; 361 | } 362 | 363 | return { 364 | init : init, 365 | login : login, 366 | logout : logout, 367 | loggedin : loggedin, 368 | loginUrl : loginUrl, 369 | token : token, 370 | instance : instanceUrl, 371 | client : client, 372 | checkChildWindowStatus : checkChildWindowStatus, 373 | childWindowUnloadNotification: childWindowUnloadNotification 374 | }; 375 | }()); 376 | 377 | $$.module('Sfdc.canvas.oauth', module); 378 | 379 | $$.oauth.init(); 380 | 381 | }(Sfdc.canvas)); -------------------------------------------------------------------------------- /js/xd.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014, salesforce.com, inc. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided 6 | * that the following conditions are met: 7 | * 8 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the 9 | * following disclaimer. 10 | * 11 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 12 | * the following disclaimer in the documentation and/or other materials provided with the distribution. 13 | * 14 | * Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or 15 | * promote products derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 19 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 23 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | * POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | 28 | (function ($$, window) { 29 | 30 | "use strict"; 31 | 32 | var module = (function() { 33 | 34 | var internalCallback; 35 | 36 | /** 37 | * @description Pass a message to the target url 38 | * @param {String} message The message to send 39 | * @param {String} target_url Specifies what the origin of the target must be for the event to be dispatched. 40 | * @param {String} [target] The window that is the message's target. Defaults to the parent of the current window. 41 | */ 42 | function postMessage(message, target_url, target) { 43 | var sfdcJson = Sfdc.JSON || JSON; 44 | 45 | // If target url was not supplied (client may have lost it), we could default to '*', 46 | // However there are security implications here as other canvas apps could receive this 47 | // canvas apps oauth token. 48 | if ($$.isNil(target_url)) { 49 | throw "ERROR: target_url was not supplied on postMessage"; 50 | } 51 | var otherWindow = $$.stripUrl(target_url); 52 | 53 | target = target || parent; // default to parent 54 | if (window.postMessage) { 55 | // the browser supports window.postMessage, so call it with a targetOrigin 56 | // set appropriately, based on the target_url parameter. 57 | 58 | // Add the targetModule as Canvas so we are the only ones interested in these events 59 | if ($$.isObject(message)) {message.targetModule = "Canvas";} 60 | message = sfdcJson.stringify(message); 61 | $$.console.log("Sending Post Message ", message); 62 | target.postMessage(message, otherWindow); 63 | } 64 | } 65 | 66 | /** 67 | * @name Sfdc.canvas.xd#receive 68 | * @description Runs the callback function when the message event is received. 69 | * @param {Function} callback Function to run when the message event is received 70 | if the event origin is acceptable. 71 | * @param {String} source_origin The origin of the desired events 72 | */ 73 | function receiveMessage(callback, source_origin) { 74 | 75 | // browser supports window.postMessage (if not not supported for pilot - removed per securities request) 76 | if (window.postMessage) { 77 | // bind the callback to the actual event associated with window.postMessage 78 | if (callback) { 79 | internalCallback = function(e) { 80 | 81 | var data, r; 82 | var sfdcJson = Sfdc.JSON || JSON; 83 | 84 | $$.console.log("Post Message Got callback", e); 85 | 86 | if (!$$.isNil(e)) { 87 | if (typeof source_origin === 'string' && e.origin !== source_origin) { 88 | $$.console.log("source origin's don't match", e.origin, source_origin); 89 | return false; 90 | } 91 | if ($$.isFunction(source_origin)) { 92 | r = source_origin(e.origin, e.data); 93 | if (r === false) { 94 | $$.console.log("source origin's function returning false", e.origin, e.data); 95 | return false; 96 | } 97 | } 98 | if ($$.appearsJson(e.data)) { 99 | try { 100 | data = sfdcJson.parse(e.data); 101 | } catch (ignore) { 102 | // Ignore parsing errors of any non json objects sent from other frames 103 | } 104 | // If we could parse the data and there is a targetModule make sure it is for us 105 | if (!$$.isNil(data) && ($$.isNil(data.targetModule) || data.targetModule === "Canvas")) { 106 | $$.console.log("Invoking callback"); 107 | callback(data, r); 108 | } 109 | } 110 | } 111 | }; 112 | } 113 | if (window.addEventListener) { 114 | window.addEventListener('message', internalCallback, false); 115 | } else { 116 | window.attachEvent('onmessage', internalCallback); 117 | } 118 | } 119 | } 120 | 121 | /** 122 | * @description Removes the message event listener 123 | * @public 124 | */ 125 | function removeListener() { 126 | 127 | // browser supports window.postMessage 128 | if (window.postMessage) { 129 | if (window.removeEventListener) { 130 | window.removeEventListener('message', internalCallback, false); 131 | } else { 132 | window.detachEvent('onmessage', internalCallback); 133 | } 134 | } 135 | } 136 | 137 | return { 138 | post : postMessage, 139 | receive : receiveMessage, 140 | remove : removeListener 141 | }; 142 | }()); 143 | 144 | $$.module('Sfdc.canvas.xd', module); 145 | 146 | }(Sfdc.canvas, window)); -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@salesforce/canvas-js-sdk", 3 | "version": "1.41.0", 4 | "lockfileVersion": 1 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@salesforce/canvas-js-sdk", 3 | "version": "1.41.0", 4 | "description": "A JavaScript SDK used to integrate applications with the Force.com Canvas framework", 5 | "main": "js/canvas-all.js", 6 | "directories": { 7 | "doc": "docs" 8 | }, 9 | "dependencies": {}, 10 | "devDependencies": {}, 11 | "scripts": { 12 | "test": "echo \"Error: no test specified\" && exit 1" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/forcedotcom/SalesforceCanvasJavascriptSDK.git" 17 | }, 18 | "keywords": [ 19 | "salesforce", 20 | "canvas" 21 | ], 22 | "author": "msenn@salesforce.com", 23 | "license": "BSD-3-Clause", 24 | "bugs": { 25 | "url": "https://github.com/forcedotcom/SalesforceCanvasJavascriptSDK/issues" 26 | }, 27 | "homepage": "https://github.com/forcedotcom/SalesforceCanvasJavascriptSDK#readme" 28 | } 29 | --------------------------------------------------------------------------------