avoid overwriting existing usercss on saving a new one

This commit is contained in:
tophf 2018-08-18 23:17:20 +03:00
parent 4bcdbb78b1
commit c0c5f1dbcc
4 changed files with 42 additions and 10 deletions

View File

@ -1259,6 +1259,10 @@
"message": "Specify @name in the code",
"description": "Placeholder text for the empty name input field when creating a new Usercss style"
},
"usercssAvoidOverwriting": {
"message": "Please change the value of @name or @namespace to avoid overwriting an existing style.",
"description": "Shown in a message box when attempting to save a new Usercss style that would overwrite an existing one."
},
"usercssReplaceTemplateConfirmation": {
"message": "Replace the default template for new Usercss styles with the current code?"
},

View File

@ -65,10 +65,21 @@
return style;
}
// Parse the source and find the duplication
function build({sourceCode, checkDup = false}) {
return buildMeta({sourceCode})
.then(usercss.buildCode)
/**
* Parse the source and find the duplication
* @param _
* @param {String} _.sourceCode
* @param {Boolean=} _.checkDup
* @param {Boolean=} _.metaOnly
* @returns {Promise<{style, dup:Boolean?}>}
*/
function build({
sourceCode,
checkDup,
metaOnly,
}) {
const task = buildMeta({sourceCode});
return (metaOnly ? task : task.then(usercss.buildCode))
.then(style => ({
style,
dup: checkDup && find(style),

View File

@ -122,11 +122,11 @@ function createSourceEditor(style) {
style.sourceCode = '';
chromeSync.getLZValue('usercssTemplate').then(code => {
const name = style.name || t('usercssReplaceTemplateName');
const date = new Date().toLocaleString();
code = code || DEFAULT_CODE;
code = code.replace(/@name(\s*)(?=[\r\n])/, (str, space) =>
`${str}${space ? '' : ' '}${
style.name ||
t('usercssReplaceTemplateName') + ' - ' + new Date().toLocaleString()}`);
`${str}${space ? '' : ' '}${name} - ${date}`);
// strip the last dummy section if any, add an empty line followed by the section
style.sourceCode = code.replace(/\s*@-moz-document[^{]*\{[^}]*\}\s*$|\s+$/g, '') + '\n\n' + section;
cm.startOperation();
@ -202,8 +202,8 @@ function createSourceEditor(style) {
function save() {
if (!dirty.isDirty()) return;
const code = cm.getValue();
return (
API.saveUsercssUnsafe({
return ensureUniqueStyle(code)
.then(() => API.saveUsercssUnsafe({
id: style.id,
reason: 'editSave',
enabled: style.enabled,
@ -214,6 +214,7 @@ function createSourceEditor(style) {
if (errors) return Promise.reject(errors);
})
.catch(err => {
if (err.handled) return;
if (err.message === t('styleMissingMeta', 'name')) {
messageBox.confirm(t('usercssReplaceTemplateConfirmation')).then(ok => ok &&
chromeSync.setLZValue('usercssTemplate', code)
@ -233,6 +234,20 @@ function createSourceEditor(style) {
});
}
function ensureUniqueStyle(code) {
return style.id ? Promise.resolve() :
API.buildUsercss({
sourceCode: code,
checkDup: true,
metaOnly: true,
}).then(({dup}) => {
if (dup) {
messageBox.alert(t('usercssAvoidOverwriting'), 'danger', t('genericError'));
return Promise.reject({handled: true});
}
});
}
function drawLinePointer(pos) {
const SIZE = 60;
const line = cm.getLine(pos.line);

View File

@ -150,10 +150,12 @@ function messageBox({
/**
* @param {String|Node|Array<String|Node>} contents
* @param {String} [className] like 'pre' for monospace font
* @param {String} [title]
* @returns {Promise<Boolean>} same as messageBox
*/
messageBox.alert = (contents, className) =>
messageBox.alert = (contents, className, title) =>
messageBox({
title,
contents,
className: `center ${className || ''}`,
buttons: [t('confirmClose')]