Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@wordpress/dom

Package Overview
Dependencies
Maintainers
6
Versions
185
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@wordpress/dom - npm Package Compare versions

Comparing version 1.0.0-alpha.3 to 1.0.0

175

build-module/dom.js

@@ -0,6 +1,7 @@

import "core-js/modules/es6.regexp.to-string";
/**
* External dependencies
*/
import { includes, first } from 'lodash';
import tinymce from 'tinymce';
import { includes } from 'lodash';
/**

@@ -11,20 +12,61 @@ * Browser dependencies

var _window = window,
getComputedStyle = _window.getComputedStyle,
DOMRect = _window.DOMRect;
getComputedStyle = _window.getComputedStyle;
var _window$Node = window.Node,
TEXT_NODE = _window$Node.TEXT_NODE,
ELEMENT_NODE = _window$Node.ELEMENT_NODE;
ELEMENT_NODE = _window$Node.ELEMENT_NODE,
DOCUMENT_POSITION_PRECEDING = _window$Node.DOCUMENT_POSITION_PRECEDING,
DOCUMENT_POSITION_FOLLOWING = _window$Node.DOCUMENT_POSITION_FOLLOWING;
/**
* Check whether the caret is horizontally at the edge of the container.
* Returns true if the given selection object is in the forward direction, or
* false otherwise.
*
* @param {Element} container Focusable element.
* @param {boolean} isReverse Set to true to check left, false for right.
* @param {boolean} collapseRanges Whether or not to collapse the selection range before the check.
* @see https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
*
* @param {Selection} selection Selection object to check.
*
* @return {boolean} Whether the selection is forward.
*/
function isSelectionForward(selection) {
var anchorNode = selection.anchorNode,
focusNode = selection.focusNode,
anchorOffset = selection.anchorOffset,
focusOffset = selection.focusOffset;
var position = anchorNode.compareDocumentPosition(focusNode); // Disable reason: `Node#compareDocumentPosition` returns a bitmask value,
// so bitwise operators are intended.
/* eslint-disable no-bitwise */
// Compare whether anchor node precedes focus node. If focus node (where
// end of selection occurs) is after the anchor node, it is forward.
if (position & DOCUMENT_POSITION_PRECEDING) {
return false;
}
if (position & DOCUMENT_POSITION_FOLLOWING) {
return true;
}
/* eslint-enable no-bitwise */
// `compareDocumentPosition` returns 0 when passed the same node, in which
// case compare offsets.
if (position === 0) {
return anchorOffset <= focusOffset;
} // This should never be reached, but return true as default case.
return true;
}
/**
* Check whether the selection is horizontally at the edge of the container.
*
* @param {Element} container Focusable element.
* @param {boolean} isReverse Set to true to check left, false for right.
*
* @return {boolean} True if at the horizontal edge, false if not.
*/
export function isHorizontalEdge(container, isReverse) {
var collapseRanges = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
if (includes(['INPUT', 'TEXTAREA'], container.tagName)) {

@@ -44,54 +86,27 @@ if (container.selectionStart !== container.selectionEnd) {

return true;
} // If the container is empty, the caret is always at the edge.
if (tinymce.DOM.isEmpty(container)) {
return true;
}
var selection = window.getSelection();
var range = selection.rangeCount ? selection.getRangeAt(0) : null;
var selection = window.getSelection(); // Create copy of range for setting selection to find effective offset.
if (collapseRanges) {
range = range.cloneRange();
range.collapse(isReverse);
}
var range = selection.getRangeAt(0).cloneRange(); // Collapse in direction of selection.
if (!range || !range.collapsed) {
return false;
if (!selection.isCollapsed) {
range.collapse(!isSelectionForward(selection));
}
var position = isReverse ? 'start' : 'end';
var order = isReverse ? 'first' : 'last';
var offset = range["".concat(position, "Offset")];
var node = range.startContainer;
var endContainer = range.endContainer,
endOffset = range.endOffset;
range.selectNodeContents(container);
range.setEnd(endContainer, endOffset); // Check if the caret position is at the expected start/end position based
// on the value of `isReverse`. If so, consider the horizontal edge to be
// reached.
if (isReverse && offset !== 0) {
return false;
}
var maxOffset = node.nodeType === TEXT_NODE ? node.nodeValue.length : node.childNodes.length;
if (!isReverse && offset !== maxOffset) {
return false;
}
while (node !== container) {
var parentNode = node.parentNode;
if (parentNode["".concat(order, "Child")] !== node) {
return false;
}
node = parentNode;
}
return true;
var caretOffset = range.toString().length;
return caretOffset === (isReverse ? 0 : container.textContent.length);
}
/**
* Check whether the caret is vertically at the edge of the container.
* Check whether the selection is vertically at the edge of the container.
*
* @param {Element} container Focusable element.
* @param {boolean} isReverse Set to true to check top, false for bottom.
* @param {boolean} collapseRanges Whether or not to collapse the selection range before the check.
* @param {Element} container Focusable element.
* @param {boolean} isReverse Set to true to check top, false for bottom.
*

@@ -102,4 +117,2 @@ * @return {boolean} True if at the edge, false if not.

export function isVerticalEdge(container, isReverse) {
var collapseRanges = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
if (includes(['INPUT', 'TEXTAREA'], container.tagName)) {

@@ -116,11 +129,3 @@ return isHorizontalEdge(container, isReverse);

if (collapseRanges && range && !range.collapsed) {
var newRange = document.createRange(); // Get the end point of the selection (see focusNode vs. anchorNode)
newRange.setStart(selection.focusNode, selection.focusOffset);
newRange.collapse(true);
range = newRange;
}
if (!range || !range.collapsed) {
if (!range) {
return false;

@@ -163,22 +168,18 @@ }

return range.getBoundingClientRect();
} // If the collapsed range starts (and therefore ends) at an element node,
// `getClientRects` will return undefined. To fix this we can get the
// bounding rectangle of the element node to create a DOMRect based on that.
}
var rect = range.getClientRects()[0]; // If the collapsed range starts (and therefore ends) at an element node,
// `getClientRects` can be empty in some browsers. This can be resolved
// by adding a temporary text node with zero-width space to the range.
//
// See: https://stackoverflow.com/a/6847328/995445
if (range.startContainer.nodeType === ELEMENT_NODE) {
var _range$startContainer = range.startContainer.getBoundingClientRect(),
x = _range$startContainer.x,
y = _range$startContainer.y,
height = _range$startContainer.height; // Create a new DOMRect with zero width.
if (!rect) {
var padNode = document.createTextNode("\u200B");
range.insertNode(padNode);
rect = range.getClientRects()[0];
padNode.parentNode.removeChild(padNode);
}
return new DOMRect(x, y, 0, height);
} // For normal collapsed ranges (exception above), the bounding rectangle of
// the range may be inaccurate in some browsers. There will only be one
// rectangle since it is a collapsed range, so it is safe to pass this as
// the union of them. This works consistently in all browsers.
return first(range.getClientRects());
return rect;
}

@@ -201,3 +202,3 @@ /**

if (!range || !range.collapsed) {
if (!range) {
return;

@@ -237,7 +238,11 @@ }

return;
}
} // Select on extent child of the container, not the container itself. This
// avoids the selection always being `endOffset` of 1 when placed at end,
// where `startContainer`, `endContainer` would always be container itself.
var rangeTarget = container[isReverse ? 'lastChild' : 'firstChild'];
var selection = window.getSelection();
var range = document.createRange();
range.selectNodeContents(container);
range.selectNodeContents(rangeTarget);
range.collapse(!isReverse);

@@ -332,3 +337,3 @@ selection.removeAllRanges();

var editableRect = container.getBoundingClientRect();
var x = rect.left + rect.width / 2;
var x = rect.left;
var y = isReverse ? editableRect.bottom - buffer : editableRect.top + buffer;

@@ -335,0 +340,0 @@ var selection = window.getSelection();

"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
require("core-js/modules/es7.array.includes");

@@ -29,6 +27,6 @@

require("core-js/modules/es6.regexp.to-string");
var _lodash = require("lodash");
var _tinymce = _interopRequireDefault(require("tinymce"));
/**

@@ -42,20 +40,61 @@ * External dependencies

var _window = window,
getComputedStyle = _window.getComputedStyle,
DOMRect = _window.DOMRect;
getComputedStyle = _window.getComputedStyle;
var _window$Node = window.Node,
TEXT_NODE = _window$Node.TEXT_NODE,
ELEMENT_NODE = _window$Node.ELEMENT_NODE;
ELEMENT_NODE = _window$Node.ELEMENT_NODE,
DOCUMENT_POSITION_PRECEDING = _window$Node.DOCUMENT_POSITION_PRECEDING,
DOCUMENT_POSITION_FOLLOWING = _window$Node.DOCUMENT_POSITION_FOLLOWING;
/**
* Check whether the caret is horizontally at the edge of the container.
* Returns true if the given selection object is in the forward direction, or
* false otherwise.
*
* @param {Element} container Focusable element.
* @param {boolean} isReverse Set to true to check left, false for right.
* @param {boolean} collapseRanges Whether or not to collapse the selection range before the check.
* @see https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
*
* @param {Selection} selection Selection object to check.
*
* @return {boolean} Whether the selection is forward.
*/
function isSelectionForward(selection) {
var anchorNode = selection.anchorNode,
focusNode = selection.focusNode,
anchorOffset = selection.anchorOffset,
focusOffset = selection.focusOffset;
var position = anchorNode.compareDocumentPosition(focusNode); // Disable reason: `Node#compareDocumentPosition` returns a bitmask value,
// so bitwise operators are intended.
/* eslint-disable no-bitwise */
// Compare whether anchor node precedes focus node. If focus node (where
// end of selection occurs) is after the anchor node, it is forward.
if (position & DOCUMENT_POSITION_PRECEDING) {
return false;
}
if (position & DOCUMENT_POSITION_FOLLOWING) {
return true;
}
/* eslint-enable no-bitwise */
// `compareDocumentPosition` returns 0 when passed the same node, in which
// case compare offsets.
if (position === 0) {
return anchorOffset <= focusOffset;
} // This should never be reached, but return true as default case.
return true;
}
/**
* Check whether the selection is horizontally at the edge of the container.
*
* @param {Element} container Focusable element.
* @param {boolean} isReverse Set to true to check left, false for right.
*
* @return {boolean} True if at the horizontal edge, false if not.
*/
function isHorizontalEdge(container, isReverse) {
var collapseRanges = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
if ((0, _lodash.includes)(['INPUT', 'TEXTAREA'], container.tagName)) {

@@ -75,54 +114,27 @@ if (container.selectionStart !== container.selectionEnd) {

return true;
} // If the container is empty, the caret is always at the edge.
if (_tinymce.default.DOM.isEmpty(container)) {
return true;
}
var selection = window.getSelection();
var range = selection.rangeCount ? selection.getRangeAt(0) : null;
var selection = window.getSelection(); // Create copy of range for setting selection to find effective offset.
if (collapseRanges) {
range = range.cloneRange();
range.collapse(isReverse);
}
var range = selection.getRangeAt(0).cloneRange(); // Collapse in direction of selection.
if (!range || !range.collapsed) {
return false;
if (!selection.isCollapsed) {
range.collapse(!isSelectionForward(selection));
}
var position = isReverse ? 'start' : 'end';
var order = isReverse ? 'first' : 'last';
var offset = range["".concat(position, "Offset")];
var node = range.startContainer;
var endContainer = range.endContainer,
endOffset = range.endOffset;
range.selectNodeContents(container);
range.setEnd(endContainer, endOffset); // Check if the caret position is at the expected start/end position based
// on the value of `isReverse`. If so, consider the horizontal edge to be
// reached.
if (isReverse && offset !== 0) {
return false;
}
var maxOffset = node.nodeType === TEXT_NODE ? node.nodeValue.length : node.childNodes.length;
if (!isReverse && offset !== maxOffset) {
return false;
}
while (node !== container) {
var parentNode = node.parentNode;
if (parentNode["".concat(order, "Child")] !== node) {
return false;
}
node = parentNode;
}
return true;
var caretOffset = range.toString().length;
return caretOffset === (isReverse ? 0 : container.textContent.length);
}
/**
* Check whether the caret is vertically at the edge of the container.
* Check whether the selection is vertically at the edge of the container.
*
* @param {Element} container Focusable element.
* @param {boolean} isReverse Set to true to check top, false for bottom.
* @param {boolean} collapseRanges Whether or not to collapse the selection range before the check.
* @param {Element} container Focusable element.
* @param {boolean} isReverse Set to true to check top, false for bottom.
*

@@ -134,4 +146,2 @@ * @return {boolean} True if at the edge, false if not.

function isVerticalEdge(container, isReverse) {
var collapseRanges = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
if ((0, _lodash.includes)(['INPUT', 'TEXTAREA'], container.tagName)) {

@@ -148,11 +158,3 @@ return isHorizontalEdge(container, isReverse);

if (collapseRanges && range && !range.collapsed) {
var newRange = document.createRange(); // Get the end point of the selection (see focusNode vs. anchorNode)
newRange.setStart(selection.focusNode, selection.focusOffset);
newRange.collapse(true);
range = newRange;
}
if (!range || !range.collapsed) {
if (!range) {
return false;

@@ -196,22 +198,18 @@ }

return range.getBoundingClientRect();
} // If the collapsed range starts (and therefore ends) at an element node,
// `getClientRects` will return undefined. To fix this we can get the
// bounding rectangle of the element node to create a DOMRect based on that.
}
var rect = range.getClientRects()[0]; // If the collapsed range starts (and therefore ends) at an element node,
// `getClientRects` can be empty in some browsers. This can be resolved
// by adding a temporary text node with zero-width space to the range.
//
// See: https://stackoverflow.com/a/6847328/995445
if (range.startContainer.nodeType === ELEMENT_NODE) {
var _range$startContainer = range.startContainer.getBoundingClientRect(),
x = _range$startContainer.x,
y = _range$startContainer.y,
height = _range$startContainer.height; // Create a new DOMRect with zero width.
if (!rect) {
var padNode = document.createTextNode("\u200B");
range.insertNode(padNode);
rect = range.getClientRects()[0];
padNode.parentNode.removeChild(padNode);
}
return new DOMRect(x, y, 0, height);
} // For normal collapsed ranges (exception above), the bounding rectangle of
// the range may be inaccurate in some browsers. There will only be one
// rectangle since it is a collapsed range, so it is safe to pass this as
// the union of them. This works consistently in all browsers.
return (0, _lodash.first)(range.getClientRects());
return rect;
}

@@ -235,3 +233,3 @@ /**

if (!range || !range.collapsed) {
if (!range) {
return;

@@ -272,7 +270,11 @@ }

return;
}
} // Select on extent child of the container, not the container itself. This
// avoids the selection always being `endOffset` of 1 when placed at end,
// where `startContainer`, `endContainer` would always be container itself.
var rangeTarget = container[isReverse ? 'lastChild' : 'firstChild'];
var selection = window.getSelection();
var range = document.createRange();
range.selectNodeContents(container);
range.selectNodeContents(rangeTarget);
range.collapse(!isReverse);

@@ -368,3 +370,3 @@ selection.removeAllRanges();

var editableRect = container.getBoundingClientRect();
var x = rect.left + rect.width / 2;
var x = rect.left;
var y = isReverse ? editableRect.bottom - buffer : editableRect.top + buffer;

@@ -371,0 +373,0 @@ var selection = window.getSelection();

{
"name": "@wordpress/dom",
"version": "1.0.0-alpha.3",
"version": "1.0.0",
"description": "DOM utils module for WordPress",

@@ -30,3 +30,3 @@ "author": "The WordPress Contributors",

},
"gitHead": "8827c049ec802471f51a5cb906d9096ffc1b4e48"
"gitHead": "6ed34d66a85436978721a06d845353e0f3109d04"
}
/**
* External dependencies
*/
import { includes, first } from 'lodash';
import tinymce from 'tinymce';
import { includes } from 'lodash';

@@ -10,15 +9,64 @@ /**

*/
const { getComputedStyle, DOMRect } = window;
const { TEXT_NODE, ELEMENT_NODE } = window.Node;
const { getComputedStyle } = window;
const {
TEXT_NODE,
ELEMENT_NODE,
DOCUMENT_POSITION_PRECEDING,
DOCUMENT_POSITION_FOLLOWING,
} = window.Node;
/**
* Check whether the caret is horizontally at the edge of the container.
* Returns true if the given selection object is in the forward direction, or
* false otherwise.
*
* @param {Element} container Focusable element.
* @param {boolean} isReverse Set to true to check left, false for right.
* @param {boolean} collapseRanges Whether or not to collapse the selection range before the check.
* @see https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
*
* @param {Selection} selection Selection object to check.
*
* @return {boolean} Whether the selection is forward.
*/
function isSelectionForward( selection ) {
const {
anchorNode,
focusNode,
anchorOffset,
focusOffset,
} = selection;
const position = anchorNode.compareDocumentPosition( focusNode );
// Disable reason: `Node#compareDocumentPosition` returns a bitmask value,
// so bitwise operators are intended.
/* eslint-disable no-bitwise */
// Compare whether anchor node precedes focus node. If focus node (where
// end of selection occurs) is after the anchor node, it is forward.
if ( position & DOCUMENT_POSITION_PRECEDING ) {
return false;
}
if ( position & DOCUMENT_POSITION_FOLLOWING ) {
return true;
}
/* eslint-enable no-bitwise */
// `compareDocumentPosition` returns 0 when passed the same node, in which
// case compare offsets.
if ( position === 0 ) {
return anchorOffset <= focusOffset;
}
// This should never be reached, but return true as default case.
return true;
}
/**
* Check whether the selection is horizontally at the edge of the container.
*
* @param {Element} container Focusable element.
* @param {boolean} isReverse Set to true to check left, false for right.
*
* @return {boolean} True if at the horizontal edge, false if not.
*/
export function isHorizontalEdge( container, isReverse, collapseRanges = false ) {
export function isHorizontalEdge( container, isReverse ) {
if ( includes( [ 'INPUT', 'TEXTAREA' ], container.tagName ) ) {

@@ -40,57 +88,32 @@ if ( container.selectionStart !== container.selectionEnd ) {

// If the container is empty, the caret is always at the edge.
if ( tinymce.DOM.isEmpty( container ) ) {
return true;
}
const selection = window.getSelection();
let range = selection.rangeCount ? selection.getRangeAt( 0 ) : null;
if ( collapseRanges ) {
range = range.cloneRange();
range.collapse( isReverse );
}
if ( ! range || ! range.collapsed ) {
return false;
}
// Create copy of range for setting selection to find effective offset.
const range = selection.getRangeAt( 0 ).cloneRange();
const position = isReverse ? 'start' : 'end';
const order = isReverse ? 'first' : 'last';
const offset = range[ `${ position }Offset` ];
let node = range.startContainer;
if ( isReverse && offset !== 0 ) {
return false;
// Collapse in direction of selection.
if ( ! selection.isCollapsed ) {
range.collapse( ! isSelectionForward( selection ) );
}
const maxOffset = node.nodeType === TEXT_NODE ? node.nodeValue.length : node.childNodes.length;
const { endContainer, endOffset } = range;
range.selectNodeContents( container );
range.setEnd( endContainer, endOffset );
if ( ! isReverse && offset !== maxOffset ) {
return false;
}
while ( node !== container ) {
const parentNode = node.parentNode;
if ( parentNode[ `${ order }Child` ] !== node ) {
return false;
}
node = parentNode;
}
return true;
// Check if the caret position is at the expected start/end position based
// on the value of `isReverse`. If so, consider the horizontal edge to be
// reached.
const caretOffset = range.toString().length;
return caretOffset === ( isReverse ? 0 : container.textContent.length );
}
/**
* Check whether the caret is vertically at the edge of the container.
* Check whether the selection is vertically at the edge of the container.
*
* @param {Element} container Focusable element.
* @param {boolean} isReverse Set to true to check top, false for bottom.
* @param {boolean} collapseRanges Whether or not to collapse the selection range before the check.
* @param {Element} container Focusable element.
* @param {boolean} isReverse Set to true to check top, false for bottom.
*
* @return {boolean} True if at the edge, false if not.
*/
export function isVerticalEdge( container, isReverse, collapseRanges = false ) {
export function isVerticalEdge( container, isReverse ) {
if ( includes( [ 'INPUT', 'TEXTAREA' ], container.tagName ) ) {

@@ -105,12 +128,4 @@ return isHorizontalEdge( container, isReverse );

const selection = window.getSelection();
let range = selection.rangeCount ? selection.getRangeAt( 0 ) : null;
if ( collapseRanges && range && ! range.collapsed ) {
const newRange = document.createRange();
// Get the end point of the selection (see focusNode vs. anchorNode)
newRange.setStart( selection.focusNode, selection.focusOffset );
newRange.collapse( true );
range = newRange;
}
if ( ! range || ! range.collapsed ) {
const range = selection.rangeCount ? selection.getRangeAt( 0 ) : null;
if ( ! range ) {
return false;

@@ -156,17 +171,17 @@ }

let rect = range.getClientRects()[ 0 ];
// If the collapsed range starts (and therefore ends) at an element node,
// `getClientRects` will return undefined. To fix this we can get the
// bounding rectangle of the element node to create a DOMRect based on that.
if ( range.startContainer.nodeType === ELEMENT_NODE ) {
const { x, y, height } = range.startContainer.getBoundingClientRect();
// Create a new DOMRect with zero width.
return new DOMRect( x, y, 0, height );
// `getClientRects` can be empty in some browsers. This can be resolved
// by adding a temporary text node with zero-width space to the range.
//
// See: https://stackoverflow.com/a/6847328/995445
if ( ! rect ) {
const padNode = document.createTextNode( '\u200b' );
range.insertNode( padNode );
rect = range.getClientRects()[ 0 ];
padNode.parentNode.removeChild( padNode );
}
// For normal collapsed ranges (exception above), the bounding rectangle of
// the range may be inaccurate in some browsers. There will only be one
// rectangle since it is a collapsed range, so it is safe to pass this as
// the union of them. This works consistently in all browsers.
return first( range.getClientRects() );
return rect;
}

@@ -189,3 +204,3 @@

if ( ! range || ! range.collapsed ) {
if ( ! range ) {
return;

@@ -225,6 +240,11 @@ }

// Select on extent child of the container, not the container itself. This
// avoids the selection always being `endOffset` of 1 when placed at end,
// where `startContainer`, `endContainer` would always be container itself.
const rangeTarget = container[ isReverse ? 'lastChild' : 'firstChild' ];
const selection = window.getSelection();
const range = document.createRange();
range.selectNodeContents( container );
range.selectNodeContents( rangeTarget );
range.collapse( ! isReverse );

@@ -323,3 +343,3 @@

const editableRect = container.getBoundingClientRect();
const x = rect.left + ( rect.width / 2 );
const x = rect.left;
const y = isReverse ? ( editableRect.bottom - buffer ) : ( editableRect.top + buffer );

@@ -326,0 +346,0 @@ const selection = window.getSelection();

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc