ckeditor5/core:context、plugincol

2020-10-01  本文已影响0人  videring

Provides a common, higher-level environment for solutions that use multiple Editor editors
or plugins that work outside the editor. Use it instead of Editor.create Editor.create()
in advanced application integrations.

Config

ckeditor5-utils下Config是一种类似于lodash get效果的类,可以通过get(obj, 'a.b.c')set(obj, 'a.b.c', 123)来获取或设置对象obj={a : { b: {c: 1}}},用来封装或操作配置。如:

let config = new Config( {
    creator: 'inline',
    language: 'pl',
    resize: {
        minHeight: 300,
        maxHeight: 800,
        icon: {
            path: 'xyz'
        }
    },
    toolbar: 'top',
    options: {
        foo: [
            { bar: 'b' },
            { bar: 'a' },
            { bar: 'z' }
        ]
    }
// 
expect( config.get( 'creator' ) ).to.equal( 'inline' );
config.set( {
    option1: 1,
    option2: {
        subOption21: 21
    }
} );
expect( config.get( 'option1' ) ).to.equal( 1 );
expect( config.get( 'option2.subOption21' ) ).to.equal( 21 );

Context

Provides a common, higher-level environment for solutions that use multiple editors or plugins that work outside the editor.
All configuration options passed to a context will be used as default options for editor instances initialized in that context.
Context plugins passed to a context instance will be shared among all editor instances initialized in this context. These will be the same plugin instances for all the editors.

// Creates and initializes a new context instance.
        const commonConfig = { ... }; // Configuration for all the plugins and editors.
        const editorPlugins = [ ... ]; // Regular plugins here.
        Context
            .create( {
                // Only context plugins here.
                plugins: [ ... ],
                // Configure the language for all the editors (it cannot be overwritten).
                language: { ... },
                // Configuration for context plugins.
                comments: { ... },
                ...
                // Default configuration for editor plugins.
                toolbar: { ... },
                image: { ... },
                ...
            } )
            .then( context => {
                const promises = [];
                promises.push( ClassicEditor.create(
                    document.getElementById( 'editor1' ),
                    {
                        editorPlugins,
                        context
                    }
                ) );
                promises.push( ClassicEditor.create(
                    document.getElementById( 'editor2' ),
                    {
                        editorPlugins,
                        context,
                        toolbar: { ... } // You can overwrite the configuration of the context.
                    }
                ) );
                return Promise.all( promises );
            } );
// An array of plugins built into the `Context` class.
// It is used in CKEditor 5 builds featuring `Context` to provide a list of context plugins which are later automatically initialized during the context initialization.
// They will be automatically initialized by `Context` unless `config.plugins` is passed.
        // Build some context plugins into the Context class first.
        Context.builtinPlugins = [ FooPlugin, BarPlugin ];
        // Normally, you need to define config.plugins, but since Context.builtinPlugins was
        // defined, now you can call create() without any configuration.
        Context
            .create()
            .then( context => {
                context.plugins.get( FooPlugin ); // -> An instance of the Foo plugin.
                context.plugins.get( BarPlugin ); // -> An instance of the Bar plugin.
            } );
Context.defaultConfig = {
    foo: 1,
    bar: 2
};
Context
    .create()
    .then( context => {
        context.config.get( 'foo' ); // -> 1
        context.config.get( 'bar' ); // -> 2
    } );
// The default options can be overridden by the configuration passed to create().
Context
    .create( { bar: 3 } )
    .then( context => {
        context.config.get( 'foo' ); // -> 1
        context.config.get( 'bar' ); // -> 3
    } );

new Context(config)实例化过程

this.locale = new Locale( {
            uiLanguage: typeof languageConfig === 'string' ? languageConfig : languageConfig.ui,
            contentLanguage: this.config.get( 'language.content' )
} );
this.t = this.locale.t;
const collection = new Collection( [ { id: 'John' }, { id: 'Mike' } ] );
console.log( collection.get( 0 ) ); // -> { id: 'John' }
console.log( collection.get( 1 ) ); // -> { id: 'Mike' }
console.log( collection.get( 'Mike' ) ); // -> { id: 'Mike' }
// Or 
const collection = new Collection();
collection.add( { id: 'John' } );
console.log( collection.get( 0 ) ); // -> { id: 'John' }
// Or  you can always pass a configuration object as the last argument of the constructor:
const emptyCollection = new Collection( { idProperty: 'name' } );
emptyCollection.add( { name: 'John' } );
console.log( collection.get( 'John' ) ); // -> { name: 'John' }
const nonEmptyCollection = new Collection( [ { name: 'John' } ], { idProperty: 'name' } );
nonEmptyCollection.add( { name: 'George' } );
console.log( collection.get( 'George' ) ); // -> { name: 'George' }
console.log( collection.get( 'John' ) ); // -> { name: 'John' }

bindTo、as和using

// Binds and synchronizes the collection with another one.
// The binding can be a simple factory:
        class FactoryClass {
            constructor( data ) {
                this.label = data.label;
            }
        }
        const source = new Collection( { idProperty: 'label' } );
        const target = new Collection();
        target.bindTo( source ).as( FactoryClass );
        source.add( { label: 'foo' } );
        source.add( { label: 'bar' } );
        console.log( target.length ); // 2
        console.log( target.get( 1 ).label ); // 'bar'
        source.remove( 0 );
        console.log( target.length ); // 1
        console.log( target.get( 0 ).label ); // 'bar'
// or the factory driven by a custom callback:
        class FooClass {
            constructor( data ) {
                this.label = data.label;
            }
        }
        class BarClass {
            constructor( data ) {
                this.label = data.label;
            }
        }
        const source = new Collection( { idProperty: 'label' } );
        const target = new Collection();
        target.bindTo( source ).using( ( item ) => {
            if ( item.label == 'foo' ) {
                return new FooClass( item );
            } else {
                return new BarClass( item );
            }
        } );
        source.add( { label: 'foo' } );
        source.add( { label: 'bar' } );
        console.log( target.length ); // 2
        console.log( target.get( 0 ) instanceof FooClass ); // true
        console.log( target.get( 1 ) instanceof BarClass ); // true
// or the factory out of property name:
        const source = new Collection( { idProperty: 'label' } );
        const target = new Collection();
        target.bindTo( source ).using( 'label' );
        source.add( { label: { value: 'foo' } } );
        source.add( { label: { value: 'bar' } } );
        console.log( target.length ); // 2
        console.log( target.get( 0 ).value ); // 'foo'
        console.log( target.get( 1 ).value ); // 'bar'
// It's possible to skip specified items by returning falsy value:
        const source = new Collection();
        const target = new Collection();
        target.bindTo( source ).using( item => {
            if ( item.hidden ) {
                return null;
            }
            return item;
        } );
        source.add( { hidden: true } );
        source.add( { hidden: false } );
        console.log( source.length ); // 2
        console.log( target.length ); // 1
/*
Reference to the editor which created the context.
Null when the context was created outside of the editor.
It is used to destroy the context when removing the editor that has created the context.
*/
this._contextOwner = null;

editor.js中,会调用Context方法和_addEditor

class Editor {
   constructor(config = {}) {
    this._context = config.context || new Context( { language: config.language } );
    this._context._addEditor( this, !config.context );
  }
}
// Adds a reference to the editor which is used with this context.
// This method should only be used by the editor.
_addEditor( editor, isContextOwner ) {
    if ( this._contextOwner ) {
        /**
         * Cannot add multiple editors to the context which is created by the editor.
         *
         * @error context-addeditor-private-context
         */
        throw new CKEditorError( 'context-addeditor-private-context' );
    }
    this.editors.add( editor );
    if ( isContextOwner ) {
        this._contextOwner = editor;
    }
}
上一篇 下一篇

猜你喜欢

热点阅读