Browse Source

refactor: extract and reuse CalcRows

tophf 4 years ago
parent
commit
b399743d1e

+ 0 - 17
src/common/ui/index.js

@@ -49,20 +49,3 @@ export function showConfirmation(text, { ok, cancel, input = false } = {}) {
     });
   });
 }
-
-export function autofitElementsHeight(elems) {
-  elems.forEach((el) => {
-    el.addEventListener('input', autofitSingleElementHeight);
-    el::autofitSingleElementHeight();
-  });
-}
-
-/** @this {HTMLTextAreaElement} */
-function autofitSingleElementHeight() {
-  this.style.height = 0;
-  this.style.height = `${
-    Math.max(this.scrollHeight, 30)
-    + (this.offsetHeight - this.clientHeight) // borders
-    + 2 // some air for the cursor
-  }px`;
-}

+ 1 - 1
src/common/ui/setting-text.vue

@@ -9,7 +9,7 @@
       :disabled="disabled"
       :title="parsedData.error"
       :placeholder="placeholder"
-      :rows="rows"
+      :rows="rows || CalcRows(value)"
       @change="onChange"
     />
     <button v-if="hasSave" v-text="i18n('buttonSave')" @click="onSave"

+ 5 - 0
src/common/ui/style/index.js

@@ -1,3 +1,5 @@
+import Vue from 'vue';
+import { i18n } from '#/common';
 import options from '../../options';
 import './style.css';
 
@@ -73,3 +75,6 @@ options.hook((changes) => {
     style = setStyle(v, style);
   }
 });
+
+Vue.prototype.i18n = i18n;
+Vue.prototype.CalcRows = val => val && (val.match(/\n.|$/g).length + 1);

+ 0 - 1
src/confirm/index.js

@@ -8,7 +8,6 @@ import '#/common/ui/style';
 import App from './views/app';
 import './style.css';
 
-Vue.prototype.i18n = i18n;
 document.title = `${i18n('labelInstall')} - ${i18n('extName')}`;
 
 options.ready.then(() => {

+ 1 - 3
src/options/index.js

@@ -1,6 +1,6 @@
 import Vue from 'vue';
 import '#/common/browser';
-import { sendCmdDirectly, i18n, getLocaleString } from '#/common';
+import { sendCmdDirectly, getLocaleString } from '#/common';
 import handlers from '#/common/handlers';
 import { loadScriptIcon } from '#/common/load-script-icon';
 import options from '#/common/options';
@@ -8,8 +8,6 @@ import '#/common/ui/style';
 import { store } from './utils';
 import App from './views/app';
 
-Vue.prototype.i18n = i18n;
-
 Object.assign(store, {
   loading: false,
   sync: [],

+ 5 - 0
src/options/style.css

@@ -70,6 +70,11 @@ section {
     margin-bottom: .3rem;
   }
 }
+textarea:not([rows="1"]) {
+  resize: vertical;
+  min-height: 2em;
+  max-height: 50vh;
+}
 @media (min-width: 1600px) {
   .tab-settings[data-show-advanced] {
     padding-top: 0;

+ 1 - 1
src/options/views/edit/index.vue

@@ -96,7 +96,7 @@ const CUSTOM_LISTS = [
 const fromList = list => (
   list
     // Adding a new row so the user can click it and type, just like in an empty textarea.
-    ? `${list.join('\n')}\n`
+    ? `${list.join('\n')}${list.length ? '\n' : ''}`
     : ''
 );
 const toList = text => (

+ 1 - 7
src/options/views/edit/settings.vue

@@ -76,7 +76,7 @@
           </label>
         </td>
         <td>
-          <textarea v-model="custom[name]" spellcheck="false" ref="area"/>
+          <textarea v-model="custom[name]" spellcheck="false" :rows="CalcRows(custom[name])"/>
         </td>
       </tr>
     </table>
@@ -86,7 +86,6 @@
 <script>
 import { i18n } from '#/common';
 import { objectGet } from '#/common/object';
-import { autofitElementsHeight } from '#/common/ui';
 
 const highlightMetaKeys = str => str.match(/^(.*?)(@[-a-z]+)(.*)/)?.slice(1) || [str, '', ''];
 
@@ -129,7 +128,6 @@ export default {
     active(val) {
       if (val) {
         this.$refs.container.querySelector('input').focus();
-        autofitElementsHeight(this.$refs.area);
       }
     },
   },
@@ -181,9 +179,5 @@ $leftColWidth: 12rem;
     background: none;
     font-weight: bold;
   }
-  textarea {
-    resize: vertical;
-    min-height: 2em;
-  }
 }
 </style>

+ 0 - 3
src/options/views/tab-settings/index.vue

@@ -278,9 +278,6 @@ export default {
       vertical-align: text-bottom;
     }
   }
-  textarea {
-    height: 10em;
-  }
   input[type="number"] {
     width: 3.5em;
     padding-left: .25em;

+ 1 - 2
src/popup/index.js

@@ -1,6 +1,6 @@
 import Vue from 'vue';
 import '#/common/browser';
-import { i18n, sendCmdDirectly } from '#/common';
+import { sendCmdDirectly } from '#/common';
 import { INJECT_PAGE } from '#/common/consts';
 import handlers from '#/common/handlers';
 import { loadScriptIcon } from '#/common/load-script-icon';
@@ -10,7 +10,6 @@ import App from './views/app';
 import { mutex, store } from './utils';
 
 mutex.init();
-Vue.prototype.i18n = i18n;
 
 const vm = new Vue({
   render: h => h(App),

+ 3 - 5
src/popup/views/app.vue

@@ -117,7 +117,8 @@
             </div>
           </div>
           <div v-if="item.excludesValue != null" class="excludes-menu flex flex-col">
-            <textarea v-model="item.excludesValue" spellcheck="false"/>
+            <textarea v-model="item.excludesValue" spellcheck="false"
+                      :rows="CalcRows(item.excludesValue)"/>
             <div>
               <button v-text="i18n('buttonOK')" @click="onExcludeSave(item)"/>
               <button v-text="i18n('buttonCancel')" @click="onExcludeClose(item)"/>
@@ -186,7 +187,6 @@ import { INJECT_AUTO } from '#/common/consts';
 import options from '#/common/options';
 import { getScriptName, i18n, makePause, sendCmd, sendTabCmd } from '#/common';
 import { objectPick } from '#/common/object';
-import { autofitElementsHeight } from '#/common/ui';
 import Icon from '#/common/ui/icon';
 import { keyboardService, isInput } from '#/common/keyboard';
 import { mutex, store } from '../utils';
@@ -418,9 +418,7 @@ export default {
       ].join('\n');
       this.$nextTick(() => {
         // not using $refs because multiple items may show textareas
-        const area = item.el.querySelector('textarea');
-        autofitElementsHeight([area]);
-        area.focus();
+        item.el.querySelector('textarea').focus();
       });
     },
     onExcludeClose(item) {