Merge branch 'master' into next

This commit is contained in:
Kim Gardner
2018-01-09 17:22:47 -05:00
committed by GitHub
3 changed files with 61 additions and 58 deletions
+9 -8
View File
@@ -35,12 +35,13 @@ function viewportDimensions() {
}
export default class Stream {
constructor(el, talkBaseUrl, query, opts) {
constructor(el, talkBaseUrl, query, config) {
this.query = query;
// Create and save the options.
// Extract the non-opts opts from the object.
const {events = null, snackBarStyles = null, onAuthChanged = null, ...opts} = config;
this.opts = opts;
this.query = query;
this.emitter = new EventEmitter({wildcard: true});
this.pym = new pym.Parent(el.id, buildStreamIframeUrl(talkBaseUrl, query), {
@@ -48,7 +49,7 @@ export default class Stream {
id: `${el.id}_iframe`,
name: `${el.id}_iframe`
});
this.snackBar = new Snackbar(opts.snackBarStyles || {});
this.snackBar = new Snackbar(snackBarStyles || {});
// Workaround: IOS Safari ignores `width` but respects `min-width` value.
this.pym.el.firstChild.style.width = '1px';
@@ -64,8 +65,8 @@ export default class Stream {
});
// Attach to the events emitted by the pym parent.
if (opts.events) {
opts.events(this.emitter);
if (events) {
events(this.emitter);
}
this.pym.onMessage('getConfig', () => {
@@ -73,9 +74,9 @@ export default class Stream {
});
// If the auth changes, and someone is listening for it, then re-emit it.
if (opts.onAuthChanged) {
if (onAuthChanged) {
this.pym.onMessage('coral-auth-changed', (message) => {
opts.onAuthChanged(message ? JSON.parse(message) : null);
onAuthChanged(message ? JSON.parse(message) : null);
});
}
+50 -48
View File
@@ -2,22 +2,43 @@ import URLSearchParams from 'url-search-params';
import Stream from './Stream';
import StreamInterface from './StreamInterface';
// Rebuild the origin if it isn't defined. This is our poor-mans polyfill
// for the location API's.
if (!window.location.origin) {
window.location.origin = `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ''}`;
}
// parses the Asset URL from the config variable
function parseAssetURL() {
try {
// Try to get the url from the canonical tag on the page.
return document.querySelector('link[rel="canonical"]').href;
} catch (e) {
console.warn(
'This page does not include a canonical link tag. Talk has inferred this asset_url from the window object. Query params have been stripped, which may cause a single thread to be present across multiple pages.'
);
return window.location.origin + window.location.pathname;
}
}
export class Talk {
/**
* Render a Talk stream
* @param {HTMLElement} el - Element to render the stream in
* @param {Object} opts - Configuration options for talk
* @param {String} opts.talk - Talk base URL
* @param {String} [opts.title] - Title of Stream (rendered in iframe)
* @param {String} [opts.asset_url] - Asset URL
* @param {String} [opts.asset_id] - Asset ID
* @param {String} [opts.auth_token] - (optional) A jwt representing the session
* @param {HTMLElement} element - Element to render the stream in
* @param {Object} config - Configuration options for talk
* @param {String} config.talk - Talk base URL
* @param {String} [config.title] - Title of Stream (rendered in iframe)
* @param {String} [config.asset_url] - Asset URL
* @param {String} [config.asset_id] - Asset ID
* @param {String} [config.auth_token] - (optional) A jwt representing the session
* @return {Object}
*
* Example:
* ```
* const embed = Talk.render(document.getElementById('talkStreamEmbed'), opts);
* const embed = Talk.render(document.getElementById('talkStreamEmbed'), config);
*
* // trigger a login with optional token.
* embed.login(token);
@@ -31,66 +52,47 @@ export class Talk {
* });
* ```
*/
static render(el, opts) {
if (!el) {
static render(element, config) {
if (!element) {
throw new Error('Please provide Coral.Talk.render() the HTMLElement you want to render Talk in.');
}
if (typeof el !== 'object') {
throw new Error(`Coral.Talk.render() expected HTMLElement but got ${el} (${typeof el})`);
if (typeof element !== 'object') {
throw new Error(`Coral.Talk.render() expected HTMLElement but got ${element} (${typeof element})`);
}
opts = opts || {};
// TODO: infer this URL without explicit user input (if possible, may have to be added at build/render time of this script)
if (!opts.talk) {
throw new Error(
'Coral.Talk.render() expects opts.talk as the Talk Base URL'
);
if (!config || typeof config !== 'object' || !config.talk) {
throw new Error('Coral.Talk.render() expected configuration with at least opts.talk as the Talk Base URL, none found');
}
// Ensure el has an id, as pym can't directly accept the HTMLElement.
if (!el.id) {
el.id = `_${Math.random()}`;
if (!element.id) {
element.id = `_${Math.random()}`;
}
// Compose the query to send down to the Talk API so it knows what to load.
const query = {};
// Parse the url parameters to extract some of the information.
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get('commentId')) {
query.comment_id = urlParams.get('commentId');
const search = new URLSearchParams(window.location.search);
// Pull the commentID out from the query params.
const commentID = search.get('commentId') || search.get('commentID');
if (commentID) {
query.comment_id = commentID;
}
// Extract the asset id from the options.
if (opts.asset_id) {
query.asset_id = opts.asset_id;
if (config.asset_id) {
query.asset_id = config.asset_id;
}
// Extract the asset url.
if (opts.asset_url) {
query.asset_url = opts.asset_url;
} else {
// The asset url was not provided so we need to infer the asset url from // details on the page.
try {
query.asset_url = document.querySelector('link[rel="canonical"]').href;
} catch (e) {
console.warn(
'This page does not include a canonical link tag. Talk has inferred this asset_url from the window object. Query params have been stripped, which may cause a single thread to be present across multiple pages.'
);
if (!window.location.origin) {
window.location.origin = `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ''}`;
}
query.asset_url = window.location.origin + window.location.pathname;
}
// Parse the Asset URL.
query.asset_url = config.asset_url;
if (!query.asset_url) {
query.asset_url = parseAssetURL();
}
// Create the new Stream.
const stream = new Stream(el, opts.talk, query, opts);
const stream = new Stream(element, config.talk, query, config);
// Return the public interface for the stream.
return new StreamInterface(stream);
+2 -2
View File
@@ -5,7 +5,7 @@ class: configuration
---
Talk requires configuration in order to customize the installation. The default
behavior is to load it's configuration from the environment, following the
behavior is to load its configuration from the environment, following the
[12 Factor App Manifesto](https://12factor.net/){:target="_blank"}.
In development, you can specify configuration in a file named `.env` and it will
be loaded into the environment when you run `yarn dev-start`.
@@ -84,7 +84,7 @@ set to `TRUE` after you've deployed Talk. (Default `FALSE`)
## TALK_JWT_ALG
The algorithm used to sign/verify JWTs used for session management. Read up
The algorithm used to sign/verify JWTs used for session management. Read up
about alternative algorithms on the
[jsonwebtoken](https://www.npmjs.com/package/jsonwebtoken#algorithms-supported){:target="_blank"}
package. (Default `HS256`)