UNPKG

nehan

Version:

Html layout engine for paged-media written in Typescript

116 lines 3.66 kB
import { Utils, Display, WhiteSpace, } from "./public-api"; let collapse_skip_tags = [ "a", "(text)", "::before", "::after", "br", "ruby", "rp", "rb", "rt", "b", "strong", ]; export class MarginCollapse { static collapse(element) { if (!this.isTarget(element)) { return; } let before = Utils.atoi(element.computedStyle.getPropertyValue("margin-before") || "0px"); let prev_max = this.getMaxAfterOfBefore(element); let new_before = (prev_max >= before) ? 0 : before - prev_max; element.computedStyle.setProperty("margin-before", String(new_before) + "px"); let after = Utils.atoi(element.computedStyle.getPropertyValue("margin-after") || "0px"); let parent_max = this.getMaxAfterOfParent(element); let new_after = (parent_max >= after) ? 0 : after - parent_max; element.computedStyle.setProperty("margin-after", String(new_after) + "px"); } static hasBorder(element, dir) { let prop = "border-" + dir + "-width"; let value = element.computedStyle.getPropertyValue(prop) || "0px"; let size = Utils.atoi(value); return size > 0; } static getMaxAfterOfBefore(element) { if (this.hasBorder(element, "before")) { return 0; } let prev = element.previousSibling, max = 0; while (prev) { if (WhiteSpace.isWhiteSpaceElement(prev)) { prev = prev.previousSibling; continue; } if (!this.isTarget(prev) || this.hasBorder(prev, "after")) { break; } let size = Utils.atoi(prev.computedStyle.getPropertyValue("margin-after") || "0px"); if (size > max) { max = size; } prev = prev.lastChild; if (!prev) { break; } } return max; } static getMaxAfterOfParent(element) { if (this.hasBorder(element, "after")) { return 0; } let parent = element.parent, max = 0; if (!parent || parent.lastChild !== element) { return 0; } while (parent) { if (!this.isTarget(parent)) { break; } let size = Utils.atoi(parent.computedStyle.getPropertyValue("margin-after") || "0px"); if (size > max) { max = size; } if (!parent.parent) { break; } let last = parent.parent.lastChild; if (last === null) { break; } while (WhiteSpace.isWhiteSpaceElement(last)) { last = last.previousSibling; if (last === null) { break; } } if (parent !== last) { break; } parent = parent.parent; } return max; } static isTarget(element) { if (element.parent === null) { return false; } if (element.isTextElement()) { return false; } if (collapse_skip_tags.indexOf(element.tagName) >= 0) { return false; } let float = element.computedStyle.getPropertyValue("float") || "none"; if (float !== "none") { return false; } let display = Display.load(element); if (display.isBlockLevel() === false) { return false; } return true; } } //# sourceMappingURL=margin-collapse.js.map