仅使用有效文本选择启用CKEditor工具栏按钮?

时间:2014-12-07 22:21:15

标签: ckeditor

我正在开发一个用于注释文本和添加边距注释的CKEditor插件,但我想只有在用户选择了一系列文本时才能启用我的一些自定义工具栏按钮。每当用户键入或光标处于单点(而不是范围)时,应禁用按钮(及其相关命令)。

我是一位非常有经验的插件作者,我花了相当多的时间来寻找core API docs,但我还没有找到任何看起来有用的东西。

3 个答案:

答案 0 :(得分:2)

你的情况有点棘手,因为浏览器没有很好地实现选择更改事件,FF是主要问题。

在您的情况下,您将非常频繁地需要检查选择更改,因为您对所有选择更改感兴趣,因此CKEditor selectionChange将不适合它。

幸运的是,编辑器中的selectionCheck事件更频繁地触发并为FF实现。

<强>解决方案:

这里有init插件方法,我嘲笑过来解决你的问题。它将按您解释的方式禁用/启用来源按钮。

我已经为此功能添加了限制功能,因此拥有较少扩展机器的客户可以欣赏您的功能:)

init: function( editor ) {
    // Funciton depending on editor selection (taken from the scope) will set the state of our command.
    function RefreshState() {
        var editable = editor.editable(),
            // Command that we want to control.
            command = editor.getCommand( 'source' ),
            range,
            commandState;

        if ( !editable ) {
            // It might be a case that editable is not yet ready.
            return;
        }

        // We assume only one range.
        range = editable.getDocument().getSelection().getRanges()[ 0 ];

        // The state we're about to set for the command.
        commandState = ( range && !range.collapsed ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED;

        command.setState( commandState );
    }

    // We'll use throttled function calls, because this event can be fired very, very frequently.
    var throttledFunction = CKEDITOR.tools.eventsBuffer( 250, RefreshState );

    // Now this is the event that detects all the selection changes.
    editor.on( 'selectionCheck', throttledFunction.input );

    // You'll most likely also want to execute this function as soon as editor is ready.
    editor.on( 'instanceReady', function( evt ) {
        // Also do state refresh on instanceReady.
        RefreshState();
    } );
}

答案 1 :(得分:0)

如果您正在使用插件,我猜您正在使用ckeditor注册command

在这种情况下,您应该提供refresh方法,CKEditor将调用该方法以在需要时更新按钮的状态:

  

由命令定义定义,用于确定命令的函数   州。当编辑器具有其状态或选择时,将调用它   改变。

您可以在CKEditor团队开发的几个插件中看到实现示例。这是一个取自the source code of the Link plugin

refresh: function( editor, path ) {

    var element = path.lastElement && path.lastElement.getAscendant( 'a', true );

    if ( element && element.getName() == 'a' && element.getAttribute( 'href' ) && element.getChildCount() )
        this.setState( CKEDITOR.TRISTATE_OFF );
    else
        this.setState( CKEDITOR.TRISTATE_DISABLED );
}

答案 2 :(得分:0)

这是 Gyum Fox 建议的使用refresh方法准确回答问题的代码。
我提到要使其起作用,必须将contextSensitive设置为1。

editor.addCommand( 'myCommand', {
    exec: function( editor ) {
        // Custom logic of the command
    },
    refresh: function( editor ) {
        var editable = editor.editable();
        range = editable.getDocument().getSelection().getRanges()[ 0 ]; // We assume only one range.
        commandState = ( range && !range.collapsed ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED;
        this.setState( commandState );
    },
    contextSensitive: 1
});

编辑:我注意到一些刷新问题。因此,因此,我将寻求Marek Lewandowski的答案。