Fix: refactor import-export
This commit is contained in:
parent
86ea846a89
commit
c55675912e
|
@ -1,11 +1,10 @@
|
||||||
/* global messageBox handleUpdate handleDelete styleSectionsEqual getOwnTab API
|
/* global messageBox styleSectionsEqual getOwnTab API
|
||||||
tryJSONparse scrollElementIntoView $ $$ API $create t animateElement */
|
tryJSONparse scrollElementIntoView $ $$ API $create t animateElement */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const STYLISH_DUMP_FILE_EXT = '.txt';
|
const STYLISH_DUMP_FILE_EXT = '.txt';
|
||||||
const STYLUS_BACKUP_FILE_EXT = '.json';
|
const STYLUS_BACKUP_FILE_EXT = '.json';
|
||||||
|
|
||||||
|
|
||||||
function importFromFile({fileTypeFilter, file} = {}) {
|
function importFromFile({fileTypeFilter, file} = {}) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const fileInput = document.createElement('input');
|
const fileInput = document.createElement('input');
|
||||||
|
@ -61,9 +60,9 @@ function importFromString(jsonString, oldStyles) {
|
||||||
if (!oldStyles) {
|
if (!oldStyles) {
|
||||||
return API.getStylesInfo().then(styles => importFromString(jsonString, styles));
|
return API.getStylesInfo().then(styles => importFromString(jsonString, styles));
|
||||||
}
|
}
|
||||||
const json = tryJSONparse(jsonString) || [];
|
const json = tryJSONparse(jsonString);
|
||||||
if (typeof json.slice !== 'function') {
|
if (!Array.isArray(json)) {
|
||||||
json.length = 0;
|
return Promise.reject(new Error('the backup is not a valid JSON file'));
|
||||||
}
|
}
|
||||||
const oldStylesById = new Map(
|
const oldStylesById = new Map(
|
||||||
oldStyles.map(style => [style.id, style]));
|
oldStyles.map(style => [style.id, style]));
|
||||||
|
@ -84,24 +83,19 @@ function importFromString(jsonString, oldStyles) {
|
||||||
const renderQueue = [];
|
const renderQueue = [];
|
||||||
const RENDER_NAP_TIME_MAX = 1000; // ms
|
const RENDER_NAP_TIME_MAX = 1000; // ms
|
||||||
const RENDER_QUEUE_MAX = 50; // number of styles
|
const RENDER_QUEUE_MAX = 50; // number of styles
|
||||||
const SAVE_OPTIONS = {reason: 'import', notify: false};
|
return proceed();
|
||||||
|
|
||||||
return new Promise(proceed);
|
function proceed() {
|
||||||
|
|
||||||
function proceed(resolve) {
|
|
||||||
while (index < json.length) {
|
while (index < json.length) {
|
||||||
const item = json[index++];
|
const item = json[index++];
|
||||||
const info = analyze(item);
|
const info = analyze(item);
|
||||||
if (info) {
|
if (!info) {
|
||||||
// using saveStyle directly since json was parsed in background page context
|
continue;
|
||||||
// FIXME: rewrite importStyle
|
|
||||||
return API.saveStyle(Object.assign(item, SAVE_OPTIONS))
|
|
||||||
.then(style => account({style, info, resolve}));
|
|
||||||
}
|
}
|
||||||
|
return API.importStyle(item)
|
||||||
|
.then(style => account({style, info}));
|
||||||
}
|
}
|
||||||
renderQueue.forEach(style => handleUpdate(style, {reason: 'import'}));
|
return done();
|
||||||
renderQueue.length = 0;
|
|
||||||
done(resolve);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function analyze(item) {
|
function analyze(item) {
|
||||||
|
@ -148,17 +142,19 @@ function importFromString(jsonString, oldStyles) {
|
||||||
.some(field => oldStyle[field] && oldStyle[field] === newStyle[field]);
|
.some(field => oldStyle[field] && oldStyle[field] === newStyle[field]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function account({style, info, resolve}) {
|
function account({style, info}) {
|
||||||
renderQueue.push(style);
|
renderQueue.push(style);
|
||||||
if (performance.now() - lastRenderTime > RENDER_NAP_TIME_MAX
|
if (performance.now() - lastRenderTime > RENDER_NAP_TIME_MAX
|
||||||
|| renderQueue.length > RENDER_QUEUE_MAX) {
|
|| renderQueue.length > RENDER_QUEUE_MAX) {
|
||||||
renderQueue.forEach(style => handleUpdate(style, {reason: 'import'}));
|
|
||||||
setTimeout(scrollElementIntoView, 0, $('#style-' + renderQueue.pop().id));
|
setTimeout(scrollElementIntoView, 0, $('#style-' + renderQueue.pop().id));
|
||||||
renderQueue.length = 0;
|
renderQueue.length = 0;
|
||||||
lastRenderTime = performance.now();
|
lastRenderTime = performance.now();
|
||||||
}
|
}
|
||||||
setTimeout(proceed, 0, resolve);
|
updateStats(style, info);
|
||||||
const {oldStyle, metaEqual, codeEqual} = info;
|
return proceed();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateStats(style, {oldStyle, metaEqual, codeEqual}) {
|
||||||
if (!oldStyle) {
|
if (!oldStyle) {
|
||||||
stats.added.names.push(style.name);
|
stats.added.names.push(style.name);
|
||||||
stats.added.ids.push(style.id);
|
stats.added.ids.push(style.id);
|
||||||
|
@ -178,12 +174,11 @@ function importFromString(jsonString, oldStyles) {
|
||||||
stats.metaOnly.ids.push(style.id);
|
stats.metaOnly.ids.push(style.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function done(resolve) {
|
function done() {
|
||||||
const numChanged = stats.metaAndCode.names.length +
|
const numChanged = stats.metaAndCode.names.length +
|
||||||
stats.metaOnly.names.length +
|
stats.metaOnly.names.length +
|
||||||
stats.codeOnly.names.length +
|
stats.codeOnly.names.length +
|
||||||
stats.added.names.length;
|
stats.added.names.length;
|
||||||
Promise.resolve(numChanged && API.refreshAllTabs()).then(() => {
|
|
||||||
const report = Object.keys(stats)
|
const report = Object.keys(stats)
|
||||||
.filter(kind => stats[kind].names.length)
|
.filter(kind => stats[kind].names.length)
|
||||||
.map(kind => {
|
.map(kind => {
|
||||||
|
@ -207,13 +202,13 @@ function importFromString(jsonString, oldStyles) {
|
||||||
contents: report.length ? report : t('importReportUnchanged'),
|
contents: report.length ? report : t('importReportUnchanged'),
|
||||||
buttons: [t('confirmClose'), numChanged && t('undo')],
|
buttons: [t('confirmClose'), numChanged && t('undo')],
|
||||||
onshow: bindClick,
|
onshow: bindClick,
|
||||||
}).then(({button}) => {
|
})
|
||||||
|
.then(({button}) => {
|
||||||
if (button === 1) {
|
if (button === 1) {
|
||||||
undo();
|
undo();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
resolve(numChanged);
|
return Promise.resolve(numChanged);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function undo() {
|
function undo() {
|
||||||
|
@ -224,24 +219,16 @@ function importFromString(jsonString, oldStyles) {
|
||||||
...stats.added.ids,
|
...stats.added.ids,
|
||||||
];
|
];
|
||||||
let tasks = Promise.resolve();
|
let tasks = Promise.resolve();
|
||||||
let tasksUI = Promise.resolve();
|
|
||||||
for (const id of newIds) {
|
for (const id of newIds) {
|
||||||
tasks = tasks.then(() => API.deleteStyle(id));
|
tasks = tasks.then(() => API.deleteStyle(id));
|
||||||
tasksUI = tasksUI.then(() => handleDelete(id));
|
|
||||||
const oldStyle = oldStylesById.get(id);
|
const oldStyle = oldStylesById.get(id);
|
||||||
if (oldStyle) {
|
if (oldStyle) {
|
||||||
Object.assign(oldStyle, SAVE_OPTIONS);
|
tasks = tasks.then(() => API.importStyle(oldStyle));
|
||||||
// FIXME: import undo
|
|
||||||
// tasks = tasks.then(() => API.saveStyle(oldStyle));
|
|
||||||
tasksUI = tasksUI.then(() => handleUpdate(oldStyle, {reason: 'import'}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// taskUI is superfast and updates style list only in this page,
|
// taskUI is superfast and updates style list only in this page,
|
||||||
// which should account for 99.99999999% of cases, supposedly
|
// which should account for 99.99999999% of cases, supposedly
|
||||||
return tasks
|
return tasks.then(() => messageBox({
|
||||||
.then(tasksUI)
|
|
||||||
.then(API.refreshAllTabs)
|
|
||||||
.then(() => messageBox({
|
|
||||||
title: t('importReportUndoneTitle'),
|
title: t('importReportUndoneTitle'),
|
||||||
contents: newIds.length + ' ' + t('importReportUndone'),
|
contents: newIds.length + ' ' + t('importReportUndone'),
|
||||||
buttons: [t('confirmClose')],
|
buttons: [t('confirmClose')],
|
||||||
|
|
Loading…
Reference in New Issue
Block a user