MediaWiki可视化编辑器:移除块节点插入HTML后的换行符
解决Visual Editor插入自定义内联标签时自动添加换行的问题
我是一名业余开发者,只会复制粘贴代码并按需修改,并非JavaScript专家。目前正在为MediaWiki 1.39版本的Visual Editor开发一款小工具,想要添加一个按钮用于插入自定义内联HTML标签<bible>。现有代码可以实现选中文本的标签包裹功能,但会在包裹内容前后自动插入换行符,求解决该问题的方案。
当前代码如下:
ve.ui.BibliaCommand = function VeUiBibliaCommand() { ve.ui.BibliaCommand.super.call( this, 'Biblia' ); }; OO.inheritClass( ve.ui.BibliaCommand, ve.ui.Command ); ve.ui.BibliaCommand.prototype.execute = function ( surface ) { var model = surface.getModel(), doc = model.getDocument(), range = model.getSelection().getRange(), docRange = doc.shallowCloneFromRange( range ); ve.init.target.getWikitextFragment( docRange, false ).done( function ( wikitext ) { var htmlfrag = model.getFragment().insertHtml('<bible>'+wikitext+'</bible>'); } ); }; ve.ui.commandRegistry.register( new ve.ui.BibliaCommand() ); ve.ui.BibliaTool = function VeUiBibliaTool() { ve.ui.BibliaTool.super.apply( this, arguments ); }; OO.inheritClass( ve.ui.BibliaTool, ve.ui.Tool ); ve.ui.BibliaTool.static.name = 'Biblia'; ve.ui.BibliaTool.static.group = 'cite'; ve.ui.BibliaTool.static.icon = 'book'; ve.ui.BibliaTool.static.title = 'Biblia'; ve.ui.BibliaTool.static.commandName = 'Biblia'; ve.ui.toolFactory.register( ve.ui.BibliaTool );
解决方案
问题出在insertHtml方法,它默认会将插入的HTML解析为块级内容,从而自动添加换行。正确的做法是直接操作Visual Editor的内容模型,使用Fragment的wrap方法来包裹选中内容,这样能保持内联元素的特性,不会产生多余换行。
修改后的完整代码如下:
ve.ui.BibliaCommand = function VeUiBibliaCommand() { ve.ui.BibliaCommand.super.call( this, 'Biblia' ); }; OO.inheritClass( ve.ui.BibliaCommand, ve.ui.Command ); ve.ui.BibliaCommand.prototype.execute = function ( surface ) { var model = surface.getModel(), fragment = model.getFragment(); // 用自定义内联标签包裹选中内容 fragment.wrapNodes( { type: 'htmltag', attributes: { name: 'bible' } }, { type: 'htmltag/end', attributes: { name: 'bible' } } ); // 让光标停留在包裹内容的末尾 fragment.select(); }; ve.ui.commandRegistry.register( new ve.ui.BibliaCommand() ); ve.ui.BibliaTool = function VeUiBibliaTool() { ve.ui.BibliaTool.super.apply( this, arguments ); }; OO.inheritClass( ve.ui.BibliaTool, ve.ui.Tool ); ve.ui.BibliaTool.static.name = 'Biblia'; ve.ui.BibliaTool.static.group = 'cite'; ve.ui.BibliaTool.static.icon = 'book'; ve.ui.BibliaTool.static.title = 'Biblia'; ve.ui.BibliaTool.static.commandName = 'Biblia'; ve.ui.toolFactory.register( ve.ui.BibliaTool );
关键说明
wrapNodes直接在VE的内容模型层面操作,将选中内容包裹为指定的HTML标签节点,完全遵循内联元素的处理逻辑,不会触发自动换行- 省去了将内容转成wikitext再回插的步骤,流程更简洁,也避免了格式转换带来的额外问题
fragment.select()可以让光标保持在包裹内容的末尾,符合常规编辑习惯
内容的提问来源于stack exchange,提问作者Huan
相关产品推荐
相关产品推荐

