Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A block API proposal v2. :) #69

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 59 additions & 19 deletions blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,12 @@ var getNextSibling = siblingGetter( 'next' );
var getPreviousSibling = siblingGetter( 'previous' );
var getTagType = getConfig.bind( null, 'tagTypes' );
var getTypeKinds = getConfig.bind( null, 'typeKinds' );
var getBlockType = getConfig.bind( null, 'blockTypes' );
var setImageFullBleed = setElementState.bind( null, 'align-full-bleed' );
var setImageAlignNone = setElementState.bind( null, '' );
var setImageAlignLeft = setElementState.bind( null, 'align-left' );
var setImageAlignRight = setElementState.bind( null, 'align-right' );

var setTextAlignLeft = setElementState.bind( null, 'align-left' );
var setTextAlignCenter = setElementState.bind( null, 'align-center' );
var setTextAlignRight = setElementState.bind( null, 'align-right' );

/**
* Globals
*/
Expand All @@ -38,6 +35,11 @@ var config = {
'image': [ 'image' ],
'paragraph': [ 'text' ],
'default': []
},
blockTypes: {
paragraph: textType,
heading: textType,
quote: textType
}
};

Expand Down Expand Up @@ -118,8 +120,10 @@ function showControls( node ) {
switcherButtons.forEach( function( element ) {
element.style.display = 'none';
} );
var blockType = getTagType( node.nodeName );
var switcherQuery = '.type-icon-' + blockType;

var type = getTagType( node.nodeName );
var switcherQuery = '.type-icon-' + type;

queryFirst( switcherQuery ).style.display = 'block';

// reposition switcher
Expand All @@ -128,20 +132,61 @@ function showControls( node ) {
switcher.style.top = ( position.top + 18 + window.scrollY ) + 'px';

// show/hide block-specific block controls
blockControls.className = 'block-controls';
getTypeKinds( blockType ).forEach( function( kind ) {
blockControls.classList.add( 'is-' + kind );
} );
blockControls.style.display = 'block';
var nodeBlockType = getBlockType( type );
if ( typeof nodeBlockType !== 'undefined' ) {
// Could be cleaned up even more by putting these controls into a block.
var nodeBlockControls = document.createElement( 'div' );
nodeBlockControls.className = 'block-controls-from-api';

var blockTypeBlockControls = nodeBlockType.controls.filter( function( control ) {
return control.displayArea === 'block'
} ).map( function( control ) {
var controlNode = control.create().render()

if ( Array.isArray( control.handlers ) ) {
control.handlers.forEach( function( handler ) {
controlNode.addEventListener( handler.type, handler.action( node ), false );
} )
}

return controlNode;
} ).map( function( control ) {
nodeBlockControls.appendChild( control )
} );

nodeBlockControls.style.display = 'block';

// reposition block-specific block controls
blockControls.style.top = ( position.top - 36 + window.scrollY ) + 'px';
blockControls.style.maxHeight = 'none';
// reposition block-specific block controls
nodeBlockControls.style.top = ( -36 ) + 'px';
nodeBlockControls.style.left = ( 0 ) + 'px';
nodeBlockControls.style.maxHeight = 'none';

node.insertBefore( nodeBlockControls, node.firstChild );
} else {
// This is the current way things are done.
var kinds = getTypeKinds( type );
var kindClasses = kinds.map( function( kind ) {
return 'is-' + kind;
} ).join( ' ' );

blockControls.className = 'block-controls ' + kindClasses;
blockControls.style.display = 'block';

// reposition block-specific block controls
blockControls.style.top = ( position.top - 36 + window.scrollY ) + 'px';
blockControls.style.maxHeight = 'none';
}
}

function hideControls() {
switcher.style.opacity = 0;
switcherMenu.style.display = 'none';

var blockControlsFromAPI = queryFirst( '.block-controls-from-api' );
if ( blockControlsFromAPI ) {
blockControlsFromAPI.parentNode.removeChild( blockControlsFromAPI )
}

blockControls.style.display = 'none';
}

Expand Down Expand Up @@ -198,11 +243,6 @@ function attachControlActions() {
}
} );

// Text block event handlers.
textAlignLeft.addEventListener( 'click', setTextAlignLeft, false );
textAlignCenter.addEventListener( 'click', setTextAlignCenter, false );
textAlignRight.addEventListener( 'click', setTextAlignRight, false );

switcherButtons.forEach( function( button ) {
button.addEventListener( 'click', showSwitcherMenu, false );
} );
Expand Down
5 changes: 5 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ <h2>1.0 Is The Loneliest Number</h2>
</div>
</div>
</div>
<script src="src/api/block.js"></script>
<script src="src/api/blockType.js"></script>
<script src="src/api/control.js"></script>
<script src="src/api/controlType.js"></script>
<script src="src/blockTypes/textType.js"></script>
<script src="blocks.js"></script>
</body>
</html>
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
"version": "1.0.0",
"description": "Prototyping a new WordPress editor experience",
"main": "index.html",
"bin": {
"mocha": "./node_modules/.bin/mocha"
},
"scripts": {
"start": "http-server -p 5000",
"test": "echo \"Error: no test specified\" && exit 1"
"test": "mocha"
},
"repository": {
"type": "git",
Expand All @@ -23,6 +26,7 @@
},
"homepage": "https://github.com/Automattic/gutenberg#readme",
"devDependencies": {
"http-server": "0.9.0"
"http-server": "0.9.0",
"mocha": "^3.2.0"
}
}
36 changes: 36 additions & 0 deletions src/api/block.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* block.js serves as an API for creating blocks.
*
* A block should provie a method/interface for creating some implementation
* of itself. This could be DOM, or virtual DOM, TinyMCE, or anything you want.
*/
( function() {
function block( properties ) {
if ( arguments.length > 1 ) {
let properties = Object.assign( ...arguments )
}

var clone = cloner( block )( properties )

return cloner( clone )
}

var cloner = function( primitiveFunction ) {
var clone = function block( properties ) {
if ( arguments.length > 1 ) {
let properties = Object.assign( ...arguments )
}
return cloner( Object.assign( clone, properties ) )
}

return Object.assign( clone, primitiveFunction )
}

if ( typeof window !== 'undefined' ) {
window.block = block
}

if ( typeof module !== 'undefined' && typeof module.exports !== 'undefined' ) {
module.exports = block
}
} () )
36 changes: 36 additions & 0 deletions src/api/blockType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* blockType.js serves as an API for creating block types.
*
* A blockType type defines the properties of a block. A text block
* type could then be used to create an actual text block.
*/
( function() {
function blockType( properties ) {
if ( arguments.length > 1 ) {
let properties = Object.assign( ...arguments )
}

var clone = cloner( blockType )( properties )

return cloner( clone )
}

var cloner = function( primitiveFunction ) {
var clone = function blockType( properties ) {
if ( arguments.length > 1 ) {
let properties = Object.assign( ...arguments )
}
return cloner( Object.assign( clone, properties ) )
}

return Object.assign( clone, primitiveFunction )
}

if ( typeof window !== 'undefined' ) {
window.blockType = blockType
}

if ( typeof module !== 'undefined' && typeof module.exports !== 'undefined' ) {
module.exports = blockType
}
} () )
36 changes: 36 additions & 0 deletions src/api/control.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* control.js serves as an API for creating controls.
*
* A control should provie a method/interface for creating some implementation
* of itself. This could be DOM, or virtual DOM, TinyMCE, or anything you want.
*/
( function() {
function control( properties ) {
if ( arguments.length > 1 ) {
let properties = Object.assign( ...arguments )
}

var clone = cloner( control )( properties )

return cloner( clone )
}

var cloner = function( primitiveFunction ) {
var clone = function control( properties ) {
if ( arguments.length > 1 ) {
let properties = Object.assign( ...arguments )
}
return cloner( Object.assign( clone, properties ) )
}

return Object.assign( clone, primitiveFunction )
}

if ( typeof window !== 'undefined' ) {
window.control = control
}

if ( typeof module !== 'undefined' && typeof module.exports !== 'undefined' ) {
module.exports = control
}
} () )
36 changes: 36 additions & 0 deletions src/api/controlType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* controlType.js serves as an API for creating control types.
*
* A controlType type defines the properties of a control. A left align control
* type could then be used to create an actual left align control.
*/
( function() {
function controlType( properties ) {
if ( arguments.length > 1 ) {
let properties = Object.assign( ...arguments )
}

var clone = cloner( controlType )( properties )

return cloner( clone )
}

var cloner = function( primitiveFunction ) {
var clone = function controlType( properties ) {
if ( arguments.length > 1 ) {
let properties = Object.assign( ...arguments )
}
return cloner( Object.assign( clone, properties ) )
}

return Object.assign( clone, primitiveFunction )
}

if ( typeof window !== 'undefined' ) {
window.controlType = controlType
}

if ( typeof module !== 'undefined' && typeof module.exports !== 'undefined' ) {
module.exports = controlType
}
} () )
Loading