diff --git a/background/style-manager.js b/background/style-manager.js index 1560f13e..02d051e2 100644 --- a/background/style-manager.js +++ b/background/style-manager.js @@ -358,7 +358,7 @@ const styleManager = (() => { if (match === 'excluded') { excluded = true; } - for (const section of data.sections) { + for (const section of (data.sections || [])) { if (styleCodeEmpty(section.code)) { continue; } diff --git a/edit/edit.js b/edit/edit.js index 78b6e78c..0c0d6d3e 100644 --- a/edit/edit.js +++ b/edit/edit.js @@ -170,7 +170,6 @@ preinit(); $('#name').title = usercss ? t('usercssReplaceTemplateName') : ''; $('#preview-label').classList.toggle('hidden', !style.id); - $('#beautify').onclick = () => beautify(editor.getEditors()); $('#lint').addEventListener('scroll', hideLintHeaderOnScroll, {passive: true}); window.addEventListener('resize', () => debounce(rememberWindowSize, 100)); @@ -341,19 +340,20 @@ function initStyleData() { // TODO: remove .replace(/^\?/, '') when minimum_chrome_version >= 52 (https://crbug.com/601425) const params = new URLSearchParams(location.search.replace(/^\?/, '')); const id = Number(params.get('id')); + const createNewSection = () => [ + Object.assign({code: ''}, + ...Object.keys(CssToProperty) + .map(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: [ - Object.assign({code: ''}, - ...Object.keys(CssToProperty) - .map(name => ({ - [CssToProperty[name]]: params.get(name) && [params.get(name)] || [] - })) - ) - ], + sections: createNewSection(), }); return fetchStyle() .then(style => { @@ -372,7 +372,12 @@ function initStyleData() { function fetchStyle() { 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()); } diff --git a/edit/sections-editor.js b/edit/sections-editor.js index 99772f2b..ac72c63e 100644 --- a/edit/sections-editor.js +++ b/edit/sections-editor.js @@ -46,7 +46,7 @@ function createSectionsEditor({style, onTitleChanged}) { let sectionOrder = ''; const initializing = new Promise(resolve => initSection({ - sections: style.sections.slice(), + sections: (style.sections || []).slice(), done:() => { // FIXME: implement this with CSS? // https://github.com/openstyles/stylus/commit/2895ce11e271788df0e4f7314b3b981fde086574 @@ -436,7 +436,7 @@ function createSectionsEditor({style, onTitleChanged}) { function chunk() { if (!originalSections.length) { setGlobalProgress(); - if (focusOn !== false) { + if (focusOn !== false && sections[focusOn]) { setTimeout(() => sections[focusOn].cm.focus()); } container.classList.remove('hidden'); @@ -545,7 +545,7 @@ function createSectionsEditor({style, onTitleChanged}) { updateSectionOrder(); } - function replaceSections(originalSections) { + function replaceSections(originalSections = []) { for (const section of sections) { section.remove(true); } diff --git a/edit/source-editor.js b/edit/source-editor.js index 7119cfa5..310c319b 100644 --- a/edit/source-editor.js +++ b/edit/source-editor.js @@ -18,7 +18,7 @@ function createSourceEditor({style, onTitleChanged}) { const dirty = dirtyReporter(); // normalize style - if (!style.id) setupNewStyle(style); + if (!style.id || !style.sections.length) setupNewStyle(style); const cm = cmFactory.create($('.single-editor'), { value: style.sourceCode, @@ -123,6 +123,7 @@ function createSourceEditor({style, onTitleChanged}) { } function setupNewStyle(style) { + if (!style.sections) style.sections = []; style.sections[0].code = ' '.repeat(prefs.get('editor.tabSize')) + `/* ${t('usercssReplaceTemplateSectionBody')} */`; let section = sectionsToMozFormat(style); diff --git a/edit/util.js b/edit/util.js index cc18b515..7a522b2a 100644 --- a/edit/util.js +++ b/edit/util.js @@ -103,7 +103,7 @@ function sectionsToMozFormat(style) { domains: 'domain', regexps: 'regexp', }; - return style.sections.map(section => { + return (style.sections || []).map(section => { let cssMds = []; for (const i in propertyToCss) { if (section[i]) { diff --git a/install-usercss/install-usercss.js b/install-usercss/install-usercss.js index afbd6419..53da010d 100644 --- a/install-usercss/install-usercss.js +++ b/install-usercss/install-usercss.js @@ -365,7 +365,7 @@ function getAppliesTo(style) { function *_gen() { - for (const section of style.sections) { + for (const section of (style.sections || [])) { for (const type of ['urls', 'urlPrefixes', 'domains', 'regexps']) { if (section[type]) { yield *section[type]; diff --git a/js/messaging.js b/js/messaging.js index 1ab433b5..8d4ac72b 100644 --- a/js/messaging.js +++ b/js/messaging.js @@ -290,8 +290,12 @@ function ignoreChromeError() { function getStyleWithNoCode(style) { const stripped = deepCopy(style); - for (const section of stripped.sections) section.code = null; - stripped.sourceCode = null; + if (stripped.sections && stripped.sections.length) { + for (const section of stripped.sections) section.code = null; + stripped.sourceCode = null; + } else { + stripped.sections = []; // Fixes #687 + } return stripped; } diff --git a/js/usercss.js b/js/usercss.js index deebcbbb..bfe62bb4 100644 --- a/js/usercss.js +++ b/js/usercss.js @@ -71,7 +71,7 @@ const usercss = (() => { if (!sections.length || errors && !allowErrors) { throw errors; } - style.sections = sections; + style.sections = sections || []; return allowErrors ? {style, errors} : style; }); } diff --git a/manage/import-export.js b/manage/import-export.js index 1a2f1d15..7f4ed619 100644 --- a/manage/import-export.js +++ b/manage/import-export.js @@ -148,7 +148,9 @@ function importFromString(jsonString) { !item || !item.name || !item.name.trim() || - (item.sections && !Array.isArray(item.sections))) { + !item.sections || + !Array.isArray(item.sections) + ) { stats.invalid.names.push(`#${index}: ${limitString(item && item.name || '')}`); return; } diff --git a/manage/manage.js b/manage/manage.js index 741fc9bc..f6e90894 100644 --- a/manage/manage.js +++ b/manage/manage.js @@ -230,7 +230,7 @@ function createStyleElement({style, name}) { // clear the code to free up some memory // (note, style is already a deep copy) style.sourceCode = null; - style.sections.forEach(section => (section.code = null)); + (style.sections || []).forEach(section => (section.code = null)); const entry = parts.entry.cloneNode(true); entry.id = ENTRY_ID_PREFIX_RAW + style.id; @@ -266,7 +266,7 @@ function createStyleTargetsElement({entry, style}) { let numTargets = 0; const displayed = new Set(); for (const type of TARGET_TYPES) { - for (const section of style.sections) { + for (const section of (style.sections || [])) { for (const targetValue of section[type] || []) { if (displayed.has(targetValue)) { continue;