Move the selection from the directive to the component
This commit is contained in:
parent
4da376d5d6
commit
6f1b0dfefd
|
|
@ -3,7 +3,6 @@
|
||||||
:class="{ 'hideable-element--greyed-out': isHidden }"
|
:class="{ 'hideable-element--greyed-out': isHidden }"
|
||||||
class="content-block__container hideable-element content-list__parent"
|
class="content-block__container hideable-element content-list__parent"
|
||||||
ref="wrapper"
|
ref="wrapper"
|
||||||
v-highlight
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
:class="specialClass"
|
:class="specialClass"
|
||||||
|
|
@ -99,7 +98,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineAsyncComponent, inject, onMounted, ref, computed } from 'vue';
|
import { defineAsyncComponent, inject, onMounted, ref, computed, onUnmounted } from 'vue';
|
||||||
|
|
||||||
import { useMutation } from '@vue/apollo-composable';
|
import { useMutation } from '@vue/apollo-composable';
|
||||||
import AddContentButton from '@/components/AddContentButton.vue';
|
import AddContentButton from '@/components/AddContentButton.vue';
|
||||||
import MoreOptionsWidget from '@/components/MoreOptionsWidget.vue';
|
import MoreOptionsWidget from '@/components/MoreOptionsWidget.vue';
|
||||||
|
|
@ -120,9 +120,13 @@ import CHAPTER_QUERY from '@/graphql/gql/queries/chapterQuery.gql';
|
||||||
import DELETE_CONTENT_BLOCK_MUTATION from '@/graphql/gql/mutations/deleteContentBlock.gql';
|
import DELETE_CONTENT_BLOCK_MUTATION from '@/graphql/gql/mutations/deleteContentBlock.gql';
|
||||||
|
|
||||||
import type { ExtendedContentBlockNode } from '@/@types';
|
import type { ExtendedContentBlockNode } from '@/@types';
|
||||||
|
|
||||||
import type { Modal } from '@/plugins/modal.types';
|
import type { Modal } from '@/plugins/modal.types';
|
||||||
|
|
||||||
import { PAGE_LOAD_TIMEOUT } from '@/consts/navigation.consts';
|
import { PAGE_LOAD_TIMEOUT } from '@/consts/navigation.consts';
|
||||||
|
|
||||||
|
import { getSelectionHandler } from '@/directives/highlight';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
contentBlock: ExtendedContentBlockNode;
|
contentBlock: ExtendedContentBlockNode;
|
||||||
parent?: any;
|
parent?: any;
|
||||||
|
|
@ -227,6 +231,18 @@ onMounted(() => {
|
||||||
window.scrollTo({ top: rect.y, behavior: 'smooth' });
|
window.scrollTo({ top: rect.y, behavior: 'smooth' });
|
||||||
}, PAGE_LOAD_TIMEOUT);
|
}, PAGE_LOAD_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add the listener from highlights
|
||||||
|
element.addEventListener('mouseup', getSelectionHandler(element, props.contentBlock));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
const element = wrapper.value;
|
||||||
|
|
||||||
|
if (element !== null) {
|
||||||
|
console.log('unmounting');
|
||||||
|
element.removeEventListener('mouseup', getSelectionHandler);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,11 @@ import ContentBlock from '@/components/ContentBlock.vue';
|
||||||
|
|
||||||
interface Highlight {
|
interface Highlight {
|
||||||
contentBlock: string; // the id
|
contentBlock: string; // the id
|
||||||
contentIndex: number;
|
contentIndex: number; // which content of the .contents array do I come from?
|
||||||
paragraphIndex: number;
|
paragraphIndex: number; // which paragraph inside the textBlock do I come from?
|
||||||
startPosition: number;
|
startPosition: number; // start of the selection
|
||||||
selectionLength: number;
|
selectionLength: number; // length of the selection
|
||||||
text: string;
|
text: string; // text that was actually selected
|
||||||
}
|
}
|
||||||
|
|
||||||
const TOP_TRESHOLD = 0;
|
const TOP_TRESHOLD = 0;
|
||||||
|
|
@ -84,7 +84,7 @@ const findPositionInParent = (element: HTMLElement, className: string = 'content
|
||||||
return children.indexOf(element);
|
return children.indexOf(element);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSelectionHandler = (el: HTMLElement, contentBlock: ContentBlockNode) => (_e: Event) => {
|
export const getSelectionHandler = (el: HTMLElement, contentBlock: ContentBlockNode) => (_e: Event) => {
|
||||||
const rect = el.getBoundingClientRect();
|
const rect = el.getBoundingClientRect();
|
||||||
if (isInsideViewport(rect.top) || isInsideViewport(rect.bottom)) {
|
if (isInsideViewport(rect.top) || isInsideViewport(rect.bottom)) {
|
||||||
// the listener only does something if the `el` is visible in the viewport, to save resources
|
// the listener only does something if the `el` is visible in the viewport, to save resources
|
||||||
|
|
@ -103,13 +103,13 @@ const getSelectionHandler = (el: HTMLElement, contentBlock: ContentBlockNode) =>
|
||||||
if (paragraph === endAncestor) {
|
if (paragraph === endAncestor) {
|
||||||
// todo: rename this variable, `parent` is not correct anymore
|
// todo: rename this variable, `parent` is not correct anymore
|
||||||
const contentComponent = findClosestAncestorWithClass(startContainer, 'content-component');
|
const contentComponent = findClosestAncestorWithClass(startContainer, 'content-component');
|
||||||
if (parent) {
|
if (contentComponent) {
|
||||||
// our selection is wholly inside the container node, we continue with it
|
// our selection is wholly inside the container node, we continue with it
|
||||||
const position = findPositionInParent(contentComponent);
|
const position = findPositionInParent(contentComponent);
|
||||||
const siblings = Array.from(paragraph.parentElement.children);
|
const siblings = Array.from(paragraph.parentElement.children);
|
||||||
const positionInTextBlock = siblings.indexOf(paragraph);
|
const positionInTextBlock = siblings.indexOf(paragraph);
|
||||||
|
|
||||||
const numOfParagraphs = Array.from(parent.children[1].children).filter(
|
const numOfParagraphs = Array.from(contentComponent.children[1].children).filter(
|
||||||
(child) => child.nodeName.toLowerCase() === 'p'
|
(child) => child.nodeName.toLowerCase() === 'p'
|
||||||
).length;
|
).length;
|
||||||
|
|
||||||
|
|
@ -126,6 +126,9 @@ const getSelectionHandler = (el: HTMLElement, contentBlock: ContentBlockNode) =>
|
||||||
contentBlock: contentBlock.id,
|
contentBlock: contentBlock.id,
|
||||||
contentIndex: position,
|
contentIndex: position,
|
||||||
startPosition: start,
|
startPosition: start,
|
||||||
|
paragraphIndex: positionInTextBlock,
|
||||||
|
selectionLength: end - start,
|
||||||
|
text: range.toString(),
|
||||||
};
|
};
|
||||||
console.log(highlightedText);
|
console.log(highlightedText);
|
||||||
// todo: how do we save this? maybe we need to move away from the directive and do this inside the mounted
|
// todo: how do we save this? maybe we need to move away from the directive and do this inside the mounted
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue