Как мой плагин CKEditor может правильно вставлять специальные фреймы с уникальным изображением-заполнителем? - PullRequest
4 голосов
/ 09 июля 2011

Существует плагин iframe, встроенный в CKEditor, который позволяет вставлять iframe в редактор, но отображает довольно некрасивый заполнитель, независимо от того, что находится в iframe.Я работаю над плагином, который принимает идентификатор видео от пользователя и создает iframe, который указывает на страницу для отображения видео на нашем веб-сайте.Я хотел бы, чтобы мои пользователи увидели местозаполнитель, который дает понять, что они вставили видео:

Гадкий местозаполнитель iframe: Ugly iframe placeholder

Довольно заполнитель видео: Pretty video placeholder

Чтобы продвинуться дальше, я добавил этот кусочек Javascript в функцию onOk моего плагина.Я включил контекст:

onOk: function () {
    var videoID = this.getValueOf('info', 'video_id');
    var caption = this.getValueOf('info', 'caption');
    var display = this.getValueOf('info', 'display');
    var size = this.getValueOf('info', 'size');
    var width = size * 160;
    var height = size * 120;

    if (videoID.length > 0) {
        if (display == 0) {
            e.insertHtml("<a onclick=window.open(this.href,this.target,'width=" + width + ",height=" + height + "'); return false; target=newVideo href=/kbs/Video.aspx?videoId=" + videoID + "&amp;Width=" + width + "&amp;Height=" + height + ">" + caption + "</a>");
        } else {/*Here is the relevant code that is applied when display is set to embedded*/
            var iframeNode;
            //iframeNode = "<iframe height='" + (height + 40) + "' width='" + (width + 40) + "' src='/kbs/Video.aspx?videoId=1&height=" + height + "&width=" + width + "' frameBorder='0' scrolling='no'></iframe>");
            iframeNode = new CKEDITOR.dom.element('iframe');
            iframeNode.setAttribute('class', 'GROK-Video');
            iframeNode.setAttribute('height', height+40);
            iframeNode.setAttribute('width', width + 40);
            iframeNode.setAttribute('src', '/kbs/Video.aspx?videoId=1&height=' + height + '&width=' + width);
            iframeNode.setAttribute('frameBorder', 0);
            iframeNode.setAttribute('scrolling', 'no');
            var newFakeImage = e.createFakeElement(iframeNode, 'cke_GROKVideo', 'iframe', true);
            e.insertElement(newFakeImage);
        }
    }
}

Волшебство в функции редактора createFakeElement.Он заменяет мой iframe фиктивным элементом, который отображается как любое изображение, которое я выбираю с этим битом CSS в моем plugin.js:

editor.addCss(
    'img.cke_GROKVideo' +
    '{' +
        'background-image: url(' + CKEDITOR.getUrl(this.path + 'images/YouTubePlayButton.png') + ');' +
        'background-position: center center;' +
        'background-repeat: no-repeat;' +
        'border: 1px solid #a9a9a9;' +
        'width: 80px;' +
        'height: 80px;' +
    '}'
);

Что ж, я довольно далеко продвинулся, но проблема возникает, когдаисточник просмотрен.Изображение снова превращается в iframe, а плагин iframe заменяет его собственным заполнителем!Еще хуже, когда документ сохраняется и снова открывается для редактирования, происходит то же самое.Как сохранить заполнитель кнопки воспроизведения, не нарушая и не заменяя встроенный заполнитель плагина iframe?Плагин для разрыва страницы, кажется, делает нечто похожее с div, но я не уверен, как CKEditor различает div разрыва страницы и обычный div, когда он помещает поддельные элементы в редактор.Кто-нибудь пробовал что-то подобное?Я бы предпочел не создавать пользовательский элемент HTML на моем веб-сайте только для этого.

1 Ответ

3 голосов
/ 14 апреля 2012

Решение состоит только из двух изменений в ваших файлах:

Добавьте это в свой plugin.js

(function () {
    [...]
    CKEDITOR.plugins.add('yourPluginNName', {
        init: .... ,
        afterInit: function(editor){
            var dataProcessor = editor.dataProcessor,
                dataFilter = dataProcessor && dataProcessor.dataFilter;

            if ( dataFilter )
            {
                dataFilter.addRules(
                    {
                        elements :
                        {
                            iframe : function( element )
                            {
                               if( element.attributes["class"] && element.attributes["class"].indexOf( "GROK-Video" ) >= 0 ){
                                 var e = editor.createFakeParserElement( element, 'cke_GROKVideo', 'iframe', true );

                                 // if you want add a thumbnail background or other 
                                 // styles then do it here. 
                                 // but note that it's a parser element, not an html 
                                 // element, it goes something like this: 
                                 e.attributes["style"] += "background: url( ... );"; 
                                 return e;
                               }
                               else{
                                 return element;
                               }
                            }
                        }
                    }, 3); //Priority allows this to overrule the iframe plugin.
            }
        }
    })
})();

Что это эффективно делает, так это подключается к начальной стадии преобразования редакторов, если он принимает элемент iframe, он заменяет его поддельным элементом.

Также обратите внимание, что он заменяет элемент, только если его имя класса - GROK-Video, все остальные элементы iframe останутся целыми и невредимыми.

Это замечательно, если у вас есть несколько различных медиа-плагинов.

Отключите плагин iframe в вашей конфигурации:

Это просто:

config.removePlugins = "iframe";

Может быть, вы можете сказать плагину iframe, чтобы он дружил с вашим плагином, но мне это не нужно, и я просто не мог быть обеспокоен.

...