Skip to content

Commit

Permalink
Merge pull request #91 from DLXPlugins/feature/mobile-selection-safari
Browse files Browse the repository at this point in the history
Fix mobile rendering on Safari and Add WP Fonts to Block
  • Loading branch information
ronalfy authored Apr 14, 2024
2 parents ed53f69 + 3bc972a commit 87a0028
Show file tree
Hide file tree
Showing 10 changed files with 178 additions and 23 deletions.
2 changes: 1 addition & 1 deletion build/has-click-to-share.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('react', 'wp-a11y', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n'), 'version' => '218cc8ffaf44f794c30a');
<?php return array('dependencies' => array('react', 'wp-a11y', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n'), 'version' => '3e1eb88b9d5efb8f9137');
4 changes: 2 additions & 2 deletions build/has-click-to-share.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/has-click-to-share.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/highlight-and-share.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions highlight-and-share.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Plugin URI: https://dlxplugins.com/plugins/highlight-and-share/
* Description: Select text, inline highlight, or use a Click to Share block and show social networks.
* Author: DLX Plugins
* Version: 4.6.0
* Version: 4.7.0
* Requires at least: 5.1
* Requires PHP: 7.2
* Author URI: https://dlxplugins.com/plugins/highlight-and-share/
Expand All @@ -17,7 +17,7 @@

namespace DLXPlugins\HAS;

define( 'HIGHLIGHT_AND_SHARE_VERSION', '4.6.0' );
define( 'HIGHLIGHT_AND_SHARE_VERSION', '4.7.0' );
define( 'HIGHLIGHT_AND_SHARE_FILE', __FILE__ );

// Support for site-level autoloading.
Expand Down
11 changes: 8 additions & 3 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Contributors: ronalfy
Tags: highlight, social media, click share, select text, highlight text
Requires at least: 5.1
Tested up to: 6.4
Stable tag: 4.6.0
Stable tag: 4.7.0
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Donate link: https://github.com/sponsors/DLXPlugins
Expand Down Expand Up @@ -112,6 +112,11 @@ So far, the latest versions of Chrome, Firefox, Safari, Edge, and IE9+.

== Changelog ==

= 4.7.0 =
* Released 2024-04-13
* Huge bug fix: Highlight and Share now works great on mobile browsers including Safari.
* Re-worked selection JS to integrate <a href="https://github.com/MaxArt2501/share-this">Share This</a> script.

= 4.6.0 =
* Released 2023-12-10
* Added Mastodon social network.
Expand Down Expand Up @@ -498,5 +503,5 @@ So far, the latest versions of Chrome, Firefox, Safari, Edge, and IE9+.

== Upgrade Notice ==

= 4.6.0 =
Added Mastodon social network. Fixed popup in the Support tab for demo video. Fixed deprecation notices.
= 4.7.0 =
Text selection works great on mobile browsers now.
35 changes: 35 additions & 0 deletions src/frontendjs/dom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
export function getOffsetScroll(_window) {
const body = _window.document.body;
const scrollReference = _window.getComputedStyle(body).position === "static" ? body.parentNode : body;
return scrollReference.getBoundingClientRect();
}

let matchFunc;
export function matches(element, selector) {
if (!matchFunc) matchFunc = getMatchFunctionName(element);
return element[matchFunc](selector);
}

export function closest(element, selector) {
let target = element;
while (target && (target.nodeType !== 1 /* === Node.ELEMENT_NODE */ || !matches(target, selector))) {
target = target.parentNode;
}

return target;
}

// `contains` in IE doesn't work with text nodes
export function contains(ancestor, target) {
const comparedPositions = ancestor.compareDocumentPosition(target);
// eslint-disable-next-line no-bitwise
return !comparedPositions || (comparedPositions & 16 /* === Node.DOCUMENT_POSITION_CONTAINED_BY */) > 0;
}

// eslint-disable-next-line consistent-return
function getMatchFunctionName(element) {
const suffix = "atchesSelector";
for (const name of [ "matches", `m${suffix}`, `webkitM${suffix}`, `mozM${suffix}`, `msM${suffix}`, `oM${suffix}` ]) {
if (element[name]) return name;
}
}
50 changes: 38 additions & 12 deletions src/frontendjs/highlight-and-share.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { constrainRange } from './selection';
( function() {
'use strict';

Expand Down Expand Up @@ -200,7 +201,7 @@
switch ( type ) {
case 'selection':
// Position the interface.
setHasContainerPositionSelection( hasClone );
setHasContainerPositionSelection( hasClone, triggerElement );
break;
case 'inline':
// Position the interface.
Expand Down Expand Up @@ -336,8 +337,8 @@
el.addEventListener( 'click', ( event ) => {
event.preventDefault();
const url = event.target.closest( 'a' ).getAttribute( 'href' );
//

//
if ( 'undefined' !== typeof Fancybox ) {
// eslint-disable-next-line no-undef
hasRemoveVisibleElements();
Expand Down Expand Up @@ -428,18 +429,16 @@
/**
* Set the Social Sharer container position for the current selection. This needs to run after cloned element has been appended to the dom.
*
* @param {element} element The cloned social sharer element.
* @param {element} element The cloned social sharer element.
* @param {element} triggerElement The event initiator (null if no trigger element).
*/
const setHasContainerPositionSelection = ( element ) => {
const setHasContainerPositionSelection = ( element, triggerElement ) => {
// Get the dimensions of the window.
const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;

// Get the dimensions and location of the selection.
const selectionRect = window
.getSelection()
.getRangeAt( 0 )
.getBoundingClientRect();
const selectionRect = getConstrainedRange( triggerElement ).getBoundingClientRect();
const selectionTop = selectionRect.top; // top position relative to view port.
const selectionLeft = selectionRect.left; // left position relative to view port.
const selectionWidth = selectionRect.width;
Expand Down Expand Up @@ -650,6 +649,30 @@
}
};

/**
* Get the constrained range.
*
* @param {Element} element The element to constrain the range to.
* @return {Range} The constrained range.
* @see https://github.com/MaxArt2501/share-this/tree/master
*/
const getConstrainedRange = ( element ) => {
const _window = document.defaultView;
const selection = _window.getSelection();
const range = selection.rangeCount && selection.getRangeAt( 0 );
if ( ! range ) {
return;
}

const constrainedRange = constrainRange( range, element );
if ( constrainedRange.collapsed || ! constrainedRange.getClientRects().length ) {
return;
}

// eslint-disable-next-line consistent-return
return constrainedRange;
};

/**
* Set the Social Sharer container position for the inline highlighter. This needs to run after cloned element has been appended to the dom.
*
Expand Down Expand Up @@ -824,7 +847,7 @@

const element = parentElement.querySelector( '.has-social-placeholder' );

// Get the highlight and share params.
// Get the highlight and share params.
const { href, title, hashtags } = getPageParams( element );

// Display Highlight and Share.
Expand All @@ -838,8 +861,11 @@

// Check if element has class `has-content-area` and if so, it's flush with the content. Select its parent, and add the event to that.
if ( element.classList.contains( 'has-content-area' ) && ! isLegacyContentMode ) {
element.parentElement.addEventListener( 'mouseup', ( event ) => {
hasHandleSelectEvents( event, element.parentElement );
const eventTypes = [ 'selectionchange', 'mouseup', 'touchend', 'touchcancel' ];
eventTypes.forEach( ( eventType ) => {
element.parentElement.addEventListener( eventType, ( event ) => {
hasHandleSelectEvents( event, element.parentElement );
} );
} );
return;
}
Expand Down
76 changes: 76 additions & 0 deletions src/frontendjs/selection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { closest, contains } from './dom.js';

export function isSelectionForward( selection ) {
if ( selection.isCollapsed ) {
return true;
}

const comparedPositions = selection.anchorNode.compareDocumentPosition( selection.focusNode );
if ( ! comparedPositions ) {
// It's the same node
return selection.anchorOffset < selection.focusOffset;
}

// eslint-disable-next-line no-bitwise
return ( comparedPositions & 4 /* === Node.DOCUMENT_POSITION_FOLLOWING */ ) > 0;
}

export function getEndLineRect( range, isForward ) {
let endLineRects;
const rangeRects = range.getClientRects();
const sliceRects = [].slice.bind( rangeRects );

if ( isForward ) {
let lastLeft = Infinity;
let i = rangeRects.length;
while ( i-- ) {
const rect = rangeRects[ i ];
if ( rect.left > lastLeft ) {
break;
}
lastLeft = rect.left;
}
endLineRects = sliceRects( i + 1 );
} else {
let lastRight = -Infinity;
let i = 0;
for ( ; i < rangeRects.length; i++ ) {
const rect = rangeRects[ i ];
if ( rect.right < lastRight ) {
break;
}
lastRight = rect.right;
}
endLineRects = sliceRects( 0, i );
}

return {
top: Math.min( ...endLineRects.map( ( rect ) => rect.top ) ),
bottom: Math.max( ...endLineRects.map( ( rect ) => rect.bottom ) ),
left: endLineRects[ 0 ].left,
right: endLineRects[ endLineRects.length - 1 ].right,
};
}

export function constrainRange( range, selector ) {
const constrainedRange = range.cloneRange();
if ( range.collapsed || ! selector ) {
return constrainedRange;
}

let ancestor = closest( range.startContainer, selector );
if ( ancestor ) {
if ( ! contains( ancestor, range.endContainer ) ) {
constrainedRange.setEnd( ancestor, ancestor.childNodes.length );
}
} else {
ancestor = closest( range.endContainer, selector );
if ( ancestor ) {
constrainedRange.setStart( ancestor, 0 );
} else {
constrainedRange.collapse();
}
}

return constrainedRange;
}
15 changes: 14 additions & 1 deletion src/react/Components/Typography/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useState, useEffect } from 'react';
import fontFamilies from '../../../fonts/fonts';
import { __ } from '@wordpress/i18n';
import { useSettings } from '@wordpress/block-editor';
import { ButtonGroup, Button, Tooltip, SelectControl, BaseControl, TextControl, Popover } from '@wordpress/components';
import { useForm, Controller, useWatch } from 'react-hook-form';
import { geHierarchicalPlaceholderValue } from '../../Utils/TypographyHelper';
Expand Down Expand Up @@ -73,6 +74,8 @@ const Typography = ( props ) => {
defaultValues: getDefaultValues(),
} );

const [ blockLevelFontFamilies ] = useSettings( 'typography.fontFamilies' );

const formValues = useWatch( { control } );

const { label } = props;
Expand Down Expand Up @@ -105,8 +108,18 @@ const Typography = ( props ) => {
const mergedFamilies = [];
families.forEach( ( fontFamily ) => {
fonts.push( { label: fontFamily.name, value: fontFamily.slug } );
mergedFamilies.push( { family: fontFamily.family, slug: fontFamily.slug, fallback: fontFamily.fallback, type: fontFamily.type } );
mergedFamilies.push( { family: fontFamily.family, slug: fontFamily.slug, fallback: fontFamily.fallback, type: fontFamily.type } );
} );
if ( blockLevelFontFamilies ) {
const { theme } = blockLevelFontFamilies;

if ( theme ) {
theme.forEach( ( fontFamily ) => {
fonts.push( { label: fontFamily.name, value: fontFamily.slug } );
mergedFamilies.push( { family: fontFamily.name, slug: fontFamily.slug, fallback: fontFamily.fallback, type: 'web' } );
} );
}
}
// Push adobe fonts to the front.
adobeFonts.forEach( ( font ) => {
fonts.unshift( { label: font.name, value: font.slug } );
Expand Down

0 comments on commit 87a0028

Please sign in to comment.