From 3a628945ade35f3ba351ba90e271608520753174 Mon Sep 17 00:00:00 2001
From: Star Rauchenberger │
- // │ │ │ ',
- templateBlock = new CKEDITOR.template(
- '
│
- // │ │
│ │
- // │ │
│
- // │ │
│ │
- // │ │
│
- // │ │
│
│ - // │ │
│ │
- // │ │
│
remains for styling purposes. - // - // 3.
.
- if ( !( el.name in { div: 1, p: 1 } ) )
- return false;
-
- var children = el.children;
-
- // Centering wrapper can have only one child.
- if ( children.length !== 1 )
- return false;
-
- var child = children[ 0 ];
-
- // Only , only centering wrapper.
- div: {
- match: centerWrapperChecker( editor )
- },
- p: {
- match: centerWrapperChecker( editor )
- },
- img: {
- attributes: '!src,alt,width,height'
- },
- figure: {
- classes: '!' + editor.config.image2_captionedClass
- },
- figcaption: true
- };
-
- if ( alignClasses ) {
- // Centering class from the config.
- rules.div.classes = alignClasses[ 1 ];
- rules.p.classes = rules.div.classes;
-
- // Left/right classes from the config.
- rules.img.classes = alignClasses[ 0 ] + ',' + alignClasses[ 2 ];
- rules.figure.classes += ',' + rules.img.classes;
- } else {
- // Centering with text-align.
- rules.div.styles = 'text-align';
- rules.p.styles = 'text-align';
-
- rules.img.styles = 'float';
- rules.figure.styles = 'float,display';
- }
-
- return rules;
- }
-
- // Returns a set of widget feature rules, depending
- // on editor configuration. Note that the following may not cover
- // all the possible cases since requiredContent supports a single
- // tag only.
- //
- // @param {CKEDITOR.editor}
- // @returns {Object}
- function getWidgetFeatures( editor ) {
- var alignClasses = editor.config.image2_alignClasses,
- features = {
- dimension: {
- requiredContent: 'img[width,height]'
- },
- align: {
- requiredContent: 'img' +
- ( alignClasses ? '(' + alignClasses[ 0 ] + ')' : '{float}' )
- },
- caption: {
- requiredContent: 'figcaption'
- }
- };
-
- return features;
- }
-
- // Returns element which is styled, considering current
- // state of the widget.
- //
- // @see CKEDITOR.plugins.widget#applyStyle
- // @param {CKEDITOR.plugins.widget} widget
- // @returns {CKEDITOR.dom.element}
- function getStyleableElement( widget ) {
- return widget.data.hasCaption ? widget.element : widget.parts.image;
- }
-} )();
-
-/**
- * A CSS class applied to the ` can be first (only) child of centering wrapper,
- // regardless of its type.
- if ( !( child.name in validChildren ) )
- return false;
-
- // If centering wrapper is
can be the child.
- //
or
or
only when enterMode
- // is ENTER_(BR|DIV).
- //
or
.
- if ( !isLinkedOrStandaloneImage( child ) )
- return false;
- }
- }
-
- // Centering wrapper got to be... centering. If image2_alignClasses are defined,
- // check for centering class. Otherwise, check the style.
- if ( alignClasses ? el.hasClass( alignClasses[ 1 ] ) :
- CKEDITOR.tools.parseCssText( el.attributes.style || '', true )[ 'text-align' ] == 'center' )
- return true;
-
- return false;
- };
- }
-
- // Checks whether element is
or
.
- //
- // @param {CKEDITOR.htmlParser.element}
- function isLinkedOrStandaloneImage( el ) {
- if ( el.name == 'img' )
- return true;
- else if ( el.name == 'a' )
- return el.children.length == 1 && el.getFirst( 'img' );
-
- return false;
- }
-
- // Sets width and height of the widget image according to current widget data.
- //
- // @param {CKEDITOR.plugins.widget} widget
- function setDimensions( widget ) {
- var data = widget.data,
- dimensions = { width: data.width, height: data.height },
- image = widget.parts.image;
-
- for ( var d in dimensions ) {
- if ( dimensions[ d ] )
- image.setAttribute( d, dimensions[ d ] );
- else
- image.removeAttribute( d );
- }
- }
-
- // Defines all features related to drag-driven image resizing.
- //
- // @param {CKEDITOR.plugins.widget} widget
- function setupResizer( widget ) {
- var editor = widget.editor,
- editable = editor.editable(),
- doc = editor.document,
-
- // Store the resizer in a widget for testing (http://dev.ckeditor.com/ticket/11004).
- resizer = widget.resizer = doc.createElement( 'span' );
-
- resizer.addClass( 'cke_image_resizer' );
- resizer.setAttribute( 'title', editor.lang.image2.resizer );
- resizer.append( new CKEDITOR.dom.text( '\u200b', doc ) );
-
- // Inline widgets don't need a resizer wrapper as an image spans the entire widget.
- if ( !widget.inline ) {
- var imageOrLink = widget.parts.link || widget.parts.image,
- oldResizeWrapper = imageOrLink.getParent(),
- resizeWrapper = doc.createElement( 'span' );
-
- resizeWrapper.addClass( 'cke_image_resizer_wrapper' );
- resizeWrapper.append( imageOrLink );
- resizeWrapper.append( resizer );
- widget.element.append( resizeWrapper, true );
-
- // Remove the old wrapper which could came from e.g. pasted HTML
- // and which could be corrupted (e.g. resizer span has been lost).
- if ( oldResizeWrapper.is( 'span' ) )
- oldResizeWrapper.remove();
- } else {
- widget.wrapper.append( resizer );
- }
-
- // Calculate values of size variables and mouse offsets.
- resizer.on( 'mousedown', function( evt ) {
- var image = widget.parts.image,
-
- // "factor" can be either 1 or -1. I.e.: For right-aligned images, we need to
- // subtract the difference to get proper width, etc. Without "factor",
- // resizer starts working the opposite way.
- factor = widget.data.align == 'right' ? -1 : 1,
-
- // The x-coordinate of the mouse relative to the screen
- // when button gets pressed.
- startX = evt.data.$.screenX,
- startY = evt.data.$.screenY,
-
- // The initial dimensions and aspect ratio of the image.
- startWidth = image.$.clientWidth,
- startHeight = image.$.clientHeight,
- ratio = startWidth / startHeight,
-
- listeners = [],
-
- // A class applied to editable during resizing.
- cursorClass = 'cke_image_s' + ( !~factor ? 'w' : 'e' ),
-
- nativeEvt, newWidth, newHeight, updateData,
- moveDiffX, moveDiffY, moveRatio;
-
- // Save the undo snapshot first: before resizing.
- editor.fire( 'saveSnapshot' );
-
- // Mousemove listeners are removed on mouseup.
- attachToDocuments( 'mousemove', onMouseMove, listeners );
-
- // Clean up the mousemove listener. Update widget data if valid.
- attachToDocuments( 'mouseup', onMouseUp, listeners );
-
- // The entire editable will have the special cursor while resizing goes on.
- editable.addClass( cursorClass );
-
- // This is to always keep the resizer element visible while resizing.
- resizer.addClass( 'cke_image_resizing' );
-
- // Attaches an event to a global document if inline editor.
- // Additionally, if classic (`iframe`-based) editor, also attaches the same event to `iframe`'s document.
- function attachToDocuments( name, callback, collection ) {
- var globalDoc = CKEDITOR.document,
- listeners = [];
-
- if ( !doc.equals( globalDoc ) )
- listeners.push( globalDoc.on( name, callback ) );
-
- listeners.push( doc.on( name, callback ) );
-
- if ( collection ) {
- for ( var i = listeners.length; i--; )
- collection.push( listeners.pop() );
- }
- }
-
- // Calculate with first, and then adjust height, preserving ratio.
- function adjustToX() {
- newWidth = startWidth + factor * moveDiffX;
- newHeight = Math.round( newWidth / ratio );
- }
-
- // Calculate height first, and then adjust width, preserving ratio.
- function adjustToY() {
- newHeight = startHeight - moveDiffY;
- newWidth = Math.round( newHeight * ratio );
- }
-
- // This is how variables refer to the geometry.
- // Note: x corresponds to moveOffset, this is the position of mouse
- // Note: o corresponds to [startX, startY].
- //
- // +--------------+--------------+
- // | | |
- // | I | II |
- // | | |
- // +------------- o -------------+ _ _ _
- // | | | ^
- // | VI | III | | moveDiffY
- // | | x _ _ _ _ _ v
- // +--------------+---------|----+
- // | |
- // <------->
- // moveDiffX
- function onMouseMove( evt ) {
- nativeEvt = evt.data.$;
-
- // This is how far the mouse is from the point the button was pressed.
- moveDiffX = nativeEvt.screenX - startX;
- moveDiffY = startY - nativeEvt.screenY;
-
- // This is the aspect ratio of the move difference.
- moveRatio = Math.abs( moveDiffX / moveDiffY );
-
- // Left, center or none-aligned widget.
- if ( factor == 1 ) {
- if ( moveDiffX <= 0 ) {
- // Case: IV.
- if ( moveDiffY <= 0 )
- adjustToX();
-
- // Case: I.
- else {
- if ( moveRatio >= ratio )
- adjustToX();
- else
- adjustToY();
- }
- } else {
- // Case: III.
- if ( moveDiffY <= 0 ) {
- if ( moveRatio >= ratio )
- adjustToY();
- else
- adjustToX();
- }
-
- // Case: II.
- else {
- adjustToY();
- }
- }
- }
-
- // Right-aligned widget. It mirrors behaviours, so I becomes II,
- // IV becomes III and vice-versa.
- else {
- if ( moveDiffX <= 0 ) {
- // Case: IV.
- if ( moveDiffY <= 0 ) {
- if ( moveRatio >= ratio )
- adjustToY();
- else
- adjustToX();
- }
-
- // Case: I.
- else {
- adjustToY();
- }
- } else {
- // Case: III.
- if ( moveDiffY <= 0 )
- adjustToX();
-
- // Case: II.
- else {
- if ( moveRatio >= ratio ) {
- adjustToX();
- } else {
- adjustToY();
- }
- }
- }
- }
-
- // Don't update attributes if less than 10.
- // This is to prevent images to visually disappear.
- if ( newWidth >= 15 && newHeight >= 15 ) {
- image.setAttributes( { width: newWidth, height: newHeight } );
- updateData = true;
- } else {
- updateData = false;
- }
- }
-
- function onMouseUp() {
- var l;
-
- while ( ( l = listeners.pop() ) )
- l.removeListener();
-
- // Restore default cursor by removing special class.
- editable.removeClass( cursorClass );
-
- // This is to bring back the regular behaviour of the resizer.
- resizer.removeClass( 'cke_image_resizing' );
-
- if ( updateData ) {
- widget.setData( { width: newWidth, height: newHeight } );
-
- // Save another undo snapshot: after resizing.
- editor.fire( 'saveSnapshot' );
- }
-
- // Don't update data twice or more.
- updateData = false;
- }
- } );
-
- // Change the position of the widget resizer when data changes.
- widget.on( 'data', function() {
- resizer[ widget.data.align == 'right' ? 'addClass' : 'removeClass' ]( 'cke_image_resizer_left' );
- } );
- }
-
- // Integrates widget alignment setting with justify
- // plugin's commands (execution and refreshment).
- // @param {CKEDITOR.editor} editor
- // @param {String} value 'left', 'right', 'center' or 'block'
- function alignCommandIntegrator( editor ) {
- var execCallbacks = [],
- enabled;
-
- return function( value ) {
- var command = editor.getCommand( 'justify' + value );
-
- // Most likely, the justify plugin isn't loaded.
- if ( !command )
- return;
-
- // This command will be manually refreshed along with
- // other commands after exec.
- execCallbacks.push( function() {
- command.refresh( editor, editor.elementPath() );
- } );
-
- if ( value in { right: 1, left: 1, center: 1 } ) {
- command.on( 'exec', function( evt ) {
- var widget = getFocusedWidget( editor );
-
- if ( widget ) {
- widget.setData( 'align', value );
-
- // Once the widget changed its align, all the align commands
- // must be refreshed: the event is to be cancelled.
- for ( var i = execCallbacks.length; i--; )
- execCallbacks[ i ]();
-
- evt.cancel();
- }
- } );
- }
-
- command.on( 'refresh', function( evt ) {
- var widget = getFocusedWidget( editor ),
- allowed = { right: 1, left: 1, center: 1 };
-
- if ( !widget )
- return;
-
- // Cache "enabled" on first use. This is because filter#checkFeature may
- // not be available during plugin's afterInit in the future — a moment when
- // alignCommandIntegrator is called.
- if ( enabled === undefined )
- enabled = editor.filter.checkFeature( editor.widgets.registered.image.features.align );
-
- // Don't allow justify commands when widget alignment is disabled (http://dev.ckeditor.com/ticket/11004).
- if ( !enabled )
- this.setState( CKEDITOR.TRISTATE_DISABLED );
- else {
- this.setState(
- ( widget.data.align == value ) ? (
- CKEDITOR.TRISTATE_ON
- ) : (
- ( value in allowed ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED
- )
- );
- }
-
- evt.cancel();
- } );
- };
- }
-
- function linkCommandIntegrator( editor ) {
- // Nothing to integrate with if link is not loaded.
- if ( !editor.plugins.link )
- return;
-
- CKEDITOR.on( 'dialogDefinition', function( evt ) {
- var dialog = evt.data;
-
- if ( dialog.name == 'link' ) {
- var def = dialog.definition;
-
- var onShow = def.onShow,
- onOk = def.onOk;
-
- def.onShow = function() {
- var widget = getFocusedWidget( editor ),
- displayTextField = this.getContentElement( 'info', 'linkDisplayText' ).getElement().getParent().getParent();
-
- // Widget cannot be enclosed in a link, i.e.
- // foo
- *
- * instead of:
- *
- *
- *
- * **Note**: Once this configuration option is set, corresponding style definitions
- * must be supplied to the editor:
- *
- * * For [classic editor](#!/guide/dev_framed) it can be done by defining additional
- * styles in the {@link CKEDITOR.config#contentsCss stylesheets loaded by the editor}. The same
- * styles must be provided on the target page where the content will be loaded.
- * * For [inline editor](#!/guide/dev_inline) the styles can be defined directly
- * with `