diff --git a/lib/hacks/grid-utils.js b/lib/hacks/grid-utils.js index e959faa94..8b5438172 100644 --- a/lib/hacks/grid-utils.js +++ b/lib/hacks/grid-utils.js @@ -345,13 +345,20 @@ function parseTemplate ({ // Insert parsed grid areas -function getMSDecls (area) { +/** + * Get an array of -ms- prefixed props and values + * @param {Object} [area] area object with columm and row data + * @param {Boolean} [addRowSpan] should we add grid-column-row value? + * @param {Boolean} [addColumnSpan] should we add grid-column-span value? + * @return {Array} + */ +function getMSDecls (area, addRowSpan = false, addColumnSpan = false) { return [].concat( { prop: '-ms-grid-row', value: String(area.row.start) }, - area.row.span > 1 ? { + (area.row.span > 1 || addRowSpan) ? { prop: '-ms-grid-row-span', value: String(area.row.span) } : [], @@ -359,7 +366,7 @@ function getMSDecls (area) { prop: '-ms-grid-column', value: String(area.column.start) }, - area.column.span > 1 ? { + (area.column.span > 1 || addColumnSpan) ? { prop: '-ms-grid-column-span', value: String(area.column.span) } : [] @@ -375,6 +382,44 @@ function getParentMedia (parent) { return getParentMedia(parent.parent) } +/** + * Check grid-template(-areas) rules with the same selector for + * -ms-grid-(row|column)-span values. If initial and compared values are + * different - return an array of boolean values which need to be updated + * @param {Declaration} decl + * @param {Object} area area object with column and row data + * @param {String} areaName area name (e.g. "head") + * @return {Array} + */ +function shouldAddSpan (decl, area, areaName) { + const root = decl.root() + const rule = decl.parent + const overrideValues = [false, false] + + root.walkRules(rule.selector, node => { + // abort if we are on the same rule + if (rule.toString() === node.toString()) { + return false + } + + node.walkDecls('grid-template', d => { + const template = parseTemplate({ decl: d, gap: getGridGap(d) }) + const comparedArea = template.areas[areaName] + if (area.row.span !== comparedArea.row.span) { + overrideValues[0] = true + } else if (area.column.span !== comparedArea.column.span) { + overrideValues[1] = true + } + + return undefined + }) + + return undefined + }) + + return overrideValues +} + function insertAreas (areas, decl, result) { let missed = Object.keys(areas) @@ -397,7 +442,8 @@ function insertAreas (areas, decl, result) { rule.removeAll() // insert prefixed decls in new rule - getMSDecls(area) + const [addRowSpan, addColumnSpan] = shouldAddSpan(decl, area, value) + getMSDecls(area, addRowSpan, addColumnSpan) .forEach(i => rule.append( Object.assign(i, { raws: { diff --git a/test/cases/grid-template.out.css b/test/cases/grid-template.out.css index 32604010c..ace8dff67 100644 --- a/test/cases/grid-template.out.css +++ b/test/cases/grid-template.out.css @@ -87,9 +87,11 @@ .head { -ms-grid-row: 1; -ms-grid-column: 1; + -ms-grid-column-span: 1; } .nav { -ms-grid-row: 2; + -ms-grid-row-span: 1; -ms-grid-column: 1; } .main { @@ -389,11 +391,13 @@ @media (min-width: 600px) { .k-1 { -ms-grid-row: 1; + -ms-grid-row-span: 1; -ms-grid-column: 1; } .k-2 { -ms-grid-row: 1; -ms-grid-column: 3; + -ms-grid-column-span: 1; } }