Prevent importing styles with no section. Fixes #687

And prevent issues with existing styles with no section
This commit is contained in:
Rob Garrison 2019-04-14 11:14:51 -05:00
parent b48817fe01
commit 4d488769fb
10 changed files with 35 additions and 23 deletions

View File

@ -358,7 +358,7 @@ const styleManager = (() => {
if (match === 'excluded') { if (match === 'excluded') {
excluded = true; excluded = true;
} }
for (const section of data.sections) { for (const section of (data.sections || [])) {
if (styleCodeEmpty(section.code)) { if (styleCodeEmpty(section.code)) {
continue; continue;
} }

View File

@ -170,7 +170,6 @@ preinit();
$('#name').title = usercss ? t('usercssReplaceTemplateName') : ''; $('#name').title = usercss ? t('usercssReplaceTemplateName') : '';
$('#preview-label').classList.toggle('hidden', !style.id); $('#preview-label').classList.toggle('hidden', !style.id);
$('#beautify').onclick = () => beautify(editor.getEditors()); $('#beautify').onclick = () => beautify(editor.getEditors());
$('#lint').addEventListener('scroll', hideLintHeaderOnScroll, {passive: true}); $('#lint').addEventListener('scroll', hideLintHeaderOnScroll, {passive: true});
window.addEventListener('resize', () => debounce(rememberWindowSize, 100)); window.addEventListener('resize', () => debounce(rememberWindowSize, 100));
@ -341,19 +340,20 @@ function initStyleData() {
// TODO: remove .replace(/^\?/, '') when minimum_chrome_version >= 52 (https://crbug.com/601425) // TODO: remove .replace(/^\?/, '') when minimum_chrome_version >= 52 (https://crbug.com/601425)
const params = new URLSearchParams(location.search.replace(/^\?/, '')); const params = new URLSearchParams(location.search.replace(/^\?/, ''));
const id = Number(params.get('id')); const id = Number(params.get('id'));
const createEmptyStyle = () => ({ const createNewSection = () => [
name: params.get('domain') ||
tryCatch(() => new URL(params.get('url-prefix')).hostname) ||
'',
enabled: true,
sections: [
Object.assign({code: ''}, Object.assign({code: ''},
...Object.keys(CssToProperty) ...Object.keys(CssToProperty)
.map(name => ({ .map(name => ({
[CssToProperty[name]]: params.get(name) && [params.get(name)] || [] [CssToProperty[name]]: params.get(name) && [params.get(name)] || []
})) }))
) )
], ];
const createEmptyStyle = () => ({
name: params.get('domain') ||
tryCatch(() => new URL(params.get('url-prefix')).hostname) ||
'',
enabled: true,
sections: createNewSection(),
}); });
return fetchStyle() return fetchStyle()
.then(style => { .then(style => {
@ -372,7 +372,12 @@ function initStyleData() {
function fetchStyle() { function fetchStyle() {
if (id) { if (id) {
return API.getStyle(id); return API.getStyle(id).then(style => {
if (!style.sections || !style.sections.length) {
style.sections = createNewSection();
}
return style;
});
} }
return Promise.resolve(createEmptyStyle()); return Promise.resolve(createEmptyStyle());
} }

View File

@ -46,7 +46,7 @@ function createSectionsEditor({style, onTitleChanged}) {
let sectionOrder = ''; let sectionOrder = '';
const initializing = new Promise(resolve => initSection({ const initializing = new Promise(resolve => initSection({
sections: style.sections.slice(), sections: (style.sections || []).slice(),
done:() => { done:() => {
// FIXME: implement this with CSS? // FIXME: implement this with CSS?
// https://github.com/openstyles/stylus/commit/2895ce11e271788df0e4f7314b3b981fde086574 // https://github.com/openstyles/stylus/commit/2895ce11e271788df0e4f7314b3b981fde086574
@ -436,7 +436,7 @@ function createSectionsEditor({style, onTitleChanged}) {
function chunk() { function chunk() {
if (!originalSections.length) { if (!originalSections.length) {
setGlobalProgress(); setGlobalProgress();
if (focusOn !== false) { if (focusOn !== false && sections[focusOn]) {
setTimeout(() => sections[focusOn].cm.focus()); setTimeout(() => sections[focusOn].cm.focus());
} }
container.classList.remove('hidden'); container.classList.remove('hidden');
@ -545,7 +545,7 @@ function createSectionsEditor({style, onTitleChanged}) {
updateSectionOrder(); updateSectionOrder();
} }
function replaceSections(originalSections) { function replaceSections(originalSections = []) {
for (const section of sections) { for (const section of sections) {
section.remove(true); section.remove(true);
} }

View File

@ -18,7 +18,7 @@ function createSourceEditor({style, onTitleChanged}) {
const dirty = dirtyReporter(); const dirty = dirtyReporter();
// normalize style // normalize style
if (!style.id) setupNewStyle(style); if (!style.id || !style.sections.length) setupNewStyle(style);
const cm = cmFactory.create($('.single-editor'), { const cm = cmFactory.create($('.single-editor'), {
value: style.sourceCode, value: style.sourceCode,
@ -123,6 +123,7 @@ function createSourceEditor({style, onTitleChanged}) {
} }
function setupNewStyle(style) { function setupNewStyle(style) {
if (!style.sections) style.sections = [];
style.sections[0].code = ' '.repeat(prefs.get('editor.tabSize')) + style.sections[0].code = ' '.repeat(prefs.get('editor.tabSize')) +
`/* ${t('usercssReplaceTemplateSectionBody')} */`; `/* ${t('usercssReplaceTemplateSectionBody')} */`;
let section = sectionsToMozFormat(style); let section = sectionsToMozFormat(style);

View File

@ -103,7 +103,7 @@ function sectionsToMozFormat(style) {
domains: 'domain', domains: 'domain',
regexps: 'regexp', regexps: 'regexp',
}; };
return style.sections.map(section => { return (style.sections || []).map(section => {
let cssMds = []; let cssMds = [];
for (const i in propertyToCss) { for (const i in propertyToCss) {
if (section[i]) { if (section[i]) {

View File

@ -365,7 +365,7 @@
function getAppliesTo(style) { function getAppliesTo(style) {
function *_gen() { function *_gen() {
for (const section of style.sections) { for (const section of (style.sections || [])) {
for (const type of ['urls', 'urlPrefixes', 'domains', 'regexps']) { for (const type of ['urls', 'urlPrefixes', 'domains', 'regexps']) {
if (section[type]) { if (section[type]) {
yield *section[type]; yield *section[type];

View File

@ -290,8 +290,12 @@ function ignoreChromeError() {
function getStyleWithNoCode(style) { function getStyleWithNoCode(style) {
const stripped = deepCopy(style); const stripped = deepCopy(style);
if (stripped.sections && stripped.sections.length) {
for (const section of stripped.sections) section.code = null; for (const section of stripped.sections) section.code = null;
stripped.sourceCode = null; stripped.sourceCode = null;
} else {
stripped.sections = []; // Fixes #687
}
return stripped; return stripped;
} }

View File

@ -71,7 +71,7 @@ const usercss = (() => {
if (!sections.length || errors && !allowErrors) { if (!sections.length || errors && !allowErrors) {
throw errors; throw errors;
} }
style.sections = sections; style.sections = sections || [];
return allowErrors ? {style, errors} : style; return allowErrors ? {style, errors} : style;
}); });
} }

View File

@ -148,7 +148,9 @@ function importFromString(jsonString) {
!item || !item ||
!item.name || !item.name ||
!item.name.trim() || !item.name.trim() ||
(item.sections && !Array.isArray(item.sections))) { !item.sections ||
!Array.isArray(item.sections)
) {
stats.invalid.names.push(`#${index}: ${limitString(item && item.name || '')}`); stats.invalid.names.push(`#${index}: ${limitString(item && item.name || '')}`);
return; return;
} }

View File

@ -230,7 +230,7 @@ function createStyleElement({style, name}) {
// clear the code to free up some memory // clear the code to free up some memory
// (note, style is already a deep copy) // (note, style is already a deep copy)
style.sourceCode = null; style.sourceCode = null;
style.sections.forEach(section => (section.code = null)); (style.sections || []).forEach(section => (section.code = null));
const entry = parts.entry.cloneNode(true); const entry = parts.entry.cloneNode(true);
entry.id = ENTRY_ID_PREFIX_RAW + style.id; entry.id = ENTRY_ID_PREFIX_RAW + style.id;
@ -266,7 +266,7 @@ function createStyleTargetsElement({entry, style}) {
let numTargets = 0; let numTargets = 0;
const displayed = new Set(); const displayed = new Set();
for (const type of TARGET_TYPES) { for (const type of TARGET_TYPES) {
for (const section of style.sections) { for (const section of (style.sections || [])) {
for (const targetValue of section[type] || []) { for (const targetValue of section[type] || []) {
if (displayed.has(targetValue)) { if (displayed.has(targetValue)) {
continue; continue;