forked from instructure/canvas-lms
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
launch LTI tool in new tab or popup if requested
refs INTEROP-6636 flag=none * open new tab/window or a popup window depending on the message the tool sends * include new data from the tool like placement (so that deep linking launches work), type of window, and width/height of popup * keep a reference to opened window and close it when the dialog that opened it also closes * send postMessages to window.opener if present, instead of window.parent - helps with tabs/popups opened by the page * include the canvas placement in the LTI 1.3 launch token, in the custom claims section - this is required so that the tool can pass it in the full window launch request, so that Canvas knows whether it should use a normal launch or a deep linking launch test plan: * make sure associated commits for the test tool and safari gem are checked out and set up, see the test plan for those * in safari, create a new assignment of type external tool * choose the test tool from the list of tools * it should tell you that it needs to open in a popup * click the button and a popup should open (note: you should not have Safari in fullscreen mode which is a bummer) * you should click submit on that form to return a resource link * the popup should close and the external tool dialog should have a url in it, like normal Change-Id: I46dc47cca7f26140041b6a638a8056a7cc0843db Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/261771 Reviewed-by: Evan Battaglia <[email protected]> Tested-by: Service Cloud Jenkins <[email protected]> QA-Review: Wagner Goncalves <[email protected]> Product-Review: Xander Moffatt <[email protected]>
- Loading branch information
1 parent
bbe345f
commit 811a119
Showing
7 changed files
with
361 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
Using window.postMessage in LTI Tools | ||
===================================== | ||
|
||
Canvas listens for events sent through the `window.postMessage` Javascript | ||
API (docs <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage" target="_blank">here</a>) | ||
from LTI tools and other children rendered in iframes or opened in new tabs/windows. Tools | ||
can send various types of events to resize windows, launch in new windows, or other | ||
functionality. Note that this is not part of the LTI specification, and is Canvas-specific. | ||
|
||
The data sent to `window.postMessage` can be of any type, and each message type looks for different | ||
data. Most data is sent as an object, with either a `messageType` or `subject` property. | ||
|
||
Some of these message handlers require the presence of a `token`, which identifies the tool launch. | ||
This token is present in the launch as a custom variable, `$com.instructure.PostMessageToken`, and | ||
should be passed in postMessage calls if it's present. | ||
|
||
If the LTI tool is launched in a iframe, as is most common, then postMessages should be sent to | ||
`window.parent`. However, if the tool is launched in a new tab, window, or popup, then postMessages | ||
should be directed to `window.opener`. The examples will use `window.parent`. | ||
|
||
# Message Types | ||
|
||
## requestFullWindowLaunch | ||
|
||
Launches the tool that sent the event in a full-window context (ie not inside a Canvas iframe). | ||
Mainly used for Safari launches, since Safari disables setting cookies inside iframes. | ||
|
||
**Required properties:** | ||
- messageType: "requestFullWindowLaunch" | ||
- data: either a string or an object | ||
- if a string, a url for relaunching the tool | ||
- if an object, has required sub-properties | ||
- data.url: a url for relaunching the tool | ||
- data.placement: the Canvas placement that the tool was launched in. Provided in the 1.3 id token | ||
under the custom claim section (`https://www.instructure.com/placement`). | ||
|
||
**Optional properties:** | ||
- data.launchType: defaults to "same_window" | ||
- "same_window": launches the tool in the same window, replacing Canvas entirely | ||
- "new_window": launches the tool in a new tab/window, which depends on user preference | ||
- "popup": launches the tool in a popup window | ||
- data.launchOptions.width: for launchType: popup, defines the popup window's width. Defaults to 800. | ||
- data.launchOptions.height: for launchType: popup, defines the popup window's height. Defaults to 600. | ||
|
||
```js | ||
window.parent.postMessage( | ||
{ | ||
messageType: "requestFullWindowLaunch", | ||
data: { | ||
url: "https://example-tool.com/launch", | ||
placement: "course_navigation", | ||
launchType: "new_window", | ||
launchOptions: { | ||
width: 1000, | ||
height: 800 | ||
} | ||
} | ||
}, | ||
"*" | ||
) | ||
``` | ||
|
||
## lti.resourceImported | ||
|
||
Notifies the Canvas page holding the tool that a resource has finished importing. | ||
Canvas will respond by reloading the page, if the tool was present in the external | ||
apps tray. Used on wiki pages. | ||
|
||
**Required properties:** | ||
- messageType: "lti.resourceImported" | ||
|
||
```js | ||
window.parent.postMessage({ messageType: "lti.resourceImported" }, "*") | ||
``` | ||
|
||
## lti.frameResize | ||
|
||
Tells Canvas to change the height of the iframe containing the tool. | ||
|
||
**Required properties:** | ||
- subject: "lti.frameResize" | ||
- height: integer, in px | ||
|
||
**Optional properties:** | ||
- token: postMessage token, discussed above. | ||
|
||
```js | ||
window.parent.postMessage( | ||
{ | ||
subject: "lti.frameResize", | ||
height: 400 | ||
}, | ||
"*" | ||
) | ||
``` | ||
|
||
## lti.fetchWindowSize | ||
|
||
Sends a postMessage event back to the tool with details about the window size of | ||
the tool's containing iframe. | ||
|
||
**Required properties:** | ||
- subject: "lti.fetchWindowSize" | ||
|
||
Returning postMessage includes the following properties: | ||
- subject: "lti.fetchWindowSize" | ||
- height: height of the iframe | ||
- width: width of the iframe | ||
- offset: jquery.offset() of the iframe's wrapper | ||
- scrollY: the number of px that the iframe is scrolled vertically | ||
|
||
```js | ||
window.parent.postMessage({ subject: "lti.fetchWindowSize" }, "*") | ||
``` | ||
|
||
## lti.showModuleNavigation | ||
|
||
Toggles the module navigation footer based on the message's content. | ||
|
||
**Required properties:** | ||
- subject: "lti.showModuleNavigation" | ||
- show: Boolean, whether to show or hide the footer | ||
|
||
```js | ||
window.parent.postMessage( | ||
{ | ||
subject: "lti.frameResize", | ||
show: true | ||
}, | ||
"*" | ||
) | ||
``` | ||
|
||
## lti.scrollToTop | ||
|
||
Scrolls the iframe all the way to the top of its container. | ||
|
||
**Required properties:** | ||
- subject: "lti.scrollToTop" | ||
|
||
```js | ||
window.parent.postMessage({ subject: "lti.scrollToTop" }, "*") | ||
``` | ||
|
||
## lti.setUnloadMessage | ||
|
||
Sets a message to be shown in a browser dialog before page closes (ie | ||
"Do you really want to leave this page?") | ||
|
||
**Required properties:** | ||
- subject: "lti.setUnloadMessage" | ||
- message: The message to be shown in the dialog | ||
|
||
```js | ||
window.parent.postMessage( | ||
{ | ||
subject: "lti.setUnloadMessage", | ||
message: "Are you sure you want to leave this app?" | ||
}, | ||
"*" | ||
) | ||
``` | ||
|
||
## lti.removeUnloadMessage | ||
|
||
Clears any set message to be shown on page close. | ||
|
||
Required properties | ||
- subject: "lti.removeUnloadMessage" | ||
|
||
```js | ||
window.parent.postMessage({ subject: "lti.removeUnloadMessage" }, "*") | ||
``` | ||
|
||
## lti.screenReaderAlert | ||
|
||
Shows an alert for screen readers. | ||
|
||
**Required properties:** | ||
- subject: "lti.screenReaderAlert" | ||
- body: The contents of the alert. | ||
|
||
```js | ||
window.parent.postMessage( | ||
{ | ||
subject: "lti.screenReaderAlert", | ||
body: "An alert just for screen readers" | ||
}, | ||
"*" | ||
) | ||
``` | ||
|
||
## lti.enableScrollEvents | ||
|
||
Sends a debounced postMessage event to the tool every time its containing | ||
iframe is scrolled. | ||
|
||
**Required properties:** | ||
- subject: "lti.enableScrollEvents" | ||
|
||
Returning postMessage includes the following properties: | ||
- subject: "lti.scroll" | ||
- scrollY: the number of px that the iframe is scrolled vertically | ||
|
||
```js | ||
window.parent.postMessage({ subject: "lti.enableScrollEvents" }, "*") | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.