Skip to content

Commit

Permalink
Jetpack Boost: Image Guide compatibility improvements (#28026)
Browse files Browse the repository at this point in the history
* Use a fixed position for the guide

* Increase padding

* Add a Portal component that teleports slot to body

* Portal the pop-up to body to fix z-index issues

* FIxed a compatibility bug with Jetpack Mosaic gallery

Wrapping caused the object-fit to break, this seems to be a more lightweight approach.

* A hacky compatibility fix across plugins

* Simplify keeping the Pop-up open using a class

* Rename classes

* Don't overlay other interactive elements as much as possible

By taking up as little space as possible.

* Be a little more clear on what's going on, WIP

* changelog

* Undo inexplicable change from merge

* Update info block position in tooltip

* Fix image guide inside links

* Refactor getClosestContainingAncestor to not use arrays to keep track of current element

* Refactor getClosestContainingAncestor to improve code readability

* Disable image guide in iframes

This is done to ensure editors using iframes don't initialize
the image guide in the WP-Admin.

* Lints

* Revert regex update that happened during trunk merge

Co-authored-by: Mark George <thingalon@gmail.com>
Co-authored-by: Peter Petrov <peter.petrov89@gmail.com>
  • Loading branch information
3 people authored Jan 13, 2023
1 parent b4a4e80 commit d1c8d7f
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 129 deletions.
2 changes: 1 addition & 1 deletion docs/testing/regression-checklist/mapping.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"testFile": [ "extensions/blocks/checklist.md" ]
},
{
"regex": "^projects\/plugins\/jetpack\/extensions\/(blocks\/(subscriptions|premium-content)\/|shared\/memberships\.js)",
"regex": "^projects/plugins/jetpack/extensions/(blocks/(subscriptions|premium-content)/|shared/memberships.js)",
"testFile": [ "extensions/blocks/subscriptions.md" ]
}
]
10 changes: 6 additions & 4 deletions projects/plugins/boost/app/features/image-guide/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ function initialize() {
* we don't need the guides sooner because
* images have likely not loaded yet.
*/
window.addEventListener( 'load', () => {
initialize();
window.addEventListener( 'resize', debounceDimensionUpdates() );
} );
if ( ! window.frameElement ) {
window.addEventListener( 'load', () => {
initialize();
window.addEventListener( 'resize', debounceDimensionUpdates() );
} );
}
36 changes: 16 additions & 20 deletions projects/plugins/boost/app/features/image-guide/src/initialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,35 @@ import type { MeasurableImage } from '@automattic/jetpack-image-guide';
function getClosestContainingAncestor( node: HTMLElement ): HTMLElement | null {
let current: HTMLElement | null = node.parentElement;

// Keep track of ancestor elements that do not have a "z-index" set
let elementsWithoutZIndex: HTMLElement[] = [];

// Keep track of target element
let target: HTMLElement;
while ( current && current instanceof HTMLElement ) {
// Don't go past the body element
if ( current === document.body ) {
break;
}

const style = getComputedStyle( current );

// Guide can't be correctly positioned inside inline elements
// because they don't have dimensions.
const canContainBlockElements = style.display !== 'inline';
const isStatic = style.position === 'static';
const isRelative = style.position === 'relative';
const hasZIndex = style.zIndex !== 'auto';
const isRelativeWithZIndex = isRelative && hasZIndex;

if (
style.zIndex === 'auto' &&
( style.position === 'static' || style.position === 'relative' )
canContainBlockElements &&
( ( ! target && ( isStatic || isRelative ) ) || isRelativeWithZIndex )
) {
elementsWithoutZIndex.push( current );
} else {
elementsWithoutZIndex = [];
target = current;
}

// Move on to the next parent element
current = current.parentElement;
}

// Return the first ancestor element that isn't affected by z-index
if ( elementsWithoutZIndex.length > 0 ) {
return elementsWithoutZIndex[ 0 ];
}

// If no element was found, return the body element
return document.body;
return target;
}

/**
Expand Down Expand Up @@ -98,10 +97,7 @@ function findContainer( image: MeasurableImage ): HTMLElement | undefined {
wrapper.classList.add( 'jetpack-boost-guide' );
wrapper.dataset.jetpackBoostGuideId = ( ++wrapperID ).toString();
if ( parentStyle.position === 'static' ) {
wrapper.classList.add( 'relative' );
Array.from( ancestor.children )
.reverse()
.forEach( child => wrapper.appendChild( child ) );
ancestor.style.position = 'relative';
}

ancestor.prepend( wrapper );
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import { backOut } from 'svelte/easing';
import { fade, fly } from 'svelte/transition';
import Spinner from './Spinner.svelte';
Expand All @@ -19,9 +20,27 @@
y: 2,
easing: backOut,
};
let bubble: HTMLElement;
const dispatch = createEventDispatcher();
function onHover() {
const rect = bubble.getBoundingClientRect();
dispatch( 'hover', {
index,
position: {
top: rect.top + rect.height + 10,
left: rect.left,
},
} );
}
</script>

<div class="interaction-area {severity}" on:mouseenter transition:fly={scaleTransition}>
<div
class="interaction-area {severity}"
bind:this={bubble}
on:mouseenter={onHover}
transition:fly={scaleTransition}
>
<div class="bubble">
{#if false === $isLoading}
<div class="bubble-inner">
Expand Down
38 changes: 30 additions & 8 deletions projects/plugins/boost/app/features/image-guide/src/ui/Main.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,16 @@
stores.forEach( store => store.updateDimensions() );
} );
function onMouseLeave() {
function closeDetails( e ) {
// Don't exit when hovering the Portal
if (
e.relatedTarget &&
// Don't exit when hovering the Popup
e.relatedTarget.classList.contains( 'keep-guide-open' )
) {
return;
}
if ( $guideState !== 'always_on' ) {
show = false;
}
Expand Down Expand Up @@ -46,21 +55,37 @@
$: show = $guideState === 'always_on' ? 0 : false;
$: toggleBackdrop( show !== false );
let position = {
top: 0,
left: 0,
};
function hover( e: CustomEvent ) {
const detail = e.detail;
const index = detail.index;
position = detail.position;
show = index;
}
</script>

{#if $guideState === 'active' || $guideState === 'always_on'}
<div class="guide {size}" class:show={show !== false} on:mouseleave={onMouseLeave}>
<div
class="guide {size}"
class:show={show !== false}
class:keep-guide-open={show !== false}
on:mouseleave={closeDetails}
>
<div class="previews">
{#each stores as store, index}
<Bubble {index} {store} on:mouseenter={() => ( show = index )} />
<Bubble {index} {store} on:hover={hover} />
{/each}
</div>
{#if show !== false}
<!--
Intentionally using only a single component here.
See <Popup> component source for details.
-->
<Popup store={stores[ show ]} {size} />
<Popup store={stores[ show ]} {size} {position} on:mouseleave={closeDetails} />
{/if}
</div>
{/if}
Expand All @@ -84,14 +109,11 @@
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 8000;
line-height: 1.55;
padding: 15px;
padding: 20px;
&.small {
font-size: 13px;
padding: 15px;
}
&.micro {
Expand Down
Loading

0 comments on commit d1c8d7f

Please sign in to comment.