diff --git a/.eslintignore b/.eslintignore index 53c37a166..a4865e1f6 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,2 @@ -dist \ No newline at end of file +dist +client/lib diff --git a/client/coral-embed-stream/public/samplearticle.html b/client/coral-embed-stream/public/samplearticle.html index 64c3fd0f8..454cb249c 100644 --- a/client/coral-embed-stream/public/samplearticle.html +++ b/client/coral-embed-stream/public/samplearticle.html @@ -7,7 +7,7 @@

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut lobortis sollicitudin eros a ornare. Curabitur dignissim vestibulum massa non rhoncus. Cras laoreet ante vel nunc hendrerit, ac imperdiet neque egestas. Suspendisse aliquet iaculis fermentum. Pellentesque interdum nec elit sed tincidunt. Donec volutpat, tellus posuere laoreet consequat, mi lacus laoreet massa, sed vehicula mauris velit non lectus. Integer non enim nec neque congue faucibus porttitor sit amet dui.

Nunc pharetra orci id diam feugiat, vitae rutrum magna efficitur. Morbi porttitor blandit lorem, et facilisis tellus luctus at. Morbi tincidunt eget nisl id placerat. Nullam consectetur quam vel mauris lacinia, non consectetur est faucibus. Duis cursus auctor nulla nec sagittis. Aenean sem erat, ultrices a hendrerit consectetur, accumsan non lorem. Integer ac neque sed magna sodales vulputate at quis neque. Praesent eget ornare lacus. Donec ultricies, dolor eget commodo faucibus, arcu velit ullamcorper tellus, in cursus tellus elit sed urna. Suspendisse in consequat magna. Duis vel ullamcorper tortor, vel cursus libero. Proin et nisi luctus ligula faucibus luctus. Morbi pulvinar, justo ac feugiat elementum, libero tellus congue justo, pharetra ultrices felis felis id leo. Integer mattis quam tempus libero porta, ac pretium ligula elementum.

- + diff --git a/client/coral-embed-stream/src/CommentStream.js b/client/coral-embed-stream/src/CommentStream.js index be40ecff6..95a6f63f3 100644 --- a/client/coral-embed-stream/src/CommentStream.js +++ b/client/coral-embed-stream/src/CommentStream.js @@ -78,13 +78,32 @@ class CommentStream extends Component { componentDidMount () { // Set up messaging between embedded Iframe an parent component // Using recommended Pym init code which violates .eslint standards - const pym = new Pym.Child({polling: 100}); + this.pym = new Pym.Child({polling: 100}); - if (/https?\:\/\/([^?]+)/.test(pym.parentUrl)) { - this.props.getStream(pym.parentUrl); - } else { - this.props.getStream(window.location); - } + const path = this.pym.parentUrl.split('#')[0]; + + this.props.getStream(path || window.location); + this.path = path; + + this.pym.sendMessage('childReady'); + + this.pym.onMessage('DOMContentLoaded', hash => { + // the comment ids can start with numbers, which is invalid for DOM id attributes + const commentId = hash.replace('#', 'c_'); + let count = 0; + const interval = setInterval(() => { + if (document.getElementById(commentId)) { + window.clearInterval(interval); + this.pym.scrollParentToChildEl(commentId); + } + + if (++count > 100) { // ~10 seconds + // give up waiting for the comments to load. + // it would be weird for the page to jump after that long. + window.clearInterval(interval); + } + }, 100); + }); } render () { @@ -109,11 +128,11 @@ class CommentStream extends Component { const {actions, users, comments} = this.props.items; const {loggedIn, user, showSignInDialog} = this.props.auth; const {activeTab} = this.state; + return
{ rootItem - ?
- + ?
Settings @@ -141,7 +160,7 @@ class CommentStream extends Component { { rootItem.comments && rootItem.comments.map((commentId) => { const comment = comments[commentId]; - return
+ return

@@ -172,8 +191,8 @@ class CommentStream extends Component { updateItem={this.props.updateItem} currentUser={this.props.auth.user}/> + commentId={commentId} + articleURL={this.path}/>
{ let reply = this.props.items.comments[replyId]; - return
+ return

@@ -220,8 +239,8 @@ class CommentStream extends Component { updateItem={this.props.updateItem} currentUser={this.props.auth.user}/>
+
+ className={`${name}-popover ${this.state.popoverOpen ? 'active' : ''}`}> this.permalinkInput = input} - value={`${publisherUrl}${this.props.asset_id}#${this.props.comment_id}`} + value={`${this.props.articleURL}#${this.props.commentId}`} onChange={() => {}} /> { - this.state.copySuccessful ?

copied to clipboard

: null + this.state.copySuccessful ?

copied to clipboard

: null } { this.state.copyFailure - ?

copying to clipboard not supported in this browser. Use Cmd + C.

+ ?

copying to clipboard not supported in this browser. Use Cmd + C.

: null }
@@ -75,20 +73,3 @@ class PermalinkButton extends React.Component { } export default onClickOutside(PermalinkButton); - -const styles = { - position: 'relative', - - popover: active => { - return { - display: active ? 'block' : 'none', - backgroundColor: 'white', - border: '1px solid black', - minWidth: 400, - position: 'absolute', - top: 30, - right: 0, - padding: 5 - }; - } -}; diff --git a/client/coral-sign-in/components/ForgotContent.js b/client/coral-sign-in/components/ForgotContent.js index bc06ae5f1..f76ebe45d 100644 --- a/client/coral-sign-in/components/ForgotContent.js +++ b/client/coral-sign-in/components/ForgotContent.js @@ -44,7 +44,7 @@ class ForgotContent extends React.Component { } { passwordRequestFailure - ?

{passwordRequestFailure}

+ ?

{passwordRequestFailure}

: null } diff --git a/client/coral-sign-in/components/styles.css b/client/coral-sign-in/components/styles.css index 1561f557b..e645885ce 100644 --- a/client/coral-sign-in/components/styles.css +++ b/client/coral-sign-in/components/styles.css @@ -138,5 +138,6 @@ input.error{ .passwordRequestFailure { border: 1px solid orange; - background-color: 1px solid coral + background-color: 1px solid coral; + padding: 10px; } diff --git a/client/lib/pym.v1.min.js b/client/lib/pym.v1.min.js new file mode 100644 index 000000000..7aa54058d --- /dev/null +++ b/client/lib/pym.v1.min.js @@ -0,0 +1,2 @@ +/*! pym.js - v1.1.2 - 2016-10-25 */ +!function(a){"function"==typeof define&&define.amd?define(a):"undefined"!=typeof module&&module.exports?module.exports=a():window.pym=a.call(this)}(function(){var a="xPYMx",b={},c=function(a){var b=new RegExp("[\\?&]"+a.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]")+"=([^&#]*)"),c=b.exec(location.search);return null===c?"":decodeURIComponent(c[1].replace(/\+/g," "))},d=function(a,b){if("*"===b.xdomain||a.origin.match(new RegExp(b.xdomain+"$")))return!0},e=function(b,c,d){var e=["pym",b,c,d];return e.join(a)},f=function(b){var c=["pym",b,"(\\S+)","(.*)"];return new RegExp("^"+c.join(a)+"$")},g=function(){for(var a=b.autoInitInstances.length,c=a-1;c>=0;c--){var d=b.autoInitInstances[c];d.el.getElementsByTagName("iframe").length&&d.el.getElementsByTagName("iframe")[0].contentWindow||b.autoInitInstances.splice(c,1)}};return b.autoInitInstances=[],b.autoInit=function(){var a=document.querySelectorAll("[data-pym-src]:not([data-pym-auto-initialized])"),c=a.length;g();for(var d=0;d-1&&(b=this.url.substring(c,this.url.length),this.url=this.url.substring(0,c)),this.url.indexOf("?")<0?this.url+="?":this.url+="&",this.iframe.src=this.url+"initialWidth="+a+"&childId="+this.id+"&parentTitle="+encodeURIComponent(document.title)+"&parentUrl="+encodeURIComponent(window.location.href)+b,this.iframe.setAttribute("width","100%"),this.iframe.setAttribute("scrolling","no"),this.iframe.setAttribute("marginheight","0"),this.iframe.setAttribute("frameborder","0"),this.settings.title&&this.iframe.setAttribute("title",this.settings.title),void 0!==this.settings.allowfullscreen&&this.settings.allowfullscreen!==!1&&this.iframe.setAttribute("allowfullscreen",""),void 0!==this.settings.sandbox&&"string"==typeof this.settings.sandbox&&this.iframe.setAttribute("sandbox",this.settings.sandbox),this.settings.id&&(document.getElementById(this.settings.id)||this.iframe.setAttribute("id",this.settings.id)),this.settings.name&&this.iframe.setAttribute("name",this.settings.name);this.el.firstChild;)this.el.removeChild(this.el.firstChild);this.el.appendChild(this.iframe),window.addEventListener("resize",this._onResize)},this._onResize=function(){this.sendWidth()}.bind(this),this._fire=function(a,b){if(a in this.messageHandlers)for(var c=0;c { - res.render('article', {title: 'Coral Talk'}); + return res.render('article', { + title: 'Coral Talk', + basePath: '/client/embed/stream' + }); }); router.get('/assets/:asset_title', (req, res) => { - res.render('article', {title: req.params.asset_title.split('-').join(' ')}); + return res.render('article', { + title: req.params.asset_title.split('-').join(' '), + basePath: '/client/embed/stream' + }); }); module.exports = router; diff --git a/views/article.ejs b/views/article.ejs index 71db59593..6fd420f82 100644 --- a/views/article.ejs +++ b/views/article.ejs @@ -32,13 +32,25 @@
- - - + + diff --git a/views/embed-stream.ejs b/views/embed-stream.ejs index e1ddb17e7..a05b699f1 100644 --- a/views/embed-stream.ejs +++ b/views/embed-stream.ejs @@ -19,14 +19,26 @@
- - - + diff --git a/webpack.config.dev.js b/webpack.config.dev.js index 571c31625..913ee35da 100644 --- a/webpack.config.dev.js +++ b/webpack.config.dev.js @@ -74,10 +74,16 @@ module.exports = { ] }, plugins: [ - new Copy(buildEmbeds.map(embed => ({ - from: path.join(__dirname, 'client', `coral-embed-${embed}`, 'style'), - to: path.join(__dirname, 'dist', 'embed', embed) - }))), + new Copy([ + ...buildEmbeds.map(embed => ({ + from: path.join(__dirname, 'client', `coral-embed-${embed}`, 'style'), + to: path.join(__dirname, 'dist', 'embed', embed) + })), + { + from: path.join(__dirname, 'client', 'lib'), + to: path.join(__dirname, 'dist', 'embed', 'stream') + } + ]), autoprefixer, precss, new webpack.ProvidePlugin({