{"size": 3807, "ext": "js", "max_stars_repo_path": "src/videostyle/videostyleediting.js", "max_stars_repo_name": "litaoren/cmsk-ckeditor", "max_stars_repo_stars_event_min_datetime": "2022-01-24T00:17:51.000Z", "max_stars_repo_stars_event_max_datetime": "2022-01-24T00:17:51.000Z", "max_issues_repo_path": "src/videostyle/videostyleediting.js", "max_issues_repo_name": "litaoren/cmsk-ckeditor", "max_issues_repo_issues_event_min_datetime": "2022-02-17T03:45:05.000Z", "max_issues_repo_issues_event_max_datetime": "2022-02-21T03:31:24.000Z", "max_forks_repo_path": "src/videostyle/videostyleediting.js", "max_forks_repo_name": "litaoren/cmsk-ckeditor", "max_forks_repo_forks_event_min_datetime": "2022-02-17T02:46:00.000Z", "max_forks_repo_forks_event_max_datetime": "2022-02-17T02:46:00.000Z"}
{"max_stars_count": 1, "max_issues_count": 4, "max_forks_count": 1, "avg_line_length": 38.8469387755, "max_line_length": 123, "alphanum_fraction": 0.6030995535}
import { Plugin } from 'ckeditor5/src/core';
import VideoStyleCommand from './videostylecommand';
import VideoUtils from '../videoutils';
import utils from './utils';
import { viewToModelStyleAttribute, modelToViewStyleAttribute } from './converters';

export default class VideoStyleEditing extends Plugin {
    static get pluginName() {
        return 'VideoStyleEditing';
    }

    static get requires() {
        return [ VideoUtils ];
    }

    init() {
        const { normalizeStyles, getDefaultStylesConfiguration } = utils;
        const editor = this.editor;
        const isBlockPluginLoaded = editor.plugins.has( 'VideoBlockEditing' );
        const isInlinePluginLoaded = editor.plugins.has( 'VideoInlineEditing' );

        editor.config.define( 'video.styles', getDefaultStylesConfiguration( isBlockPluginLoaded, isInlinePluginLoaded ) );

        this.normalizedStyles = normalizeStyles( {
            configuredStyles: editor.config.get( 'video.styles' ),
            isBlockPluginLoaded,
            isInlinePluginLoaded
        } );

        this._setupConversion( isBlockPluginLoaded, isInlinePluginLoaded );
        this._setupPostFixer();

        editor.commands.add( 'videoStyle', new VideoStyleCommand( editor, this.normalizedStyles ) );
    }

    _setupConversion( isBlockPluginLoaded, isInlinePluginLoaded ) {
        const editor = this.editor;
        const schema = editor.model.schema;

        const modelToViewConverter = modelToViewStyleAttribute( this.normalizedStyles );
        const viewToModelConverter = viewToModelStyleAttribute( this.normalizedStyles );

        editor.editing.downcastDispatcher.on( 'attribute:videoStyle', modelToViewConverter );
        editor.data.downcastDispatcher.on( 'attribute:videoStyle', modelToViewConverter );

        if ( isBlockPluginLoaded ) {
            schema.extend( 'videoBlock', { allowAttributes: 'videoStyle' } );
            editor.data.upcastDispatcher.on( 'element:figure', viewToModelConverter, { priority: 'low' } );
        }

        if ( isInlinePluginLoaded ) {
            schema.extend( 'videoInline', { allowAttributes: 'videoStyle' } );
            editor.data.upcastDispatcher.on( 'element:video', viewToModelConverter, { priority: 'low' } );
        }
    }

    _setupPostFixer() {
        const editor = this.editor;
        const document = editor.model.document;

        const videoUtils = editor.plugins.get( VideoUtils );
        const stylesMap = new Map( this.normalizedStyles.map( style => [ style.name, style ] ) );

        document.registerPostFixer( writer => {
            let changed = false;

            for ( const change of document.differ.getChanges() ) {
                if ( change.type === 'insert' || change.type === 'attribute' && change.attributeKey === 'videoStyle' ) {
                    let element = change.type === 'insert' ? change.position.nodeAfter : change.range.start.nodeAfter;

                    if ( element && element.is( 'element', 'paragraph' ) && element.childCount > 0 ) {
                        element = element.getChild( 0 );
                    }

                    if ( !videoUtils.isVideo( element ) ) {
                        continue;
                    }

                    const videoStyle = element.getAttribute( 'videoStyle' );

                    if ( !videoStyle ) {
                        continue;
                    }

                    const videoStyleDefinition = stylesMap.get( videoStyle );

                    if ( !videoStyleDefinition || !videoStyleDefinition.modelElements.includes( element.name ) ) {
                        writer.removeAttribute( 'videoStyle', element );
                        changed = true;
                    }
                }
            }

            return changed;
        } );
    }
}
