diff --git a/shared/index.css b/shared/index.css
index b0134ca198d0f..2d93b543545d5 100644
--- a/shared/index.css
+++ b/shared/index.css
@@ -102,7 +102,8 @@ body {
#editor figure {
clear: both;
float: none;
- margin: 1em 0;
+ margin-left: auto;
+ margin-right: auto;
width: 100%;
/*transition: margin 0.5s, width 0.5s;*/
}
@@ -152,7 +153,7 @@ body {
#editor figure img,
#editor figure iframe {
display: block;
- margin: 0;
+ margin: 0 auto;
}
#editor pre {
diff --git a/tinymce-single/blocks/core/gallery/register.js b/tinymce-single/blocks/core/gallery/register.js
index 8c39f71e6060d..2356d343dc3e1 100644
--- a/tinymce-single/blocks/core/gallery/register.js
+++ b/tinymce-single/blocks/core/gallery/register.js
@@ -1,31 +1,85 @@
-window.wp.blocks.registerBlock( {
- name: 'gallery',
- namespace: 'core',
- displayName: 'Gallery',
- type: 'media',
- keywords: [],
- icon: 'gridicons-image-multiple',
- editable: [ 'figcaption' ],
- controls: [
- 'block-align-left',
- 'block-align-center',
- 'block-align-right',
- 'block-align-full',
- // {
- // type: 'select',
- // label: 'Columns'
- // },
- // {
- // type: 'button',
- // label: 'Columns',
- // icon: 'gridicons-image',
- // command: function( editor, node ) {
- // // body...
- // }
- // },
- {
- icon: 'gridicons-cog'
+( function( wp ) {
+
+ function insertEmpty() {
+ return (
+ ''
+ );
+ }
+
+ function pickTarget( parents, child ) {
+ for ( var i = 0; i < parents.length; i++ ) {
+ if ( parents[ i ] === child || parents[ i ].contains( child ) ) {
+ return parents[ i ]
+ }
}
- ],
- insert: function() {}
-} );
+ }
+
+ function onClick( event, block, adjustUI ) {
+ var target = pickTarget( block.querySelectorAll( 'div' ), event.target );
+
+ if ( ! target ) {
+ return;
+ }
+
+ if ( ( ' ' + target.className + ' ' ).indexOf( ' wp-blocks-placeholder ' ) === -1 ) {
+ return;
+ }
+
+ wp.filePicker( false, 'image/*' )
+ .then( function( files ) {
+ if ( ! files || ! files.length ) {
+ return;
+ }
+
+ if ( files[0].type.indexOf( 'image/' ) !== 0 ) {
+ return;
+ }
+
+ var img = document.createElement( 'img' );
+
+ img.src = URL.createObjectURL( files[0] );
+ img.onload = adjustUI;
+
+ target.parentNode.replaceChild( img, target );
+ } )
+ .catch( function() {} );
+ }
+
+ wp.blocks.registerBlock( {
+ name: 'gallery',
+ namespace: 'core',
+ displayName: 'Gallery',
+ type: 'media',
+ keywords: [],
+ icon: 'gridicons-image-multiple',
+ editable: [ 'figcaption' ],
+ controls: [
+ 'block-align-left',
+ 'block-align-center',
+ 'block-align-right',
+ 'block-align-full',
+ {
+ icon: 'gridicons-cog'
+ }
+ ],
+ insert: insertEmpty,
+ onClick: onClick
+ } );
+} )( window.wp );
diff --git a/tinymce-single/blocks/core/gallery/structure.css b/tinymce-single/blocks/core/gallery/structure.css
index 09c2ed9317a09..c05a0000b3a1e 100644
--- a/tinymce-single/blocks/core/gallery/structure.css
+++ b/tinymce-single/blocks/core/gallery/structure.css
@@ -33,7 +33,7 @@
}
#editor figure[data-wp-block-type="core:gallery"][data-wp-block-setting-column="2"] figure {
- width: 43%;
+ width: 49%;
}
#editor figure[data-wp-block-type="core:gallery"][data-wp-block-setting-column="3"] figure {
diff --git a/tinymce-single/blocks/core/image/register.js b/tinymce-single/blocks/core/image/register.js
index a9a4293a9cd7a..1492d96e5b0f6 100644
--- a/tinymce-single/blocks/core/image/register.js
+++ b/tinymce-single/blocks/core/image/register.js
@@ -1,40 +1,90 @@
-window.wp.blocks.registerBlock( {
- name: 'image',
- namespace: 'core',
- displayName: 'Image',
- type: 'media',
- icon: 'gridicons-image',
- editable: [ 'figcaption' ],
- controls: [
- 'block-align-left',
- 'block-align-center',
- 'block-align-right',
- 'block-align-full',
- {
- icon: 'gridicons-caption',
- onClick: function( block ) {
- var figcaption = block.querySelector( 'figcaption' );
-
- if ( figcaption ) {
- block.removeChild( figcaption );
- } else {
- block.insertAdjacentHTML( 'beforeend',
- '
' );
- }
+( function( wp ) {
- window.wp.blocks.selectBlock( block );
- },
- isActive: function( block ) {
- return !! block.querySelector( 'figcaption' );
- }
- }
- ],
- insert: function() {
+ function insertEmpty() {
return (
- '' +
- '' +
- 'I have no idea which mountain this is. It looks tall!' +
+ '' +
+ '' +
+ '
' +
+ '
Pick image
' +
+ '
' +
''
);
}
-} );
+
+ function pickTarget( parents, child ) {
+ for ( var i = 0; i < parents.length; i++ ) {
+ if ( parents[ i ] === child || parents[ i ].contains( child ) ) {
+ return parents[ i ]
+ }
+ }
+ }
+
+ function onClick( event, block, adjustUI ) {
+ var target = pickTarget( block.querySelectorAll( 'div' ), event.target );
+
+ if ( ! target ) {
+ return;
+ }
+
+ if ( ( ' ' + target.className + ' ' ).indexOf( ' wp-blocks-placeholder ' ) === -1 ) {
+ return;
+ }
+
+ wp.filePicker( false, 'image/*' )
+ .then( function( files ) {
+ if ( ! files || ! files.length ) {
+ return;
+ }
+
+ if ( files[0].type.indexOf( 'image/' ) !== 0 ) {
+ return;
+ }
+
+ var img = document.createElement( 'img' );
+
+ img.src = URL.createObjectURL( files[0] );
+ img.onload = adjustUI;
+
+ target.parentNode.replaceChild( img, target );
+ } )
+ .catch( function() {} );
+ }
+
+ wp.blocks.registerBlock( {
+ name: 'image',
+ namespace: 'core',
+ displayName: 'Image',
+ type: 'media',
+ icon: 'gridicons-image',
+ editable: [ 'figcaption' ],
+ controls: [
+ 'block-align-left',
+ 'block-align-center',
+ 'block-align-right',
+ 'block-align-full',
+ {
+ icon: 'gridicons-caption',
+ onClick: function( block ) {
+ var figcaption = block.querySelector( 'figcaption' );
+
+ if ( figcaption ) {
+ block.removeChild( figcaption );
+ } else {
+ block.insertAdjacentHTML( 'beforeend',
+ '
' );
+ }
+
+ window.wp.blocks.selectBlock( block );
+ },
+ isActive: function( block ) {
+ return !! block.querySelector( 'figcaption' );
+ }
+ }
+ ],
+ insert: insertEmpty,
+ onClick: onClick
+ } );
+
+} )( window.wp );
diff --git a/tinymce-single/blocks/elements/lists/register.js b/tinymce-single/blocks/elements/lists/register.js
index d9420f13cf556..0ea5b8d8534d2 100644
--- a/tinymce-single/blocks/elements/lists/register.js
+++ b/tinymce-single/blocks/elements/lists/register.js
@@ -1,60 +1,90 @@
-window.wp.blocks.registerBlock( {
- name: 'list',
- displayName: 'List',
- elements: [ 'ul', 'ol' ],
- type: 'text',
- icon: 'gridicons-list-unordered',
- controls: [
- {
- icon: 'gridicons-list-unordered',
- stateSelector: 'ul',
- onClick: function( block, editor ) {
- // Use native command to toggle current selected list.
- editor.execCommand( 'InsertUnorderedList' );
- }
- },
- {
- icon: 'gridicons-list-ordered',
- stateSelector: 'ol',
- onClick: function( block, editor ) {
- // Use native command to toggle current selected list.
- editor.execCommand( 'InsertOrderedList' );
+( function( wp ) {
+
+ function insertEmpty() {
+ return '';
+ }
+
+ function fromBaseState( state ) {
+ var list = document.createElement( 'UL' );
+ var item = document.createElement( 'LI' );
+
+ list.appendChild( item );
+
+ while ( state.firstChild ) {
+ if ( state.firstChild.nodeName === 'BR' ) {
+ item = document.createElement( 'LI' );
+ list.appendChild( item );
+ state.removeChild( state.firstChild );
+ } else {
+ item.appendChild( state.firstChild );
}
- },
- {
- classes: 'remove-formatting',
- icon: 'gridicons-list-unordered',
- onClick: function( block, editor ) {
- var p = document.createElement( 'P' );
-
- function build( list, p ) {
- var item;
-
- while ( item = list.firstChild ) {
- if ( p.childNodes.length ) {
- p.appendChild( document.createElement( 'BR' ) );
- }
-
- while ( item.firstChild ) {
- if ( item.firstChild.nodeName === 'UL' || item.firstChild.nodeName === 'OL' ) {
- build( item.firstChild, p )
- item.removeChild( item.firstChild );
- } else {
- p.appendChild( item.firstChild );
- }
- }
-
- list.removeChild( item );
- }
+ }
+
+ state.parentNode.replaceChild( list, state );
+ }
+
+ function toBaseState( block ) {
+ var state = document.createElement( 'P' );
+
+ function build( list, state ) {
+ var item;
+
+ while ( item = list.firstChild ) {
+ if ( state.childNodes.length ) {
+ state.appendChild( document.createElement( 'BR' ) );
}
- build( block, p );
+ while ( item.firstChild ) {
+ if ( item.firstChild.nodeName === 'UL' || item.firstChild.nodeName === 'OL' ) {
+ build( item.firstChild, state )
+ item.removeChild( item.firstChild );
+ } else {
+ state.appendChild( item.firstChild );
+ }
+ }
- block.parentNode.replaceChild( p, block );
+ list.removeChild( item );
}
}
- ],
- insert: function() {
- return '';
+
+ build( block, state );
+
+ block.parentNode.replaceChild( state, block );
}
-} );
+
+ wp.blocks.registerBlock( {
+ name: 'list',
+ displayName: 'List',
+ elements: [ 'ul', 'ol' ],
+ type: 'text',
+ icon: 'gridicons-list-unordered',
+ base: 'elements:paragraph',
+ insert: insertEmpty,
+ toBaseState: toBaseState,
+ fromBaseState: fromBaseState,
+ controls: [
+ {
+ icon: 'gridicons-list-unordered',
+ stateSelector: 'ul',
+ onClick: function( block, editor ) {
+ // Use native command to toggle current selected list.
+ editor.execCommand( 'InsertUnorderedList' );
+ }
+ },
+ {
+ icon: 'gridicons-list-ordered',
+ stateSelector: 'ol',
+ onClick: function( block, editor ) {
+ // Use native command to toggle current selected list.
+ editor.execCommand( 'InsertOrderedList' );
+ }
+ },
+ {
+ classes: 'remove-formatting',
+ icon: 'gridicons-list-unordered',
+ onClick: toBaseState
+ }
+ ]
+ } );
+
+} )( window.wp );
diff --git a/tinymce-single/blocks/elements/paragraph/register.js b/tinymce-single/blocks/elements/paragraph/register.js
index 33f24f714bed1..46d96a1393529 100644
--- a/tinymce-single/blocks/elements/paragraph/register.js
+++ b/tinymce-single/blocks/elements/paragraph/register.js
@@ -19,23 +19,8 @@ window.wp.blocks.registerBlock( {
},
{
icon: 'gridicons-list-unordered',
- onClick: function( block, editor ) {
- var list = document.createElement( 'UL' );
- var item = document.createElement( 'LI' );
-
- list.appendChild( item );
-
- while ( block.firstChild ) {
- if ( block.firstChild.nodeName === 'BR' ) {
- item = document.createElement( 'LI' );
- list.appendChild( item );
- block.removeChild( block.firstChild );
- } else {
- item.appendChild( block.firstChild );
- }
- }
-
- block.parentNode.replaceChild( list, block );
+ onClick: function( block ) {
+ wp.blocks.getBlockSettings( 'elements:list' ).fromBaseState( block );
}
},
{
diff --git a/tinymce-single/blocks/my-awesome-plugin/youtube/register.js b/tinymce-single/blocks/my-awesome-plugin/youtube/register.js
index 35acf6f4c511b..5dc04a52b05fb 100644
--- a/tinymce-single/blocks/my-awesome-plugin/youtube/register.js
+++ b/tinymce-single/blocks/my-awesome-plugin/youtube/register.js
@@ -1,19 +1,52 @@
-window.wp.blocks.registerBlock( {
- name: 'youtube',
- namespace: 'my-awesome-plugin',
- displayName: 'YouTube Video',
- type: 'media',
- keywords: [],
- icon: 'gridicons-video',
- editable: [ 'figcaption' ],
- controls: [
- 'block-align-left',
- 'block-align-center',
- 'block-align-right',
- 'block-align-full',
- {
- icon: 'gridicons-cog'
+( function( wp ) {
+
+ function insertEmpty() {
+ return (
+ '' +
+ '' +
+ '
' +
+ '
Paste YouTube link here
' +
+ '
' +
+ ''
+ );
+ }
+
+ function onPaste( event, block ) {
+ var target = block.querySelector( 'div' );
+
+ if ( ! target ) {
+ return;
}
- ],
- insert: function() {}
-} );
+
+ var regEx = /https?:\/\/(?:www\.)?(?:youtube\.com\/watch\?v=|youtu\.be\/)([^?&]+).*/;
+ var matches = regEx.exec( event.content );
+
+ if ( matches && matches.length ) {
+ target.outerHTML = '';
+ }
+ }
+
+ wp.blocks.registerBlock( {
+ name: 'youtube',
+ namespace: 'my-awesome-plugin',
+ displayName: 'YouTube Video',
+ type: 'media',
+ keywords: [],
+ icon: 'gridicons-video',
+ editable: [ 'figcaption' ],
+ controls: [
+ 'block-align-left',
+ 'block-align-center',
+ 'block-align-right',
+ 'block-align-full',
+ {
+ icon: 'gridicons-cog'
+ }
+ ],
+ insert: insertEmpty,
+ onPaste: onPaste
+ } );
+
+} )( window.wp );
diff --git a/tinymce-single/controls/align.js b/tinymce-single/controls/align.js
index 0556326761416..dd5158c23dac5 100644
--- a/tinymce-single/controls/align.js
+++ b/tinymce-single/controls/align.js
@@ -1,31 +1,20 @@
-( function( wp, $ ) {
- var RX_ALIGN_CLASSNAME = /^(text-align-|align)([\w-]+)/;
-
+( function( wp ) {
function createOnClick( classNamePrefix, position ) {
return function( node ) {
- return $( node )
- .removeClass( function( i, className ) {
- return RX_ALIGN_CLASSNAME.test( className ) ? className : '';
- } )
- .addClass( classNamePrefix + position );
+ node.className = node.className.replace( new RegExp( classNamePrefix + '[^ ]+ ?', 'g' ), '' ).trim();
+ node.className += ( node.className ? ' ' : '' ) + classNamePrefix + position;
};
}
- function createIsActive( classNamePrefix, position ) {
+ function createIsActive( classNamePrefix, position, normal ) {
return function( node ) {
- var classNames = node.className.split( ' ' ),
- i, className, match;
-
- for ( i = 0; i < classNames.length; i++ ) {
- className = classNames[ i ];
- match = className.match( RX_ALIGN_CLASSNAME );
+ var matches = node.className.match( new RegExp( classNamePrefix + '([^ ]+)' ) );
- if ( match && classNamePrefix === match[ 1 ] ) {
- return position === match[ 2 ];
- }
+ if ( matches ) {
+ return position === matches[ 1 ];
+ } else {
+ return position === normal;
}
-
- return 'left' === position;
};
}
@@ -33,13 +22,13 @@
wp.blocks.registerControl( 'text-align-' + position, {
icon: 'gridicons-align-' + position,
onClick: createOnClick( 'text-align-', position ),
- isActive: createIsActive( 'text-align-', position )
+ isActive: createIsActive( 'text-align-', position, 'left' )
} );
wp.blocks.registerControl( 'block-align-' + position, {
icon: 'gridicons-align-image-' + position,
onClick: createOnClick( 'align', position ),
- isActive: createIsActive( 'align', position )
+ isActive: createIsActive( 'align', position, 'center' )
} );
} );
-} )( window.wp = window.wp || {}, window.jQuery );
+} )( window.wp );
diff --git a/tinymce-single/filePicker.js b/tinymce-single/filePicker.js
new file mode 100644
index 0000000000000..2a7ca932b600d
--- /dev/null
+++ b/tinymce-single/filePicker.js
@@ -0,0 +1,25 @@
+window.wp = window.wp || {};
+window.wp.filePicker = ( function() {
+ return function( multiple, accept ) {
+ return new Promise( function( resolve, reject ) {
+ var input = document.createElement( 'input' );
+
+ input.type = 'file';
+ input.accept = accept;
+ input.multiple = multiple;
+ input.style.position = 'fixed';
+ input.style.left = 0;
+ input.style.top = 0;
+ input.style.opacity = 0.001;
+
+ input.onchange = function( event ) {
+ resolve( event.target.files );
+ input.parentNode.removeChild( input );
+ }
+
+ document.body.appendChild( input );
+
+ input.click();
+ } );
+ }
+} )();
diff --git a/tinymce-single/index.html b/tinymce-single/index.html
index 1d11125304b54..40e39d9cfc1e7 100644
--- a/tinymce-single/index.html
+++ b/tinymce-single/index.html
@@ -66,9 +66,9 @@ NASA discovers system of seven Earth-sized planets
-
+
diff --git a/tinymce-single/tinymce/block.css b/tinymce-single/tinymce/block.css
index ad651cccbcb3d..8d32598413c22 100644
--- a/tinymce-single/tinymce/block.css
+++ b/tinymce-single/tinymce/block.css
@@ -283,3 +283,14 @@ div.mce-inline-toolbar-grp.block-toolbar > div.mce-stack-layout {
.insert-menu .mce-btn-has-text svg.gridicons-heading {
margin: 0;
}
+
+#editor .wp-blocks-placeholder {
+ padding: 50px 0;
+ background: #f0f2f4;
+ text-align: center;
+}
+
+#editor .wp-blocks-placeholder svg {
+ display: block;
+ margin: 0 auto 20px;
+}
diff --git a/tinymce-single/tinymce/block.js b/tinymce-single/tinymce/block.js
index 79339f8295958..a12ec933ea04f 100644
--- a/tinymce-single/tinymce/block.js
+++ b/tinymce-single/tinymce/block.js
@@ -46,6 +46,24 @@
editor.addButton( name, settings );
} );
+ editor.on( 'pastePreProcess', function( event ) {
+ var block = getSelectedBlock();
+ var settings = wp.blocks.getBlockSettingsByElement( block );
+
+ if ( settings.onPaste ) {
+ settings.onPaste( event, block )
+ }
+ } );
+
+ editor.on( 'click', function( event ) {
+ var block = getSelectedBlock();
+ var settings = wp.blocks.getBlockSettingsByElement( block );
+
+ if ( settings.onClick ) {
+ settings.onClick( event, block, function() { editor.nodeChanged() } )
+ }
+ } );
+
editor.on( 'setContent', function( event ) {
$blocks = editor.$( editor.getBody() ).find( '*[data-wp-block-type]' );
$blocks.attr( 'contenteditable', 'false' );
@@ -60,6 +78,17 @@
} );
} );
+ editor.on( 'nodeChange', function( event ) {
+ var block = wp.blocks.getSelectedBlock();
+ var settings = wp.blocks.getBlockSettingsByElement( block );
+
+ if ( settings && settings.editable ) {
+ settings.editable.forEach( function( selector ) {
+ editor.$( block ).find( selector ).attr( 'contenteditable', 'true' );
+ } );
+ }
+ } );
+
function toInlineContent( content ) {
var settings = {
valid_elements: 'strong,em,del,a[href]'
@@ -318,7 +347,7 @@
var key;
var types = [ 'text', 'media', 'separator' ];
- function onClick( callback ) {
+ function onClick( callback, settings ) {
return function( block ) {
var content = callback.apply( this, arguments );
var args = {
@@ -340,6 +369,10 @@
block.parentNode.replaceChild( content, block );
+ if ( ! settings.elements ) {
+ content.setAttribute( 'data-wp-block-type', settings._id );
+ }
+
editor.fire( 'setContent', args );
}
@@ -360,7 +393,7 @@
buttons.push( {
text: allSettings[ key ].displayName,
icon: allSettings[ key ].icon,
- onClick: onClick( allSettings[ key ].insert )
+ onClick: onClick( allSettings[ key ].insert, allSettings[ key ] )
} );
}
}