From 20141b7bfa7f840bd21a597ad437b4d8d2278cfb Mon Sep 17 00:00:00 2001 From: tophf Date: Sat, 11 Jul 2015 17:35:04 +0300 Subject: [PATCH] Editor: add global-replace/replaceAll commands * Collateral fix: correctly restore openDialog() after Esc * refactor html templates --- _locales/en/messages.json | 24 +++++ edit.html | 9 ++ edit.js | 211 ++++++++++++++++++++++++++++++-------- 3 files changed, 201 insertions(+), 43 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index b594d71f..580ef244 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -100,6 +100,18 @@ "message": "Theme", "description": "Label for the style editor's CSS theme." }, + "confirmNo": { + "message": "No", + "description": "'No' button in a confirm dialog" + }, + "confirmStop": { + "message": "Stop", + "description": "'Stop' button in a confirm dialog" + }, + "confirmYes": { + "message": "Yes", + "description": "'Yes' button in a confirm dialog" + }, "dbError": { "message": "An error has occurred using the Stylish database. Would you like to visit a web page with possible solutions?", "description": "Prompt when a DB error is encountered" @@ -229,6 +241,18 @@ "message": "Show number of styles active for the current site on the toolbar button", "description": "Label for the checkbox controlling toolbar badge text." }, + "replace": { + "message": "Replace", + "description": "Label before the replace input field in the editor shown on Ctrl-H" + }, + "replaceAll": { + "message": "Replace all", + "description": "Label before the replace input field in the editor shown on 'replaceAll' hotkey" + }, + "replaceWith": { + "message": "Replace with", + "description": "Label before the replace-with input field in the editor shown on Ctrl-H etc." + }, "search": { "message": "Search", "description": "Label before the search input field in the editor shown on Ctrl-F" diff --git a/edit.html b/edit.html index 680fb56e..18d67a66 100644 --- a/edit.html +++ b/edit.html @@ -160,6 +160,15 @@ outline: -webkit-focus-ring-color auto 5px; outline-offset: -2px; } + .CodeMirror-search-field { + width: 10em; + } + .CodeMirror-jump-field { + width: 5em; + } + .CodeMirror-search-hint { + color: #888; + } @-webkit-keyframes highlight { from { background-color: #ff9; diff --git a/edit.js b/edit.js index d1cf8b61..7ad00314 100644 --- a/edit.js +++ b/edit.js @@ -10,8 +10,8 @@ var useHistoryBack; // use browser history back when "back to manage" is click var propertyToCss = {urls: "url", urlPrefixes: "url-prefix", domains: "domain", regexps: "regexp"}; var CssToProperty = {"url": "urls", "url-prefix": "urlPrefixes", "domain": "domains", "regexp": "regexps"}; -// templates -var appliesToTemplate = tHTML('\ +var template = { +appliesTo: '\
  • \ \ @@ -46,12 +44,44 @@ var sectionTemplate = tHTML('\ \ \ \ -'); - -var findTemplate = t("search") + ':  ' + - '(' + t("searchRegexp") + ')'; - -var jumpToLineTemplate = t('editGotoLine') + ': '; + ', +find: '\ + : \ +  \ + ()\ + \ + ', +replace: '\ + : \ +  \ + ()\ + \ + ', +replaceAll: '\ + : \ +  \ + ()\ + \ + ', +replaceWith: '\ + : \ + \ + \ + ', +replaceConfirm: '\ + ? \ +  \ +  \ + \ + \ + ', +jumpToLine: '\ + : \ + \ + \ + ' +} +Object.keys(template).forEach(function(name) { template[name] = tHTML(template[name]); }); // make querySelectorAll enumeration code readable ["forEach", "some", "indexOf"].forEach(function(method) { @@ -61,6 +91,12 @@ var jumpToLineTemplate = t('editGotoLine') + ': = 0) { + if (dlg) { + dlg.remove(); + } + doReplace(); + } + } + }); + originalOpenConfirm.call(cm, template.replaceConfirm.innerHTML, ovrCallbacks, opt); + }; + } + } + + function replaceAll(cm) { + replace(cm, true); + } + CodeMirror.commands.find = find; CodeMirror.commands.findNext = findNext; CodeMirror.commands.findPrev = findPrev; + CodeMirror.commands.replace = replace; + CodeMirror.commands.replaceAll = replaceAll; } function jumpToLine(cm) { var cur = cm.getCursor(); - cm.openDialog(jumpToLineTemplate, function(str) { + cm.openDialog(template.jumpToLine.innerHTML, function(str) { var m = str.match(/^\s*(\d+)(?:\s*:\s*(\d+))?\s*$/); if (m) { cm.setCursor(m[1] - 1, m[2] ? m[2] - 1 : cur.ch); @@ -1087,7 +1212,7 @@ function validate() { // validate the regexps if (document.querySelectorAll(".applies-to-list").some(function(list) { return list.childNodes.some(function(li) { - if (li.className == appliesToEverythingTemplate.className) { + if (li.className == template.appliesToEverything.className) { return false; } var valueElement = li.querySelector("[name=applies-value]"); @@ -1153,7 +1278,7 @@ function getSections() { function getMeta(e) { var meta = {}; e.querySelector(".applies-to-list").childNodes.forEach(function(li) { - if (li.className == appliesToEverythingTemplate.className) { + if (li.className == template.appliesToEverything.className) { return; } var type = li.querySelector("[name=applies-type]").value;