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