├── README.md
├── alpine.js
├── android-chrome-192x192.png
├── android-chrome-512x512.png
├── apple-touch-icon.png
├── atom-one-dark.css
├── atom-one-light.css
├── demo.png
├── examples.html
├── favicon-16x16.png
├── favicon-32x32.png
├── favicon.ico
├── highlight.pack.js
├── index.html
├── logo.png
├── profile.png
├── ridge-dark.css
├── ridge-light.css
├── ridge.css
├── site.webmanifest
├── social.png
└── themes
├── ridge-valentines-dark.css
├── ridge-valentines-light.css
├── ridge-watermelon-dark.css
└── ridge-watermelon-light.css
/README.md:
--------------------------------------------------------------------------------
1 | # ridge.css
2 |
3 | > The clearest way into the Universe is through a forest wilderness. - John Muir
4 |
5 | ridge.css is a set of classless css themes, layout helpers via [pylon.css](https://github.com/almonk/pylon) and optional [alpine.js](https://github.com/alpinejs/alpine) code to help you write _fast web apps fast_
6 |
7 | ## Usage
8 | Try before you buy! Here's how your html could look after applying ridge.css (with the default dark theme)
9 |
10 | ```html
11 |
12 |
13 |
14 |
15 |
16 | ridge.css
17 |
18 |
19 |
20 |
21 |
22 |
23 | Cool logo
24 |
25 |
26 | Pricing
27 |
28 | Sign up
29 |
30 |
31 |
32 |
33 |
34 | Welcome to ridge.css!
35 |
36 |
37 |
38 |
39 | ```
40 |
41 | Here's a screenshot of how that looks:
42 |
43 | 
44 |
45 | ## Install
46 |
47 | Download a theme, and add it to your html:
48 |
49 | ```html
50 |
51 |
52 |
53 |
54 |
55 | ```
56 |
57 | The example above adds both light and dark default themes and switches depending on the OS's dark mode setting.
58 |
--------------------------------------------------------------------------------
/alpine.js:
--------------------------------------------------------------------------------
1 | (function (global, factory) {
2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3 | typeof define === 'function' && define.amd ? define(factory) :
4 | (global = global || self, global.Alpine = factory());
5 | }(this, (function () { 'use strict';
6 |
7 | function _defineProperty(obj, key, value) {
8 | if (key in obj) {
9 | Object.defineProperty(obj, key, {
10 | value: value,
11 | enumerable: true,
12 | configurable: true,
13 | writable: true
14 | });
15 | } else {
16 | obj[key] = value;
17 | }
18 |
19 | return obj;
20 | }
21 |
22 | function ownKeys(object, enumerableOnly) {
23 | var keys = Object.keys(object);
24 |
25 | if (Object.getOwnPropertySymbols) {
26 | var symbols = Object.getOwnPropertySymbols(object);
27 | if (enumerableOnly) symbols = symbols.filter(function (sym) {
28 | return Object.getOwnPropertyDescriptor(object, sym).enumerable;
29 | });
30 | keys.push.apply(keys, symbols);
31 | }
32 |
33 | return keys;
34 | }
35 |
36 | function _objectSpread2(target) {
37 | for (var i = 1; i < arguments.length; i++) {
38 | var source = arguments[i] != null ? arguments[i] : {};
39 |
40 | if (i % 2) {
41 | ownKeys(Object(source), true).forEach(function (key) {
42 | _defineProperty(target, key, source[key]);
43 | });
44 | } else if (Object.getOwnPropertyDescriptors) {
45 | Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
46 | } else {
47 | ownKeys(Object(source)).forEach(function (key) {
48 | Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
49 | });
50 | }
51 | }
52 |
53 | return target;
54 | }
55 |
56 | // Thanks @stimulus:
57 | // https://github.com/stimulusjs/stimulus/blob/master/packages/%40stimulus/core/src/application.ts
58 | function domReady() {
59 | return new Promise(resolve => {
60 | if (document.readyState == "loading") {
61 | document.addEventListener("DOMContentLoaded", resolve);
62 | } else {
63 | resolve();
64 | }
65 | });
66 | }
67 | function arrayUnique(array) {
68 | return Array.from(new Set(array));
69 | }
70 | function isTesting() {
71 | return navigator.userAgent.includes("Node.js") || navigator.userAgent.includes("jsdom");
72 | }
73 | function kebabCase(subject) {
74 | return subject.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/[_\s]/, '-').toLowerCase();
75 | }
76 | function walk(el, callback) {
77 | if (callback(el) === false) return;
78 | let node = el.firstElementChild;
79 |
80 | while (node) {
81 | walk(node, callback);
82 | node = node.nextElementSibling;
83 | }
84 | }
85 | function debounce(func, wait) {
86 | var timeout;
87 | return function () {
88 | var context = this,
89 | args = arguments;
90 |
91 | var later = function later() {
92 | timeout = null;
93 | func.apply(context, args);
94 | };
95 |
96 | clearTimeout(timeout);
97 | timeout = setTimeout(later, wait);
98 | };
99 | }
100 | function saferEval(expression, dataContext, additionalHelperVariables = {}) {
101 | return new Function(['$data', ...Object.keys(additionalHelperVariables)], `var result; with($data) { result = ${expression} }; return result`)(dataContext, ...Object.values(additionalHelperVariables));
102 | }
103 | function saferEvalNoReturn(expression, dataContext, additionalHelperVariables = {}) {
104 | // For the cases when users pass only a function reference to the caller: `x-on:click="foo"`
105 | // Where "foo" is a function. Also, we'll pass the function the event instance when we call it.
106 | if (Object.keys(dataContext).includes(expression)) {
107 | let methodReference = new Function(['dataContext', ...Object.keys(additionalHelperVariables)], `with(dataContext) { return ${expression} }`)(dataContext, ...Object.values(additionalHelperVariables));
108 |
109 | if (typeof methodReference === 'function') {
110 | return methodReference.call(dataContext, additionalHelperVariables['$event']);
111 | }
112 | }
113 |
114 | return new Function(['dataContext', ...Object.keys(additionalHelperVariables)], `with(dataContext) { ${expression} }`)(dataContext, ...Object.values(additionalHelperVariables));
115 | }
116 | const xAttrRE = /^x-(on|bind|data|text|html|model|if|for|show|cloak|transition|ref)\b/;
117 | function isXAttr(attr) {
118 | const name = replaceAtAndColonWithStandardSyntax(attr.name);
119 | return xAttrRE.test(name);
120 | }
121 | function getXAttrs(el, type) {
122 | return Array.from(el.attributes).filter(isXAttr).map(attr => {
123 | const name = replaceAtAndColonWithStandardSyntax(attr.name);
124 | const typeMatch = name.match(xAttrRE);
125 | const valueMatch = name.match(/:([a-zA-Z\-:]+)/);
126 | const modifiers = name.match(/\.[^.\]]+(?=[^\]]*$)/g) || [];
127 | return {
128 | type: typeMatch ? typeMatch[1] : null,
129 | value: valueMatch ? valueMatch[1] : null,
130 | modifiers: modifiers.map(i => i.replace('.', '')),
131 | expression: attr.value
132 | };
133 | }).filter(i => {
134 | // If no type is passed in for filtering, bypass filter
135 | if (!type) return true;
136 | return i.type === type;
137 | });
138 | }
139 | function isBooleanAttr(attrName) {
140 | // As per HTML spec table https://html.spec.whatwg.org/multipage/indices.html#attributes-3:boolean-attribute
141 | // Array roughly ordered by estimated usage
142 | const booleanAttributes = ['disabled', 'checked', 'required', 'readonly', 'hidden', 'open', 'selected', 'autofocus', 'itemscope', 'multiple', 'novalidate', 'allowfullscreen', 'allowpaymentrequest', 'formnovalidate', 'autoplay', 'controls', 'loop', 'muted', 'playsinline', 'default', 'ismap', 'reversed', 'async', 'defer', 'nomodule'];
143 | return booleanAttributes.includes(attrName);
144 | }
145 | function replaceAtAndColonWithStandardSyntax(name) {
146 | if (name.startsWith('@')) {
147 | return name.replace('@', 'x-on:');
148 | } else if (name.startsWith(':')) {
149 | return name.replace(':', 'x-bind:');
150 | }
151 |
152 | return name;
153 | }
154 | function transitionIn(el, show, forceSkip = false) {
155 | // We don't want to transition on the initial page load.
156 | if (forceSkip) return show();
157 | const attrs = getXAttrs(el, 'transition');
158 | const showAttr = getXAttrs(el, 'show')[0]; // If this is triggered by a x-show.transition.
159 |
160 | if (showAttr && showAttr.modifiers.includes('transition')) {
161 | let modifiers = showAttr.modifiers; // If x-show.transition.out, we'll skip the "in" transition.
162 |
163 | if (modifiers.includes('out') && !modifiers.includes('in')) return show();
164 | const settingBothSidesOfTransition = modifiers.includes('in') && modifiers.includes('out'); // If x-show.transition.in...out... only use "in" related modifiers for this transition.
165 |
166 | modifiers = settingBothSidesOfTransition ? modifiers.filter((i, index) => index < modifiers.indexOf('out')) : modifiers;
167 | transitionHelperIn(el, modifiers, show); // Otherwise, we can assume x-transition:enter.
168 | } else if (attrs.length > 0) {
169 | transitionClassesIn(el, attrs, show);
170 | } else {
171 | // If neither, just show that damn thing.
172 | show();
173 | }
174 | }
175 | function transitionOut(el, hide, forceSkip = false) {
176 | if (forceSkip) return hide();
177 | const attrs = getXAttrs(el, 'transition');
178 | const showAttr = getXAttrs(el, 'show')[0];
179 |
180 | if (showAttr && showAttr.modifiers.includes('transition')) {
181 | let modifiers = showAttr.modifiers;
182 | if (modifiers.includes('in') && !modifiers.includes('out')) return hide();
183 | const settingBothSidesOfTransition = modifiers.includes('in') && modifiers.includes('out');
184 | modifiers = settingBothSidesOfTransition ? modifiers.filter((i, index) => index > modifiers.indexOf('out')) : modifiers;
185 | transitionHelperOut(el, modifiers, settingBothSidesOfTransition, hide);
186 | } else if (attrs.length > 0) {
187 | transitionClassesOut(el, attrs, hide);
188 | } else {
189 | hide();
190 | }
191 | }
192 | function transitionHelperIn(el, modifiers, showCallback) {
193 | // Default values inspired by: https://material.io/design/motion/speed.html#duration
194 | const styleValues = {
195 | duration: modifierValue(modifiers, 'duration', 150),
196 | origin: modifierValue(modifiers, 'origin', 'center'),
197 | first: {
198 | opacity: 0,
199 | scale: modifierValue(modifiers, 'scale', 95)
200 | },
201 | second: {
202 | opacity: 1,
203 | scale: 100
204 | }
205 | };
206 | transitionHelper(el, modifiers, showCallback, () => {}, styleValues);
207 | }
208 | function transitionHelperOut(el, modifiers, settingBothSidesOfTransition, hideCallback) {
209 | // Make the "out" transition .5x slower than the "in". (Visually better)
210 | // HOWEVER, if they explicitly set a duration for the "out" transition,
211 | // use that.
212 | const duration = settingBothSidesOfTransition ? modifierValue(modifiers, 'duration', 150) : modifierValue(modifiers, 'duration', 150) / 2;
213 | const styleValues = {
214 | duration: duration,
215 | origin: modifierValue(modifiers, 'origin', 'center'),
216 | first: {
217 | opacity: 1,
218 | scale: 100
219 | },
220 | second: {
221 | opacity: 0,
222 | scale: modifierValue(modifiers, 'scale', 95)
223 | }
224 | };
225 | transitionHelper(el, modifiers, () => {}, hideCallback, styleValues);
226 | }
227 |
228 | function modifierValue(modifiers, key, fallback) {
229 | // If the modifier isn't present, use the default.
230 | if (modifiers.indexOf(key) === -1) return fallback; // If it IS present, grab the value after it: x-show.transition.duration.500ms
231 |
232 | const rawValue = modifiers[modifiers.indexOf(key) + 1];
233 | if (!rawValue) return fallback;
234 |
235 | if (key === 'scale') {
236 | // Check if the very next value is NOT a number and return the fallback.
237 | // If x-show.transition.scale, we'll use the default scale value.
238 | // That is how a user opts out of the opacity transition.
239 | if (!isNumeric(rawValue)) return fallback;
240 | }
241 |
242 | if (key === 'duration') {
243 | // Support x-show.transition.duration.500ms && duration.500
244 | let match = rawValue.match(/([0-9]+)ms/);
245 | if (match) return match[1];
246 | }
247 |
248 | if (key === 'origin') {
249 | // Support chaining origin directions: x-show.transition.top.right
250 | if (['top', 'right', 'left', 'center', 'bottom'].includes(modifiers[modifiers.indexOf(key) + 2])) {
251 | return [rawValue, modifiers[modifiers.indexOf(key) + 2]].join(' ');
252 | }
253 | }
254 |
255 | return rawValue;
256 | }
257 |
258 | function transitionHelper(el, modifiers, hook1, hook2, styleValues) {
259 | // If the user set these style values, we'll put them back when we're done with them.
260 | const opacityCache = el.style.opacity;
261 | const transformCache = el.style.transform;
262 | const transformOriginCache = el.style.transformOrigin; // If no modifiers are present: x-show.transition, we'll default to both opacity and scale.
263 |
264 | const noModifiers = !modifiers.includes('opacity') && !modifiers.includes('scale');
265 | const transitionOpacity = noModifiers || modifiers.includes('opacity');
266 | const transitionScale = noModifiers || modifiers.includes('scale'); // These are the explicit stages of a transition (same stages for in and for out).
267 | // This way you can get a birds eye view of the hooks, and the differences
268 | // between them.
269 |
270 | const stages = {
271 | start() {
272 | if (transitionOpacity) el.style.opacity = styleValues.first.opacity;
273 | if (transitionScale) el.style.transform = `scale(${styleValues.first.scale / 100})`;
274 | },
275 |
276 | during() {
277 | if (transitionScale) el.style.transformOrigin = styleValues.origin;
278 | el.style.transitionProperty = [transitionOpacity ? `opacity` : ``, transitionScale ? `transform` : ``].join(' ').trim();
279 | el.style.transitionDuration = `${styleValues.duration / 1000}s`;
280 | el.style.transitionTimingFunction = `cubic-bezier(0.4, 0.0, 0.2, 1)`;
281 | },
282 |
283 | show() {
284 | hook1();
285 | },
286 |
287 | end() {
288 | if (transitionOpacity) el.style.opacity = styleValues.second.opacity;
289 | if (transitionScale) el.style.transform = `scale(${styleValues.second.scale / 100})`;
290 | },
291 |
292 | hide() {
293 | hook2();
294 | },
295 |
296 | cleanup() {
297 | if (transitionOpacity) el.style.opacity = opacityCache;
298 | if (transitionScale) el.style.transform = transformCache;
299 | if (transitionScale) el.style.transformOrigin = transformOriginCache;
300 | el.style.transitionProperty = null;
301 | el.style.transitionDuration = null;
302 | el.style.transitionTimingFunction = null;
303 | }
304 |
305 | };
306 | transition(el, stages);
307 | }
308 | function transitionClassesIn(el, directives, showCallback) {
309 | const enter = (directives.find(i => i.value === 'enter') || {
310 | expression: ''
311 | }).expression.split(' ').filter(i => i !== '');
312 | const enterStart = (directives.find(i => i.value === 'enter-start') || {
313 | expression: ''
314 | }).expression.split(' ').filter(i => i !== '');
315 | const enterEnd = (directives.find(i => i.value === 'enter-end') || {
316 | expression: ''
317 | }).expression.split(' ').filter(i => i !== '');
318 | transitionClasses(el, enter, enterStart, enterEnd, showCallback, () => {});
319 | }
320 | function transitionClassesOut(el, directives, hideCallback) {
321 | const leave = (directives.find(i => i.value === 'leave') || {
322 | expression: ''
323 | }).expression.split(' ').filter(i => i !== '');
324 | const leaveStart = (directives.find(i => i.value === 'leave-start') || {
325 | expression: ''
326 | }).expression.split(' ').filter(i => i !== '');
327 | const leaveEnd = (directives.find(i => i.value === 'leave-end') || {
328 | expression: ''
329 | }).expression.split(' ').filter(i => i !== '');
330 | transitionClasses(el, leave, leaveStart, leaveEnd, () => {}, hideCallback);
331 | }
332 | function transitionClasses(el, classesDuring, classesStart, classesEnd, hook1, hook2) {
333 | const originalClasses = el.__x_original_classes || [];
334 | const stages = {
335 | start() {
336 | el.classList.add(...classesStart);
337 | },
338 |
339 | during() {
340 | el.classList.add(...classesDuring);
341 | },
342 |
343 | show() {
344 | hook1();
345 | },
346 |
347 | end() {
348 | // Don't remove classes that were in the original class attribute.
349 | el.classList.remove(...classesStart.filter(i => !originalClasses.includes(i)));
350 | el.classList.add(...classesEnd);
351 | },
352 |
353 | hide() {
354 | hook2();
355 | },
356 |
357 | cleanup() {
358 | el.classList.remove(...classesDuring.filter(i => !originalClasses.includes(i)));
359 | el.classList.remove(...classesEnd.filter(i => !originalClasses.includes(i)));
360 | }
361 |
362 | };
363 | transition(el, stages);
364 | }
365 | function transition(el, stages) {
366 | stages.start();
367 | stages.during();
368 | requestAnimationFrame(() => {
369 | // Note: Safari's transitionDuration property will list out comma separated transition durations
370 | // for every single transition property. Let's grab the first one and call it a day.
371 | let duration = Number(getComputedStyle(el).transitionDuration.replace(/,.*/, '').replace('s', '')) * 1000;
372 | stages.show();
373 | requestAnimationFrame(() => {
374 | stages.end();
375 | setTimeout(() => {
376 | stages.hide(); // Adding an "isConnected" check, in case the callback
377 | // removed the element from the DOM.
378 |
379 | if (el.isConnected) {
380 | stages.cleanup();
381 | }
382 | }, duration);
383 | });
384 | });
385 | }
386 | function isNumeric(subject) {
387 | return !isNaN(subject);
388 | }
389 |
390 | function handleForDirective(component, templateEl, expression, initialUpdate, extraVars) {
391 | warnIfNotTemplateTag(templateEl);
392 | let iteratorNames = parseForExpression(expression);
393 | let items = evaluateItemsAndReturnEmptyIfXIfIsPresentAndFalseOnElement(component, templateEl, iteratorNames, extraVars); // As we walk the array, we'll also walk the DOM (updating/creating as we go).
394 |
395 | let currentEl = templateEl;
396 | items.forEach((item, index) => {
397 | let iterationScopeVariables = getIterationScopeVariables(iteratorNames, item, index, items, extraVars());
398 | let currentKey = generateKeyForIteration(component, templateEl, index, iterationScopeVariables);
399 | let nextEl = lookAheadForMatchingKeyedElementAndMoveItIfFound(currentEl.nextElementSibling, currentKey); // If we haven't found a matching key, insert the element at the current position.
400 |
401 | if (!nextEl) {
402 | nextEl = addElementInLoopAfterCurrentEl(templateEl, currentEl); // And transition it in if it's not the first page load.
403 |
404 | transitionIn(nextEl, () => {}, initialUpdate);
405 | nextEl.__x_for = iterationScopeVariables;
406 | component.initializeElements(nextEl, () => nextEl.__x_for); // Otherwise update the element we found.
407 | } else {
408 | // Temporarily remove the key indicator to allow the normal "updateElements" to work.
409 | delete nextEl.__x_for_key;
410 | nextEl.__x_for = iterationScopeVariables;
411 | component.updateElements(nextEl, () => nextEl.__x_for);
412 | }
413 |
414 | currentEl = nextEl;
415 | currentEl.__x_for_key = currentKey;
416 | });
417 | removeAnyLeftOverElementsFromPreviousUpdate(currentEl);
418 | } // This was taken from VueJS 2.* core. Thanks Vue!
419 |
420 | function parseForExpression(expression) {
421 | let forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
422 | let stripParensRE = /^\(|\)$/g;
423 | let forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
424 | let inMatch = expression.match(forAliasRE);
425 | if (!inMatch) return;
426 | let res = {};
427 | res.items = inMatch[2].trim();
428 | let item = inMatch[1].trim().replace(stripParensRE, '');
429 | let iteratorMatch = item.match(forIteratorRE);
430 |
431 | if (iteratorMatch) {
432 | res.item = item.replace(forIteratorRE, '').trim();
433 | res.index = iteratorMatch[1].trim();
434 |
435 | if (iteratorMatch[2]) {
436 | res.collection = iteratorMatch[2].trim();
437 | }
438 | } else {
439 | res.item = item;
440 | }
441 |
442 | return res;
443 | }
444 |
445 | function getIterationScopeVariables(iteratorNames, item, index, items, extraVars) {
446 | // We must create a new object, so each iteration has a new scope
447 | let scopeVariables = extraVars ? _objectSpread2({}, extraVars) : {};
448 | scopeVariables[iteratorNames.item] = item;
449 | if (iteratorNames.index) scopeVariables[iteratorNames.index] = index;
450 | if (iteratorNames.collection) scopeVariables[iteratorNames.collection] = items;
451 | return scopeVariables;
452 | }
453 |
454 | function generateKeyForIteration(component, el, index, iterationScopeVariables) {
455 | let bindKeyAttribute = getXAttrs(el, 'bind').filter(attr => attr.value === 'key')[0]; // If the dev hasn't specified a key, just return the index of the iteration.
456 |
457 | if (!bindKeyAttribute) return index;
458 | return component.evaluateReturnExpression(el, bindKeyAttribute.expression, () => iterationScopeVariables);
459 | }
460 |
461 | function warnIfNotTemplateTag(el) {
462 | if (el.tagName.toLowerCase() !== 'template') console.warn('Alpine: [x-for] directive should only be added to tags.');
463 | }
464 |
465 | function evaluateItemsAndReturnEmptyIfXIfIsPresentAndFalseOnElement(component, el, iteratorNames, extraVars) {
466 | let ifAttribute = getXAttrs(el, 'if')[0];
467 |
468 | if (ifAttribute && !component.evaluateReturnExpression(el, ifAttribute.expression)) {
469 | return [];
470 | }
471 |
472 | return component.evaluateReturnExpression(el, iteratorNames.items, extraVars);
473 | }
474 |
475 | function addElementInLoopAfterCurrentEl(templateEl, currentEl) {
476 | let clone = document.importNode(templateEl.content, true);
477 | if (clone.childElementCount !== 1) console.warn('Alpine: tag with [x-for] encountered with multiple element roots. Make sure only has a single child node.');
478 | currentEl.parentElement.insertBefore(clone, currentEl.nextElementSibling);
479 | return currentEl.nextElementSibling;
480 | }
481 |
482 | function lookAheadForMatchingKeyedElementAndMoveItIfFound(nextEl, currentKey) {
483 | if (!nextEl) return; // If the the key's DO match, no need to look ahead.
484 |
485 | if (nextEl.__x_for_key === currentKey) return nextEl; // If they don't, we'll look ahead for a match.
486 | // If we find it, we'll move it to the current position in the loop.
487 |
488 | let tmpNextEl = nextEl;
489 |
490 | while (tmpNextEl) {
491 | if (tmpNextEl.__x_for_key === currentKey) {
492 | return tmpNextEl.parentElement.insertBefore(tmpNextEl, nextEl);
493 | }
494 |
495 | tmpNextEl = tmpNextEl.nextElementSibling && tmpNextEl.nextElementSibling.__x_for_key !== undefined ? tmpNextEl.nextElementSibling : false;
496 | }
497 | }
498 |
499 | function removeAnyLeftOverElementsFromPreviousUpdate(currentEl) {
500 | var nextElementFromOldLoop = currentEl.nextElementSibling && currentEl.nextElementSibling.__x_for_key !== undefined ? currentEl.nextElementSibling : false;
501 |
502 | while (nextElementFromOldLoop) {
503 | let nextElementFromOldLoopImmutable = nextElementFromOldLoop;
504 | let nextSibling = nextElementFromOldLoop.nextElementSibling;
505 | transitionOut(nextElementFromOldLoop, () => {
506 | nextElementFromOldLoopImmutable.remove();
507 | });
508 | nextElementFromOldLoop = nextSibling && nextSibling.__x_for_key !== undefined ? nextSibling : false;
509 | }
510 | }
511 |
512 | function handleAttributeBindingDirective(component, el, attrName, expression, extraVars, attrType) {
513 | var value = component.evaluateReturnExpression(el, expression, extraVars);
514 |
515 | if (attrName === 'value') {
516 | // If nested model key is undefined, set the default value to empty string.
517 | if (value === undefined && expression.match(/\./).length) {
518 | value = '';
519 | }
520 |
521 | if (el.type === 'radio') {
522 | // Set radio value from x-bind:value, if no "value" attribute exists.
523 | // If there are any initial state values, radio will have a correct
524 | // "checked" value since x-bind:value is processed before x-model.
525 | if (el.attributes.value === undefined && attrType === 'bind') {
526 | el.value = value;
527 | } else if (attrType !== 'bind') {
528 | el.checked = el.value == value;
529 | }
530 | } else if (el.type === 'checkbox') {
531 | if (Array.isArray(value)) {
532 | // I'm purposely not using Array.includes here because it's
533 | // strict, and because of Numeric/String mis-casting, I
534 | // want the "includes" to be "fuzzy".
535 | let valueFound = false;
536 | value.forEach(val => {
537 | if (val == el.value) {
538 | valueFound = true;
539 | }
540 | });
541 | el.checked = valueFound;
542 | } else {
543 | el.checked = !!value;
544 | } // If we are explicitly binding a string to the :value, set the string,
545 | // If the value is a boolean, leave it alone, it will be set to "on"
546 | // automatically.
547 |
548 |
549 | if (typeof value === 'string') {
550 | el.value = value;
551 | }
552 | } else if (el.tagName === 'SELECT') {
553 | updateSelect(el, value);
554 | } else {
555 | if (el.value === value) return;
556 | el.value = value;
557 | }
558 | } else if (attrName === 'class') {
559 | if (Array.isArray(value)) {
560 | const originalClasses = el.__x_original_classes || [];
561 | el.setAttribute('class', arrayUnique(originalClasses.concat(value)).join(' '));
562 | } else if (typeof value === 'object') {
563 | // Sorting the keys / class names by their boolean value will ensure that
564 | // anything that evaluates to `false` and needs to remove classes is run first.
565 | const keysSortedByBooleanValue = Object.keys(value).sort((a, b) => value[a] - value[b]);
566 | keysSortedByBooleanValue.forEach(classNames => {
567 | if (value[classNames]) {
568 | classNames.split(' ').filter(Boolean).forEach(className => el.classList.add(className));
569 | } else {
570 | classNames.split(' ').filter(Boolean).forEach(className => el.classList.remove(className));
571 | }
572 | });
573 | } else {
574 | const originalClasses = el.__x_original_classes || [];
575 | const newClasses = value.split(' ').filter(Boolean);
576 | el.setAttribute('class', arrayUnique(originalClasses.concat(newClasses)).join(' '));
577 | }
578 | } else {
579 | // If an attribute's bound value is null, undefined or false, remove the attribute
580 | if ([null, undefined, false].includes(value)) {
581 | el.removeAttribute(attrName);
582 | } else {
583 | isBooleanAttr(attrName) ? el.setAttribute(attrName, attrName) : el.setAttribute(attrName, value);
584 | }
585 | }
586 | }
587 |
588 | function updateSelect(el, value) {
589 | const arrayWrappedValue = [].concat(value).map(value => {
590 | return value + '';
591 | });
592 | Array.from(el.options).forEach(option => {
593 | option.selected = arrayWrappedValue.includes(option.value || option.text);
594 | });
595 | }
596 |
597 | function handleTextDirective(el, output, expression) {
598 | // If nested model key is undefined, set the default value to empty string.
599 | if (output === undefined && expression.match(/\./).length) {
600 | output = '';
601 | }
602 |
603 | el.innerText = output;
604 | }
605 |
606 | function handleHtmlDirective(component, el, expression, extraVars) {
607 | el.innerHTML = component.evaluateReturnExpression(el, expression, extraVars);
608 | }
609 |
610 | function handleShowDirective(component, el, value, modifiers, initialUpdate = false) {
611 | const hide = () => {
612 | el.style.display = 'none';
613 | };
614 |
615 | const show = () => {
616 | if (el.style.length === 1 && el.style.display === 'none') {
617 | el.removeAttribute('style');
618 | } else {
619 | el.style.removeProperty('display');
620 | }
621 | };
622 |
623 | if (initialUpdate === true) {
624 | if (value) {
625 | show();
626 | } else {
627 | hide();
628 | }
629 |
630 | return;
631 | }
632 |
633 | const handle = resolve => {
634 | if (!value) {
635 | if (el.style.display !== 'none') {
636 | transitionOut(el, () => {
637 | resolve(() => {
638 | hide();
639 | });
640 | });
641 | } else {
642 | resolve(() => {});
643 | }
644 | } else {
645 | if (el.style.display !== '') {
646 | transitionIn(el, () => {
647 | show();
648 | });
649 | } // Resolve immediately, only hold up parent `x-show`s for hidin.
650 |
651 |
652 | resolve(() => {});
653 | }
654 | }; // The working of x-show is a bit complex because we need to
655 | // wait for any child transitions to finish before hiding
656 | // some element. Also, this has to be done recursively.
657 | // If x-show.immediate, foregoe the waiting.
658 |
659 |
660 | if (modifiers.includes('immediate')) {
661 | handle(finish => finish());
662 | return;
663 | } // x-show is encountered during a DOM tree walk. If an element
664 | // we encounter is NOT a child of another x-show element we
665 | // can execute the previous x-show stack (if one exists).
666 |
667 |
668 | if (component.showDirectiveLastElement && !component.showDirectiveLastElement.contains(el)) {
669 | component.executeAndClearRemainingShowDirectiveStack();
670 | } // We'll push the handler onto a stack to be handled later.
671 |
672 |
673 | component.showDirectiveStack.push(handle);
674 | component.showDirectiveLastElement = el;
675 | }
676 |
677 | function handleIfDirective(component, el, expressionResult, initialUpdate, extraVars) {
678 | if (el.nodeName.toLowerCase() !== 'template') console.warn(`Alpine: [x-if] directive should only be added to tags. See https://github.com/alpinejs/alpine#x-if`);
679 | const elementHasAlreadyBeenAdded = el.nextElementSibling && el.nextElementSibling.__x_inserted_me === true;
680 |
681 | if (expressionResult && !elementHasAlreadyBeenAdded) {
682 | const clone = document.importNode(el.content, true);
683 | el.parentElement.insertBefore(clone, el.nextElementSibling);
684 | transitionIn(el.nextElementSibling, () => {}, initialUpdate);
685 | component.initializeElements(el.nextElementSibling, extraVars);
686 | el.nextElementSibling.__x_inserted_me = true;
687 | } else if (!expressionResult && elementHasAlreadyBeenAdded) {
688 | transitionOut(el.nextElementSibling, () => {
689 | el.nextElementSibling.remove();
690 | }, initialUpdate);
691 | }
692 | }
693 |
694 | function registerListener(component, el, event, modifiers, expression, extraVars = {}) {
695 | if (modifiers.includes('away')) {
696 | let handler = e => {
697 | // Don't do anything if the click came form the element or within it.
698 | if (el.contains(e.target)) return; // Don't do anything if this element isn't currently visible.
699 |
700 | if (el.offsetWidth < 1 && el.offsetHeight < 1) return; // Now that we are sure the element is visible, AND the click
701 | // is from outside it, let's run the expression.
702 |
703 | runListenerHandler(component, expression, e, extraVars);
704 |
705 | if (modifiers.includes('once')) {
706 | document.removeEventListener(event, handler);
707 | }
708 | }; // Listen for this event at the root level.
709 |
710 |
711 | document.addEventListener(event, handler);
712 | } else {
713 | let listenerTarget = modifiers.includes('window') ? window : modifiers.includes('document') ? document : el;
714 |
715 | let handler = e => {
716 | // Remove this global event handler if the element that declared it
717 | // has been removed. It's now stale.
718 | if (listenerTarget === window || listenerTarget === document) {
719 | if (!document.body.contains(el)) {
720 | listenerTarget.removeEventListener(event, handler);
721 | return;
722 | }
723 | }
724 |
725 | if (isKeyEvent(event)) {
726 | if (isListeningForASpecificKeyThatHasntBeenPressed(e, modifiers)) {
727 | return;
728 | }
729 | }
730 |
731 | if (modifiers.includes('prevent')) e.preventDefault();
732 | if (modifiers.includes('stop')) e.stopPropagation(); // If the .self modifier isn't present, or if it is present and
733 | // the target element matches the element we are registering the
734 | // event on, run the handler
735 |
736 | if (!modifiers.includes('self') || e.target === el) {
737 | const returnValue = runListenerHandler(component, expression, e, extraVars);
738 |
739 | if (returnValue === false) {
740 | e.preventDefault();
741 | } else {
742 | if (modifiers.includes('once')) {
743 | listenerTarget.removeEventListener(event, handler);
744 | }
745 | }
746 | }
747 | };
748 |
749 | if (modifiers.includes('debounce')) {
750 | let nextModifier = modifiers[modifiers.indexOf('debounce') + 1] || 'invalid-wait';
751 | let wait = isNumeric(nextModifier.split('ms')[0]) ? Number(nextModifier.split('ms')[0]) : 250;
752 | handler = debounce(handler, wait);
753 | }
754 |
755 | listenerTarget.addEventListener(event, handler);
756 | }
757 | }
758 |
759 | function runListenerHandler(component, expression, e, extraVars) {
760 | return component.evaluateCommandExpression(e.target, expression, () => {
761 | return _objectSpread2({}, extraVars(), {
762 | '$event': e
763 | });
764 | });
765 | }
766 |
767 | function isKeyEvent(event) {
768 | return ['keydown', 'keyup'].includes(event);
769 | }
770 |
771 | function isListeningForASpecificKeyThatHasntBeenPressed(e, modifiers) {
772 | let keyModifiers = modifiers.filter(i => {
773 | return !['window', 'document', 'prevent', 'stop'].includes(i);
774 | });
775 |
776 | if (keyModifiers.includes('debounce')) {
777 | let debounceIndex = keyModifiers.indexOf('debounce');
778 | keyModifiers.splice(debounceIndex, isNumeric((keyModifiers[debounceIndex + 1] || 'invalid-wait').split('ms')[0]) ? 2 : 1);
779 | } // If no modifier is specified, we'll call it a press.
780 |
781 |
782 | if (keyModifiers.length === 0) return false; // If one is passed, AND it matches the key pressed, we'll call it a press.
783 |
784 | if (keyModifiers.length === 1 && keyModifiers[0] === keyToModifier(e.key)) return false; // The user is listening for key combinations.
785 |
786 | const systemKeyModifiers = ['ctrl', 'shift', 'alt', 'meta', 'cmd', 'super'];
787 | const selectedSystemKeyModifiers = systemKeyModifiers.filter(modifier => keyModifiers.includes(modifier));
788 | keyModifiers = keyModifiers.filter(i => !selectedSystemKeyModifiers.includes(i));
789 |
790 | if (selectedSystemKeyModifiers.length > 0) {
791 | const activelyPressedKeyModifiers = selectedSystemKeyModifiers.filter(modifier => {
792 | // Alias "cmd" and "super" to "meta"
793 | if (modifier === 'cmd' || modifier === 'super') modifier = 'meta';
794 | return e[`${modifier}Key`];
795 | }); // If all the modifiers selected are pressed, ...
796 |
797 | if (activelyPressedKeyModifiers.length === selectedSystemKeyModifiers.length) {
798 | // AND the remaining key is pressed as well. It's a press.
799 | if (keyModifiers[0] === keyToModifier(e.key)) return false;
800 | }
801 | } // We'll call it NOT a valid keypress.
802 |
803 |
804 | return true;
805 | }
806 |
807 | function keyToModifier(key) {
808 | switch (key) {
809 | case '/':
810 | return 'slash';
811 |
812 | case ' ':
813 | case 'Spacebar':
814 | return 'space';
815 |
816 | default:
817 | return key && kebabCase(key);
818 | }
819 | }
820 |
821 | function registerModelListener(component, el, modifiers, expression, extraVars) {
822 | // If the element we are binding to is a select, a radio, or checkbox
823 | // we'll listen for the change event instead of the "input" event.
824 | var event = el.tagName.toLowerCase() === 'select' || ['checkbox', 'radio'].includes(el.type) || modifiers.includes('lazy') ? 'change' : 'input';
825 | const listenerExpression = `${expression} = rightSideOfExpression($event, ${expression})`;
826 | registerListener(component, el, event, modifiers, listenerExpression, () => {
827 | return _objectSpread2({}, extraVars(), {
828 | rightSideOfExpression: generateModelAssignmentFunction(el, modifiers, expression)
829 | });
830 | });
831 | }
832 |
833 | function generateModelAssignmentFunction(el, modifiers, expression) {
834 | if (el.type === 'radio') {
835 | // Radio buttons only work properly when they share a name attribute.
836 | // People might assume we take care of that for them, because
837 | // they already set a shared "x-model" attribute.
838 | if (!el.hasAttribute('name')) el.setAttribute('name', expression);
839 | }
840 |
841 | return (event, currentValue) => {
842 | // Check for event.detail due to an issue where IE11 handles other events as a CustomEvent.
843 | if (event instanceof CustomEvent && event.detail) {
844 | return event.detail;
845 | } else if (el.type === 'checkbox') {
846 | // If the data we are binding to is an array, toggle it's value inside the array.
847 | if (Array.isArray(currentValue)) {
848 | return event.target.checked ? currentValue.concat([event.target.value]) : currentValue.filter(i => i !== event.target.value);
849 | } else {
850 | return event.target.checked;
851 | }
852 | } else if (el.tagName.toLowerCase() === 'select' && el.multiple) {
853 | return modifiers.includes('number') ? Array.from(event.target.selectedOptions).map(option => {
854 | const rawValue = option.value || option.text;
855 | const number = rawValue ? parseFloat(rawValue) : null;
856 | return isNaN(number) ? rawValue : number;
857 | }) : Array.from(event.target.selectedOptions).map(option => {
858 | return option.value || option.text;
859 | });
860 | } else {
861 | const rawValue = event.target.value;
862 | const number = rawValue ? parseFloat(rawValue) : null;
863 | return modifiers.includes('number') ? isNaN(number) ? rawValue : number : modifiers.includes('trim') ? rawValue.trim() : rawValue;
864 | }
865 | };
866 | }
867 |
868 | /**
869 | * Copyright (C) 2017 salesforce.com, inc.
870 | */
871 | const { isArray } = Array;
872 | const { getPrototypeOf, create: ObjectCreate, defineProperty: ObjectDefineProperty, defineProperties: ObjectDefineProperties, isExtensible, getOwnPropertyDescriptor, getOwnPropertyNames, getOwnPropertySymbols, preventExtensions, hasOwnProperty, } = Object;
873 | const { push: ArrayPush, concat: ArrayConcat, map: ArrayMap, } = Array.prototype;
874 | function isUndefined(obj) {
875 | return obj === undefined;
876 | }
877 | function isFunction(obj) {
878 | return typeof obj === 'function';
879 | }
880 | function isObject(obj) {
881 | return typeof obj === 'object';
882 | }
883 | const proxyToValueMap = new WeakMap();
884 | function registerProxy(proxy, value) {
885 | proxyToValueMap.set(proxy, value);
886 | }
887 | const unwrap = (replicaOrAny) => proxyToValueMap.get(replicaOrAny) || replicaOrAny;
888 |
889 | function wrapValue(membrane, value) {
890 | return membrane.valueIsObservable(value) ? membrane.getProxy(value) : value;
891 | }
892 | /**
893 | * Unwrap property descriptors will set value on original descriptor
894 | * We only need to unwrap if value is specified
895 | * @param descriptor external descrpitor provided to define new property on original value
896 | */
897 | function unwrapDescriptor(descriptor) {
898 | if (hasOwnProperty.call(descriptor, 'value')) {
899 | descriptor.value = unwrap(descriptor.value);
900 | }
901 | return descriptor;
902 | }
903 | function lockShadowTarget(membrane, shadowTarget, originalTarget) {
904 | const targetKeys = ArrayConcat.call(getOwnPropertyNames(originalTarget), getOwnPropertySymbols(originalTarget));
905 | targetKeys.forEach((key) => {
906 | let descriptor = getOwnPropertyDescriptor(originalTarget, key);
907 | // We do not need to wrap the descriptor if configurable
908 | // Because we can deal with wrapping it when user goes through
909 | // Get own property descriptor. There is also a chance that this descriptor
910 | // could change sometime in the future, so we can defer wrapping
911 | // until we need to
912 | if (!descriptor.configurable) {
913 | descriptor = wrapDescriptor(membrane, descriptor, wrapValue);
914 | }
915 | ObjectDefineProperty(shadowTarget, key, descriptor);
916 | });
917 | preventExtensions(shadowTarget);
918 | }
919 | class ReactiveProxyHandler {
920 | constructor(membrane, value) {
921 | this.originalTarget = value;
922 | this.membrane = membrane;
923 | }
924 | get(shadowTarget, key) {
925 | const { originalTarget, membrane } = this;
926 | const value = originalTarget[key];
927 | const { valueObserved } = membrane;
928 | valueObserved(originalTarget, key);
929 | return membrane.getProxy(value);
930 | }
931 | set(shadowTarget, key, value) {
932 | const { originalTarget, membrane: { valueMutated } } = this;
933 | const oldValue = originalTarget[key];
934 | if (oldValue !== value) {
935 | originalTarget[key] = value;
936 | valueMutated(originalTarget, key);
937 | }
938 | else if (key === 'length' && isArray(originalTarget)) {
939 | // fix for issue #236: push will add the new index, and by the time length
940 | // is updated, the internal length is already equal to the new length value
941 | // therefore, the oldValue is equal to the value. This is the forking logic
942 | // to support this use case.
943 | valueMutated(originalTarget, key);
944 | }
945 | return true;
946 | }
947 | deleteProperty(shadowTarget, key) {
948 | const { originalTarget, membrane: { valueMutated } } = this;
949 | delete originalTarget[key];
950 | valueMutated(originalTarget, key);
951 | return true;
952 | }
953 | apply(shadowTarget, thisArg, argArray) {
954 | /* No op */
955 | }
956 | construct(target, argArray, newTarget) {
957 | /* No op */
958 | }
959 | has(shadowTarget, key) {
960 | const { originalTarget, membrane: { valueObserved } } = this;
961 | valueObserved(originalTarget, key);
962 | return key in originalTarget;
963 | }
964 | ownKeys(shadowTarget) {
965 | const { originalTarget } = this;
966 | return ArrayConcat.call(getOwnPropertyNames(originalTarget), getOwnPropertySymbols(originalTarget));
967 | }
968 | isExtensible(shadowTarget) {
969 | const shadowIsExtensible = isExtensible(shadowTarget);
970 | if (!shadowIsExtensible) {
971 | return shadowIsExtensible;
972 | }
973 | const { originalTarget, membrane } = this;
974 | const targetIsExtensible = isExtensible(originalTarget);
975 | if (!targetIsExtensible) {
976 | lockShadowTarget(membrane, shadowTarget, originalTarget);
977 | }
978 | return targetIsExtensible;
979 | }
980 | setPrototypeOf(shadowTarget, prototype) {
981 | }
982 | getPrototypeOf(shadowTarget) {
983 | const { originalTarget } = this;
984 | return getPrototypeOf(originalTarget);
985 | }
986 | getOwnPropertyDescriptor(shadowTarget, key) {
987 | const { originalTarget, membrane } = this;
988 | const { valueObserved } = this.membrane;
989 | // keys looked up via hasOwnProperty need to be reactive
990 | valueObserved(originalTarget, key);
991 | let desc = getOwnPropertyDescriptor(originalTarget, key);
992 | if (isUndefined(desc)) {
993 | return desc;
994 | }
995 | const shadowDescriptor = getOwnPropertyDescriptor(shadowTarget, key);
996 | if (!isUndefined(shadowDescriptor)) {
997 | return shadowDescriptor;
998 | }
999 | // Note: by accessing the descriptor, the key is marked as observed
1000 | // but access to the value, setter or getter (if available) cannot observe
1001 | // mutations, just like regular methods, in which case we just do nothing.
1002 | desc = wrapDescriptor(membrane, desc, wrapValue);
1003 | if (!desc.configurable) {
1004 | // If descriptor from original target is not configurable,
1005 | // We must copy the wrapped descriptor over to the shadow target.
1006 | // Otherwise, proxy will throw an invariant error.
1007 | // This is our last chance to lock the value.
1008 | // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor#Invariants
1009 | ObjectDefineProperty(shadowTarget, key, desc);
1010 | }
1011 | return desc;
1012 | }
1013 | preventExtensions(shadowTarget) {
1014 | const { originalTarget, membrane } = this;
1015 | lockShadowTarget(membrane, shadowTarget, originalTarget);
1016 | preventExtensions(originalTarget);
1017 | return true;
1018 | }
1019 | defineProperty(shadowTarget, key, descriptor) {
1020 | const { originalTarget, membrane } = this;
1021 | const { valueMutated } = membrane;
1022 | const { configurable } = descriptor;
1023 | // We have to check for value in descriptor
1024 | // because Object.freeze(proxy) calls this method
1025 | // with only { configurable: false, writeable: false }
1026 | // Additionally, method will only be called with writeable:false
1027 | // if the descriptor has a value, as opposed to getter/setter
1028 | // So we can just check if writable is present and then see if
1029 | // value is present. This eliminates getter and setter descriptors
1030 | if (hasOwnProperty.call(descriptor, 'writable') && !hasOwnProperty.call(descriptor, 'value')) {
1031 | const originalDescriptor = getOwnPropertyDescriptor(originalTarget, key);
1032 | descriptor.value = originalDescriptor.value;
1033 | }
1034 | ObjectDefineProperty(originalTarget, key, unwrapDescriptor(descriptor));
1035 | if (configurable === false) {
1036 | ObjectDefineProperty(shadowTarget, key, wrapDescriptor(membrane, descriptor, wrapValue));
1037 | }
1038 | valueMutated(originalTarget, key);
1039 | return true;
1040 | }
1041 | }
1042 |
1043 | function wrapReadOnlyValue(membrane, value) {
1044 | return membrane.valueIsObservable(value) ? membrane.getReadOnlyProxy(value) : value;
1045 | }
1046 | class ReadOnlyHandler {
1047 | constructor(membrane, value) {
1048 | this.originalTarget = value;
1049 | this.membrane = membrane;
1050 | }
1051 | get(shadowTarget, key) {
1052 | const { membrane, originalTarget } = this;
1053 | const value = originalTarget[key];
1054 | const { valueObserved } = membrane;
1055 | valueObserved(originalTarget, key);
1056 | return membrane.getReadOnlyProxy(value);
1057 | }
1058 | set(shadowTarget, key, value) {
1059 | return false;
1060 | }
1061 | deleteProperty(shadowTarget, key) {
1062 | return false;
1063 | }
1064 | apply(shadowTarget, thisArg, argArray) {
1065 | /* No op */
1066 | }
1067 | construct(target, argArray, newTarget) {
1068 | /* No op */
1069 | }
1070 | has(shadowTarget, key) {
1071 | const { originalTarget, membrane: { valueObserved } } = this;
1072 | valueObserved(originalTarget, key);
1073 | return key in originalTarget;
1074 | }
1075 | ownKeys(shadowTarget) {
1076 | const { originalTarget } = this;
1077 | return ArrayConcat.call(getOwnPropertyNames(originalTarget), getOwnPropertySymbols(originalTarget));
1078 | }
1079 | setPrototypeOf(shadowTarget, prototype) {
1080 | }
1081 | getOwnPropertyDescriptor(shadowTarget, key) {
1082 | const { originalTarget, membrane } = this;
1083 | const { valueObserved } = membrane;
1084 | // keys looked up via hasOwnProperty need to be reactive
1085 | valueObserved(originalTarget, key);
1086 | let desc = getOwnPropertyDescriptor(originalTarget, key);
1087 | if (isUndefined(desc)) {
1088 | return desc;
1089 | }
1090 | const shadowDescriptor = getOwnPropertyDescriptor(shadowTarget, key);
1091 | if (!isUndefined(shadowDescriptor)) {
1092 | return shadowDescriptor;
1093 | }
1094 | // Note: by accessing the descriptor, the key is marked as observed
1095 | // but access to the value or getter (if available) cannot be observed,
1096 | // just like regular methods, in which case we just do nothing.
1097 | desc = wrapDescriptor(membrane, desc, wrapReadOnlyValue);
1098 | if (hasOwnProperty.call(desc, 'set')) {
1099 | desc.set = undefined; // readOnly membrane does not allow setters
1100 | }
1101 | if (!desc.configurable) {
1102 | // If descriptor from original target is not configurable,
1103 | // We must copy the wrapped descriptor over to the shadow target.
1104 | // Otherwise, proxy will throw an invariant error.
1105 | // This is our last chance to lock the value.
1106 | // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor#Invariants
1107 | ObjectDefineProperty(shadowTarget, key, desc);
1108 | }
1109 | return desc;
1110 | }
1111 | preventExtensions(shadowTarget) {
1112 | return false;
1113 | }
1114 | defineProperty(shadowTarget, key, descriptor) {
1115 | return false;
1116 | }
1117 | }
1118 | function createShadowTarget(value) {
1119 | let shadowTarget = undefined;
1120 | if (isArray(value)) {
1121 | shadowTarget = [];
1122 | }
1123 | else if (isObject(value)) {
1124 | shadowTarget = {};
1125 | }
1126 | return shadowTarget;
1127 | }
1128 | const ObjectDotPrototype = Object.prototype;
1129 | function defaultValueIsObservable(value) {
1130 | // intentionally checking for null
1131 | if (value === null) {
1132 | return false;
1133 | }
1134 | // treat all non-object types, including undefined, as non-observable values
1135 | if (typeof value !== 'object') {
1136 | return false;
1137 | }
1138 | if (isArray(value)) {
1139 | return true;
1140 | }
1141 | const proto = getPrototypeOf(value);
1142 | return (proto === ObjectDotPrototype || proto === null || getPrototypeOf(proto) === null);
1143 | }
1144 | const defaultValueObserved = (obj, key) => {
1145 | /* do nothing */
1146 | };
1147 | const defaultValueMutated = (obj, key) => {
1148 | /* do nothing */
1149 | };
1150 | const defaultValueDistortion = (value) => value;
1151 | function wrapDescriptor(membrane, descriptor, getValue) {
1152 | const { set, get } = descriptor;
1153 | if (hasOwnProperty.call(descriptor, 'value')) {
1154 | descriptor.value = getValue(membrane, descriptor.value);
1155 | }
1156 | else {
1157 | if (!isUndefined(get)) {
1158 | descriptor.get = function () {
1159 | // invoking the original getter with the original target
1160 | return getValue(membrane, get.call(unwrap(this)));
1161 | };
1162 | }
1163 | if (!isUndefined(set)) {
1164 | descriptor.set = function (value) {
1165 | // At this point we don't have a clear indication of whether
1166 | // or not a valid mutation will occur, we don't have the key,
1167 | // and we are not sure why and how they are invoking this setter.
1168 | // Nevertheless we preserve the original semantics by invoking the
1169 | // original setter with the original target and the unwrapped value
1170 | set.call(unwrap(this), membrane.unwrapProxy(value));
1171 | };
1172 | }
1173 | }
1174 | return descriptor;
1175 | }
1176 | class ReactiveMembrane {
1177 | constructor(options) {
1178 | this.valueDistortion = defaultValueDistortion;
1179 | this.valueMutated = defaultValueMutated;
1180 | this.valueObserved = defaultValueObserved;
1181 | this.valueIsObservable = defaultValueIsObservable;
1182 | this.objectGraph = new WeakMap();
1183 | if (!isUndefined(options)) {
1184 | const { valueDistortion, valueMutated, valueObserved, valueIsObservable } = options;
1185 | this.valueDistortion = isFunction(valueDistortion) ? valueDistortion : defaultValueDistortion;
1186 | this.valueMutated = isFunction(valueMutated) ? valueMutated : defaultValueMutated;
1187 | this.valueObserved = isFunction(valueObserved) ? valueObserved : defaultValueObserved;
1188 | this.valueIsObservable = isFunction(valueIsObservable) ? valueIsObservable : defaultValueIsObservable;
1189 | }
1190 | }
1191 | getProxy(value) {
1192 | const unwrappedValue = unwrap(value);
1193 | const distorted = this.valueDistortion(unwrappedValue);
1194 | if (this.valueIsObservable(distorted)) {
1195 | const o = this.getReactiveState(unwrappedValue, distorted);
1196 | // when trying to extract the writable version of a readonly
1197 | // we return the readonly.
1198 | return o.readOnly === value ? value : o.reactive;
1199 | }
1200 | return distorted;
1201 | }
1202 | getReadOnlyProxy(value) {
1203 | value = unwrap(value);
1204 | const distorted = this.valueDistortion(value);
1205 | if (this.valueIsObservable(distorted)) {
1206 | return this.getReactiveState(value, distorted).readOnly;
1207 | }
1208 | return distorted;
1209 | }
1210 | unwrapProxy(p) {
1211 | return unwrap(p);
1212 | }
1213 | getReactiveState(value, distortedValue) {
1214 | const { objectGraph, } = this;
1215 | let reactiveState = objectGraph.get(distortedValue);
1216 | if (reactiveState) {
1217 | return reactiveState;
1218 | }
1219 | const membrane = this;
1220 | reactiveState = {
1221 | get reactive() {
1222 | const reactiveHandler = new ReactiveProxyHandler(membrane, distortedValue);
1223 | // caching the reactive proxy after the first time it is accessed
1224 | const proxy = new Proxy(createShadowTarget(distortedValue), reactiveHandler);
1225 | registerProxy(proxy, value);
1226 | ObjectDefineProperty(this, 'reactive', { value: proxy });
1227 | return proxy;
1228 | },
1229 | get readOnly() {
1230 | const readOnlyHandler = new ReadOnlyHandler(membrane, distortedValue);
1231 | // caching the readOnly proxy after the first time it is accessed
1232 | const proxy = new Proxy(createShadowTarget(distortedValue), readOnlyHandler);
1233 | registerProxy(proxy, value);
1234 | ObjectDefineProperty(this, 'readOnly', { value: proxy });
1235 | return proxy;
1236 | }
1237 | };
1238 | objectGraph.set(distortedValue, reactiveState);
1239 | return reactiveState;
1240 | }
1241 | }
1242 | /** version: 0.26.0 */
1243 |
1244 | function wrap(data, mutationCallback) {
1245 |
1246 | let membrane = new ReactiveMembrane({
1247 | valueMutated(target, key) {
1248 | mutationCallback(target, key);
1249 | }
1250 |
1251 | });
1252 | return {
1253 | data: membrane.getProxy(data),
1254 | membrane: membrane
1255 | };
1256 | }
1257 | function unwrap$1(membrane, observable) {
1258 | let unwrappedData = membrane.unwrapProxy(observable);
1259 | let copy = {};
1260 | Object.keys(unwrappedData).forEach(key => {
1261 | if (['$el', '$refs', '$nextTick', '$watch'].includes(key)) return;
1262 | copy[key] = unwrappedData[key];
1263 | });
1264 | return copy;
1265 | }
1266 |
1267 | class Component {
1268 | constructor(el, seedDataForCloning = null) {
1269 | this.$el = el;
1270 | const dataAttr = this.$el.getAttribute('x-data');
1271 | const dataExpression = dataAttr === '' ? '{}' : dataAttr;
1272 | const initExpression = this.$el.getAttribute('x-init');
1273 | this.unobservedData = seedDataForCloning ? seedDataForCloning : saferEval(dataExpression, {});
1274 | // Construct a Proxy-based observable. This will be used to handle reactivity.
1275 |
1276 | let {
1277 | membrane,
1278 | data
1279 | } = this.wrapDataInObservable(this.unobservedData);
1280 | this.$data = data;
1281 | this.membrane = membrane; // After making user-supplied data methods reactive, we can now add
1282 | // our magic properties to the original data for access.
1283 |
1284 | this.unobservedData.$el = this.$el;
1285 | this.unobservedData.$refs = this.getRefsProxy();
1286 | this.nextTickStack = [];
1287 |
1288 | this.unobservedData.$nextTick = callback => {
1289 | this.nextTickStack.push(callback);
1290 | };
1291 |
1292 | this.watchers = {};
1293 |
1294 | this.unobservedData.$watch = (property, callback) => {
1295 | if (!this.watchers[property]) this.watchers[property] = [];
1296 | this.watchers[property].push(callback);
1297 | };
1298 |
1299 | this.showDirectiveStack = [];
1300 | this.showDirectiveLastElement;
1301 | var initReturnedCallback; // If x-init is present AND we aren't cloning (skip x-init on clone)
1302 |
1303 | if (initExpression && !seedDataForCloning) {
1304 | // We want to allow data manipulation, but not trigger DOM updates just yet.
1305 | // We haven't even initialized the elements with their Alpine bindings. I mean c'mon.
1306 | this.pauseReactivity = true;
1307 | initReturnedCallback = this.evaluateReturnExpression(this.$el, initExpression);
1308 | this.pauseReactivity = false;
1309 | } // Register all our listeners and set all our attribute bindings.
1310 |
1311 |
1312 | this.initializeElements(this.$el); // Use mutation observer to detect new elements being added within this component at run-time.
1313 | // Alpine's just so darn flexible amirite?
1314 |
1315 | this.listenForNewElementsToInitialize();
1316 |
1317 | if (typeof initReturnedCallback === 'function') {
1318 | // Run the callback returned from the "x-init" hook to allow the user to do stuff after
1319 | // Alpine's got it's grubby little paws all over everything.
1320 | initReturnedCallback.call(this.$data);
1321 | }
1322 | }
1323 |
1324 | getUnobservedData() {
1325 | return unwrap$1(this.membrane, this.$data);
1326 | }
1327 |
1328 | wrapDataInObservable(data) {
1329 | var self = this;
1330 | let updateDom = debounce(function () {
1331 | self.updateElements(self.$el);
1332 | }, 0);
1333 | return wrap(data, (target, key) => {
1334 | if (self.watchers[key]) {
1335 | // If there's a watcher for this specific key, run it.
1336 | self.watchers[key].forEach(callback => callback(target[key]));
1337 | } else {
1338 | // Let's walk through the watchers with "dot-notation" (foo.bar) and see
1339 | // if this mutation fits any of them.
1340 | Object.keys(self.watchers).filter(i => i.includes('.')).forEach(fullDotNotationKey => {
1341 | let dotNotationParts = fullDotNotationKey.split('.'); // If this dot-notation watcher's last "part" doesn't match the current
1342 | // key, then skip it early for performance reasons.
1343 |
1344 | if (key !== dotNotationParts[dotNotationParts.length - 1]) return; // Now, walk through the dot-notation "parts" recursively to find
1345 | // a match, and call the watcher if one's found.
1346 |
1347 | dotNotationParts.reduce((comparisonData, part) => {
1348 | if (Object.is(target, comparisonData)) {
1349 | // Run the watchers.
1350 | self.watchers[fullDotNotationKey].forEach(callback => callback(target[key]));
1351 | }
1352 |
1353 | return comparisonData[part];
1354 | }, self.getUnobservedData());
1355 | });
1356 | } // Don't react to data changes for cases like the `x-created` hook.
1357 |
1358 |
1359 | if (self.pauseReactivity) return;
1360 | updateDom();
1361 | });
1362 | }
1363 |
1364 | walkAndSkipNestedComponents(el, callback, initializeComponentCallback = () => {}) {
1365 | walk(el, el => {
1366 | // We've hit a component.
1367 | if (el.hasAttribute('x-data')) {
1368 | // If it's not the current one.
1369 | if (!el.isSameNode(this.$el)) {
1370 | // Initialize it if it's not.
1371 | if (!el.__x) initializeComponentCallback(el); // Now we'll let that sub-component deal with itself.
1372 |
1373 | return false;
1374 | }
1375 | }
1376 |
1377 | return callback(el);
1378 | });
1379 | }
1380 |
1381 | initializeElements(rootEl, extraVars = () => {}) {
1382 | this.walkAndSkipNestedComponents(rootEl, el => {
1383 | // Don't touch spawns from for loop
1384 | if (el.__x_for_key !== undefined) return false; // Don't touch spawns from if directives
1385 |
1386 | if (el.__x_inserted_me !== undefined) return false;
1387 | this.initializeElement(el, extraVars);
1388 | }, el => {
1389 | el.__x = new Component(el);
1390 | });
1391 | this.executeAndClearRemainingShowDirectiveStack();
1392 | this.executeAndClearNextTickStack(rootEl);
1393 | }
1394 |
1395 | initializeElement(el, extraVars) {
1396 | // To support class attribute merging, we have to know what the element's
1397 | // original class attribute looked like for reference.
1398 | if (el.hasAttribute('class') && getXAttrs(el).length > 0) {
1399 | el.__x_original_classes = el.getAttribute('class').split(' ');
1400 | }
1401 |
1402 | this.registerListeners(el, extraVars);
1403 | this.resolveBoundAttributes(el, true, extraVars);
1404 | }
1405 |
1406 | updateElements(rootEl, extraVars = () => {}) {
1407 | this.walkAndSkipNestedComponents(rootEl, el => {
1408 | // Don't touch spawns from for loop (and check if the root is actually a for loop in a parent, don't skip it.)
1409 | if (el.__x_for_key !== undefined && !el.isSameNode(this.$el)) return false;
1410 | this.updateElement(el, extraVars);
1411 | }, el => {
1412 | el.__x = new Component(el);
1413 | });
1414 | this.executeAndClearRemainingShowDirectiveStack();
1415 | this.executeAndClearNextTickStack(rootEl);
1416 | }
1417 |
1418 | executeAndClearNextTickStack(el) {
1419 | // Skip spawns from alpine directives
1420 | if (el === this.$el) {
1421 | // Walk through the $nextTick stack and clear it as we go.
1422 | while (this.nextTickStack.length > 0) {
1423 | this.nextTickStack.shift()();
1424 | }
1425 | }
1426 | }
1427 |
1428 | executeAndClearRemainingShowDirectiveStack() {
1429 | // The goal here is to start all the x-show transitions
1430 | // and build a nested promise chain so that elements
1431 | // only hide when the children are finished hiding.
1432 | this.showDirectiveStack.reverse().map(thing => {
1433 | return new Promise(resolve => {
1434 | thing(finish => {
1435 | resolve(finish);
1436 | });
1437 | });
1438 | }).reduce((nestedPromise, promise) => {
1439 | return nestedPromise.then(() => {
1440 | return promise.then(finish => finish());
1441 | });
1442 | }, Promise.resolve(() => {})); // We've processed the handler stack. let's clear it.
1443 |
1444 | this.showDirectiveStack = [];
1445 | this.showDirectiveLastElement = undefined;
1446 | }
1447 |
1448 | updateElement(el, extraVars) {
1449 | this.resolveBoundAttributes(el, false, extraVars);
1450 | }
1451 |
1452 | registerListeners(el, extraVars) {
1453 | getXAttrs(el).forEach(({
1454 | type,
1455 | value,
1456 | modifiers,
1457 | expression
1458 | }) => {
1459 | switch (type) {
1460 | case 'on':
1461 | registerListener(this, el, value, modifiers, expression, extraVars);
1462 | break;
1463 |
1464 | case 'model':
1465 | registerModelListener(this, el, modifiers, expression, extraVars);
1466 | break;
1467 | }
1468 | });
1469 | }
1470 |
1471 | resolveBoundAttributes(el, initialUpdate = false, extraVars) {
1472 | let attrs = getXAttrs(el);
1473 |
1474 | if (el.type !== undefined && el.type === 'radio') {
1475 | // If there's an x-model on a radio input, move it to end of attribute list
1476 | // to ensure that x-bind:value (if present) is processed first.
1477 | const modelIdx = attrs.findIndex(attr => attr.type === 'model');
1478 |
1479 | if (modelIdx > -1) {
1480 | attrs.push(attrs.splice(modelIdx, 1)[0]);
1481 | }
1482 | }
1483 |
1484 | attrs.forEach(({
1485 | type,
1486 | value,
1487 | modifiers,
1488 | expression
1489 | }) => {
1490 | switch (type) {
1491 | case 'model':
1492 | handleAttributeBindingDirective(this, el, 'value', expression, extraVars, type);
1493 | break;
1494 |
1495 | case 'bind':
1496 | // The :key binding on an x-for is special, ignore it.
1497 | if (el.tagName.toLowerCase() === 'template' && value === 'key') return;
1498 | handleAttributeBindingDirective(this, el, value, expression, extraVars, type);
1499 | break;
1500 |
1501 | case 'text':
1502 | var output = this.evaluateReturnExpression(el, expression, extraVars);
1503 | handleTextDirective(el, output, expression);
1504 | break;
1505 |
1506 | case 'html':
1507 | handleHtmlDirective(this, el, expression, extraVars);
1508 | break;
1509 |
1510 | case 'show':
1511 | var output = this.evaluateReturnExpression(el, expression, extraVars);
1512 | handleShowDirective(this, el, output, modifiers, initialUpdate);
1513 | break;
1514 |
1515 | case 'if':
1516 | // If this element also has x-for on it, don't process x-if.
1517 | // We will let the "x-for" directive handle the "if"ing.
1518 | if (attrs.filter(i => i.type === 'for').length > 0) return;
1519 | var output = this.evaluateReturnExpression(el, expression, extraVars);
1520 | handleIfDirective(this, el, output, initialUpdate, extraVars);
1521 | break;
1522 |
1523 | case 'for':
1524 | handleForDirective(this, el, expression, initialUpdate, extraVars);
1525 | break;
1526 |
1527 | case 'cloak':
1528 | el.removeAttribute('x-cloak');
1529 | break;
1530 | }
1531 | });
1532 | }
1533 |
1534 | evaluateReturnExpression(el, expression, extraVars = () => {}) {
1535 | return saferEval(expression, this.$data, _objectSpread2({}, extraVars(), {
1536 | $dispatch: this.getDispatchFunction(el)
1537 | }));
1538 | }
1539 |
1540 | evaluateCommandExpression(el, expression, extraVars = () => {}) {
1541 | return saferEvalNoReturn(expression, this.$data, _objectSpread2({}, extraVars(), {
1542 | $dispatch: this.getDispatchFunction(el)
1543 | }));
1544 | }
1545 |
1546 | getDispatchFunction(el) {
1547 | return (event, detail = {}) => {
1548 | el.dispatchEvent(new CustomEvent(event, {
1549 | detail,
1550 | bubbles: true
1551 | }));
1552 | };
1553 | }
1554 |
1555 | listenForNewElementsToInitialize() {
1556 | const targetNode = this.$el;
1557 | const observerOptions = {
1558 | childList: true,
1559 | attributes: true,
1560 | subtree: true
1561 | };
1562 | const observer = new MutationObserver(mutations => {
1563 | for (let i = 0; i < mutations.length; i++) {
1564 | // Filter out mutations triggered from child components.
1565 | const closestParentComponent = mutations[i].target.closest('[x-data]');
1566 | if (!(closestParentComponent && closestParentComponent.isSameNode(this.$el))) continue;
1567 |
1568 | if (mutations[i].type === 'attributes' && mutations[i].attributeName === 'x-data') {
1569 | const rawData = saferEval(mutations[i].target.getAttribute('x-data'), {});
1570 | Object.keys(rawData).forEach(key => {
1571 | if (this.$data[key] !== rawData[key]) {
1572 | this.$data[key] = rawData[key];
1573 | }
1574 | });
1575 | }
1576 |
1577 | if (mutations[i].addedNodes.length > 0) {
1578 | mutations[i].addedNodes.forEach(node => {
1579 | if (node.nodeType !== 1 || node.__x_inserted_me) return;
1580 |
1581 | if (node.matches('[x-data]')) {
1582 | node.__x = new Component(node);
1583 | return;
1584 | }
1585 |
1586 | this.initializeElements(node);
1587 | });
1588 | }
1589 | }
1590 | });
1591 | observer.observe(targetNode, observerOptions);
1592 | }
1593 |
1594 | getRefsProxy() {
1595 | var self = this;
1596 | var refObj = {};
1597 | // One of the goals of this is to not hold elements in memory, but rather re-evaluate
1598 | // the DOM when the system needs something from it. This way, the framework is flexible and
1599 | // friendly to outside DOM changes from libraries like Vue/Livewire.
1600 | // For this reason, I'm using an "on-demand" proxy to fake a "$refs" object.
1601 |
1602 | return new Proxy(refObj, {
1603 | get(object, property) {
1604 | if (property === '$isAlpineProxy') return true;
1605 | var ref; // We can't just query the DOM because it's hard to filter out refs in
1606 | // nested components.
1607 |
1608 | self.walkAndSkipNestedComponents(self.$el, el => {
1609 | if (el.hasAttribute('x-ref') && el.getAttribute('x-ref') === property) {
1610 | ref = el;
1611 | }
1612 | });
1613 | return ref;
1614 | }
1615 |
1616 | });
1617 | }
1618 |
1619 | }
1620 |
1621 | const Alpine = {
1622 | version: "2.3.3",
1623 | start: async function start() {
1624 | if (!isTesting()) {
1625 | await domReady();
1626 | }
1627 |
1628 | this.discoverComponents(el => {
1629 | this.initializeComponent(el);
1630 | }); // It's easier and more performant to just support Turbolinks than listen
1631 | // to MutationObserver mutations at the document level.
1632 |
1633 | document.addEventListener("turbolinks:load", () => {
1634 | this.discoverUninitializedComponents(el => {
1635 | this.initializeComponent(el);
1636 | });
1637 | });
1638 | this.listenForNewUninitializedComponentsAtRunTime(el => {
1639 | this.initializeComponent(el);
1640 | });
1641 | },
1642 | discoverComponents: function discoverComponents(callback) {
1643 | const rootEls = document.querySelectorAll('[x-data]');
1644 | rootEls.forEach(rootEl => {
1645 | callback(rootEl);
1646 | });
1647 | },
1648 | discoverUninitializedComponents: function discoverUninitializedComponents(callback, el = null) {
1649 | const rootEls = (el || document).querySelectorAll('[x-data]');
1650 | Array.from(rootEls).filter(el => el.__x === undefined).forEach(rootEl => {
1651 | callback(rootEl);
1652 | });
1653 | },
1654 | listenForNewUninitializedComponentsAtRunTime: function listenForNewUninitializedComponentsAtRunTime(callback) {
1655 | const targetNode = document.querySelector('body');
1656 | const observerOptions = {
1657 | childList: true,
1658 | attributes: true,
1659 | subtree: true
1660 | };
1661 | const observer = new MutationObserver(mutations => {
1662 | for (let i = 0; i < mutations.length; i++) {
1663 | if (mutations[i].addedNodes.length > 0) {
1664 | mutations[i].addedNodes.forEach(node => {
1665 | // Discard non-element nodes (like line-breaks)
1666 | if (node.nodeType !== 1) return; // Discard any changes happening within an existing component.
1667 | // They will take care of themselves.
1668 |
1669 | if (node.parentElement && node.parentElement.closest('[x-data]')) return;
1670 | this.discoverUninitializedComponents(el => {
1671 | this.initializeComponent(el);
1672 | }, node.parentElement);
1673 | });
1674 | }
1675 | }
1676 | });
1677 | observer.observe(targetNode, observerOptions);
1678 | },
1679 | initializeComponent: function initializeComponent(el) {
1680 | if (!el.__x) {
1681 | el.__x = new Component(el);
1682 | }
1683 | },
1684 | clone: function clone(component, newEl) {
1685 | if (!newEl.__x) {
1686 | newEl.__x = new Component(newEl, component.getUnobservedData());
1687 | }
1688 | }
1689 | };
1690 |
1691 | if (!isTesting()) {
1692 | window.Alpine = Alpine;
1693 |
1694 | if (window.deferLoadingAlpine) {
1695 | window.deferLoadingAlpine(function () {
1696 | window.Alpine.start();
1697 | });
1698 | } else {
1699 | window.Alpine.start();
1700 | }
1701 | }
1702 |
1703 | return Alpine;
1704 |
1705 | })));
1706 |
--------------------------------------------------------------------------------
/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swlkr/ridgecss/a15065241e71c0992e6b5984f5d9e3bba0b4558f/android-chrome-192x192.png
--------------------------------------------------------------------------------
/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swlkr/ridgecss/a15065241e71c0992e6b5984f5d9e3bba0b4558f/android-chrome-512x512.png
--------------------------------------------------------------------------------
/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swlkr/ridgecss/a15065241e71c0992e6b5984f5d9e3bba0b4558f/apple-touch-icon.png
--------------------------------------------------------------------------------
/atom-one-dark.css:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Atom One Dark by Daniel Gamage
4 | Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax
5 |
6 | base: #282c34
7 | mono-1: #abb2bf
8 | mono-2: #818896
9 | mono-3: #5c6370
10 | hue-1: #56b6c2
11 | hue-2: #61aeee
12 | hue-3: #c678dd
13 | hue-4: #98c379
14 | hue-5: #e06c75
15 | hue-5-2: #be5046
16 | hue-6: #d19a66
17 | hue-6-2: #e6c07b
18 |
19 | */
20 |
21 | .hljs {
22 | display: block;
23 | overflow-x: auto;
24 | padding: 0.5em;
25 | color: #abb2bf;
26 | background: #282c34;
27 | }
28 |
29 | .hljs-comment,
30 | .hljs-quote {
31 | color: #5c6370;
32 | font-style: italic;
33 | }
34 |
35 | .hljs-doctag,
36 | .hljs-keyword,
37 | .hljs-formula {
38 | color: #c678dd;
39 | }
40 |
41 | .hljs-section,
42 | .hljs-name,
43 | .hljs-selector-tag,
44 | .hljs-deletion,
45 | .hljs-subst {
46 | color: #e06c75;
47 | }
48 |
49 | .hljs-literal {
50 | color: #56b6c2;
51 | }
52 |
53 | .hljs-string,
54 | .hljs-regexp,
55 | .hljs-addition,
56 | .hljs-attribute,
57 | .hljs-meta-string {
58 | color: #98c379;
59 | }
60 |
61 | .hljs-built_in,
62 | .hljs-class .hljs-title {
63 | color: #e6c07b;
64 | }
65 |
66 | .hljs-attr,
67 | .hljs-variable,
68 | .hljs-template-variable,
69 | .hljs-type,
70 | .hljs-selector-class,
71 | .hljs-selector-attr,
72 | .hljs-selector-pseudo,
73 | .hljs-number {
74 | color: #d19a66;
75 | }
76 |
77 | .hljs-symbol,
78 | .hljs-bullet,
79 | .hljs-link,
80 | .hljs-meta,
81 | .hljs-selector-id,
82 | .hljs-title {
83 | color: #61aeee;
84 | }
85 |
86 | .hljs-emphasis {
87 | font-style: italic;
88 | }
89 |
90 | .hljs-strong {
91 | font-weight: bold;
92 | }
93 |
94 | .hljs-link {
95 | text-decoration: underline;
96 | }
97 |
--------------------------------------------------------------------------------
/atom-one-light.css:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Atom One Light by Daniel Gamage
4 | Original One Light Syntax theme from https://github.com/atom/one-light-syntax
5 |
6 | base: #fafafa
7 | mono-1: #383a42
8 | mono-2: #686b77
9 | mono-3: #a0a1a7
10 | hue-1: #0184bb
11 | hue-2: #4078f2
12 | hue-3: #a626a4
13 | hue-4: #50a14f
14 | hue-5: #e45649
15 | hue-5-2: #c91243
16 | hue-6: #986801
17 | hue-6-2: #c18401
18 |
19 | */
20 |
21 | .hljs {
22 | display: block;
23 | overflow-x: auto;
24 | padding: 0.5em;
25 | color: #383a42;
26 | background: #fafafa;
27 | }
28 |
29 | .hljs-comment,
30 | .hljs-quote {
31 | color: #a0a1a7;
32 | font-style: italic;
33 | }
34 |
35 | .hljs-doctag,
36 | .hljs-keyword,
37 | .hljs-formula {
38 | color: #a626a4;
39 | }
40 |
41 | .hljs-section,
42 | .hljs-name,
43 | .hljs-selector-tag,
44 | .hljs-deletion,
45 | .hljs-subst {
46 | color: #e45649;
47 | }
48 |
49 | .hljs-literal {
50 | color: #0184bb;
51 | }
52 |
53 | .hljs-string,
54 | .hljs-regexp,
55 | .hljs-addition,
56 | .hljs-attribute,
57 | .hljs-meta-string {
58 | color: #50a14f;
59 | }
60 |
61 | .hljs-built_in,
62 | .hljs-class .hljs-title {
63 | color: #c18401;
64 | }
65 |
66 | .hljs-attr,
67 | .hljs-variable,
68 | .hljs-template-variable,
69 | .hljs-type,
70 | .hljs-selector-class,
71 | .hljs-selector-attr,
72 | .hljs-selector-pseudo,
73 | .hljs-number {
74 | color: #986801;
75 | }
76 |
77 | .hljs-symbol,
78 | .hljs-bullet,
79 | .hljs-link,
80 | .hljs-meta,
81 | .hljs-selector-id,
82 | .hljs-title {
83 | color: #4078f2;
84 | }
85 |
86 | .hljs-emphasis {
87 | font-style: italic;
88 | }
89 |
90 | .hljs-strong {
91 | font-weight: bold;
92 | }
93 |
94 | .hljs-link {
95 | text-decoration: underline;
96 | }
97 |
--------------------------------------------------------------------------------
/demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swlkr/ridgecss/a15065241e71c0992e6b5984f5d9e3bba0b4558f/demo.png
--------------------------------------------------------------------------------
/examples.html:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | ridge.css
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | ridge.css
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | Examples
69 |
76 | Github
77 |
78 |
79 |
80 |
81 |
82 | ridge.css examples
83 | Examples, they get the people goin'
84 |
85 |
86 |
87 |
88 | Layout
89 |
90 | Preview
91 | Code
92 |
93 |
94 |
95 |
96 |
97 | vstack
98 |
99 | vstack 1
100 | vstack 2
101 | vstack 3
102 | vstack 4
103 | vstack 5
104 |
105 |
106 |
107 |
108 | vstack centered
109 |
110 |
111 |
112 | hstack
113 |
114 | hstack 1
115 | hstack 2
116 | hstack 3
117 | hstack 4
118 | hstack 5
119 | hstack 6
120 | hstack 7
121 |
122 |
123 | hstack center
124 |
125 | centered 1
126 | centered 2
127 | centered 3
128 |
129 |
130 | hstack stretch
131 |
132 | stretch 1
133 | stretch 2
134 | stretch 3
135 |
136 |
137 | hstack responsive
138 |
139 | responsive 1
140 | responsive 2
141 | responsive 3
142 | responsive 4
143 | responsive 5
144 | responsive 6
145 |
146 |
147 |
148 | section
149 |
150 | section 1
151 | section 2
152 | section 3
153 | section 4
154 | section 5
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 | Alerts
170 |
171 | Preview
172 | Code
173 |
174 |
175 |
176 |
177 |
178 |
179 | A simple well that uses the default theme colors
180 |
181 |
182 | A simple well that uses the default theme colors
183 |
184 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 | Stats
210 |
211 | Preview
212 | Code
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 | Visitors
221 | 1,337
222 |
223 |
224 |
225 |
226 | Bounce Rate
227 | 3%
228 |
229 |
230 |
231 |
232 | Conversion Rate
233 | 23.57%
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 | Cards
252 |
253 | Preview
254 | Code
255 |
256 |
257 |
258 |
259 |
260 |
270 |
271 |
281 |
282 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 | Description List Card
306 |
307 | Preview
308 | Code
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 | A demo description list component
318 | A smaller more in-depth description of this component
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 | Description title
327 | Description
328 |
329 |
330 |
331 | Name
332 | Sean Walker
333 |
334 |
335 |
336 |
337 |
338 | Email
339 | sean@example.com
340 |
341 |
342 |
343 | Project
344 | ridge.css
345 |
346 |
347 |
348 |
349 | About
350 | ridge.css helps you make fast web apps fast with just plain html
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 | Section
369 |
370 | Preview
371 | Code
372 |
373 |
374 |
375 |
376 |
377 | Section Title
378 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 | Dashboard
416 |
417 | Preview
418 | Code
419 |
420 |
421 |
422 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 | Dashboard w/ Sidebar
508 |
509 | Preview
510 | Code
511 |
512 |
513 |
514 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 | Home
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 | Examples
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 | Themes
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 | Github
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 | Default
643 | Watermelon
644 | Valentines
645 |
646 |
647 |
658 |
659 |
660 |
--------------------------------------------------------------------------------
/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swlkr/ridgecss/a15065241e71c0992e6b5984f5d9e3bba0b4558f/favicon-16x16.png
--------------------------------------------------------------------------------
/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swlkr/ridgecss/a15065241e71c0992e6b5984f5d9e3bba0b4558f/favicon-32x32.png
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swlkr/ridgecss/a15065241e71c0992e6b5984f5d9e3bba0b4558f/favicon.ico
--------------------------------------------------------------------------------
/highlight.pack.js:
--------------------------------------------------------------------------------
1 | /*
2 | Highlight.js 10.0.3 (a4b1bd2d)
3 | License: BSD-3-Clause
4 | Copyright (c) 2006-2020, Ivan Sagalaev
5 | */
6 | var hljs=function(){"use strict";function e(n){Object.freeze(n);var t="function"==typeof n;return Object.getOwnPropertyNames(n).forEach((function(r){!n.hasOwnProperty(r)||null===n[r]||"object"!=typeof n[r]&&"function"!=typeof n[r]||t&&("caller"===r||"callee"===r||"arguments"===r)||Object.isFrozen(n[r])||e(n[r])})),n}function n(e){return e.replace(/&/g,"&").replace(//g,">")}function t(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach((function(e){for(n in e)t[n]=e[n]})),t}function r(e){return e.nodeName.toLowerCase()}var a=Object.freeze({__proto__:null,escapeHTML:n,inherit:t,nodeStream:function(e){var n=[];return function e(t,a){for(var i=t.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=e(i,a),r(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n},mergeStreams:function(e,t,a){var i=0,s="",o=[];function l(){return e.length&&t.length?e[0].offset!==t[0].offset?e[0].offset"}function u(e){s+=""+r(e)+">"}function d(e){("start"===e.event?c:u)(e.node)}for(;e.length||t.length;){var g=l();if(s+=n(a.substring(i,g[0].offset)),i=g[0].offset,g===e){o.reverse().forEach(u);do{d(g.splice(0,1)[0]),g=l()}while(g===e&&g.length&&g[0].offset===i);o.reverse().forEach(c)}else"start"===g[0].event?o.push(g[0].node):o.pop(),d(g.splice(0,1)[0])}return s+n(a.substr(i))}});const i="",s=e=>!!e.kind;class o{constructor(e,n){this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){this.buffer+=n(e)}openNode(e){if(!s(e))return;let n=e.kind;e.sublanguage||(n=`${this.classPrefix}${n}`),this.span(n)}closeNode(e){s(e)&&(this.buffer+=i)}span(e){this.buffer+=``}value(){return this.buffer}}class l{constructor(){this.rootNode={children:[]},this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){this.top.children.push(e)}openNode(e){let n={kind:e,children:[]};this.add(n),this.stack.push(n)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,n){return"string"==typeof n?e.addText(n):n.children&&(e.openNode(n),n.children.forEach(n=>this._walk(e,n)),e.closeNode(n)),e}static _collapse(e){e.children&&(e.children.every(e=>"string"==typeof e)?(e.text=e.children.join(""),delete e.children):e.children.forEach(e=>{"string"!=typeof e&&l._collapse(e)}))}}class c extends l{constructor(e){super(),this.options=e}addKeyword(e,n){""!==e&&(this.openNode(n),this.addText(e),this.closeNode())}addText(e){""!==e&&this.add(e)}addSublanguage(e,n){let t=e.root;t.kind=n,t.sublanguage=!0,this.add(t)}toHTML(){return new o(this,this.options).value()}finalize(){}}function u(e){return e&&e.source||e}const d="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",g={begin:"\\\\[\\s\\S]",relevance:0},h={className:"string",begin:"'",end:"'",illegal:"\\n",contains:[g]},f={className:"string",begin:'"',end:'"',illegal:"\\n",contains:[g]},p={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},m=function(e,n,r){var a=t({className:"comment",begin:e,end:n,contains:[]},r||{});return a.contains.push(p),a.contains.push({className:"doctag",begin:"(?:TODO|FIXME|NOTE|BUG|XXX):",relevance:0}),a},b=m("//","$"),v=m("/\\*","\\*/"),x=m("#","$");var _=Object.freeze({__proto__:null,IDENT_RE:"[a-zA-Z]\\w*",UNDERSCORE_IDENT_RE:"[a-zA-Z_]\\w*",NUMBER_RE:"\\b\\d+(\\.\\d+)?",C_NUMBER_RE:d,BINARY_NUMBER_RE:"\\b(0b[01]+)",RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",BACKSLASH_ESCAPE:g,APOS_STRING_MODE:h,QUOTE_STRING_MODE:f,PHRASAL_WORDS_MODE:p,COMMENT:m,C_LINE_COMMENT_MODE:b,C_BLOCK_COMMENT_MODE:v,HASH_COMMENT_MODE:x,NUMBER_MODE:{className:"number",begin:"\\b\\d+(\\.\\d+)?",relevance:0},C_NUMBER_MODE:{className:"number",begin:d,relevance:0},BINARY_NUMBER_MODE:{className:"number",begin:"\\b(0b[01]+)",relevance:0},CSS_NUMBER_MODE:{className:"number",begin:"\\b\\d+(\\.\\d+)?(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},REGEXP_MODE:{begin:/(?=\/[^\/\n]*\/)/,contains:[{className:"regexp",begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[g,{begin:/\[/,end:/\]/,relevance:0,contains:[g]}]}]},TITLE_MODE:{className:"title",begin:"[a-zA-Z]\\w*",relevance:0},UNDERSCORE_TITLE_MODE:{className:"title",begin:"[a-zA-Z_]\\w*",relevance:0},METHOD_GUARD:{begin:"\\.\\s*[a-zA-Z_]\\w*",relevance:0}}),E="of and for in not or if then".split(" ");function R(e,n){return n?+n:(t=e,E.includes(t.toLowerCase())?0:1);var t}const N=n,w=t,{nodeStream:y,mergeStreams:O}=a;return function(n){var r=[],a={},i={},s=[],o=!0,l=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,d="Could not find the language '{}', did you forget to load/include a language module?",g={noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0,__emitter:c};function h(e){return g.noHighlightRe.test(e)}function f(e,n,t,r){var a={code:n,language:e};T("before:highlight",a);var i=a.result?a.result:p(a.language,a.code,t,r);return i.code=a.code,T("after:highlight",i),i}function p(e,n,r,i){var s=n;function l(e,n){var t=v.case_insensitive?n[0].toLowerCase():n[0];return e.keywords.hasOwnProperty(t)&&e.keywords[t]}function c(){null!=_.subLanguage?function(){if(""!==k){var e="string"==typeof _.subLanguage;if(!e||a[_.subLanguage]){var n=e?p(_.subLanguage,k,!0,E[_.subLanguage]):m(k,_.subLanguage.length?_.subLanguage:void 0);_.relevance>0&&(T+=n.relevance),e&&(E[_.subLanguage]=n.top),w.addSublanguage(n.emitter,n.language)}else w.addText(k)}}():function(){var e,n,t,r;if(_.keywords){for(n=0,_.lexemesRe.lastIndex=0,t=_.lexemesRe.exec(k),r="";t;){r+=k.substring(n,t.index);var a=null;(e=l(_,t))?(w.addText(r),r="",T+=e[1],a=e[0],w.addKeyword(t[0],a)):r+=t[0],n=_.lexemesRe.lastIndex,t=_.lexemesRe.exec(k)}r+=k.substr(n),w.addText(r)}else w.addText(k)}(),k=""}function h(e){e.className&&w.openNode(e.className),_=Object.create(e,{parent:{value:_}})}var f={};function b(n,t){var a,i=t&&t[0];if(k+=n,null==i)return c(),0;if("begin"==f.type&&"end"==t.type&&f.index==t.index&&""===i){if(k+=s.slice(t.index,t.index+1),!o)throw(a=Error("0 width match regex")).languageName=e,a.badRule=f.rule,a;return 1}if(f=t,"begin"===t.type)return function(e){var n=e[0],t=e.rule;return t.__onBegin&&(t.__onBegin(e)||{}).ignoreMatch?function(e){return 0===_.matcher.regexIndex?(k+=e[0],1):(B=!0,0)}(n):(t&&t.endSameAsBegin&&(t.endRe=RegExp(n.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&"),"m")),t.skip?k+=n:(t.excludeBegin&&(k+=n),c(),t.returnBegin||t.excludeBegin||(k=n)),h(t),t.returnBegin?0:n.length)}(t);if("illegal"===t.type&&!r)throw(a=Error('Illegal lexeme "'+i+'" for mode "'+(_.className||"")+'"')).mode=_,a;if("end"===t.type){var l=function(e){var n=e[0],t=s.substr(e.index),r=function e(n,t){if(function(e,n){var t=e&&e.exec(n);return t&&0===t.index}(n.endRe,t)){for(;n.endsParent&&n.parent;)n=n.parent;return n}if(n.endsWithParent)return e(n.parent,t)}(_,t);if(r){var a=_;a.skip?k+=n:(a.returnEnd||a.excludeEnd||(k+=n),c(),a.excludeEnd&&(k=n));do{_.className&&w.closeNode(),_.skip||_.subLanguage||(T+=_.relevance),_=_.parent}while(_!==r.parent);return r.starts&&(r.endSameAsBegin&&(r.starts.endRe=r.endRe),h(r.starts)),a.returnEnd?0:n.length}}(t);if(null!=l)return l}if("illegal"===t.type&&""===i)return 1;if(A>1e5&&A>3*t.index)throw Error("potential infinite loop, way more iterations than matches");return k+=i,i.length}var v=M(e);if(!v)throw console.error(d.replace("{}",e)),Error('Unknown language: "'+e+'"');!function(e){function n(n,t){return RegExp(u(n),"m"+(e.case_insensitive?"i":"")+(t?"g":""))}class r{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(e,n){n.position=this.position++,this.matchIndexes[this.matchAt]=n,this.regexes.push([n,e]),this.matchAt+=function(e){return RegExp(e.toString()+"|").exec("").length-1}(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null);let e=this.regexes.map(e=>e[1]);this.matcherRe=n(function(e,n){for(var t=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./,r=0,a="",i=0;i0&&(a+="|"),a+="(";o.length>0;){var l=t.exec(o);if(null==l){a+=o;break}a+=o.substring(0,l.index),o=o.substring(l.index+l[0].length),"\\"==l[0][0]&&l[1]?a+="\\"+(+l[1]+s):(a+=l[0],"("==l[0]&&r++)}a+=")"}return a}(e),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex;let n=this.matcherRe.exec(e);if(!n)return null;let t=n.findIndex((e,n)=>n>0&&null!=e),r=this.matchIndexes[t];return Object.assign(n,r)}}class a{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){if(this.multiRegexes[e])return this.multiRegexes[e];let n=new r;return this.rules.slice(e).forEach(([e,t])=>n.addRule(e,t)),n.compile(),this.multiRegexes[e]=n,n}considerAll(){this.regexIndex=0}addRule(e,n){this.rules.push([e,n]),"begin"===n.type&&this.count++}exec(e){let n=this.getMatcher(this.regexIndex);n.lastIndex=this.lastIndex;let t=n.exec(e);return t&&(this.regexIndex+=t.position+1,this.regexIndex===this.count&&(this.regexIndex=0)),t}}function i(e){let n=e.input[e.index-1],t=e.input[e.index+e[0].length];if("."===n||"."===t)return{ignoreMatch:!0}}if(e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");!function r(s,o){s.compiled||(s.compiled=!0,s.__onBegin=null,s.keywords=s.keywords||s.beginKeywords,s.keywords&&(s.keywords=function(e,n){var t={};return"string"==typeof e?r("keyword",e):Object.keys(e).forEach((function(n){r(n,e[n])})),t;function r(e,r){n&&(r=r.toLowerCase()),r.split(" ").forEach((function(n){var r=n.split("|");t[r[0]]=[e,R(r[0],r[1])]}))}}(s.keywords,e.case_insensitive)),s.lexemesRe=n(s.lexemes||/\w+/,!0),o&&(s.beginKeywords&&(s.begin="\\b("+s.beginKeywords.split(" ").join("|")+")(?=\\b|\\s)",s.__onBegin=i),s.begin||(s.begin=/\B|\b/),s.beginRe=n(s.begin),s.endSameAsBegin&&(s.end=s.begin),s.end||s.endsWithParent||(s.end=/\B|\b/),s.end&&(s.endRe=n(s.end)),s.terminator_end=u(s.end)||"",s.endsWithParent&&o.terminator_end&&(s.terminator_end+=(s.end?"|":"")+o.terminator_end)),s.illegal&&(s.illegalRe=n(s.illegal)),null==s.relevance&&(s.relevance=1),s.contains||(s.contains=[]),s.contains=[].concat(...s.contains.map((function(e){return function(e){return e.variants&&!e.cached_variants&&(e.cached_variants=e.variants.map((function(n){return t(e,{variants:null},n)}))),e.cached_variants?e.cached_variants:function e(n){return!!n&&(n.endsWithParent||e(n.starts))}(e)?t(e,{starts:e.starts?t(e.starts):null}):Object.isFrozen(e)?t(e):e}("self"===e?s:e)}))),s.contains.forEach((function(e){r(e,s)})),s.starts&&r(s.starts,o),s.matcher=function(e){let n=new a;return e.contains.forEach(e=>n.addRule(e.begin,{rule:e,type:"begin"})),e.terminator_end&&n.addRule(e.terminator_end,{type:"end"}),e.illegal&&n.addRule(e.illegal,{type:"illegal"}),n}(s))}(e)}(v);var x,_=i||v,E={},w=new g.__emitter(g);!function(){for(var e=[],n=_;n!==v;n=n.parent)n.className&&e.unshift(n.className);e.forEach(e=>w.openNode(e))}();var y,O,k="",T=0,L=0,A=0,B=!1;try{for(_.matcher.considerAll();A++,B?B=!1:(_.matcher.lastIndex=L,_.matcher.considerAll()),y=_.matcher.exec(s);)O=b(s.substring(L,y.index),y),L=y.index+O;return b(s.substr(L)),w.closeAllNodes(),w.finalize(),x=w.toHTML(),{relevance:T,value:x,language:e,illegal:!1,emitter:w,top:_}}catch(n){if(n.message&&n.message.includes("Illegal"))return{illegal:!0,illegalBy:{msg:n.message,context:s.slice(L-100,L+100),mode:n.mode},sofar:x,relevance:0,value:N(s),emitter:w};if(o)return{relevance:0,value:N(s),emitter:w,language:e,top:_,errorRaised:n};throw n}}function m(e,n){n=n||g.languages||Object.keys(a);var t=function(e){const n={relevance:0,emitter:new g.__emitter(g),value:N(e),illegal:!1,top:E};return n.emitter.addText(e),n}(e),r=t;return n.filter(M).filter(k).forEach((function(n){var a=p(n,e,!1);a.language=n,a.relevance>r.relevance&&(r=a),a.relevance>t.relevance&&(r=t,t=a)})),r.language&&(t.second_best=r),t}function b(e){return g.tabReplace||g.useBR?e.replace(l,(function(e,n){return g.useBR&&"\n"===e?" ":g.tabReplace?n.replace(/\t/g,g.tabReplace):""})):e}function v(e){var n,t,r,a,s,o=function(e){var n,t=e.className+" ";if(t+=e.parentNode?e.parentNode.className:"",n=g.languageDetectRe.exec(t)){var r=M(n[1]);return r||(console.warn(d.replace("{}",n[1])),console.warn("Falling back to no-highlight mode for this block.",e)),r?n[1]:"no-highlight"}return t.split(/\s+/).find(e=>h(e)||M(e))}(e);h(o)||(T("before:highlightBlock",{block:e,language:o}),g.useBR?(n=document.createElement("div")).innerHTML=e.innerHTML.replace(/\n/g,"").replace(/ /g,"\n"):n=e,s=n.textContent,r=o?f(o,s,!0):m(s),(t=y(n)).length&&((a=document.createElement("div")).innerHTML=r.value,r.value=O(t,y(a),s)),r.value=b(r.value),T("after:highlightBlock",{block:e,result:r}),e.innerHTML=r.value,e.className=function(e,n,t){var r=n?i[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),e.includes(r)||a.push(r),a.join(" ").trim()}(e.className,o,r.language),e.result={language:r.language,re:r.relevance},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.relevance}))}function x(){if(!x.called){x.called=!0;var e=document.querySelectorAll("pre code");r.forEach.call(e,v)}}const E={disableAutodetect:!0,name:"Plain text"};function M(e){return e=(e||"").toLowerCase(),a[e]||a[i[e]]}function k(e){var n=M(e);return n&&!n.disableAutodetect}function T(e,n){var t=e;s.forEach((function(e){e[t]&&e[t](n)}))}Object.assign(n,{highlight:f,highlightAuto:m,fixMarkup:b,highlightBlock:v,configure:function(e){g=w(g,e)},initHighlighting:x,initHighlightingOnLoad:function(){window.addEventListener("DOMContentLoaded",x,!1)},registerLanguage:function(e,t){var r;try{r=t(n)}catch(n){if(console.error("Language definition for '{}' could not be registered.".replace("{}",e)),!o)throw n;console.error(n),r=E}r.name||(r.name=e),a[e]=r,r.rawDefinition=t.bind(null,n),r.aliases&&r.aliases.forEach((function(n){i[n]=e}))},listLanguages:function(){return Object.keys(a)},getLanguage:M,requireLanguage:function(e){var n=M(e);if(n)return n;throw Error("The '{}' language is required, but not loaded.".replace("{}",e))},autoDetection:k,inherit:w,addPlugin:function(e,n){s.push(e)}}),n.debugMode=function(){o=!1},n.safeMode=function(){o=!0},n.versionString="10.0.3";for(const n in _)"object"==typeof _[n]&&e(_[n]);return Object.assign(n,_),n}({})}();"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs);hljs.registerLanguage("xml",function(){"use strict";return function(e){var n={className:"symbol",begin:"&[a-z]+;|[0-9]+;|[a-f0-9]+;"},a={begin:"\\s",contains:[{className:"meta-keyword",begin:"#?[a-z_][a-z1-9_-]+",illegal:"\\n"}]},s=e.inherit(a,{begin:"\\(",end:"\\)"}),t=e.inherit(e.APOS_STRING_MODE,{className:"meta-string"}),i=e.inherit(e.QUOTE_STRING_MODE,{className:"meta-string"}),c={endsWithParent:!0,illegal:/,relevance:0,contains:[{className:"attr",begin:"[A-Za-z0-9\\._:-]+",relevance:0},{begin:/=\s*/,relevance:0,contains:[{className:"string",endsParent:!0,variants:[{begin:/"/,end:/"/,contains:[n]},{begin:/'/,end:/'/,contains:[n]},{begin:/[^\s"'=<>`]+/}]}]}]};return{name:"HTML, XML",aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,contains:[{className:"meta",begin:"",relevance:10,contains:[a,i,t,s,{begin:"\\[",end:"\\]",contains:[{className:"meta",begin:"",contains:[a,s,i,t]}]}]},e.COMMENT("\x3c!--","--\x3e",{relevance:10}),{begin:"<\\!\\[CDATA\\[",end:"\\]\\]>",relevance:10},n,{className:"meta",begin:/<\?xml/,end:/\?>/,relevance:10},{className:"tag",begin:"",returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:"
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | ridge.css
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | Examples
62 |
69 | Github
70 |
71 |
72 |
73 |
74 |
75 |
76 | Make web apps quickly without writing css
77 |
78 |
79 | Make web apps quickly without writing css
80 |
81 |
82 | classless css mixed with a dash of atomic css , swift ui inspired elements and alpine.js markup
83 |
84 |
85 |
86 |
87 | Typography
88 |
89 | h1
90 | h2
91 | h3
92 | h4
93 | h5
94 | h6
95 |
96 |
97 | This is a short bit of text in a paragraph tag
98 |
99 | strong
100 | b
101 | em
102 | italic
103 | underline
104 | strikethrough
105 | mark
106 | l x w x h
107 | Cmd +P
108 |
109 |
110 |
111 | Climb the mountains and get their good tidings
112 |
115 |
116 |
117 |
118 |
119 | Lists
120 |
124 |
125 |
126 | Ordered list
127 | Ordered links
128 |
129 |
130 |
131 |
132 | Description title
133 | Description
134 |
135 |
136 |
137 |
138 |
139 | Buttons
140 |
141 |
142 | Button
143 |
144 | Link Button
145 |
146 | Disabled
147 |
148 |
149 |
150 |
151 | Forms
152 | Text
153 |
154 |
155 | Text Area
156 |
157 |
158 |
159 |
160 | Radio 1
161 |
162 |
163 |
164 |
165 | Radio 2
166 |
167 |
168 |
169 |
170 | Checkbox
171 |
172 |
173 | Range
174 |
175 |
176 | Dropdown
177 |
178 | One
179 | Two
180 | Three
181 |
182 |
183 |
184 |
185 | Tables
186 |
187 |
188 |
189 | One
190 | Two
191 | Three
192 | Four
193 | Five
194 | Six
195 |
196 |
197 |
198 |
199 | One
200 | Two
201 | Three
202 | Four
203 | Five
204 | Six
205 |
206 |
207 | Seven
208 | Eight
209 | Nine
210 | Ten
211 | Eleven
212 | Twelve
213 |
214 |
215 | Thirteen
216 | Fourteen
217 | Fifteen
218 | Sixteen
219 | Seventeen
220 | Eighteen
221 |
222 |
223 |
224 |
225 |
226 |
227 | Cards
228 |
229 |
230 |
231 | I'm a card!
232 |
233 |
234 |
235 |
236 |
237 | I'm a card!
238 |
239 |
240 |
241 |
242 |
243 | I'm a card!
244 |
245 |
246 |
247 |
248 |
249 |
250 | I'm a card!
251 |
252 |
253 |
254 |
255 |
256 | Details
257 |
258 | The deets
259 | Something small enough to escape casual notice
260 |
261 |
262 |
263 |
264 | Code blocks
265 |
266 |
267 | Code blocks look like this
268 |
269 |
270 |
271 |
272 |
273 | Footer
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 | Home
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 | Examples
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 | Themes
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 | Github
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 | Default
327 | Watermelon
328 | Valentines
329 |
330 |
331 |