Skip to content

fix: Implement select all functionality in JavaScript and C++ layers#337

Merged
deepin-bot[bot] merged 1 commit intolinuxdeepin:develop/snipefrom
dengzhongyuan365-dev:commit2026205
Feb 5, 2026
Merged

fix: Implement select all functionality in JavaScript and C++ layers#337
deepin-bot[bot] merged 1 commit intolinuxdeepin:develop/snipefrom
dengzhongyuan365-dev:commit2026205

Conversation

@dengzhongyuan365-dev
Copy link

  • Added callJsSelectAll method in jscontent.h to notify the frontend for select all operations.
  • Updated WebEngineHandler to emit the new signal when the select all action is triggered.
  • Implemented selectAllText function in index.js to handle selection logic based on the context of the right-click position, allowing for intelligent selection of text in specific areas.

These changes enhance user experience by providing a more intuitive way to select all text within the editing interface.

bug: https://pms.uniontech.com/bug-view-339521.html

- Added `callJsSelectAll` method in `jscontent.h` to notify the frontend for select all operations.
- Updated `WebEngineHandler` to emit the new signal when the select all action is triggered.
- Implemented `selectAllText` function in `index.js` to handle selection logic based on the context of the right-click position, allowing for intelligent selection of text in specific areas.

These changes enhance user experience by providing a more intuitive way to select all text within the editing interface.

bug: https://pms.uniontech.com/bug-view-339521.html
@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: dengzhongyuan365-dev, lzwind

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@deepin-ci-robot
Copy link

deepin pr auto review

这段代码主要实现了在富文本编辑器中对语音块(voiceBox)和转写文本区域(translateText)进行全选的功能,并优化了右键菜单的交互逻辑。以下是对代码的详细审查和改进建议:

1. 语法与逻辑审查

优点:

  • 功能实现完整:成功将C++层的全选操作转发到JS层,并根据点击位置(转写文本区域 vs 整个编辑区)实现了智能全选。
  • 交互逻辑优化:在 rightClickshowRightMenu 中增加了对 .translateText.translateHeader 的判断,使得在这些区域操作时能正确触发对应的菜单或隐藏工具栏,逻辑清晰。
  • 边界处理:在 isRangeVoice 中增加了对 .voiceInfoBox 的检查,修复了选中语音块内部内容时可能导致的判断错误。

潜在问题:

  • selectAllText 依赖全局状态:该函数严重依赖于 lastRightClickXlastRightClickY 这两个全局变量来获取点击元素。如果全选操作不是通过右键菜单触发的(例如通过快捷键 Ctrl+A),或者用户在右键后移动了鼠标/滚动了页面,elementFromPoint 可能会获取到错误的元素,导致全选范围不符合预期。
  • 右键菜单与全选的耦合:目前的实现假设全选操作总是紧随右键点击之后。这种强耦合降低了代码的健壮性。

2. 代码质量

优点:

  • 注释清晰:关键逻辑处添加了注释,方便理解。
  • 命名规范:函数名和变量名语义明确。

改进建议:

  • 减少全局变量:尽量避免使用 lastRightClickXlastRightClickY 这种隐式的全局状态传递。
  • 代码复用selectAllText 中创建 Range 和 Selection 的代码有重复,可以封装成辅助函数。

3. 代码性能

  • DOM 查询selectAllText 中使用了 $(elementAtClick).closest('.translateText'),这是必要的。但要注意 elementFromPoint 本身虽然快,但在复杂布局下仍需谨慎使用。
  • 选择器效率$('.note-editable') 每次全选都会查询整个 DOM。建议在初始化时缓存这个选择器结果,或者通过更具体的 ID/上下文来查找。

4. 代码安全

  • XSS 风险:虽然这里主要是操作 DOM Range,不直接涉及 HTML 插入,但在处理 jsonKey 等 DOM 属性时,始终要注意数据来源的可靠性。
  • 空指针检查:在 selectAllText 中,elementAtPoint 有可能返回 null(例如坐标在视口外),代码中虽然后续通过 $translateText.length 进行了判断,但显式检查 if (!elementAtClick) 会更安全。

5. 具体改进建议与代码示例

修改 selectAllText 函数,降低对全局坐标的依赖,增加健壮性

建议修改全选的逻辑,不仅仅依赖右键点击的坐标,而是优先检查当前已有的 Selection(光标焦点位置)。如果当前焦点就在 translateText 内,则直接全选该区域;否则再回退到检查点击坐标或默认全选编辑器。

/**
 * 全选操作
 * 优先级:
 * 1. 检查当前焦点是否在 .translateText 区域内
 * 2. 检查右键点击位置是否在 .translateText 区域内
 * 3. 默认选中整个编辑区
 */
function selectAllText() {
    var selection = window.getSelection();
    var range = null;
    var targetNode = null;

    // 1. 尝试从当前选区获取上下文
    if (selection.rangeCount > 0) {
        var currentRange = selection.getRangeAt(0);
        // 检查选区起点是否在 translateText 内
        var $container = $(currentRange.commonAncestorContainer);
        if ($container.nodeType === Node.TEXT_NODE) {
            $container = $container.parent();
        }
        var $translateText = $container.closest('.translateText');
        if ($translateText.length > 0) {
            targetNode = $translateText[0];
        }
    }

    // 2. 如果当前选区无法确定,尝试使用右键点击坐标
    if (!targetNode && typeof lastRightClickX !== 'undefined' && typeof lastRightClickY !== 'undefined') {
        var elementAtClick = document.elementFromPoint(lastRightClickX, lastRightClickY);
        if (elementAtClick) {
            var $translateText = $(elementAtClick).closest('.translateText');
            if ($translateText.length > 0) {
                targetNode = $translateText[0];
            }
        }
    }

    // 3. 执行选区设置
    if (targetNode) {
        // 选中特定区域
        range = document.createRange();
        range.selectNodeContents(targetNode);
        selection.removeAllRanges();
        selection.addRange(range);
        console.log("全选: 特定区域;
    } else {
        // 选中整个编辑区
        var $editable = $('#summernote').find('.note-editable'); // 使用 ID 限定范围,性能更好
        if ($editable.length > 0) {
            range = document.createRange();
            range.selectNodeContents($editable[0]);
            selection.removeAllRanges();
            selection.addRange(range);
            console.log("全选: 整个编辑区");
        }
    }
}

优化 showRightMenu 中的 DOM 查询

function showRightMenu(x, y) {
    var selection = window.getSelection();
    if (selection && selection.rangeCount > 0) {
        var range = selection.getRangeAt(0);
        var container = range.commonAncestorContainer;
        
        // 使用原生 nodeType 判断,比 jQuery 稍快
        if (container.nodeType === 3) { // Node.TEXT_NODE
            container = container.parentNode;
        }
        
        // 使用 jQuery 的 is 方法或 closest 直接判断,减少中间变量
        // 注意:这里需要确保 container 是 DOM 元素,如果是文本节点需先转父节点
        if ($(container).closest('.translateText, .voiceBox').length) {
            console.log("在 translateText/voiceBox 区域,不显示悬浮工具栏");
            return;
        }
    }
    $('#summernote').summernote('airPopover.rightUpdate', x, y);
}

C++ 层改进建议

web_engine_handler.cpp 中,移除 USE_QT5 的宏判断是合理的,简化了代码。目前的实现直接发射 JS 信号,符合架构设计。无需额外修改。

总结

这段代码整体逻辑正确,主要问题在于 selectAllText 对全局坐标的强依赖。通过引入基于当前焦点的判断逻辑作为第一优先级,可以显著提升功能在非右键菜单触发场景下的表现(如快捷键全选)。同时,微调 DOM 查询方式可以略微提升性能。

@dengzhongyuan365-dev
Copy link
Author

/forcemerge

@deepin-bot
Copy link
Contributor

deepin-bot bot commented Feb 5, 2026

This pr force merged! (status: unstable)

@deepin-bot deepin-bot bot merged commit 3c1b4d8 into linuxdeepin:develop/snipe Feb 5, 2026
15 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants