Diffdown is a real-time collaborative Markdown editor/previewer built on the AT Protocol
diffdown.com
1var C = "\u037c"
2var COUNT = typeof Symbol == "undefined" ? "__" + C : Symbol.for(C)
3var SET = typeof Symbol == "undefined" ? "__styleSet" + Math.floor(Math.random() * 1e8) : Symbol("styleSet")
4var top = typeof globalThis != "undefined" ? globalThis : typeof window != "undefined" ? window : {}
5
6// :: - Style modules encapsulate a set of CSS rules defined from
7// JavaScript. Their definitions are only available in a given DOM
8// root after it has been _mounted_ there with `StyleModule.mount`.
9//
10// Style modules should be created once and stored somewhere, as
11// opposed to re-creating them every time you need them. The amount of
12// CSS rules generated for a given DOM root is bounded by the amount
13// of style modules that were used. So to avoid leaking rules, don't
14// create these dynamically, but treat them as one-time allocations.
15var StyleModule = exports.StyleModule = function StyleModule(spec, options) {
16 this.rules = []
17 var ref = options || {};
18 var finish = ref.finish;
19
20 function splitSelector(selector) {
21 return /^@/.test(selector) ? [selector] : selector.split(/,\s*/)
22 }
23
24 function render(selectors, spec, target, isKeyframes) {
25 var local = [], isAt = /^@(\w+)\b/.exec(selectors[0]), keyframes = isAt && isAt[1] == "keyframes"
26 if (isAt && spec == null) { return target.push(selectors[0] + ";") }
27 for (var prop in spec) {
28 var value = spec[prop]
29 if (/&/.test(prop)) {
30 render(prop.split(/,\s*/).map(function (part) { return selectors.map(function (sel) { return part.replace(/&/, sel); }); }).reduce(function (a, b) { return a.concat(b); }),
31 value, target)
32 } else if (value && typeof value == "object") {
33 if (!isAt) { throw new RangeError("The value of a property (" + prop + ") should be a primitive value.") }
34 render(splitSelector(prop), value, local, keyframes)
35 } else if (value != null) {
36 local.push(prop.replace(/_.*/, "").replace(/[A-Z]/g, function (l) { return "-" + l.toLowerCase(); }) + ": " + value + ";")
37 }
38 }
39 if (local.length || keyframes) {
40 target.push((finish && !isAt && !isKeyframes ? selectors.map(finish) : selectors).join(", ") +
41 " {" + local.join(" ") + "}")
42 }
43 }
44
45 for (var prop in spec) { render(splitSelector(prop), spec[prop], this.rules) }
46};
47
48// :: () → string
49// Returns a string containing the module's CSS rules.
50StyleModule.prototype.getRules = function getRules () { return this.rules.join("\n") };
51
52// :: () → string
53// Generate a new unique CSS class name.
54StyleModule.newName = function newName () {
55 var id = top[COUNT] || 1
56 top[COUNT] = id + 1
57 return C + id.toString(36)
58};
59
60// :: (union<Document, ShadowRoot>, union<[StyleModule], StyleModule>, ?{nonce: ?string})
61//
62// Mount the given set of modules in the given DOM root, which ensures
63// that the CSS rules defined by the module are available in that
64// context.
65//
66// Rules are only added to the document once per root.
67//
68// Rule order will follow the order of the modules, so that rules from
69// modules later in the array take precedence of those from earlier
70// modules. If you call this function multiple times for the same root
71// in a way that changes the order of already mounted modules, the old
72// order will be changed.
73//
74// If a Content Security Policy nonce is provided, it is added to
75// the `<style>` tag generated by the library.
76StyleModule.mount = function mount (root, modules, options) {
77 var set = root[SET], nonce = options && options.nonce
78 if (!set) { set = new StyleSet(root, nonce) }
79 else if (nonce) { set.setNonce(nonce) }
80 set.mount(Array.isArray(modules) ? modules : [modules], root)
81};
82
83var adoptedSet = new Map //<Document, StyleSet>
84
85var StyleSet = function StyleSet(root, nonce) {
86 var doc = root.ownerDocument || root, win = doc.defaultView
87 if (!root.head && root.adoptedStyleSheets && win.CSSStyleSheet) {
88 var adopted = adoptedSet.get(doc)
89 if (adopted) { return root[SET] = adopted }
90 this.sheet = new win.CSSStyleSheet
91 adoptedSet.set(doc, this)
92 } else {
93 this.styleTag = doc.createElement("style")
94 if (nonce) { this.styleTag.setAttribute("nonce", nonce) }
95 }
96 this.modules = []
97 root[SET] = this
98};
99
100StyleSet.prototype.mount = function mount (modules, root) {
101 var sheet = this.sheet
102 var pos = 0 /* Current rule offset */, j = 0 /* Index into this.modules */
103 for (var i = 0; i < modules.length; i++) {
104 var mod = modules[i], index = this.modules.indexOf(mod)
105 if (index < j && index > -1) { // Ordering conflict
106 this.modules.splice(index, 1)
107 j--
108 index = -1
109 }
110 if (index == -1) {
111 this.modules.splice(j++, 0, mod)
112 if (sheet) { for (var k = 0; k < mod.rules.length; k++)
113 { sheet.insertRule(mod.rules[k], pos++) } }
114 } else {
115 while (j < index) { pos += this.modules[j++].rules.length }
116 pos += mod.rules.length
117 j++
118 }
119 }
120
121 if (sheet) {
122 if (root.adoptedStyleSheets.indexOf(this.sheet) < 0)
123 { root.adoptedStyleSheets = [this.sheet ].concat( root.adoptedStyleSheets) }
124 } else {
125 var text = ""
126 for (var i$1 = 0; i$1 < this.modules.length; i$1++)
127 { text += this.modules[i$1].getRules() + "\n" }
128 this.styleTag.textContent = text
129 var target = root.head || root
130 if (this.styleTag.parentNode != target)
131 { target.insertBefore(this.styleTag, target.firstChild) }
132 }
133};
134
135StyleSet.prototype.setNonce = function setNonce (nonce) {
136 if (this.styleTag && this.styleTag.getAttribute("nonce") != nonce)
137 { this.styleTag.setAttribute("nonce", nonce) }
138};
139
140// Style::Object<union<Style,string>>
141//
142// A style is an object that, in the simple case, maps CSS property
143// names to strings holding their values, as in `{color: "red",
144// fontWeight: "bold"}`. The property names can be given in
145// camel-case—the library will insert a dash before capital letters
146// when converting them to CSS.
147//
148// If you include an underscore in a property name, it and everything
149// after it will be removed from the output, which can be useful when
150// providing a property multiple times, for browser compatibility
151// reasons.
152//
153// A property in a style object can also be a sub-selector, which
154// extends the current context to add a pseudo-selector or a child
155// selector. Such a property should contain a `&` character, which
156// will be replaced by the current selector. For example `{"&:before":
157// {content: '"hi"'}}`. Sub-selectors and regular properties can
158// freely be mixed in a given object. Any property containing a `&` is
159// assumed to be a sub-selector.
160//
161// Finally, a property can specify an @-block to be wrapped around the
162// styles defined inside the object that's the property's value. For
163// example to create a media query you can do `{"@media screen and
164// (min-width: 400px)": {...}}`.
165