/** * Silex, live web creation * http://projects.silexlabs.org/?/silex/ * * Copyright (c) 2012 Silex Labs * http://www.silexlabs.org/ * * Silex is available under the GPL license * http://www.silexlabs.org/silex/silex-licensing/ */ /** * @fileoverview * This class represents a the body of the opened file, * which is rendered by the Stage class * It has methods to manipulate the dom */ import {View} from '../types'; import {Model} from '../types'; /** * @param model model class which holds the other models * @param view view class which holds the other views */ export class Body { /** * input element to get the focus * used to blur the UI inputs * @static */ static focusInput: HTMLElement; /** * remove the focus from text fields * TODO: make this a method of body (problem is: ModalDialog needs it but is static) * @static */ static resetFocus() { // setTimeout because we might need to wait for a click to finish bubbling // e.g. when edit text, the UI layer is hidden, click on the stage => focus on the stage iframe setTimeout(() => { Body.focusInput.focus(); Body.focusInput.blur(); document.getSelection().removeAllRanges(); }, 0); } constructor(private model: Model, private view: View) { // hide the focus input and attach it to the DOM Body.focusInput.style.left = '-1000px'; Body.focusInput.style.position = 'absolute'; document.body.appendChild(Body.focusInput); } /** * @return body element */ getBodyElement(): HTMLElement { return this.model.file.getContentDocument().body; } /** * @return array of elements which are currently selected */ getSelection(): HTMLElement[] { const elements = this.view.stageWrapper.getSelection().map((s) => s.el); if (!elements || elements.length === 0) { // default, return the body const bodyElement = this.getBodyElement(); if (!bodyElement) { console.warn( 'Could not get body element because it is not created yet.'); return []; } return [bodyElement]; } // build the result array const res = []; elements.forEach((element) => { res.push(element); }); return res; } emptySelection() { this.setSelection([]); } /** * @param selectedElements array of elements which are to select */ setSelection(selectedElements: HTMLElement[]) { if (selectedElements.length === 0) { selectedElements = [this.getBodyElement()]; } const selection = this.view.stageWrapper.getSelection().map((s) => s.el); // only if selection changed if (selection.filter((el) => !selectedElements.find((s) => s === el)).length !== 0 || selectedElements.filter((el) => !selection.find((s) => s === el)).length !== 0) { this.view.stageWrapper.setSelection(selectedElements); } this.refreshViews(selectedElements); } refreshViews(selectedElements = this.getSelection()) { // refresh views const pages = this.model.page.getPages(); const page = this.model.page.getCurrentPage(); this.view.pageTool.redraw(selectedElements, pages, page); this.view.propertyTool.redraw(this.view.stageWrapper.getSelection(), pages, page); this.view.textFormatBar.redraw(selectedElements, pages, page); this.view.contextMenu.redraw(selectedElements, pages, page); this.view.breadCrumbs.redraw(selectedElements, pages, page); this.view.htmlEditor.setSelection(selectedElements); } removeWysihtmlMarkup(root: HTMLElement|Document) { Array.from(root.querySelectorAll('.wysihtml-editor')).forEach((el) => { el.classList.remove('wysihtml-sandbox', 'wysihtml-editor'); el.removeAttribute('contenteditable'); }); } } Body.focusInput = document.createElement('input');