Ensure the bottom of dashboard panes is visible

Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/1304

On small displays, not being able to scroll down
could become a usability issue.
This commit is contained in:
Raymond Hill 2020-10-21 12:50:24 -04:00
parent a33b44b0ff
commit b75758808e
No known key found for this signature in database
GPG key ID: 25E1490B761470C2
7 changed files with 57 additions and 41 deletions

View file

@ -2,6 +2,9 @@
0% { transform: rotate(0deg); } 0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); } 100% { transform: rotate(360deg); }
} }
body {
margin-bottom: 6rem;
}
#actions { #actions {
background-color: var(--default-surface); background-color: var(--default-surface);
padding: var(--default-gap-small) 0 var(--default-gap-xsmall) 0; padding: var(--default-gap-small) 0 var(--default-gap-xsmall) 0;

View file

@ -1,3 +1,6 @@
body {
margin-bottom: 6rem;
}
.entries { .entries {
margin: 0.5em 0; margin: 0.5em 0;
margin-inline-start: 2em; margin-inline-start: 2em;

View file

@ -12,6 +12,9 @@
height: 100%; height: 100%;
width: 100%; width: 100%;
} }
.CodeMirror-lines {
padding-bottom: 6rem;
}
.CodeMirror-gutters { .CodeMirror-gutters {
background-color: var(--cm-gutter-surface); background-color: var(--cm-gutter-surface);
border-color: var(--cm-gutter-border); border-color: var(--cm-gutter-border);

View file

@ -1,3 +1,6 @@
body {
margin-bottom: 6rem;
}
.synopsis { .synopsis {
font-size: 90%; font-size: 90%;
} }

View file

@ -63,6 +63,17 @@ let cachedUserFilters = '';
/******************************************************************************/ /******************************************************************************/
const getEditorText = function() {
const text = cmEditor.getValue().replace(/\s+$/, '');
return text === '' ? text : text + '\n';
};
const setEditorText = function(text) {
cmEditor.setValue(text.replace(/\s+$/, '') + '\n\n');
};
/******************************************************************************/
// This is to give a visual hint that the content of user blacklist has changed. // This is to give a visual hint that the content of user blacklist has changed.
const userFiltersChanged = function(changed) { const userFiltersChanged = function(changed) {
@ -83,10 +94,7 @@ const renderUserFilters = async function() {
let content = details.content.trim(); let content = details.content.trim();
cachedUserFilters = content; cachedUserFilters = content;
if ( content.length !== 0 ) { setEditorText(content);
content += '\n';
}
cmEditor.setValue(content);
userFiltersChanged(false); userFiltersChanged(false);
}; };
@ -117,13 +125,10 @@ const handleImportFilePicker = function() {
const fileReaderOnLoadHandler = function() { const fileReaderOnLoadHandler = function() {
let content = abpImporter(this.result); let content = abpImporter(this.result);
content = uBlockDashboard.mergeNewLines( content = uBlockDashboard.mergeNewLines(getEditorText(), content);
cmEditor.getValue().trim(),
content
);
cmEditor.operation(( ) => { cmEditor.operation(( ) => {
const cmPos = cmEditor.getCursor(); const cmPos = cmEditor.getCursor();
cmEditor.setValue(`${content}\n`); setEditorText(content);
cmEditor.setCursor(cmPos); cmEditor.setCursor(cmPos);
cmEditor.focus(); cmEditor.focus();
}); });
@ -150,7 +155,7 @@ const startImportFilePicker = function() {
/******************************************************************************/ /******************************************************************************/
const exportUserFiltersToFile = function() { const exportUserFiltersToFile = function() {
const val = cmEditor.getValue().trim(); const val = getEditorText();
if ( val === '' ) { return; } if ( val === '' ) { return; }
const filename = vAPI.i18n('1pExportFilename') const filename = vAPI.i18n('1pExportFilename')
.replace('{{datetime}}', uBlockDashboard.dateNowToSensibleString()) .replace('{{datetime}}', uBlockDashboard.dateNowToSensibleString())
@ -166,7 +171,7 @@ const exportUserFiltersToFile = function() {
const applyChanges = async function() { const applyChanges = async function() {
const details = await vAPI.messaging.send('dashboard', { const details = await vAPI.messaging.send('dashboard', {
what: 'writeUserFilters', what: 'writeUserFilters',
content: cmEditor.getValue(), content: getEditorText(),
}); });
if ( details instanceof Object === false || details.error ) { return; } if ( details instanceof Object === false || details.error ) { return; }
@ -178,23 +183,19 @@ const applyChanges = async function() {
}; };
const revertChanges = function() { const revertChanges = function() {
let content = cachedUserFilters; setEditorText(cachedUserFilters);
if ( content.length !== 0 ) {
content += '\n';
}
cmEditor.setValue(content);
}; };
/******************************************************************************/ /******************************************************************************/
const getCloudData = function() { const getCloudData = function() {
return cmEditor.getValue(); return getEditorText();
}; };
const setCloudData = function(data, append) { const setCloudData = function(data, append) {
if ( typeof data !== 'string' ) { return; } if ( typeof data !== 'string' ) { return; }
if ( append ) { if ( append ) {
data = uBlockDashboard.mergeNewLines(cmEditor.getValue(), data); data = uBlockDashboard.mergeNewLines(getEditorText(), data);
} }
cmEditor.setValue(data); cmEditor.setValue(data);
}; };
@ -205,7 +206,7 @@ self.cloud.onPull = setCloudData;
/******************************************************************************/ /******************************************************************************/
self.hasUnsavedData = function() { self.hasUnsavedData = function() {
return cmEditor.getValue().trim() !== cachedUserFilters; return getEditorText().trim() !== cachedUserFilters;
}; };
/******************************************************************************/ /******************************************************************************/

View file

@ -39,7 +39,7 @@ const mergeView = new CodeMirror.MergeView(
lineWrapping: false, lineWrapping: false,
origLeft: '', origLeft: '',
revertButtons: true, revertButtons: true,
value: '' value: '',
} }
); );
mergeView.editor().setOption('styleActiveLine', true); mergeView.editor().setOption('styleActiveLine', true);

View file

@ -92,7 +92,7 @@ const cmEditor = new CodeMirror(
autofocus: true, autofocus: true,
lineNumbers: true, lineNumbers: true,
lineWrapping: true, lineWrapping: true,
styleActiveLine: true styleActiveLine: true,
} }
); );
@ -100,10 +100,21 @@ uBlockDashboard.patchCodeMirrorEditor(cmEditor);
/******************************************************************************/ /******************************************************************************/
const getEditorText = function() {
let text = cmEditor.getValue().replace(/\s+$/, '');
return text === '' ? text : text + '\n';
};
const setEditorText = function(text) {
cmEditor.setValue(text.replace(/\s+$/, '') + '\n');
};
/******************************************************************************/
const whitelistChanged = function() { const whitelistChanged = function() {
const whitelistElem = uDom.nodeFromId('whitelist'); const whitelistElem = uDom.nodeFromId('whitelist');
const bad = whitelistElem.querySelector('.cm-error') !== null; const bad = whitelistElem.querySelector('.cm-error') !== null;
const changedWhitelist = cmEditor.getValue().trim(); const changedWhitelist = getEditorText().trim();
const changed = changedWhitelist !== cachedWhitelist; const changed = changedWhitelist !== cachedWhitelist;
uDom.nodeFromId('whitelistApply').disabled = !changed || bad; uDom.nodeFromId('whitelistApply').disabled = !changed || bad;
uDom.nodeFromId('whitelistRevert').disabled = !changed; uDom.nodeFromId('whitelistRevert').disabled = !changed;
@ -144,12 +155,9 @@ const renderWhitelist = async function() {
} }
return ad.localeCompare(bd); return ad.localeCompare(bd);
}); });
let whitelistStr = details.whitelist.join('\n').trim(); const whitelistStr = details.whitelist.join('\n').trim();
cachedWhitelist = whitelistStr; cachedWhitelist = whitelistStr;
if ( whitelistStr !== '' ) { setEditorText(whitelistStr);
whitelistStr += '\n';
}
cmEditor.setValue(whitelistStr);
if ( first ) { if ( first ) {
cmEditor.clearHistory(); cmEditor.clearHistory();
} }
@ -164,11 +172,8 @@ const handleImportFilePicker = function() {
const fr = new FileReader(); const fr = new FileReader();
fr.onload = ev => { fr.onload = ev => {
if ( ev.type !== 'load' ) { return; } if ( ev.type !== 'load' ) { return; }
cmEditor.setValue( setEditorText(
[ [ getEditorText().trim(), fr.result.trim() ].join('\n').trim()
cmEditor.getValue().trim(),
fr.result.trim()
].join('\n').trim()
); );
}; };
fr.readAsText(file); fr.readAsText(file);
@ -188,7 +193,7 @@ const startImportFilePicker = function() {
/******************************************************************************/ /******************************************************************************/
const exportWhitelistToFile = function() { const exportWhitelistToFile = function() {
const val = cmEditor.getValue().trim(); const val = getEditorText();
if ( val === '' ) { return; } if ( val === '' ) { return; }
const filename = const filename =
vAPI.i18n('whitelistExportFilename') vAPI.i18n('whitelistExportFilename')
@ -203,7 +208,7 @@ const exportWhitelistToFile = function() {
/******************************************************************************/ /******************************************************************************/
const applyChanges = async function() { const applyChanges = async function() {
cachedWhitelist = cmEditor.getValue().trim(); cachedWhitelist = getEditorText().trim();
await messaging.send('dashboard', { await messaging.send('dashboard', {
what: 'setWhitelist', what: 'setWhitelist',
whitelist: cachedWhitelist, whitelist: cachedWhitelist,
@ -212,23 +217,21 @@ const applyChanges = async function() {
}; };
const revertChanges = function() { const revertChanges = function() {
let content = cachedWhitelist; setEditorText(cachedWhitelist);
if ( content !== '' ) { content += '\n'; }
cmEditor.setValue(content);
}; };
/******************************************************************************/ /******************************************************************************/
const getCloudData = function() { const getCloudData = function() {
return cmEditor.getValue(); return getEditorText();
}; };
const setCloudData = function(data, append) { const setCloudData = function(data, append) {
if ( typeof data !== 'string' ) { return; } if ( typeof data !== 'string' ) { return; }
if ( append ) { if ( append ) {
data = uBlockDashboard.mergeNewLines(cmEditor.getValue().trim(), data); data = uBlockDashboard.mergeNewLines(getEditorText().trim(), data);
} }
cmEditor.setValue(data.trim() + '\n'); setEditorText(data.trim());
}; };
self.cloud.onPush = getCloudData; self.cloud.onPush = getCloudData;
@ -237,7 +240,7 @@ self.cloud.onPull = setCloudData;
/******************************************************************************/ /******************************************************************************/
self.hasUnsavedData = function() { self.hasUnsavedData = function() {
return cmEditor.getValue().trim() !== cachedWhitelist; return getEditorText().trim() !== cachedWhitelist;
}; };
/******************************************************************************/ /******************************************************************************/