mirror of
				https://github.com/BookStackApp/BookStack.git
				synced 2025-10-31 03:50:27 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			72 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			72 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import {EditorContainerUiElement, EditorUiElement} from "./core";
 | |
| 
 | |
| import {el} from "../../utils/dom";
 | |
| 
 | |
| export type EditorContextToolbarDefinition = {
 | |
|     selector: string;
 | |
|     content: EditorUiElement[],
 | |
|     displayTargetLocator?: (originalTarget: HTMLElement) => HTMLElement;
 | |
| };
 | |
| 
 | |
| export class EditorContextToolbar extends EditorContainerUiElement {
 | |
| 
 | |
|     protected target: HTMLElement;
 | |
| 
 | |
|     constructor(target: HTMLElement, children: EditorUiElement[]) {
 | |
|         super(children);
 | |
|         this.target = target;
 | |
|     }
 | |
| 
 | |
|     protected buildDOM(): HTMLElement {
 | |
|         return el('div', {
 | |
|             class: 'editor-context-toolbar',
 | |
|         }, this.getChildren().map(child => child.getDOMElement()));
 | |
|     }
 | |
| 
 | |
|     updatePosition() {
 | |
|         const editorBounds = this.getContext().scrollDOM.getBoundingClientRect();
 | |
|         const targetBounds = this.target.getBoundingClientRect();
 | |
|         const dom = this.getDOMElement();
 | |
|         const domBounds = dom.getBoundingClientRect();
 | |
| 
 | |
|         const showing = targetBounds.bottom > editorBounds.top
 | |
|             && targetBounds.top < editorBounds.bottom;
 | |
| 
 | |
|         dom.hidden = !showing;
 | |
| 
 | |
|         if (!showing) {
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         const showAbove: boolean = targetBounds.bottom + 6 + domBounds.height > editorBounds.bottom;
 | |
|         dom.classList.toggle('is-above', showAbove);
 | |
| 
 | |
|         const targetMid = targetBounds.left + (targetBounds.width / 2);
 | |
|         const targetLeft = targetMid - (domBounds.width / 2);
 | |
|         if (showAbove) {
 | |
|             dom.style.top = (targetBounds.top - 6 - domBounds.height) + 'px';
 | |
|         } else {
 | |
|             dom.style.top = (targetBounds.bottom + 6) + 'px';
 | |
|         }
 | |
|         dom.style.left = targetLeft + 'px';
 | |
|     }
 | |
| 
 | |
|     insert(children: EditorUiElement[]) {
 | |
|         this.addChildren(...children);
 | |
|         const dom = this.getDOMElement();
 | |
|         dom.append(...children.map(child => child.getDOMElement()));
 | |
|     }
 | |
| 
 | |
|     protected empty() {
 | |
|         const children = this.getChildren();
 | |
|         for (const child of children) {
 | |
|             child.getDOMElement().remove();
 | |
|         }
 | |
|         this.removeChildren(...children);
 | |
|     }
 | |
| 
 | |
|     destroy() {
 | |
|         this.empty();
 | |
|         this.getDOMElement().remove();
 | |
|     }
 | |
| } |