diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 127b9ff9..358acaff 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -191,6 +191,10 @@ "message": "Enable", "description": "Label for the button to enable a style" }, + "editDeleteText": { + "message": "Delete", + "description": "Label for the context menu item in the editor to delete selected text" + }, "exportLabel": { "message": "Export", "description": "Label for the button to export a style ('edit' page) or all styles ('manage' page)" diff --git a/background.js b/background.js index 8658aad8..80d2a1b5 100644 --- a/background.js +++ b/background.js @@ -116,6 +116,23 @@ const contextMenus = { }, }; +// detect browsers without Delete by looking at the end of UA string +// Google Chrome: Safari/# +// but skip CentBrowser: Safari/# plus Shockwave Flash in plugins +// Vivaldi: Vivaldi/# +if (/Vivaldi\/[\d.]+$/.test(navigator.userAgent) + || /Safari\/[\d.]+$/.test(navigator.userAgent) + && ![...navigator.plugins].some(p => p.name == 'Shockwave Flash')) { + contextMenus.editDeleteText = { + title: 'editDeleteText', + contexts: ['editable'], + documentUrlPatterns: [OWN_ORIGIN + 'edit*'], + click: (info, tab) => { + chrome.tabs.sendMessage(tab.id, {method: 'editDeleteText'}); + }, + }; +} + chrome.contextMenus.onClicked.addListener((info, tab) => contextMenus[info.menuItemId].click(info, tab)); diff --git a/edit.js b/edit.js index 7fc06efd..94b647aa 100644 --- a/edit.js +++ b/edit.js @@ -325,6 +325,7 @@ function setupCodeMirror(textarea, index) { hotkeyRerouter.setState(false); cm.display.wrapper.classList.add("CodeMirror-active"); }); + cm.on('mousedown', (cm, event) => toggleContextMenuDelete.call(cm, event)); var resizeGrip = cm.display.wrapper.appendChild(document.createElement("div")); resizeGrip.className = "resize-grip"; @@ -1168,11 +1169,28 @@ function initHooks() { document.querySelector("#lint h2").addEventListener("click", toggleLintReport); } + document.querySelectorAll( + 'input:not([type]), input[type="text"], input[type="search"], input[type="number"]') + .forEach(e => e.addEventListener('mousedown', toggleContextMenuDelete)); + setupGlobalSearch(); setCleanGlobal(); updateTitle(); } + +function toggleContextMenuDelete(event) { + if (event.button == 2) { + chrome.contextMenus.update('editDeleteText', { + enabled: Boolean( + this.selectionStart != this.selectionEnd || + this.somethingSelected && this.somethingSelected() + ), + }); + } +} + + function maximizeCodeHeight(sectionDiv, isLast) { var cm = sectionDiv.CodeMirror; var stats = maximizeCodeHeight.stats = maximizeCodeHeight.stats || {totalHeight: 0, deltas: []}; @@ -1662,6 +1680,10 @@ chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { if (request.prefName == "editor.smartIndent") { CodeMirror.setOption("smartIndent", request.value); } + break; + case 'editDeleteText': + document.execCommand('delete'); + break; } });