| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- /**
- * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
- /**
- * @module image/image/utils
- */
- import { findOptimalInsertionPosition, isWidget, toWidget } from '@ckeditor/ckeditor5-widget/src/utils';
- const imageSymbol = Symbol( 'isImage' );
- /**
- * Converts a given {@link module:engine/view/element~Element} to an image widget:
- * * Adds a {@link module:engine/view/element~Element#_setCustomProperty custom property} allowing to recognize the image widget element.
- * * Calls the {@link module:widget/utils~toWidget} function with the proper element's label creator.
- *
- * @param {module:engine/view/element~Element} viewElement
- * @param {module:engine/view/downcastwriter~DowncastWriter} writer An instance of the view writer.
- * @param {String} label The element's label. It will be concatenated with the image `alt` attribute if one is present.
- * @returns {module:engine/view/element~Element}
- */
- export function toImageWidget( viewElement, writer, label ) {
- writer.setCustomProperty( imageSymbol, true, viewElement );
- return toWidget( viewElement, writer, { label: labelCreator } );
- function labelCreator() {
- const imgElement = viewElement.getChild( 0 );
- const altText = imgElement.getAttribute( 'alt' );
- return altText ? `${ altText } ${ label }` : label;
- }
- }
- /**
- * Checks if a given view element is an image widget.
- *
- * @param {module:engine/view/element~Element} viewElement
- * @returns {Boolean}
- */
- export function isImageWidget( viewElement ) {
- return !!viewElement.getCustomProperty( imageSymbol ) && isWidget( viewElement );
- }
- /**
- * Checks if an image widget is the only selected element.
- *
- * @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} selection
- * @returns {Boolean}
- */
- export function isImageWidgetSelected( selection ) {
- const viewElement = selection.getSelectedElement();
- return !!( viewElement && isImageWidget( viewElement ) );
- }
- /**
- * Checks if the provided model element is an `image`.
- *
- * @param {module:engine/model/element~Element} modelElement
- * @returns {Boolean}
- */
- export function isImage( modelElement ) {
- return !!modelElement && modelElement.is( 'image' );
- }
- /**
- * Handles inserting single file. This method unifies image insertion using {@link module:widget/utils~findOptimalInsertionPosition} method.
- *
- * model.change( writer => {
- * insertImage( writer, model, { src: 'path/to/image.jpg' } );
- * } );
- *
- * @param {module:engine/model/writer~Writer} writer
- * @param {module:engine/model/model~Model} model
- * @param {Object} [attributes={}] Attributes of inserted image
- */
- export function insertImage( writer, model, attributes = {} ) {
- const imageElement = writer.createElement( 'image', attributes );
- const insertAtSelection = findOptimalInsertionPosition( model.document.selection, model );
- model.insertContent( imageElement, insertAtSelection );
- // Inserting an image might've failed due to schema regulations.
- if ( imageElement.parent ) {
- writer.setSelection( imageElement, 'on' );
- }
- }
- /**
- * Checks if image can be inserted at current model selection.
- *
- * @param {module:engine/model/model~Model} model
- * @returns {Boolean}
- */
- export function isImageAllowed( model ) {
- const schema = model.schema;
- const selection = model.document.selection;
- return isImageAllowedInParent( selection, schema, model ) &&
- !checkSelectionOnObject( selection, schema ) &&
- isInOtherImage( selection );
- }
- // Checks if image is allowed by schema in optimal insertion parent.
- //
- // @returns {Boolean}
- function isImageAllowedInParent( selection, schema, model ) {
- const parent = getInsertImageParent( selection, model );
- return schema.checkChild( parent, 'image' );
- }
- // Check if selection is on object.
- //
- // @returns {Boolean}
- function checkSelectionOnObject( selection, schema ) {
- const selectedElement = selection.getSelectedElement();
- return selectedElement && schema.isObject( selectedElement );
- }
- // Checks if selection is placed in other image (ie. in caption).
- function isInOtherImage( selection ) {
- return [ ...selection.focus.getAncestors() ].every( ancestor => !ancestor.is( 'image' ) );
- }
- // Returns a node that will be used to insert image with `model.insertContent` to check if image can be placed there.
- function getInsertImageParent( selection, model ) {
- const insertAt = findOptimalInsertionPosition( selection, model );
- const parent = insertAt.parent;
- if ( parent.isEmpty && !parent.is( '$root' ) ) {
- return parent.parent;
- }
- return parent;
- }
|