Skip to content

Commit

Permalink
Editor: Add support for editing embeds inside a post
Browse files Browse the repository at this point in the history
This is a work in progress.

See #1729
  • Loading branch information
iandunn committed Sep 21, 2017
1 parent fb33db9 commit 9c4ae43
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 0 deletions.
45 changes: 45 additions & 0 deletions client/components/tinymce/plugins/wpcom-view/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ var tinymce = require( 'tinymce/tinymce' ),
import views from './views';
import { renderWithReduxStore } from 'lib/react-helpers';
import { getSelectedSiteId } from 'state/ui/selectors';
import EmbedDialog from 'components/tinymce/plugins/wpcom-view/views/embed/embed-dialog';
import LinkDialog from 'components/tinymce/plugins/wplink/dialog'; //tmp

/**
* WordPress View plugin.
Expand Down Expand Up @@ -825,6 +827,49 @@ function wpview( editor ) {
}
});


function footemp(a) {
//console.log('a',a);
// what is this supposed to be?
// it's not getting called, but it's required to be here
}

// shoujld maybe go elsewhere?
editor.addCommand( 'embedEditLink', content => {
function renderModal( visibility = 'show' ) {
let node = editor.selection.getNode(); // not sure if retrieved this correctly
const store = editor.getParam( 'redux_store' ); // not sure if retrieved this correctly

//console.log('node',node);
//console.log( 'store',store);

renderWithReduxStore(
React.createElement( EmbedDialog, {
// this works, but it's hiding it by default
// also creating infinite number instead of creating 1 and reusing
isVisible: true,
embedUrl: content,
footemp, //remove this, but need to replace w/ something else? orjust random piece of data copy/pasted?
onInsert( productData ) { // rename
console.log( 'productdata',productData ); // this isn't firing

editor.execCommand( 'mceInsertContent', false, serialize( productData ) );
renderModal( 'hide' );
},
onClose() {
editor.focus();
renderModal( 'hide' );
},
} ),
node,
store,
);
}

renderModal();
return 'test';
} );

editor.addButton( 'wp_view_edit', {
tooltip: i18n.translate( 'Edit', { context: 'verb' } ),
icon: 'dashicon dashicons-edit',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* External dependencies
*/
import React, { PureComponent } from 'react';

/**
* Internal dependencies
*/
import Button from 'components/button';
import Card from 'components/card';
import EmbedDialog from 'components/tinymce/plugins/wpcom-view/views/embed/embed-dialog/';

class EmbedDialogExample extends PureComponent {
state = { showDialog: false };

openDialog = () => this.setState( { showDialog: true } );
handleClose = () => this.setState( { showDialog: false } );

render() {
return (
<Card>
<Button onClick={ this.openDialog }>Open Embed Dialog</Button>
<EmbedDialog
embedUrl={ 'https://www.youtube.com/watch?v=_hWhPBfsbK0' }
isVisible={ this.state.showDialog }
onClose={ this.handleClose }
/>
</Card>
);
}
}

export default EmbedDialogExample;
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/**
* External dependencies
*/
import React, { Component, PropTypes } from 'react';

/**
* Internal dependencies
*/
import Dialog from 'components/dialog';
import Button from 'components/button';
import FormTextInput from 'components/forms/form-text-input';
import PostEditEmbedsStore from 'lib/embeds/store';

class EmbedDialog extends Component {
static propTypes = {
isVisible: PropTypes.bool,
embedUrl: PropTypes.string,
//onClose: PropTypes.func,
};

static defaultProps = {
isVisible: false,
embedUrl: '',
//onClose: noop,
};

state = {
embedUrl: this.props.embedUrl,
embedMarkup: PostEditEmbedsStore.get( this.props.embedUrl ),
};

onUpdateEmbed = ( event ) => {
console.log('on update');
// set to state. this.embedUrl ?
// update tinymce content w/ state.embedUrl & re-render the embed inside the tinymce component
this.props.onClose();
};

onChangeEmbedUrl = ( event ) => {
this.setState( {
embedUrl: event.target.value,
embedMarkup: PostEditEmbedsStore.get( event.target.value ),
} );

// this is breaking. embedurl gets set correctly, but embedmarkup is an empty object
// re-reder preview - should happen automatically
// need to debounce or something so not every single second
};

render() {
return (
<Dialog
isVisible={ this.props.isVisible }
onClose={ this.props.onClose }
buttons={ [
<Button onClick={ this.props.onClose }>
Cancel
</Button>,
<Button primary onClick={ this.onUpdateEmbed }>
Update
</Button>
] }
>
<h3>Embed URL</h3>

<FormTextInput
defaultValue={ this.state.embedUrl }
onChange={ this.onChangeEmbedUrl }
/>

<div className="embed-dialog-preview" dangerouslySetInnerHTML={ { __html: this.state.embedMarkup.body } } />
</Dialog>
);

{/*
solved problems below w/ PostEditEmbedStore?
better way to set the preview content other than dangerouslysetinnerhtml?
which component to use to embed the url?
will it work with all supported embeds, in addition to youtube?
how does core do it? calypso probably has similar thing
<ResizableIframe src={ this.state.embedUrl } frameBorder="0" seamless width="100%" />
security issue above with src="user input", need to use wpcom oembed provider whitelist.
lib/embeds/list-store ?
also want iframe sandbox params etc?
also need to transform to canonical embeddable URL. youtube will block main url via x-frame-options, have to use `/embed/{id}` url
shouldn't all those issues be handled by whatever component embeds the url?
localize strings
*/}
}
}

export default EmbedDialog;
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,8 @@ export default class EmbedViewManager extends EventEmitter {
getComponent() {
return EmbedView;
}

edit( editor, content ) {
editor.execCommand( 'embedEditLink', content );
}
}
2 changes: 2 additions & 0 deletions client/devdocs/design/blocks.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ import ReaderEmailSettings from 'blocks/reader-email-settings/docs/example';
import UploadImage from 'blocks/upload-image/docs/example';
import ConversationCommentList from 'blocks/conversations/docs/example';
import SimplePaymentsDialog from 'components/tinymce/plugins/simple-payments/dialog/docs/example';
import EmbedDialog from 'components/tinymce/plugins/wpcom-view/views/embed/embed-dialog/docs/example';
import ConversationCaterpillar from 'blocks/conversation-caterpillar/docs/example';
import ColorSchemePicker from 'blocks/color-scheme-picker/docs/example';

Expand Down Expand Up @@ -167,6 +168,7 @@ export default class AppComponents extends React.Component {
<ReaderImportButton />
<SharingPreviewPane />
<SimplePaymentsDialog />
<EmbedDialog />
<ReaderShare />
<ReaderEmailSettings />
<UploadImage />
Expand Down

0 comments on commit 9c4ae43

Please sign in to comment.