Redactor.js列表编辑导致Chrome崩溃,cpu变为100%

时间:2014-10-20 14:40:48

标签: google-chrome contenteditable redactor execcommand

我们使用Redactor.js作为富文本编辑器。

不可否认,我们在一个相当复杂的网页上使用它,但我们一切正常,除了......

重现的步骤

(1)在redactor contenteditable div中选择所有这三个项目:

  • 第1项
  • 第2项

    第3项

(2)选择将三个项目转换为无序列表。在redactor的网站上,它将项目转换为:

第1项

第2项

  • 第3项

在我们的网站上,Chrome标签变得没有响应,cpu使用率达到100%,但Chrome从未正式关闭或崩溃标签。选项卡保持不变,直到您强制退出该过程。

JS代码

中发生了什么

在redactor.js源代码(版本10.0.2)中,无序列表处理程序在第4232行调用列表切换功能。当该函数运行时,它确定需要添加列表并删除列表(第4251行)。然后运行列表删除功能(第4356行),该功能运行:

document.execCommand('insert' + cmd);

变量cmd等于字符串“unorderedlist”,Chrome停止工作(在我们的网站上,而不是在redactor的网站上)。

有什么区别?

对redactor配置的更改似乎对此问题没有影响。尽管如此,这是我们的redactor.js配置对象:

 $this.redactor({
       allowedTags: ['a', 'abbr', 'acronym', 'address', 'article', 'aside', 'b', 'big', 'blockquote', 'br', 'button', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'dd', 'del', 'div', 'dl', 'dt', 'em', 'fieldset', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'i', 'img', 'label', 'legend', 'li', 'marquee', 'ol', 'option', 'p', 'pre', 'q', 's', 'samp', 'section', 'select', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'tt', 'u', 'ul', 'var', 'wbr'], 
        buttons: ['formatting', 'bold', 'italic', 'link', 'orderedlist', 'unorderedlist', 'outdent', 'indent'],
        cleanOnPaste: true, 
        clipboardImageUpload: false, 
        dragImageUpload: false, 
        dragFileUpload: false, 
        formatting: ['p', 'h1', 'blockquote', 'pre'],
        imageEditable: false, 
        imageLink: false, 
        imagePosition: false, 
        imageResizable: false, 
        linkTooltip: true,
        placeholder: self.config.placeholder,
        removeAttr:  [
          ['blockquote', 'class'],
          ['h1', 'class'],
          ['ol', 'class'],
          ['p', 'class'],
          ['ul', 'class']
        ],
        removeComments: true, 
        removeDataAttr: true, 
        removeEmpty: ['blockquote', 'em', 'h1', 'ol', 'p', 'pre', 'span', 'strong', 'ul'],
        replaceTags: [
          ['big', 'strong'],
          ['strike', 'del']
        ],
        tabKey: true,
        toolbarExternal: '#mceTextTools' + index,
        blurCallback: function(e) {
        },
        changeCallback: function() {
        },
        clickCallback: function(e) {
        },
        focusCallback: function(e) {
        },
        keyupCallback: function(e) {
        },
        pasteCallback: function(html) {
        },
        pasteBeforeCallback: function(html) {
        },
        modalOpenedCallback: function (name, modal) {
        },
        initCallback: function() {
        }
      }); 

另外,我们怀疑问题可能是由于某些特定的CSS规则对document.execCommand没有很好的反应。以下是我们在s上使用的计算样式。

ul {
    -webkit-font-smoothing: antialiased;
    box-sizing: border-box;
    color: rgb(68, 68, 68);
    cursor: auto;
    display: block;
    font-family: Georgia, Cambria, 'Times New Roman', serif;
    font-size: 18px;
    height: 32px;
    line-height: 32.4000015258789px;
    list-style-type: disc;
    margin-bottom: 0px;
    margin-left: 0px;
    margin-right: 0px;
    margin-top: 0px;
    padding-bottom: 0px;
    padding-left: 20px;
    padding-right: 20px;
    padding-top: 0px;
    width: 688px;
    word-wrap: break-word;
}
li {
    -webkit-font-smoothing: antialiased;
    box-sizing: border-box;
    color: rgb(68, 68, 68);
    display: list-item;
    font-family: Georgia, Cambria, 'Times New Roman', serif;
    font-size: 18px;
    height: 32px;
    line-height: 32.4000015258789px;
    list-style-type: disc;
    margin-top: 0px;
    text-align: left;
    width: 648px;
    word-wrap: break-word;
}

非常感谢任何想法!

2 个答案:

答案 0 :(得分:0)

我们能找到的唯一解决方案是将其添加到列表切换功能的开头(第4235行):

var test = this.selection.getNodes();
_.each(test, function(v){
    if (v.tagName === 'BR'){
        this.selection.selectElement(this.selection.getBlocks()[0]);
    }
});

问题似乎与this.selection.getCurrent()有关。有时,当选择中存在BR时,getCurrent()不会返回正确的文档节点。使用上面的代码重置选择可以防止Chrome崩溃,但也会稍微改变有序/无序列表按钮的行为。

答案 1 :(得分:0)

这是Redactor支持的回复:

感谢您与我们联系。很遗憾,我无法在http://imperavi.com/redactor重现此问题。我怀疑你的代码中某处可能存在某种冲突。

如果您有任何疑问,请与我们联系。