Fix: parallel import
This commit is contained in:
parent
4d06435486
commit
f08faea149
|
@ -19,6 +19,7 @@ window.API_METHODS = Object.assign(window.API_METHODS || {}, {
|
|||
importStyle: styleManager.importStyle,
|
||||
styleExists: styleManager.styleExists,
|
||||
getStyle: styleManager.get,
|
||||
getAllStyles: styleManager.getAllStyles, // used by importer
|
||||
|
||||
getTabUrlPrefix() {
|
||||
return this.sender.tab.url.match(/^([\w-]+:\/+[^/#]+)/)[1];
|
||||
|
|
|
@ -56,8 +56,12 @@ const styleManager = (() => {
|
|||
port = null;
|
||||
if (id) {
|
||||
const style = styles.get(id);
|
||||
if (!style) {
|
||||
// maybe deleted
|
||||
return;
|
||||
}
|
||||
style.preview = null;
|
||||
broadcastStyleUpdated(style.data, 'editPreview');
|
||||
broadcastStyleUpdated(style.data, 'editPreviewEnd');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -128,7 +132,7 @@ const styleManager = (() => {
|
|||
function importStyle(data) {
|
||||
// FIXME: is it a good idea to save the data directly?
|
||||
return saveStyle(data)
|
||||
.then(newData => handleSave(newData));
|
||||
.then(newData => handleSave(newData, 'import'));
|
||||
}
|
||||
|
||||
function installStyle(data) {
|
||||
|
|
|
@ -56,19 +56,14 @@ function importFromFile({fileTypeFilter, file} = {}) {
|
|||
}
|
||||
|
||||
|
||||
function importFromString(jsonString, oldStyles) {
|
||||
if (!oldStyles) {
|
||||
return API.getStylesInfo().then(styles => importFromString(jsonString, styles));
|
||||
}
|
||||
function importFromString(jsonString) {
|
||||
const json = tryJSONparse(jsonString);
|
||||
if (!Array.isArray(json)) {
|
||||
return Promise.reject(new Error('the backup is not a valid JSON file'));
|
||||
}
|
||||
const oldStylesById = new Map(
|
||||
oldStyles.map(style => [style.id, style]));
|
||||
const oldStylesByName = json.length && new Map(
|
||||
oldStyles.map(style => [style.name.trim(), style]));
|
||||
|
||||
let oldStyles;
|
||||
let oldStylesById;
|
||||
let oldStylesByName;
|
||||
const stats = {
|
||||
added: {names: [], ids: [], legend: 'importReportLegendAdded'},
|
||||
unchanged: {names: [], ids: [], legend: 'importReportLegendIdentical'},
|
||||
|
@ -78,27 +73,25 @@ function importFromString(jsonString, oldStyles) {
|
|||
invalid: {names: [], legend: 'importReportLegendInvalid'},
|
||||
};
|
||||
|
||||
let index = 0;
|
||||
let lastRenderTime = performance.now();
|
||||
const renderQueue = [];
|
||||
const RENDER_NAP_TIME_MAX = 1000; // ms
|
||||
const RENDER_QUEUE_MAX = 50; // number of styles
|
||||
return proceed();
|
||||
|
||||
function proceed() {
|
||||
while (index < json.length) {
|
||||
const item = json[index++];
|
||||
const info = analyze(item);
|
||||
if (!info) {
|
||||
continue;
|
||||
return API.getAllStyles().then(styles => {
|
||||
// make a copy of the current database, that may be used when we want to
|
||||
// undo
|
||||
oldStyles = styles;
|
||||
oldStylesById = new Map(
|
||||
oldStyles.map(style => [style.id, style]));
|
||||
oldStylesByName = json.length && new Map(
|
||||
oldStyles.map(style => [style.name.trim(), style]));
|
||||
return Promise.all(json.map((item, i) => {
|
||||
const info = analyze(item, i);
|
||||
if (info) {
|
||||
return API.importStyle(item)
|
||||
.then(style => updateStats(style, info));
|
||||
}
|
||||
return API.importStyle(item)
|
||||
.then(style => account({style, info}));
|
||||
}
|
||||
return done();
|
||||
}
|
||||
}));
|
||||
})
|
||||
.then(done);
|
||||
|
||||
function analyze(item) {
|
||||
function analyze(item, index) {
|
||||
if (typeof item !== 'object' ||
|
||||
!item ||
|
||||
!item.name ||
|
||||
|
@ -142,18 +135,6 @@ function importFromString(jsonString, oldStyles) {
|
|||
.some(field => oldStyle[field] && oldStyle[field] === newStyle[field]);
|
||||
}
|
||||
|
||||
function account({style, info}) {
|
||||
renderQueue.push(style);
|
||||
if (performance.now() - lastRenderTime > RENDER_NAP_TIME_MAX
|
||||
|| renderQueue.length > RENDER_QUEUE_MAX) {
|
||||
setTimeout(scrollElementIntoView, 0, $('#style-' + renderQueue.pop().id));
|
||||
renderQueue.length = 0;
|
||||
lastRenderTime = performance.now();
|
||||
}
|
||||
updateStats(style, info);
|
||||
return proceed();
|
||||
}
|
||||
|
||||
function updateStats(style, {oldStyle, metaEqual, codeEqual}) {
|
||||
if (!oldStyle) {
|
||||
stats.added.names.push(style.name);
|
||||
|
|
|
@ -48,7 +48,8 @@ function onRuntimeMessage(msg) {
|
|||
switch (msg.method) {
|
||||
case 'styleUpdated':
|
||||
case 'styleAdded':
|
||||
handleUpdate(msg.style, msg);
|
||||
API.getStylesInfo({id: msg.style.id})
|
||||
.then(([style]) => handleUpdate(style, msg));
|
||||
break;
|
||||
case 'styleDeleted':
|
||||
handleDelete(msg.style.id);
|
||||
|
@ -521,7 +522,7 @@ function handleUpdate(style, {reason, method} = {}) {
|
|||
if (reason === 'editPreview') return;
|
||||
// the style was toggled and refreshAllTabs() sent a mini-notification,
|
||||
// but we've already processed 'styleUpdated' sent directly from notifyAllTabs()
|
||||
if (!style.sections) return;
|
||||
// if (!style.sections) return;
|
||||
let entry;
|
||||
let oldEntry = $(ENTRY_ID_PREFIX + style.id);
|
||||
if (oldEntry && method === 'styleUpdated') {
|
||||
|
|
|
@ -25,10 +25,14 @@ getActiveTab()
|
|||
)
|
||||
.then(url => Promise.all([
|
||||
(tabURL = URLS.supported(url) ? url : '') &&
|
||||
API.getStylesInfoByUrl(tabURL),
|
||||
API.getStylesInfoByUrl(tabURL),
|
||||
onDOMready().then(initPopup),
|
||||
]))
|
||||
.then(([results]) => {
|
||||
if (!results) {
|
||||
// unsupported URL;
|
||||
return;
|
||||
}
|
||||
showStyles(results.map(r => Object.assign(r.data, r)));
|
||||
})
|
||||
.catch(console.error);
|
||||
|
|
Loading…
Reference in New Issue
Block a user