Skip to content

Commit

Permalink
Drag and drop: fix firefox compat logic (#67439)
Browse files Browse the repository at this point in the history
Co-authored-by: ellatrix <[email protected]>
Co-authored-by: youknowriad <[email protected]>
  • Loading branch information
3 people authored Dec 5, 2024
1 parent 0b3a191 commit 094bd3a
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,6 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {
canMove,
} = useContext( PrivateBlockContext );

const canDrag = canMove && ! hasChildSelected;

// translators: %s: Type of block (i.e. Text, Image etc)
const blockLabel = sprintf( __( 'Block: %s' ), blockTitle );
const htmlSuffix = mode === 'html' && ! __unstableIsHtml ? '-visual' : '';
Expand All @@ -125,7 +123,7 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {
isEnabled: isSectionBlock,
} ),
useScrollIntoView( { isSelected } ),
canDrag ? ffDragRef : undefined,
canMove ? ffDragRef : undefined,
] );

const blockEditContext = useBlockEditContext();
Expand Down Expand Up @@ -158,7 +156,7 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {

return {
tabIndex: blockEditingMode === 'disabled' ? -1 : 0,
draggable: canDrag ? true : undefined,
draggable: canMove && ! hasChildSelected ? true : undefined,
...wrapperProps,
...props,
ref: mergedRefs,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,68 @@
*/
import { useRefEffect } from '@wordpress/compose';

const nodesByDocument = new Map();

function add( doc, node ) {
let set = nodesByDocument.get( doc );
if ( ! set ) {
set = new Set();
nodesByDocument.set( doc, set );
doc.addEventListener( 'pointerdown', down );
}
set.add( node );
}

function remove( doc, node ) {
const set = nodesByDocument.get( doc );
if ( set ) {
set.delete( node );
restore( node );
if ( set.size === 0 ) {
nodesByDocument.delete( doc );
doc.removeEventListener( 'pointerdown', down );
}
}
}

function restore( node ) {
const prevDraggable = node.getAttribute( 'data-draggable' );
if ( prevDraggable ) {
node.removeAttribute( 'data-draggable' );
// Only restore if `draggable` is still removed. It could have been
// changed by React in the meantime.
if ( prevDraggable === 'true' && ! node.getAttribute( 'draggable' ) ) {
node.setAttribute( 'draggable', 'true' );
}
}
}

function down( event ) {
const { target } = event;
const { ownerDocument, isContentEditable } = target;
const nodes = nodesByDocument.get( ownerDocument );

if ( isContentEditable ) {
// Whenever an editable element is clicked, check which draggable
// blocks contain this element, and temporarily disable draggability.
for ( const node of nodes ) {
if (
node.getAttribute( 'draggable' ) === 'true' &&
node.contains( target )
) {
node.removeAttribute( 'draggable' );
node.setAttribute( 'data-draggable', 'true' );
}
}
} else {
// Whenever a non-editable element is clicked, re-enable draggability
// for any blocks that were previously disabled.
for ( const node of nodes ) {
restore( node );
}
}
}

/**
* In Firefox, the `draggable` and `contenteditable` attributes don't play well
* together. When `contenteditable` is within a `draggable` element, selection
Expand All @@ -13,13 +75,9 @@ import { useRefEffect } from '@wordpress/compose';
*/
export function useFirefoxDraggableCompatibility() {
return useRefEffect( ( node ) => {
function onDown( event ) {
node.draggable = ! event.target.isContentEditable;
}
const { ownerDocument } = node;
ownerDocument.addEventListener( 'pointerdown', onDown );
add( node.ownerDocument, node );
return () => {
ownerDocument.removeEventListener( 'pointerdown', onDown );
remove( node.ownerDocument, node );
};
}, [] );
}

0 comments on commit 094bd3a

Please sign in to comment.