使用“pastefromword”在 CKEditor 3 中过滤所有粘贴的内容

发布于 2024-10-20 21:46:05 字数 2392 浏览 3 评论 0原文

CKEditor 是一个很棒的编辑器,pastefromword 插件也非常好。我希望将插件提供的过滤应用于所有粘贴的文本。例如,从 Word 粘贴时,所有字体和大小都会被删除。从电子邮件粘贴时不会发生这种情况。

也就是说,我提出了以下解决方案并将其发布在这里以获取一些反馈。我想知道是否我把它弄得太复杂了,或者是否有更简单的方法。我只是从pastefromword/plugin.js 复制了代码。

通过我的自定义 config.js

...
CKEDITOR.config.pasteFromWordCleanupFile = '/pastefromword.js';
...
CKEDITOR.on( 'instanceReady', function( ev ) {
    /**
     * Paste event to apply Paste From Word filtering on all text.
     *
     * The pastefromword plugin will only process text that has tell-tale signs
     * it is from Word. Use this hook to treat all pasted text as if
     * it is coming from Word.
     *
     * This method is a slightly modified version of code found in
     * plugins/pastefromword/plugin.js
     */
    ev.editor.on( 'paste', function( evt ) {    
        var data = evt.data,
            editor = evt.editor,
            content;

        /**
         * "pasteFromWordHappened" is a custom property set in custom
         * pastefromword.js, so that filtering does not happen twice for content
         * actually coming from Word. It's a dirty hack I know.
         */
        if( editor.pasteFromWordHappened ) {
            // Reset property and exit paste event
            editor.pasteFromWordHappened = 0;
            return;
        }

        var loadRules = function( callback ) {
            var isLoaded = CKEDITOR.cleanWord;

            if( isLoaded ) {
                callback();
            }
            else {
                CKEDITOR.scriptLoader.load( CKEDITOR.config.pasteFromWordCleanupFile, callback, null, false, true );
            }

            return !isLoaded;
        };

        content = data['html'];

        // No need to filter text if html tags are not presence, so perform a regex
        // to test for html tags.
        if( content && (/<[^<]+?>/).test(content) ) {
            var isLazyLoad = loadRules( function(){
                if( isLazyLoad ) {
                    editor.fire('paste', data);
                }
                else {
                    data[ 'html' ] = CKEDITOR.cleanWord( content, editor );
                    // Reset property or if user tries to paste again, it won't work
                    editor.pasteFromWordHappened = 0;
                }
            });

            isLazyLoad && evt.cancel();
        }

    });
});

CKEditor is a great editor and the pastefromword plugin is very good. I'd like to have the filtering provided by the plugin applied to all pasted text. For example, when pasting from word, all fonts and sizes are stripped. This does not happen when pasting from an email.

That said, I came up with the following solution and posting it here to get some feedback. I'm wondering if I made it too complicated, or if there is an easier way. I kind of just copied the code from pastefromword/plugin.js.

via my custom config.js

...
CKEDITOR.config.pasteFromWordCleanupFile = '/pastefromword.js';
...
CKEDITOR.on( 'instanceReady', function( ev ) {
    /**
     * Paste event to apply Paste From Word filtering on all text.
     *
     * The pastefromword plugin will only process text that has tell-tale signs
     * it is from Word. Use this hook to treat all pasted text as if
     * it is coming from Word.
     *
     * This method is a slightly modified version of code found in
     * plugins/pastefromword/plugin.js
     */
    ev.editor.on( 'paste', function( evt ) {    
        var data = evt.data,
            editor = evt.editor,
            content;

        /**
         * "pasteFromWordHappened" is a custom property set in custom
         * pastefromword.js, so that filtering does not happen twice for content
         * actually coming from Word. It's a dirty hack I know.
         */
        if( editor.pasteFromWordHappened ) {
            // Reset property and exit paste event
            editor.pasteFromWordHappened = 0;
            return;
        }

        var loadRules = function( callback ) {
            var isLoaded = CKEDITOR.cleanWord;

            if( isLoaded ) {
                callback();
            }
            else {
                CKEDITOR.scriptLoader.load( CKEDITOR.config.pasteFromWordCleanupFile, callback, null, false, true );
            }

            return !isLoaded;
        };

        content = data['html'];

        // No need to filter text if html tags are not presence, so perform a regex
        // to test for html tags.
        if( content && (/<[^<]+?>/).test(content) ) {
            var isLazyLoad = loadRules( function(){
                if( isLazyLoad ) {
                    editor.fire('paste', data);
                }
                else {
                    data[ 'html' ] = CKEDITOR.cleanWord( content, editor );
                    // Reset property or if user tries to paste again, it won't work
                    editor.pasteFromWordHappened = 0;
                }
            });

            isLazyLoad && evt.cancel();
        }

    });
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

月棠 2024-10-27 21:46:05

我正在尝试做类似的事情。我想要一个 CKEditor 实例,它将 PasteFromWord 插件中包含的 HTML 清理规则应用于我粘贴的所有内容(主要是网络文章的片段)。目前,这种情况仅发生在以下两种情况下:

  1. 用户单击“从 Word 粘贴”工具栏图标
  2. 用户粘贴从 MS Word 本身复制的内容

在第二种情况下,CKEditor 会查找 MS Word 格式的迹象。它通过根据以下正则表达式测试您粘贴的任何内容来实现此目的:

/(class=\"?Mso|style=\"[^\"]*\bmso\-|w:WordDocument)/

如果存在匹配项,则会将其清除。否则它将正常粘贴。

不想编辑插件代码或重复它。这是我根据 jbarreiros 的代码得出的结论:

CKEDITOR.on('instanceReady', function(ev) {
    ev.editor.on('paste', function(evt) {    
        evt.data['html'] = '<!--class="Mso"-->'+evt.data['html'];
    }, null, null, 9);
});

我没有进行广泛的测试,但这似乎按预期工作(CKEditor 3.6.2)。

该代码的作用是为粘贴事件注册一个新的侦听器,就像从 Word 插件粘贴一样。当它收到粘贴的 HTML 时,它只是在前面添加一个 HTML 注释,其中包含“从 Word 粘贴”插件查找的字符串之一。侦听器的优先级为 9,以确保它在插件之前运行,从而触发实际的清理(默认优先级为 10)。

我的解决方案在此博客条目中: http ://www.keyvan.net/2012/11/clean-up-html-on-paste-in-ckeditor/

I'm trying to do something similar. I want a CKEditor instance which applies HTML cleanup rules contained in the pastefromword plugin to everything I paste (mostly snippets of web articles). At the moment this only happens in the following two cases:

  1. User clicks the 'paste from word' toolbar icon
  2. User pastes content copied from MS Word itself

In the second case, CKEditor looks for signs of MS Word formatting. It does this by testing whatever you paste against the following regular expression:

/(class=\"?Mso|style=\"[^\"]*\bmso\-|w:WordDocument)/

If there's a match, it will be cleaned up. Otherwise it will paste as normal.

Not wanting to edit the plugin code, or duplicate it. Here's what I've come up with, based on jbarreiros's code:

CKEDITOR.on('instanceReady', function(ev) {
    ev.editor.on('paste', function(evt) {    
        evt.data['html'] = '<!--class="Mso"-->'+evt.data['html'];
    }, null, null, 9);
});

I haven't tested extensively, but this appears to work as expected (CKEditor 3.6.2).

What the code does is it registers a new listener for the paste event, just like the Paste from Word plugin. When it receives the pasted HTML, it simply prepends an HTML comment containing one of the strings the Paste from Word plugin looks for. The listener has a priority of 9 to ensure it runs before the plugin which will trigger the actual cleaning (default priority of 10).

My solution is in this blog entry: http://www.keyvan.net/2012/11/clean-up-html-on-paste-in-ckeditor/

故乡的云 2024-10-27 21:46:05

评论一个老问题:
当前的问题不仅仅是 CKEditor 中的单词清理。
当您通过 javascript api 请求剪贴板内容时,浏览器会做什么也是一个问题。 IE、FF、Safari 等之间的差异很大。通常,非 IE 浏览器会在将 HTML 提供给浏览器之前自行清理 HTML。从而删除了很多格式。

Commenting on a old question:
The issue at hand is not just word cleaning in CKEditor.
Its also a matter of what the browser does when you ask for clip board content via javascript api. that differs heavily between IE, FF, Safari etc. Typically the non IE browsers will clean up the HTML themself, beofore giving the HTML to the browser. Thus removing a lot of formatting.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文