Editor: preserve intermediary global sections on import
Because the order of sections influences which rules will apply when several matching rules are present both in a global section and previously declared scoped one.
This commit is contained in:
parent
426b4d37ba
commit
ad8706e107
97
edit.js
97
edit.js
|
@ -1332,19 +1332,24 @@ function fromMozillaFormat() {
|
||||||
popup.querySelector(".close-icon").click();
|
popup.querySelector(".close-icon").click();
|
||||||
var mozStyle = trimNewLines(popup.codebox.getValue());
|
var mozStyle = trimNewLines(popup.codebox.getValue());
|
||||||
var parser = new exports.css.Parser(), lines = mozStyle.split("\n");
|
var parser = new exports.css.Parser(), lines = mozStyle.split("\n");
|
||||||
var sectionStack = [{code: "", cursor: {line: 1, col: 1}}];
|
var sectionStack = [{code: "", start: {line: 1, col: 1}}];
|
||||||
var errors = "", oldSectionCount = editors.length;
|
var errors = "", oldSectionCount = editors.length;
|
||||||
|
var firstAddedCM;
|
||||||
|
|
||||||
parser.addListener("startdocument", function(e) {
|
parser.addListener("startdocument", function(e) {
|
||||||
var outerText = getRange(sectionStack.last.cursor, (--e.col, e));
|
var outerText = getRange(sectionStack.last.start, (--e.col, e));
|
||||||
var gapComment = outerText.match(/(\/\*[\s\S]*?\*\/)[\s\n]*$/);
|
var gapComment = outerText.match(/(\/\*[\s\S]*?\*\/)[\s\n]*$/);
|
||||||
var section = {code: "", cursor: backtrackTo(this, exports.css.Tokens.LBRACE, "end")};
|
var section = {code: "", start: backtrackTo(this, exports.css.Tokens.LBRACE, "end")};
|
||||||
// move last comment before @-moz-document inside the section
|
// move last comment before @-moz-document inside the section
|
||||||
if (gapComment && !gapComment[1].match(/\/\*\s*AGENT_SHEET\s*\*\//)) {
|
if (gapComment && !gapComment[1].match(/\/\*\s*AGENT_SHEET\s*\*\//)) {
|
||||||
section.code = gapComment[1] + "\n";
|
section.code = gapComment[1] + "\n";
|
||||||
outerText = trimNewLines(outerText.substring(0, gapComment.index));
|
outerText = trimNewLines(outerText.substring(0, gapComment.index));
|
||||||
}
|
}
|
||||||
addContinuation(sectionStack.last, outerText);
|
if (outerText) {
|
||||||
|
sectionStack.last.code = outerText;
|
||||||
|
doAddSection(sectionStack.last);
|
||||||
|
sectionStack.last.code = "";
|
||||||
|
}
|
||||||
e.functions.forEach(function(f) {
|
e.functions.forEach(function(f) {
|
||||||
var m = f.match(/^(url|url-prefix|domain|regexp)\((['"]?)(.+?)\2?\)$/);
|
var m = f.match(/^(url|url-prefix|domain|regexp)\((['"]?)(.+?)\2?\)$/);
|
||||||
var aType = CssToProperty[m[1]];
|
var aType = CssToProperty[m[1]];
|
||||||
|
@ -1355,50 +1360,27 @@ function fromMozillaFormat() {
|
||||||
});
|
});
|
||||||
|
|
||||||
parser.addListener("enddocument", function(e) {
|
parser.addListener("enddocument", function(e) {
|
||||||
var cursor = backtrackTo(this, exports.css.Tokens.RBRACE, "start");
|
var end = backtrackTo(this, exports.css.Tokens.RBRACE, "start");
|
||||||
var section = sectionStack.pop();
|
var section = sectionStack.pop();
|
||||||
addContinuation(section, getRange(section.cursor, cursor));
|
section.code += getRange(section.start, end);
|
||||||
sectionStack.last.cursor = (++cursor.col, cursor);
|
sectionStack.last.start = (++end.col, end);
|
||||||
doAddSection(section);
|
doAddSection(section);
|
||||||
});
|
});
|
||||||
|
|
||||||
parser.addListener("endstylesheet", function() {
|
parser.addListener("endstylesheet", function() {
|
||||||
// add nonclosed (broken) outer sections except for the global one
|
// add nonclosed outer sections (either broken or the last global one)
|
||||||
sectionStack.slice(1).forEach(doAddSection);
|
var endOfText = {line: lines.length, col: lines.last.length + 1};
|
||||||
|
sectionStack.last.code += getRange(sectionStack.last.start, endOfText);
|
||||||
if (!replaceOldStyle) {
|
sectionStack.forEach(doAddSection);
|
||||||
var lastOldCM = editors[oldSectionCount - 1];
|
|
||||||
var lastOldSection = lastOldCM.getSection();
|
|
||||||
var addAfter = {target: lastOldSection.querySelector(".add-section")};
|
|
||||||
|
|
||||||
if (oldSectionCount < editors.length
|
|
||||||
&& lastOldCM.getValue() == ""
|
|
||||||
&& lastOldSection.querySelector(".applies-to-everything")) {
|
|
||||||
removeSection(addAfter);
|
|
||||||
oldSectionCount--;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var addAfter = {target: editors[0].getSection().previousElementSibling.firstElementChild};
|
|
||||||
}
|
|
||||||
|
|
||||||
var globalSection = sectionStack[0];
|
|
||||||
addContinuation(globalSection,
|
|
||||||
getRange(sectionStack.last.cursor, {line: lines.length, col: lines.last.length + 1}));
|
|
||||||
// only add global section if it contains actual code
|
|
||||||
if (globalSection.code
|
|
||||||
.replace("@namespace url(http://www.w3.org/1999/xhtml);", "") /* strip boilerplate NS */
|
|
||||||
.replace(/\/\*[\s\S]*?\*\//g, "") /* strip comments */
|
|
||||||
.replace(/[\s\n]/g, "")) { /* strip all whitespace including new lines */
|
|
||||||
setCleanItem(addSection(addAfter, {code: globalSection.code}), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete maximizeCodeHeight.stats;
|
delete maximizeCodeHeight.stats;
|
||||||
editors.forEach(function(cm, i) {
|
editors.forEach(function(cm) {
|
||||||
maximizeCodeHeight(cm.getSection(), i == editors.length - 1);
|
maximizeCodeHeight(cm.getSection(), cm == editors.last);
|
||||||
});
|
});
|
||||||
|
|
||||||
makeSectionVisible(editors[oldSectionCount]);
|
makeSectionVisible(firstAddedCM);
|
||||||
editors[oldSectionCount].focus();
|
firstAddedCM.focus();
|
||||||
|
|
||||||
if (errors) {
|
if (errors) {
|
||||||
showHelp(t("issues"), errors);
|
showHelp(t("issues"), errors);
|
||||||
}
|
}
|
||||||
|
@ -1412,7 +1394,7 @@ function fromMozillaFormat() {
|
||||||
|
|
||||||
function getRange(start, end) {
|
function getRange(start, end) {
|
||||||
if (start.line == end.line) {
|
if (start.line == end.line) {
|
||||||
return lines[start.line - 1].substring(start.col - 1, end.col - 1).trim();
|
return lines[start.line - 1].substr(start.col - 1, end.col - start.col + 1).trim();
|
||||||
} else {
|
} else {
|
||||||
return trimNewLines(lines[start.line - 1].substr(start.col - 1) + "\n" +
|
return trimNewLines(lines[start.line - 1].substr(start.col - 1) + "\n" +
|
||||||
lines.slice(start.line, end.line - 1).join("\n") +
|
lines.slice(start.line, end.line - 1).join("\n") +
|
||||||
|
@ -1420,13 +1402,36 @@ function fromMozillaFormat() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function doAddSection(section) {
|
function doAddSection(section) {
|
||||||
if (replaceOldStyle && oldSectionCount > 0) {
|
if (!firstAddedCM) {
|
||||||
oldSectionCount = 0;
|
if (!initFirstSection(section)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// don't add empty sections
|
||||||
|
if (!(section.code || section.urls || section.urlPrefixes || section.domains || section.regexps)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setCleanItem(addSection(null, section), false);
|
||||||
|
firstAddedCM = firstAddedCM || editors.last;
|
||||||
|
}
|
||||||
|
// do onetime housekeeping as the imported text is confirmed to be a valid style
|
||||||
|
function initFirstSection(section) {
|
||||||
|
// skip adding the first global section when there's no code/comments
|
||||||
|
if (!section.code.replace("@namespace url(http://www.w3.org/1999/xhtml);", "") /* ignore boilerplate NS */
|
||||||
|
.replace(/[\s\n]/g, "")) { /* ignore all whitespace including new lines */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (replaceOldStyle) {
|
||||||
editors.slice(0).reverse().forEach(function(cm) {
|
editors.slice(0).reverse().forEach(function(cm) {
|
||||||
removeSection({target: cm.getSection().firstElementChild});
|
removeSection({target: cm.getSection().firstElementChild});
|
||||||
});
|
});
|
||||||
|
} else if (!editors.last.getValue()) {
|
||||||
|
// nuke the last blank section
|
||||||
|
if (editors.last.getSection().querySelector(".applies-to-everything")) {
|
||||||
|
removeSection({target: editors.last.getSection()});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setCleanItem(addSection(null, section), false);
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function backtrackTo(parser, tokenType, startEnd) {
|
function backtrackTo(parser, tokenType, startEnd) {
|
||||||
|
@ -1440,12 +1445,6 @@ function fromMozillaFormat() {
|
||||||
function trimNewLines(s) {
|
function trimNewLines(s) {
|
||||||
return s.replace(/^[\s\n]+/, "").replace(/[\s\n]+$/, "");
|
return s.replace(/^[\s\n]+/, "").replace(/[\s\n]+$/, "");
|
||||||
}
|
}
|
||||||
function addContinuation(section, addendum) {
|
|
||||||
section.code = section.code && addendum
|
|
||||||
? section.code + "\n/**************************/\n" + addendum
|
|
||||||
: section.code || addendum;
|
|
||||||
return section.code;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function showSectionHelp() {
|
function showSectionHelp() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user