diff --git a/blocks/library/index.js b/blocks/library/index.js index 93a71f0cc3accb..a8bf7438692355 100644 --- a/blocks/library/index.js +++ b/blocks/library/index.js @@ -9,6 +9,7 @@ import './separator'; import './button'; import './pullquote'; import './table'; +import './table2'; import './preformatted'; import './code'; import './html'; diff --git a/blocks/library/table2/index.js b/blocks/library/table2/index.js new file mode 100644 index 00000000000000..7ac3a8cdb3a5f4 --- /dev/null +++ b/blocks/library/table2/index.js @@ -0,0 +1,71 @@ +/** + * Internal dependencies + */ +import './style.scss'; +import { registerBlockType, query as hpq } from '../../api'; +import TableBlock from './table-block'; +import BlockControls from '../../block-controls'; +import BlockAlignmentToolbar from '../../block-alignment-toolbar'; + +const { children } = hpq; + +registerBlockType( 'core/table2', { + title: wp.i18n.__( 'TinyMCE Table' ), + icon: 'editor-table', + category: 'formatting', + + attributes: { + content: children( 'table' ), + }, + + defaultAttributes: { + content: [ + +

+

+ , + ], + }, + + getEditWrapperProps( attributes ) { + const { align } = attributes; + if ( 'left' === align || 'right' === align || 'wide' === align ) { + return { 'data-align': align }; + } + }, + + edit( { attributes, setAttributes, focus, setFocus, className } ) { + const { content } = attributes; + const updateAlignment = ( nextAlign ) => setAttributes( { align: nextAlign } ); + return [ + focus && ( + + + + ), + { + setAttributes( { content: nextContent } ); + } } + content={ content } + focus={ focus } + onFocus={ setFocus } + className={ className } + />, + ]; + }, + + save( { attributes } ) { + const { content } = attributes; + return ( + + { content } +
+ ); + }, +} ); diff --git a/blocks/library/table2/style.scss b/blocks/library/table2/style.scss new file mode 100644 index 00000000000000..70ad43999e2331 --- /dev/null +++ b/blocks/library/table2/style.scss @@ -0,0 +1,38 @@ +.editor-visual-editor__block[data-type="core/table2"] { + + .editor-visual-editor__block-controls > div { + display: flex; + } + + &[data-align="left"], + &[data-align="right"] { + min-width: 33%; + max-width: 50%; + } + + &[data-align="left"] { + float: left; + margin-right: $block-padding; + } + + &[data-align="right"] { + float: right; + margin-left: $block-padding; + } +} + +.wp-block-table-2 { + table { + border-collapse: collapse; + width: 100%; + } + + td, th { + padding: 0.5em; + border: 1px solid currentColor; + } + + td[data-mce-selected="1"], th[data-mce-selected="1"] { + background-color: $light-gray-500; + } +} diff --git a/blocks/library/table2/table-block.js b/blocks/library/table2/table-block.js new file mode 100644 index 00000000000000..567aac26b79dfa --- /dev/null +++ b/blocks/library/table2/table-block.js @@ -0,0 +1,90 @@ +import Editable from '../../editable'; +import BlockControls from '../../block-controls'; +import { Toolbar, DropdownMenu } from 'components'; + +function execCommand( command ) { + return ( editor ) => { + if ( editor ) { + editor.execCommand( command ); + } + }; +} + +const TABLE_CONTROLS = [ + { + icon: 'table-row-before', + title: wp.i18n.__( 'Insert Row Before' ), + onClick: execCommand( 'mceTableInsertRowBefore' ), + }, + { + icon: 'table-row-after', + title: wp.i18n.__( 'Insert Row After' ), + onClick: execCommand( 'mceTableInsertRowAfter' ), + }, + { + icon: 'table-row-delete', + title: wp.i18n.__( 'Delete Row' ), + onClick: execCommand( 'mceTableDeleteRow' ), + }, + { + icon: 'table-col-before', + title: wp.i18n.__( 'Insert Column Before' ), + onClick: execCommand( 'mceTableInsertColBefore' ), + }, + { + icon: 'table-col-after', + title: wp.i18n.__( 'Insert Column After' ), + onClick: execCommand( 'mceTableInsertColAfter' ), + }, + { + icon: 'table-col-delete', + title: wp.i18n.__( 'Delete Column' ), + onClick: execCommand( 'mceTableDeleteCol' ), + }, +]; + +export default class TableBlock extends wp.element.Component { + constructor() { + super(); + this.state = { + editor: null, + }; + } + + render() { + const { content, focus, onFocus, onChange, className } = this.props; + + return [ + ( { + ...settings, + plugins: ( settings.plugins || [] ).concat( 'table' ), + } ) } + onSetup={ ( editor ) => this.setState( { editor } ) } + onChange={ onChange } + value={ content } + focus={ focus } + onFocus={ onFocus } + />, + focus && ( + + +
  • + ( { + ...control, + onClick: () => control.onClick( this.state.editor ), + } ) ) } + /> +
  • +
    +
    + ), + ]; + } +} diff --git a/blocks/test/fixtures/core__table2.html b/blocks/test/fixtures/core__table2.html new file mode 100644 index 00000000000000..6b5205d3a0b45a --- /dev/null +++ b/blocks/test/fixtures/core__table2.html @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VersionMusicianDate
    .70No musician chosen.May 27, 2003
    1.0Miles DavisJanuary 3, 2004
    Lots of versions skipped, see the full list
    4.4Clifford BrownDecember 8, 2015
    4.5Coleman HawkinsApril 12, 2016
    4.6Pepper AdamsAugust 16, 2016
    4.7Sarah VaughanDecember 6, 2016
    + + diff --git a/blocks/test/fixtures/core__table2.json b/blocks/test/fixtures/core__table2.json new file mode 100644 index 00000000000000..fb877aac30beb1 --- /dev/null +++ b/blocks/test/fixtures/core__table2.json @@ -0,0 +1,246 @@ +[ + { + "uid": "_uid_0", + "name": "core/table2", + "attributes": { + "content": [ + "\n ", + { + "type": "thead", + "children": [ + "\n ", + { + "type": "tr", + "children": [ + "\n ", + { + "type": "th", + "children": "Version" + }, + "\n ", + { + "type": "th", + "children": "Musician" + }, + "\n ", + { + "type": "th", + "children": "Date" + }, + "\n " + ] + }, + "\n " + ] + }, + "\n ", + { + "type": "tbody", + "children": [ + "\n ", + { + "type": "tr", + "children": [ + "\n ", + { + "type": "td", + "children": { + "type": "a", + "attributes": { + "href": "https://wordpress.org/news/2003/05/wordpress-now-available/" + }, + "children": ".70" + } + }, + "\n ", + { + "type": "td", + "children": "No musician chosen." + }, + "\n ", + { + "type": "td", + "children": "May 27, 2003" + }, + "\n " + ] + }, + "\n ", + { + "type": "tr", + "children": [ + "\n ", + { + "type": "td", + "children": { + "type": "a", + "attributes": { + "href": "https://wordpress.org/news/2004/01/wordpress-10/" + }, + "children": "1.0" + } + }, + "\n ", + { + "type": "td", + "children": "Miles Davis" + }, + "\n ", + { + "type": "td", + "children": "January 3, 2004" + }, + "\n " + ] + }, + "\n ", + { + "type": "tr", + "children": [ + "\n ", + { + "type": "td", + "children": [ + "Lots of versions skipped, see ", + { + "type": "a", + "attributes": { + "href": "https://codex.wordpress.org/WordPress_Versions" + }, + "children": "the full list" + } + ] + }, + "\n ", + { + "type": "td", + "children": "…" + }, + "\n ", + { + "type": "td", + "children": "…" + }, + "\n " + ] + }, + "\n ", + { + "type": "tr", + "children": [ + "\n ", + { + "type": "td", + "children": { + "type": "a", + "attributes": { + "href": "https://wordpress.org/news/2015/12/clifford/" + }, + "children": "4.4" + } + }, + "\n ", + { + "type": "td", + "children": "Clifford Brown" + }, + "\n ", + { + "type": "td", + "children": "December 8, 2015" + }, + "\n " + ] + }, + "\n ", + { + "type": "tr", + "children": [ + "\n ", + { + "type": "td", + "children": { + "type": "a", + "attributes": { + "href": "https://wordpress.org/news/2016/04/coleman/" + }, + "children": "4.5" + } + }, + "\n ", + { + "type": "td", + "children": "Coleman Hawkins" + }, + "\n ", + { + "type": "td", + "children": "April 12, 2016" + }, + "\n " + ] + }, + "\n ", + { + "type": "tr", + "children": [ + "\n ", + { + "type": "td", + "children": { + "type": "a", + "attributes": { + "href": "https://wordpress.org/news/2016/08/pepper/" + }, + "children": "4.6" + } + }, + "\n ", + { + "type": "td", + "children": "Pepper Adams" + }, + "\n ", + { + "type": "td", + "children": "August 16, 2016" + }, + "\n " + ] + }, + "\n ", + { + "type": "tr", + "children": [ + "\n ", + { + "type": "td", + "children": { + "type": "a", + "attributes": { + "href": "https://wordpress.org/news/2016/12/vaughan/" + }, + "children": "4.7" + } + }, + "\n ", + { + "type": "td", + "children": "Sarah Vaughan" + }, + "\n ", + { + "type": "td", + "children": "December 6, 2016" + }, + "\n " + ] + }, + "\n " + ] + }, + "\n" + ] + } + } +] diff --git a/blocks/test/fixtures/core__table2.parsed.json b/blocks/test/fixtures/core__table2.parsed.json new file mode 100644 index 00000000000000..3a71111906ab81 --- /dev/null +++ b/blocks/test/fixtures/core__table2.parsed.json @@ -0,0 +1,11 @@ +[ + { + "blockName": "core/table2", + "attrs": null, + "rawContent": "\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
    VersionMusicianDate
    .70No musician chosen.May 27, 2003
    1.0Miles DavisJanuary 3, 2004
    Lots of versions skipped, see the full list
    4.4Clifford BrownDecember 8, 2015
    4.5Coleman HawkinsApril 12, 2016
    4.6Pepper AdamsAugust 16, 2016
    4.7Sarah VaughanDecember 6, 2016
    \n" + }, + { + "attrs": {}, + "rawContent": "\n\n" + } +] diff --git a/blocks/test/fixtures/core__table2.serialized.html b/blocks/test/fixtures/core__table2.serialized.html new file mode 100644 index 00000000000000..6696490689288e --- /dev/null +++ b/blocks/test/fixtures/core__table2.serialized.html @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    VersionMusicianDate
    .70No musician chosen.May 27, 2003
    1.0Miles DavisJanuary 3, 2004
    Lots of versions skipped, see the full list
    4.4Clifford BrownDecember 8, 2015
    4.5Coleman HawkinsApril 12, 2016
    4.6Pepper AdamsAugust 16, 2016
    4.7Sarah VaughanDecember 6, 2016
    + \ No newline at end of file diff --git a/components/dashicon/index.js b/components/dashicon/index.js index 0e7328fbbfbfa5..bfc8ec1ebbb71c 100644 --- a/components/dashicon/index.js +++ b/components/dashicon/index.js @@ -696,6 +696,24 @@ export default class Dashicon extends wp.element.Component { case 'store': path = 'M1 10c.41.29.96.43 1.5.43.55 0 1.09-.14 1.5-.43.62-.46 1-1.17 1-2 0 .83.37 1.54 1 2 .41.29.96.43 1.5.43.55 0 1.09-.14 1.5-.43.62-.46 1-1.17 1-2 0 .83.37 1.54 1 2 .41.29.96.43 1.51.43.54 0 1.08-.14 1.49-.43.62-.46 1-1.17 1-2 0 .83.37 1.54 1 2 .41.29.96.43 1.5.43.55 0 1.09-.14 1.5-.43.63-.46 1-1.17 1-2V7l-3-7H4L0 7v1c0 .83.37 1.54 1 2zm2 8.99h5v-5h4v5h5v-7c-.37-.05-.72-.22-1-.43-.63-.45-1-.73-1-1.56 0 .83-.38 1.11-1 1.56-.41.3-.95.43-1.49.44-.55 0-1.1-.14-1.51-.44-.63-.45-1-.73-1-1.56 0 .83-.38 1.11-1 1.56-.41.3-.95.43-1.5.44-.54 0-1.09-.14-1.5-.44-.63-.45-1-.73-1-1.57 0 .84-.38 1.12-1 1.57-.29.21-.63.38-1 .44v6.99z'; break; + case 'table-col-delete': + path = 'M6.4,9.98l1.28,-1.28v-0.256l-1.28,-1.28v2.8160000000000003zM12.8,8.448l1.28,-1.28v2.752l-1.28,-1.28v-0.192zM20.48,17.92v-17.92h-20.48v17.92h20.48zM19.2,15.36h-5.12v-1.024l-0.256,0.256l-1.024,-1.024v1.7919999999999998h-5.12v-1.7919999999999998l-1.024,1.024l-0.256,-0.256v1.024h-5.12v-14.08h5.12v2.3680000000000003l0.7040000000000001,-0.7040000000000001l0.5760000000000001,0.5760000000000001v-2.3040000000000003h5.12v2.3040000000000003l0.96,-0.96l0.32,0.32v-1.6640000000000001h5.12v14.144000000000002zM13.44,13.248l-3.136,-3.136l-3.264,3.264l-1.536,-1.536l3.264,-3.264l-3.136,-3.136l1.536,-1.536l3.136,3.136l3.2,-3.2l1.536,1.536l-3.2,3.2l3.136,3.136l-1.536,1.536z'; + break; + case 'table-col-after': + path = 'M14.08,12.864v-3.648h3.648v-1.7919999999999998h-3.648v-3.648h-1.7280000000000002v3.648h-3.7119999999999997v1.7919999999999998h3.7119999999999997v3.648zM0,17.92v-17.92h20.48v17.92h-20.48zM6.4,1.28h-5.12v3.84h5.12v-3.84zM6.4,6.4h-5.12v3.84h5.12v-3.84zM6.4,11.52h-5.12v3.84h5.12v-3.84zM19.2,1.28h-11.52v14.08h11.52v-14.08z'; + break; + case 'table-col-before': + path = 'M6.4,3.7760000000000002v3.648h-3.648v1.7919999999999998h3.648v3.648h1.7280000000000002v-3.648h3.7119999999999997v-1.7919999999999998h-3.7119999999999997v-3.648zM0,17.92v-17.92h20.48v17.92h-20.48zM12.8,1.28h-11.52v14.08h11.52v-14.08zM19.2,1.28h-5.12v3.84h5.12v-3.84zM19.2,6.4h-5.12v3.84h5.12v-3.84zM19.2,11.52h-5.12v3.84h5.12v-3.84z'; + break; + case 'table-row-delete': + path = 'M17.728,11.456l-3.136,-3.136l3.2,-3.2l-1.536,-1.536l-3.2,3.2l-3.136,-3.136l-1.536,1.472l3.2,3.2l-3.264,3.264l1.536,1.536l3.264,-3.264l3.136,3.136l1.472,-1.536zM0,17.92v-17.92h20.48v17.92h-20.48zM19.2,11.52h-0.44799999999999995l-1.28,-1.28h1.7280000000000002v-3.84h-1.7919999999999998l1.28,-1.28h0.512v-3.84h-17.92v3.84h6.207999999999999l1.28,1.28h-7.4879999999999995v3.84h7.4239999999999995l-1.28,1.28h-6.144v3.84h17.92v-3.84z'; + break; + case 'table-row-after': + path = 'M13.824000000000002,10.176h-2.88v-2.88h-1.4080000000000001v2.88h-2.88v1.344h2.88v2.88h1.4080000000000001v-2.88h2.88zM0,17.92v-17.92h20.48v17.92h-20.48zM6.4,1.28h-5.12v3.84h5.12v-3.84zM12.8,1.28h-5.12v3.84h5.12v-3.84zM19.2,1.28h-5.12v3.84h5.12v-3.84zM19.2,6.336h-17.92v9.024h17.92v-9.024z'; + break; + case 'table-row-before': + path = 'M6.656000000000001,6.4639999999999995h2.88v2.88h1.4080000000000001v-2.88h2.88v-1.344h-2.88v-2.88h-1.4080000000000001v2.88h-2.88zM0,17.92v-17.92h20.48v17.92h-20.48zM7.68,15.36h5.12v-3.84h-5.12v3.84zM1.28,15.36h5.12v-3.84h-5.12v3.84zM19.2,1.28h-17.92v9.024h17.92v-9.024zM19.2,11.52h-5.12v3.84h5.12v-3.84z'; + break; case 'tablet': path = 'M4 2h12c.55 0 1 .45 1 1v14c0 .55-.45 1-1 1H4c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1zm11 14V4H5v12h10zM6 5h6l-6 5V5z'; break; diff --git a/components/dropdown-menu/index.js b/components/dropdown-menu/index.js new file mode 100644 index 00000000000000..5d017fa8e172f1 --- /dev/null +++ b/components/dropdown-menu/index.js @@ -0,0 +1,222 @@ +/** + * External dependencies + */ +import classNames from 'classnames'; +import clickOutside from 'react-click-outside'; +import { findIndex } from 'lodash'; + +/** + * WordPress dependencies + */ +import IconButton from 'components/icon-button'; +import Dashicon from 'components/dashicon'; +import { findDOMNode } from 'element'; +import { TAB, ESCAPE, LEFT, UP, RIGHT, DOWN } from 'utils/keycodes'; + +/** + * Internal dependencies + */ +import './style.scss'; + +class DropdownMenu extends wp.element.Component { + constructor() { + super( ...arguments ); + this.bindMenuRef = this.bindMenuRef.bind( this ); + this.closeMenu = this.closeMenu.bind( this ); + this.toggleMenu = this.toggleMenu.bind( this ); + this.findActiveIndex = this.findActiveIndex.bind( this ); + this.focusIndex = this.focusIndex.bind( this ); + this.focusPrevious = this.focusPrevious.bind( this ); + this.focusNext = this.focusNext.bind( this ); + this.handleKeyDown = this.handleKeyDown.bind( this ); + this.menuRef = null; + this.state = { + open: false, + }; + } + + bindMenuRef( node ) { + this.menuRef = node; + } + + handleClickOutside() { + if ( ! this.state.open ) { + return; + } + + this.closeMenu(); + } + + closeMenu() { + this.setState( { + open: false, + } ); + } + + toggleMenu() { + this.setState( { + open: ! this.state.open, + } ); + } + + findActiveIndex() { + if ( this.menuRef ) { + const menu = findDOMNode( this.menuRef ); + const menuItem = document.activeElement; + if ( menuItem.parentNode === menu ) { + return findIndex( menu.children, ( child ) => child === menuItem ); + } + return -1; + } + } + + focusIndex( index ) { + if ( this.menuRef ) { + const menu = findDOMNode( this.menuRef ); + if ( index < 0 ) { + menu.previousElementSibling.focus(); + } else { + menu.children[ index ].focus(); + } + } + } + + focusPrevious() { + const i = this.findActiveIndex(); + const prevI = i <= -1 ? -1 : i - 1; + this.focusIndex( prevI ); + } + + focusNext() { + const i = this.findActiveIndex(); + const maxI = this.props.controls.length - 1; + const nextI = i >= maxI ? maxI : i + 1; + this.focusIndex( nextI ); + } + + handleKeyDown( keydown ) { + if ( this.state.open ) { + switch ( keydown.keyCode ) { + case ESCAPE: + keydown.preventDefault(); + keydown.stopPropagation(); + this.closeMenu(); + const node = findDOMNode( this ); + const toggle = node.querySelector( '.components-dropdown-menu__toggle' ); + toggle.focus(); + if ( this.props.onSelect ) { + this.props.onSelect( null ); + } + break; + + case TAB: + keydown.preventDefault(); + if ( keydown.shiftKey ) { + this.focusPrevious(); + } else { + this.focusNext(); + } + break; + + case LEFT: + case UP: + keydown.preventDefault(); + this.focusPrevious(); + break; + + case RIGHT: + case DOWN: + keydown.preventDefault(); + this.focusNext(); + break; + + default: + break; + } + } else { + switch ( keydown.keyCode ) { + case DOWN: + keydown.preventDefault(); + this.toggleMenu(); + break; + + default: + break; + } + } + } + + componentDidMount() { + const node = findDOMNode( this ); + node.addEventListener( 'keydown', this.handleKeyDown, false ); + } + + componentWillUnmount() { + const node = findDOMNode( this ); + node.removeEventListener( 'keydown', this.handleKeyDown, false ); + } + + render() { + const { + icon = 'menu', + label, + menuLabel, + controls, + onSelect, + } = this.props; + + if ( ! controls || ! controls.length ) { + return null; + } + + return ( +
    + + + + { this.state.open && +
    + { controls.map( ( control, index ) => ( + { + event.stopPropagation(); + this.closeMenu(); + if ( control.onClick ) { + control.onClick(); + } + if ( onSelect ) { + onSelect( index ); + } + } } + className="components-dropdown-menu__menu-item" + icon={ control.icon } + role="menuitem" + > + { control.title } + + ) ) } +
    + } +
    + ); + } +} + +export default clickOutside( DropdownMenu ); diff --git a/components/dropdown-menu/style.scss b/components/dropdown-menu/style.scss new file mode 100644 index 00000000000000..398c2003706959 --- /dev/null +++ b/components/dropdown-menu/style.scss @@ -0,0 +1,81 @@ +.components-dropdown-menu { + padding: 3px; + position: relative; + display: flex; + + .components-dropdown-menu__toggle { + width: auto; + margin: 0px; + padding: 4px; + border: 1px solid transparent; + border-radius: 0; + display: flex; + flex-direction: row; + + &.is-active, + &.is-active:hover { + background-color: $dark-gray-500; + color: $white; + } + + &:focus:before { + top: -3px; + right: -3px; + bottom: -3px; + left: -3px; + } + + &:hover, + &:focus, + &:not(:disabled):hover { + box-shadow: none; + outline: none; + color: $dark-gray-500; + border-color: $dark-gray-500; + } + + &.is-active > svg, + &.is-active:hover > svg { + background-color: $dark-gray-500; + color: $white; + } + } +} + +.components-dropdown-menu__menu { + position: absolute; + top: $block-controls-height - 1px; + left: -1px; + box-shadow: $shadow-popover; + border: 1px solid $light-gray-500; + background: $white; + padding: 3px 3px 0 3px; + font-family: $default-font; + font-size: $default-font-size; + line-height: $default-line-height; + + .components-dropdown-menu__menu-item { + width: 100%; + margin-bottom: 3px; + padding: 6px; + background: none; + border: 1px solid transparent; + border-radius: 0; + outline: none; + color: $dark-gray-500; + cursor: pointer; + + &:hover, + &:focus, + &:not(:disabled):hover { + box-shadow: none; + color: $dark-gray-500; + border-color: $dark-gray-500; + } + + .dashicon { + margin-right: 5px; + } + } +} + diff --git a/components/index.js b/components/index.js index 8d5a608fa52d42..6e7e951a400c24 100644 --- a/components/index.js +++ b/components/index.js @@ -15,6 +15,7 @@ export { default as ResponsiveWrapper } from './responsive-wrapper'; export { default as SandBox } from './sandbox'; export { default as Spinner } from './spinner'; export { default as Toolbar } from './toolbar'; +export { default as DropdownMenu } from './dropdown-menu'; export { default as Popover } from './popover'; // Higher-Order Components diff --git a/lib/client-assets.php b/lib/client-assets.php index d13492e66f0058..c0dd42335918f9 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -103,7 +103,7 @@ function gutenberg_register_scripts_and_styles() { wp_register_script( 'wp-blocks', gutenberg_url( 'blocks/build/index.js' ), - array( 'wp-element', 'wp-components', 'wp-utils', 'tinymce-nightly', 'tinymce-nightly-lists', 'tinymce-nightly-paste' ), + array( 'wp-element', 'wp-components', 'wp-utils', 'tinymce-nightly', 'tinymce-nightly-lists', 'tinymce-nightly-paste', 'tinymce-nightly-table' ), filemtime( gutenberg_dir_path() . 'blocks/build/index.js' ) ); @@ -177,6 +177,11 @@ function gutenberg_register_vendor_scripts() { 'https://fiddle.azurewebsites.net/tinymce/nightly/plugins/paste/plugin' . $suffix . '.js', array( 'tinymce-nightly' ) ); + gutenberg_register_vendor_script( + 'tinymce-nightly-table', + 'https://fiddle.azurewebsites.net/tinymce/nightly/plugins/table/plugin' . $suffix . '.js', + array( 'tinymce-nightly' ) + ); } /**