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); }
100% { transform: rotate(360deg); }
}
body {
margin-bottom: 6rem;
}
#actions {
background-color: var(--default-surface);
padding: var(--default-gap-small) 0 var(--default-gap-xsmall) 0;

View file

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

View file

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

View file

@ -1,3 +1,6 @@
body {
margin-bottom: 6rem;
}
.synopsis {
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.
const userFiltersChanged = function(changed) {
@ -83,10 +94,7 @@ const renderUserFilters = async function() {
let content = details.content.trim();
cachedUserFilters = content;
if ( content.length !== 0 ) {
content += '\n';
}
cmEditor.setValue(content);
setEditorText(content);
userFiltersChanged(false);
};
@ -117,13 +125,10 @@ const handleImportFilePicker = function() {
const fileReaderOnLoadHandler = function() {
let content = abpImporter(this.result);
content = uBlockDashboard.mergeNewLines(
cmEditor.getValue().trim(),
content
);
content = uBlockDashboard.mergeNewLines(getEditorText(), content);
cmEditor.operation(( ) => {
const cmPos = cmEditor.getCursor();
cmEditor.setValue(`${content}\n`);
setEditorText(content);
cmEditor.setCursor(cmPos);
cmEditor.focus();
});
@ -150,7 +155,7 @@ const startImportFilePicker = function() {
/******************************************************************************/
const exportUserFiltersToFile = function() {
const val = cmEditor.getValue().trim();
const val = getEditorText();
if ( val === '' ) { return; }
const filename = vAPI.i18n('1pExportFilename')
.replace('{{datetime}}', uBlockDashboard.dateNowToSensibleString())
@ -166,7 +171,7 @@ const exportUserFiltersToFile = function() {
const applyChanges = async function() {
const details = await vAPI.messaging.send('dashboard', {
what: 'writeUserFilters',
content: cmEditor.getValue(),
content: getEditorText(),
});
if ( details instanceof Object === false || details.error ) { return; }
@ -178,23 +183,19 @@ const applyChanges = async function() {
};
const revertChanges = function() {
let content = cachedUserFilters;
if ( content.length !== 0 ) {
content += '\n';
}
cmEditor.setValue(content);
setEditorText(cachedUserFilters);
};
/******************************************************************************/
const getCloudData = function() {
return cmEditor.getValue();
return getEditorText();
};
const setCloudData = function(data, append) {
if ( typeof data !== 'string' ) { return; }
if ( append ) {
data = uBlockDashboard.mergeNewLines(cmEditor.getValue(), data);
data = uBlockDashboard.mergeNewLines(getEditorText(), data);
}
cmEditor.setValue(data);
};
@ -205,7 +206,7 @@ self.cloud.onPull = setCloudData;
/******************************************************************************/
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,
origLeft: '',
revertButtons: true,
value: ''
value: '',
}
);
mergeView.editor().setOption('styleActiveLine', true);

View file

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