diff --git a/components.js b/components.js
index 4c81c44..9a65a38 100644
--- a/components.js
+++ b/components.js
@@ -3427,4 +3427,234 @@ customElements.define('sm-switch', class extends HTMLElement {
}
}
+})
+
+const textField = document.createElement('template')
+textField.innerHTML = `
+
+
+`
+
+customElements.define('text-field', class extends HTMLElement {
+ constructor() {
+ super()
+ this.attachShadow({
+ mode: 'open'
+ }).append(textField.content.cloneNode(true))
+
+ this.textField = this.shadowRoot.querySelector('.text-field')
+ this.textContainer = this.textField.children[0]
+ this.iconsContainer = this.textField.children[1]
+ this.editButton = this.textField.querySelector('.edit-button')
+ this.saveButton = this.textField.querySelector('.save-button')
+ this.isTextEditable = false
+ this.isDisabled = false
+
+ this.fireEvent = this.fireEvent.bind(this)
+ this.setEditable = this.setEditable.bind(this)
+ this.setNonEditable = this.setNonEditable.bind(this)
+ this.revert = this.revert.bind(this)
+ }
+
+ static get observedAttributes() {
+ return ['disabled', 'value']
+ }
+
+ get value() {
+ return this.text
+ }
+ set value(val) {
+ this.setAttribute('value', val)
+ }
+ set disabled(val) {
+ this.isDisabled = val
+ if (this.isDisabled)
+ this.setAttribute('disabled', '')
+ else
+ this.removeAttribute('disabled')
+ }
+ fireEvent(value) {
+ let event = new CustomEvent('change', {
+ bubbles: true,
+ cancelable: true,
+ composed: true,
+ detail: {
+ value
+ }
+ });
+ this.dispatchEvent(event);
+ }
+
+ setEditable() {
+ if (this.isTextEditable) return
+ this.textContainer.contentEditable = true
+ this.textContainer.classList.add('editable')
+ this.textContainer.focus()
+ document.execCommand('selectAll', false, null);
+ this.editButton.animate(this.rotateOut, this.animOptions).onfinish = () => {
+ this.editButton.classList.add('hide')
+ }
+ setTimeout(() => {
+ this.saveButton.classList.remove('hide')
+ this.saveButton.animate(this.rotateIn, this.animOptions)
+ }, 100);
+ this.isTextEditable = true
+ }
+ setNonEditable() {
+ if (!this.isTextEditable) return
+ this.textContainer.contentEditable = false
+ this.textContainer.classList.remove('editable')
+ const newValue = this.textContainer.textContent.trim()
+ if (this.text !== newValue && newValue !== '') {
+ this.setAttribute('value', this.textContainer.textContent)
+ this.text = this.textContainer.textContent.trim()
+ this.fireEvent(this.text)
+ } else {
+ this.value = this.text
+ }
+ this.saveButton.animate(this.rotateOut, this.animOptions).onfinish = () => {
+ this.saveButton.classList.add('hide')
+ }
+ setTimeout(() => {
+ this.editButton.classList.remove('hide')
+ this.editButton.animate(this.rotateIn, this.animOptions)
+ }, 100);
+ this.isTextEditable = false
+ }
+
+ revert() {
+ if (this.textContainer.isContentEditable) {
+ this.value = this.text
+ this.setNonEditable()
+ }
+ }
+
+ connectedCallback() {
+ this.text
+ if (this.hasAttribute('value')) {
+ this.text = this.getAttribute('value')
+ this.textContainer.textContent = this.text
+ }
+ if (this.hasAttribute('disabled'))
+ this.isDisabled = true
+ else
+ this.isDisabled = false
+
+ this.rotateOut = [
+ {
+ transform: 'rotate(0)',
+ opacity: 1
+ },
+ {
+ transform: 'rotate(90deg)',
+ opacity: 0
+ },
+ ]
+ this.rotateIn = [
+ {
+ transform: 'rotate(-90deg)',
+ opacity: 0
+ },
+ {
+ transform: 'rotate(0)',
+ opacity: 1
+ },
+ ]
+ this.animOptions = {
+ duration: 300,
+ easing: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',
+ fill: 'forwards'
+ }
+ if (!this.isDisabled) {
+ this.iconsContainer.classList.remove('hide')
+ this.textContainer.addEventListener('dblclick', this.setEditable)
+ this.editButton.addEventListener('click', this.setEditable)
+ this.saveButton.addEventListener('click', this.setNonEditable)
+ }
+ }
+ attributeChangedCallback(name, oldValue, newValue) {
+ if (name === 'disabled') {
+ if (this.hasAttribute('disabled')) {
+ this.textContainer.removeEventListener('dblclick', this.setEditable)
+ this.editButton.removeEventListener('click', this.setEditable)
+ this.saveButton.removeEventListener('click', this.setNonEditable)
+ this.revert()
+ }
+ else {
+ this.textContainer.addEventListener('dblclick', this.setEditable)
+ this.editButton.addEventListener('click', this.setEditable)
+ this.saveButton.addEventListener('click', this.setNonEditable)
+ }
+ } else if (name === 'value') {
+ this.text = newValue
+ this.textContainer.textContent = newValue
+ }
+ }
+ disconnectedCallback() {
+ this.textContainer.removeEventListener('dblclick', this.setEditable)
+ this.editButton.removeEventListener('click', this.setEditable)
+ this.saveButton.removeEventListener('click', this.setNonEditable)
+ }
})
\ No newline at end of file
diff --git a/css/main.css b/css/main.css
index 22a28d1..6c40768 100644
--- a/css/main.css
+++ b/css/main.css
@@ -552,6 +552,31 @@ sm-checkbox {
grid-template-columns: minmax(0, 1fr);
}
+#current_article_title {
+ font-weight: 700;
+}
+
+.article-link {
+ padding: 1rem;
+ color: rgba(var(--text-color), 0.8);
+ font-weight: 500;
+ border-radius: 0.3rem;
+}
+.article-link::first-letter {
+ text-transform: uppercase;
+}
+
+.default-article {
+ margin-left: auto;
+ font-size: 0.7rem;
+ background-color: #00e67650;
+ padding: 0.2rem 0.4rem;
+ border-radius: 0.3rem;
+ font-weight: 700;
+ letter-spacing: 0.05em;
+ color: rgba(var(--text-color), 0.8);
+}
+
#article_wrapper {
display: -webkit-box;
display: -ms-flexbox;
@@ -565,6 +590,7 @@ sm-checkbox {
}
.heading {
+ font-weight: 700;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
@@ -592,16 +618,12 @@ sm-checkbox {
.article-section:not(:last-of-type) {
margin-bottom: 1.5rem;
}
-
-.content-card-container {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- gap: 0.5rem;
+.article-section::-webkit-scrollbar {
+ display: none;
}
.content-card {
- scroll-snap-align: start;
+ scroll-snap-align: center;
width: min(46ch, 100%);
-ms-flex-negative: 0;
flex-shrink: 0;
@@ -778,7 +800,7 @@ sm-checkbox {
}
.entry__changes .added > *,
.entry__changes .removed > * {
- background-color: inherit;
+ background-color: transparent;
}
.entry__changes .added {
background-color: #00e67650;
diff --git a/css/main.min.css b/css/main.min.css
index f241c7d..c1b7c7d 100644
--- a/css/main.min.css
+++ b/css/main.min.css
@@ -1 +1 @@
-*{padding:0;margin:0;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:"Inter",sans-serif}:root{font-size:clamp(1rem, 1.2vmax, 1.2rem)}html,body{height:100%;scroll-behavior:smooth}body{color:rgba(var(--text-color), 1);background:rgba(var(--background-color), 1)}body,body *{--accent-color: #504dff;--accent-color--light: #eeeeff;--text-color: 36, 36, 36;--background-color: 248, 248, 248;--foreground-color: rgb(255, 255, 255);--danger-color: rgb(255, 75, 75);--green: #1cad59;--yellow: #f3a600;--loan-color: rgb(255, 171, 93);scrollbar-width:thin}body[data-theme=dark],body[data-theme=dark] *{--accent-color: #a3a1ff;--accent-color--light: rgba(142, 140, 255, 0.06);--text-color: 230, 230, 230;--text-color-light: 170, 170, 170;--background-color: 10, 10, 10;--foreground-color: rgb(24, 24, 24);--danger-color: rgb(255, 106, 106);--green: #00e676;--yellow: #ffd13a;--loan-color: rgb(255, 232, 170)}body[data-theme=dark] sm-popup::part(popup){background-color:var(--foreground-color)}p,strong{font-size:.9rem;max-width:70ch;line-height:1.7;color:rgba(var(--text-color), 0.8)}p:not(:last-of-type),strong:not(:last-of-type){margin-bottom:1.5rem}a:where([class]){color:inherit;text-decoration:none}a:where([class]):focus-visible{-webkit-box-shadow:0 0 0 .1rem rgba(var(--text-color), 1) inset;box-shadow:0 0 0 .1rem rgba(var(--text-color), 1) inset}a{color:var(--accent-color)}button,.button{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;border:none;background-color:transparent;overflow:hidden;color:inherit;cursor:pointer;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s, -webkit-transform .3s;-webkit-tap-highlight-color:transparent;-webkit-box-align:center;-ms-flex-align:center;align-items:center;font-size:.9rem;font-weight:500}.button{white-space:nowrap;padding:.6rem 1rem;border-radius:.3rem;background-color:rgba(var(--text-color), 0.06);color:rgba(var(--text-color), 0.8);-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.button--primary{background-color:var(--accent-color);color:rgba(var(--background-color), 1)}button:disabled{opacity:.5}a:-webkit-any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}a:-moz-any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}a:any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}sm-input{font-size:.9rem;--border-radius: 0.3rem}sm-button{--padding: 0.7rem 1rem}sm-button[variant=primary] .icon{fill:rgba(var(--background-color), 1)}sm-button[disabled] .icon{fill:rgba(var(--text-color), 0.6)}sm-button.uppercase{letter-spacing:.05em}sm-button.danger{--background: var(--danger-color);color:rgba(var(--background-color), 1)}ul{list-style:none}.flex{display:-webkit-box;display:-ms-flexbox;display:flex}.grid{display:grid}.hide{opacity:0;pointer-events:none}.hide-completely{display:none !important}.overflow-ellipsis{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.breakable{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-ms-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.full-bleed{grid-column:1/4}.h1{font-size:1.5rem}.h2{font-size:1.2rem}.h3{font-size:1rem}.h4{font-size:.9rem}.h5{font-size:.8rem}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.flex{display:-webkit-box;display:-ms-flexbox;display:flex}.grid{display:grid}.grid-3{grid-template-columns:1fr auto auto}.flow-column{grid-auto-flow:column}.gap-0-5{gap:.5rem}.gap-1{gap:1rem}.gap-1-5{gap:1.5rem}.gap-2{gap:2rem}.gap-3{gap:3rem}.text-align-right{text-align:right}.align-start{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.align-center{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.text-center{text-align:center}.justify-start{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:start}.justify-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.justify-right{margin-left:auto}.align-self-center{-ms-flex-item-align:center;align-self:center}.justify-self-center{justify-self:center}.justify-self-start{justify-self:start}.justify-self-end{justify-self:end}.direction-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.space-between{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.w-100{width:100%}.interact{position:relative;cursor:pointer;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s, -webkit-transform .3s;-webkit-tap-highlight-color:transparent}.empty-state{display:grid;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;text-align:center;width:100%;padding:1.5rem}.observe-empty-state:empty{display:none}.observe-empty-state:not(:empty)+.empty-state{display:none}.icon{width:1.2rem;height:1.2rem;fill:rgba(var(--text-color), 0.8)}.button__icon{height:1.2rem;width:1.2rem}.button__icon--left{margin-right:.5rem}.button__icon--right{margin-left:.5rem}.icon-button{padding:.6rem;border-radius:.8rem;background-color:rgba(var(--text-color), 0.1);height:-webkit-max-content;height:-moz-max-content;height:max-content}.icon-button .icon{fill:var(--accent-color)}#confirmation_popup,#prompt_popup{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}#confirmation_popup h4,#prompt_popup h4{font-weight:500;margin-bottom:.5rem}#confirmation_popup sm-button,#prompt_popup sm-button{margin:0}#confirmation_popup .flex,#prompt_popup .flex{padding:0;margin-top:1rem}#confirmation_popup .flex sm-button:first-of-type,#prompt_popup .flex sm-button:first-of-type{margin-right:.6rem;margin-left:auto}#prompt_message{margin-bottom:1.5rem}button:active,.button:active,.interact:active{-webkit-transform:scale(0.96);transform:scale(0.96)}.popup__header{display:grid;gap:.5rem;width:100%;padding:0 1.5rem 0 .5rem;-webkit-box-align:center;-ms-flex-align:center;align-items:center;grid-template-columns:auto 1fr auto}.popup__header__close{padding:.5rem;cursor:pointer}.logo{display:grid;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;grid-template-columns:auto 1fr;gap:0 .5rem;margin-right:1rem}.logo h4{text-transform:capitalize;font-size:.9rem;font-weight:600}.logo .main-logo{height:1.4rem;width:1.4rem;fill:rgba(var(--text-color), 1);stroke:none}details summary{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer}details[open]>summary{margin-bottom:1rem}details[open]>summary .icon{-webkit-transform:rotate(180deg);transform:rotate(180deg)}sm-select,sm-option{font-size:.9rem}sm-checkbox{--height: 1rem;--width: 1rem;-webkit-tap-highlight-color:transparent}.warning{background-color:khaki;color:rgba(0,0,0,.7);padding:1rem;border-radius:.5rem;line-height:1.5}.page-layout{display:grid;grid-template-columns:1rem minmax(0, 1fr) 1rem}.page-layout>*{grid-column:2/3}.page{height:100%}#main_header{display:grid;gap:1rem;padding:1rem 1.5rem;-webkit-box-align:center;-ms-flex-align:center;align-items:center;grid-template-columns:auto 1fr auto auto;grid-column:1/-1;background-color:var(--foreground-color)}.label{font-size:.8rem;color:rgba(var(--text-color), 0.8);margin-bottom:.2rem}.icon--success{fill:var(--green)}.icon--failure,.icon--error{fill:var(--danger-color)}#main_page{grid-template-columns:minmax(0, 1fr)}#article_wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding:1rem;gap:1rem 0}.heading{display:-webkit-box;display:-ms-flexbox;display:flex}.heading::before{content:"";width:.3rem;height:100%;margin-right:.7rem;border-radius:.5rem;background-color:var(--accent-color)}.article-section{display:-webkit-box;display:-ms-flexbox;display:flex;gap:.5rem;overflow-x:auto;-ms-flex-negative:0;flex-shrink:0;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory}.article-section:not(:last-of-type){margin-bottom:1.5rem}.content-card-container{display:-webkit-box;display:-ms-flexbox;display:flex;gap:.5rem}.content-card{scroll-snap-align:start;width:min(46ch, 100%);-ms-flex-negative:0;flex-shrink:0;border-radius:.5rem;background-color:var(--foreground-color);border:solid thin rgba(var(--text-color), 0.16)}.content__area{border-radius:inherit;padding:1rem;white-space:pre-line;font-size:.9rem;line-height:1.7;color:rgba(var(--text-color), 0.8);background-color:rgba(var(--text-color), 0.02);border-radius:.5rem;-webkit-transition:-webkit-box-shadow .1s;transition:-webkit-box-shadow .1s;transition:box-shadow .1s;transition:box-shadow .1s, -webkit-box-shadow .1s;height:60vh;overflow-y:auto}.content__area:empty::before{content:attr(placeholder);opacity:.6;pointer-events:none}.content__area:focus-within{outline:none;-webkit-box-shadow:0 0 0 .1rem var(--accent-color) inset;box-shadow:0 0 0 .1rem var(--accent-color) inset}.content__options{gap:.5rem;padding:.5rem 1rem;grid-template-columns:auto auto 1fr auto}.content__editor{font-size:.8rem;background-color:rgba(var(--text-color), 0.06);border-radius:.3rem;padding:.2rem .3rem;color:rgba(var(--text-color), 0.8)}.actionable-button{padding:.5rem .8rem;background-color:rgba(var(--text-color), 0.1);border-radius:2rem;border:solid thin rgba(var(--text-color), 0.3)}.actionable-button__title{font-size:.8rem;margin-left:.3rem}#text_toolbar{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:absolute;z-index:1;left:0;top:0;-webkit-transition:-webkit-transform .1s;transition:-webkit-transform .1s;transition:transform .1s;transition:transform .1s, -webkit-transform .1s;background-color:var(--foreground-color);border:solid thin rgba(var(--text-color), 0.2);padding:.2rem;border-radius:.3rem;-webkit-box-shadow:0 .1rem .2rem rgba(0,0,0,.06),0 1rem 1.5rem -0.5rem rgba(0,0,0,.2);box-shadow:0 .1rem .2rem rgba(0,0,0,.06),0 1rem 1.5rem -0.5rem rgba(0,0,0,.2)}.formatting-button{padding:.3rem;border-radius:.3rem;-webkit-transition:background-color .1s;transition:background-color .1s}.formatting-button.active:hover{background-color:var(--accent-color)}.active{background-color:var(--accent-color)}.active .icon{fill:#fff}.quote-template{position:relative;padding:1rem;margin:1rem 0;background-color:var(--foreground-color);border:solid thin rgba(var(--text-color), 0.2);border-radius:.5rem;overflow:hidden;justify-self:center;padding-left:1.3rem}.quote-template::before{display:-webkit-box;display:-ms-flexbox;display:flex;position:absolute;content:"";height:100%;width:.3rem;background-color:var(--accent-color)}.quote-template blockquote{display:-webkit-box;display:-ms-flexbox;display:flex}.quote-template figcaption{margin-top:.5rem;color:rgba(var(--text-color), 0.8);font-size:.8rem}#version_history_panel{border-radius:.5rem;width:min(24rem, 100%);background-color:var(--foreground-color);overflow-y:auto}#version_history_panel>:first-child{padding:1rem}#version_timeline{padding:1rem;height:100%;overflow-y:auto}.history-entry:not(:last-of-type){padding-bottom:1rem;border-bottom:thin solid rgba(var(--text-color), 0.3)}.history-entry:last-of-type::before{content:"CREATED";letter-spacing:.03em;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;justify-self:flex-start;font-weight:500;padding:.2rem .3rem;font-size:.7rem;border-radius:.2rem;border:solid thin rgba(var(--text-color), 0.5)}.entry__time,.entry__author{font-size:.8rem;font-weight:500}.entry__changes{font-size:.9rem;line-height:1.7;color:rgba(var(--text-color), 0.8)}.entry__changes .added>*,.entry__changes .removed>*{background-color:inherit}.entry__changes .added{background-color:#00e67650}.entry__changes .removed{background-color:#ff3a4a50}@media screen and (max-width: 40rem)and (any-hover: none){.cancel-order span{display:none}}@media screen and (max-width: 40rem){sm-button{--padding: 0.9rem 1.6rem}.hide-on-mobile{display:none}}@media screen and (min-width: 40rem){sm-popup{--width: 24rem}.h1{font-size:2rem}.h2{font-size:1.8rem}.h3{font-size:1.3rem}.h4{font-size:1rem}.popup__header{grid-column:1/-1;padding:1rem 1.5rem 0 .5rem}#confirmation_popup{--width: 24rem}.page-layout{grid-template-columns:1.5rem minmax(0, 1fr) 1.5rem}.hide-on-desktop{display:none}#main_page.active-sidebar{height:100%;overflow-y:hidden;grid-template-rows:auto 1fr;grid-template-columns:minmax(0, 1fr) 24rem}#main_page.active-sidebar #article_wrapper{height:100%;overflow-y:auto}}@media(any-hover: hover){::-webkit-scrollbar{width:.5rem;height:.5rem}::-webkit-scrollbar-thumb{background:rgba(var(--text-color), 0.3);border-radius:1rem}::-webkit-scrollbar-thumb:hover{background:rgba(var(--text-color), 0.5)}.interact,button{-webkit-transition:background-color .3s,-webkit-transform .3s;transition:background-color .3s,-webkit-transform .3s;transition:background-color .3s,transform .3s;transition:background-color .3s,transform .3s,-webkit-transform .3s}.interact:hover,button:hover{background-color:rgba(var(--text-color), 0.1)}.transaction-card button{opacity:0;-webkit-transition:opacity .3s;transition:opacity .3s}.transaction-card:hover button{opacity:1}}
\ No newline at end of file
+*{padding:0;margin:0;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:"Inter",sans-serif}:root{font-size:clamp(1rem, 1.2vmax, 1.2rem)}html,body{height:100%;scroll-behavior:smooth}body{color:rgba(var(--text-color), 1);background:rgba(var(--background-color), 1)}body,body *{--accent-color: #504dff;--accent-color--light: #eeeeff;--text-color: 36, 36, 36;--background-color: 248, 248, 248;--foreground-color: rgb(255, 255, 255);--danger-color: rgb(255, 75, 75);--green: #1cad59;--yellow: #f3a600;--loan-color: rgb(255, 171, 93);scrollbar-width:thin}body[data-theme=dark],body[data-theme=dark] *{--accent-color: #a3a1ff;--accent-color--light: rgba(142, 140, 255, 0.06);--text-color: 230, 230, 230;--text-color-light: 170, 170, 170;--background-color: 10, 10, 10;--foreground-color: rgb(24, 24, 24);--danger-color: rgb(255, 106, 106);--green: #00e676;--yellow: #ffd13a;--loan-color: rgb(255, 232, 170)}body[data-theme=dark] sm-popup::part(popup){background-color:var(--foreground-color)}p,strong{font-size:.9rem;max-width:70ch;line-height:1.7;color:rgba(var(--text-color), 0.8)}p:not(:last-of-type),strong:not(:last-of-type){margin-bottom:1.5rem}a:where([class]){color:inherit;text-decoration:none}a:where([class]):focus-visible{-webkit-box-shadow:0 0 0 .1rem rgba(var(--text-color), 1) inset;box-shadow:0 0 0 .1rem rgba(var(--text-color), 1) inset}a{color:var(--accent-color)}button,.button{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;border:none;background-color:transparent;overflow:hidden;color:inherit;cursor:pointer;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s, -webkit-transform .3s;-webkit-tap-highlight-color:transparent;-webkit-box-align:center;-ms-flex-align:center;align-items:center;font-size:.9rem;font-weight:500}.button{white-space:nowrap;padding:.6rem 1rem;border-radius:.3rem;background-color:rgba(var(--text-color), 0.06);color:rgba(var(--text-color), 0.8);-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.button--primary{background-color:var(--accent-color);color:rgba(var(--background-color), 1)}button:disabled{opacity:.5}a:-webkit-any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}a:-moz-any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}a:any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}sm-input{font-size:.9rem;--border-radius: 0.3rem}sm-button{--padding: 0.7rem 1rem}sm-button[variant=primary] .icon{fill:rgba(var(--background-color), 1)}sm-button[disabled] .icon{fill:rgba(var(--text-color), 0.6)}sm-button.uppercase{letter-spacing:.05em}sm-button.danger{--background: var(--danger-color);color:rgba(var(--background-color), 1)}ul{list-style:none}.flex{display:-webkit-box;display:-ms-flexbox;display:flex}.grid{display:grid}.hide{opacity:0;pointer-events:none}.hide-completely{display:none !important}.overflow-ellipsis{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.breakable{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-ms-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.full-bleed{grid-column:1/4}.h1{font-size:1.5rem}.h2{font-size:1.2rem}.h3{font-size:1rem}.h4{font-size:.9rem}.h5{font-size:.8rem}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.flex{display:-webkit-box;display:-ms-flexbox;display:flex}.grid{display:grid}.grid-3{grid-template-columns:1fr auto auto}.flow-column{grid-auto-flow:column}.gap-0-5{gap:.5rem}.gap-1{gap:1rem}.gap-1-5{gap:1.5rem}.gap-2{gap:2rem}.gap-3{gap:3rem}.text-align-right{text-align:right}.align-start{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.align-center{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.text-center{text-align:center}.justify-start{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:start}.justify-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.justify-right{margin-left:auto}.align-self-center{-ms-flex-item-align:center;align-self:center}.justify-self-center{justify-self:center}.justify-self-start{justify-self:start}.justify-self-end{justify-self:end}.direction-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.space-between{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.w-100{width:100%}.interact{position:relative;cursor:pointer;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s, -webkit-transform .3s;-webkit-tap-highlight-color:transparent}.empty-state{display:grid;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;text-align:center;width:100%;padding:1.5rem}.observe-empty-state:empty{display:none}.observe-empty-state:not(:empty)+.empty-state{display:none}.icon{width:1.2rem;height:1.2rem;fill:rgba(var(--text-color), 0.8)}.button__icon{height:1.2rem;width:1.2rem}.button__icon--left{margin-right:.5rem}.button__icon--right{margin-left:.5rem}.icon-button{padding:.6rem;border-radius:.8rem;background-color:rgba(var(--text-color), 0.1);height:-webkit-max-content;height:-moz-max-content;height:max-content}.icon-button .icon{fill:var(--accent-color)}#confirmation_popup,#prompt_popup{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}#confirmation_popup h4,#prompt_popup h4{font-weight:500;margin-bottom:.5rem}#confirmation_popup sm-button,#prompt_popup sm-button{margin:0}#confirmation_popup .flex,#prompt_popup .flex{padding:0;margin-top:1rem}#confirmation_popup .flex sm-button:first-of-type,#prompt_popup .flex sm-button:first-of-type{margin-right:.6rem;margin-left:auto}#prompt_message{margin-bottom:1.5rem}button:active,.button:active,.interact:active{-webkit-transform:scale(0.96);transform:scale(0.96)}.popup__header{display:grid;gap:.5rem;width:100%;padding:0 1.5rem 0 .5rem;-webkit-box-align:center;-ms-flex-align:center;align-items:center;grid-template-columns:auto 1fr auto}.popup__header__close{padding:.5rem;cursor:pointer}.logo{display:grid;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;grid-template-columns:auto 1fr;gap:0 .5rem;margin-right:1rem}.logo h4{text-transform:capitalize;font-size:.9rem;font-weight:600}.logo .main-logo{height:1.4rem;width:1.4rem;fill:rgba(var(--text-color), 1);stroke:none}details summary{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer}details[open]>summary{margin-bottom:1rem}details[open]>summary .icon{-webkit-transform:rotate(180deg);transform:rotate(180deg)}sm-select,sm-option{font-size:.9rem}sm-checkbox{--height: 1rem;--width: 1rem;-webkit-tap-highlight-color:transparent}.warning{background-color:khaki;color:rgba(0,0,0,.7);padding:1rem;border-radius:.5rem;line-height:1.5}.page-layout{display:grid;grid-template-columns:1rem minmax(0, 1fr) 1rem}.page-layout>*{grid-column:2/3}.page{height:100%}#main_header{display:grid;gap:1rem;padding:1rem 1.5rem;-webkit-box-align:center;-ms-flex-align:center;align-items:center;grid-template-columns:auto 1fr auto auto;grid-column:1/-1;background-color:var(--foreground-color)}.label{font-size:.8rem;color:rgba(var(--text-color), 0.8);margin-bottom:.2rem}.icon--success{fill:var(--green)}.icon--failure,.icon--error{fill:var(--danger-color)}#main_page{grid-template-columns:minmax(0, 1fr)}#current_article_title{font-weight:700}.article-link{padding:1rem;color:rgba(var(--text-color), 0.8);font-weight:500;border-radius:.3rem}.article-link::first-letter{text-transform:uppercase}.default-article{margin-left:auto;font-size:.7rem;background-color:#00e67650;padding:.2rem .4rem;border-radius:.3rem;font-weight:700;letter-spacing:.05em;color:rgba(var(--text-color), 0.8)}#article_wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding:1rem;gap:1rem 0}.heading{font-weight:700;display:-webkit-box;display:-ms-flexbox;display:flex}.heading::before{content:"";width:.3rem;height:100%;margin-right:.7rem;border-radius:.5rem;background-color:var(--accent-color)}.article-section{display:-webkit-box;display:-ms-flexbox;display:flex;gap:.5rem;overflow-x:auto;-ms-flex-negative:0;flex-shrink:0;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory}.article-section:not(:last-of-type){margin-bottom:1.5rem}.article-section::-webkit-scrollbar{display:none}.content-card{scroll-snap-align:center;width:min(46ch, 100%);-ms-flex-negative:0;flex-shrink:0;border-radius:.5rem;background-color:var(--foreground-color);border:solid thin rgba(var(--text-color), 0.16)}.content__area{border-radius:inherit;padding:1rem;white-space:pre-line;font-size:.9rem;line-height:1.7;color:rgba(var(--text-color), 0.8);background-color:rgba(var(--text-color), 0.02);border-radius:.5rem;-webkit-transition:-webkit-box-shadow .1s;transition:-webkit-box-shadow .1s;transition:box-shadow .1s;transition:box-shadow .1s, -webkit-box-shadow .1s;height:60vh;overflow-y:auto}.content__area:empty::before{content:attr(placeholder);opacity:.6;pointer-events:none}.content__area:focus-within{outline:none;-webkit-box-shadow:0 0 0 .1rem var(--accent-color) inset;box-shadow:0 0 0 .1rem var(--accent-color) inset}.content__options{gap:.5rem;padding:.5rem 1rem;grid-template-columns:auto auto 1fr auto}.content__editor{font-size:.8rem;background-color:rgba(var(--text-color), 0.06);border-radius:.3rem;padding:.2rem .3rem;color:rgba(var(--text-color), 0.8)}.actionable-button{padding:.5rem .8rem;background-color:rgba(var(--text-color), 0.1);border-radius:2rem;border:solid thin rgba(var(--text-color), 0.3)}.actionable-button__title{font-size:.8rem;margin-left:.3rem}#text_toolbar{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:absolute;z-index:1;left:0;top:0;-webkit-transition:-webkit-transform .1s;transition:-webkit-transform .1s;transition:transform .1s;transition:transform .1s, -webkit-transform .1s;background-color:var(--foreground-color);border:solid thin rgba(var(--text-color), 0.2);padding:.2rem;border-radius:.3rem;-webkit-box-shadow:0 .1rem .2rem rgba(0,0,0,.06),0 1rem 1.5rem -0.5rem rgba(0,0,0,.2);box-shadow:0 .1rem .2rem rgba(0,0,0,.06),0 1rem 1.5rem -0.5rem rgba(0,0,0,.2)}.formatting-button{padding:.3rem;border-radius:.3rem;-webkit-transition:background-color .1s;transition:background-color .1s}.formatting-button.active:hover{background-color:var(--accent-color)}.active{background-color:var(--accent-color)}.active .icon{fill:#fff}.quote-template{position:relative;padding:1rem;margin:1rem 0;background-color:var(--foreground-color);border:solid thin rgba(var(--text-color), 0.2);border-radius:.5rem;overflow:hidden;justify-self:center;padding-left:1.3rem}.quote-template::before{display:-webkit-box;display:-ms-flexbox;display:flex;position:absolute;content:"";height:100%;width:.3rem;background-color:var(--accent-color)}.quote-template blockquote{display:-webkit-box;display:-ms-flexbox;display:flex}.quote-template figcaption{margin-top:.5rem;color:rgba(var(--text-color), 0.8);font-size:.8rem}#version_history_panel{border-radius:.5rem;width:min(24rem, 100%);background-color:var(--foreground-color);overflow-y:auto}#version_history_panel>:first-child{padding:1rem}#version_timeline{padding:1rem;height:100%;overflow-y:auto}.history-entry:not(:last-of-type){padding-bottom:1rem;border-bottom:thin solid rgba(var(--text-color), 0.3)}.history-entry:last-of-type::before{content:"CREATED";letter-spacing:.03em;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;justify-self:flex-start;font-weight:500;padding:.2rem .3rem;font-size:.7rem;border-radius:.2rem;border:solid thin rgba(var(--text-color), 0.5)}.entry__time,.entry__author{font-size:.8rem;font-weight:500}.entry__changes{font-size:.9rem;line-height:1.7;color:rgba(var(--text-color), 0.8)}.entry__changes .added>*,.entry__changes .removed>*{background-color:transparent}.entry__changes .added{background-color:#00e67650}.entry__changes .removed{background-color:#ff3a4a50}@media screen and (max-width: 40rem)and (any-hover: none){.cancel-order span{display:none}}@media screen and (max-width: 40rem){sm-button{--padding: 0.9rem 1.6rem}.hide-on-mobile{display:none}}@media screen and (min-width: 40rem){sm-popup{--width: 24rem}.h1{font-size:2rem}.h2{font-size:1.8rem}.h3{font-size:1.3rem}.h4{font-size:1rem}.popup__header{grid-column:1/-1;padding:1rem 1.5rem 0 .5rem}#confirmation_popup{--width: 24rem}.page-layout{grid-template-columns:1.5rem minmax(0, 1fr) 1.5rem}.hide-on-desktop{display:none}#main_page.active-sidebar{height:100%;overflow-y:hidden;grid-template-rows:auto 1fr;grid-template-columns:minmax(0, 1fr) 24rem}#main_page.active-sidebar #article_wrapper{height:100%;overflow-y:auto}}@media(any-hover: hover){::-webkit-scrollbar{width:.5rem;height:.5rem}::-webkit-scrollbar-thumb{background:rgba(var(--text-color), 0.3);border-radius:1rem}::-webkit-scrollbar-thumb:hover{background:rgba(var(--text-color), 0.5)}.interact,button{-webkit-transition:background-color .3s,-webkit-transform .3s;transition:background-color .3s,-webkit-transform .3s;transition:background-color .3s,transform .3s;transition:background-color .3s,transform .3s,-webkit-transform .3s}.interact:hover,button:hover{background-color:rgba(var(--text-color), 0.1)}.transaction-card button{opacity:0;-webkit-transition:opacity .3s;transition:opacity .3s}.transaction-card:hover button{opacity:1}}
\ No newline at end of file
diff --git a/css/main.scss b/css/main.scss
index 2c18567..6e61e29 100644
--- a/css/main.scss
+++ b/css/main.scss
@@ -485,6 +485,30 @@ sm-checkbox {
grid-template-columns: minmax(0, 1fr);
}
+#current_article_title {
+ font-weight: 700;
+}
+
+.article-link {
+ padding: 1rem;
+ color: rgba(var(--text-color), 0.8);
+ font-weight: 500;
+ border-radius: 0.3rem;
+ &::first-letter {
+ text-transform: uppercase;
+ }
+}
+.default-article {
+ margin-left: auto;
+ font-size: 0.7rem;
+ background-color: #00e67650;
+ padding: 0.2rem 0.4rem;
+ border-radius: 0.3rem;
+ font-weight: 700;
+ letter-spacing: 0.05em;
+ color: rgba(var(--text-color), 0.8);
+}
+
#article_wrapper {
display: flex;
flex-direction: column;
@@ -493,6 +517,7 @@ sm-checkbox {
}
.heading {
+ font-weight: 700;
display: flex;
&::before {
content: "";
@@ -513,14 +538,12 @@ sm-checkbox {
&:not(:last-of-type) {
margin-bottom: 1.5rem;
}
+ &::-webkit-scrollbar {
+ display: none;
+ }
}
-.content-card-container {
- display: flex;
- gap: 0.5rem;
-}
-
.content-card {
- scroll-snap-align: start;
+ scroll-snap-align: center;
width: min(46ch, 100%);
flex-shrink: 0;
border-radius: 0.5rem;
@@ -675,7 +698,7 @@ sm-checkbox {
color: rgba(var(--text-color), 0.8);
.added > *,
.removed > * {
- background-color: inherit;
+ background-color: transparent;
}
.added {
background-color: #00e67650;
diff --git a/index.html b/index.html
index fc93514..36f8774 100644
--- a/index.html
+++ b/index.html
@@ -80,7 +80,7 @@
-
+
-
+
@@ -533,51 +534,26 @@
}
} else {
if (targetPage.includes('/')) {
- const pages = targetPage.split('/')
- pageId = pages[1]
+ if (targetPage.includes('?')) {
+ const splitAddress = targetPage.split('?')
+ searchParams = splitAddress.pop()
+ const pages = splitAddress.pop().split('/')
+ pageId = pages[1]
+ subPageId = pages[2]
+ } else {
+ const pages = targetPage.split('/')
+ pageId = pages[1]
+ subPageId = pages[2]
+ }
} else {
pageId = targetPage
}
}
if (pagesData.lastPage !== pageId) {
- let target
- switch (pageId) {
- case 'dashboard':
- target = 'dashboard'
- break;
- case 'my_orders':
- target = 'my_orders_section'
- break;
- case 'market':
- target = 'market_orders_section'
- break;
- case 'wallet':
- target = 'user_section'
- break;
- }
- if (target) {
- document.querySelectorAll('.mobile-page').forEach(elem => elem.classList.add('hide-on-mobile'))
- getRef(target).classList.remove('hide-on-mobile')
- document.querySelectorAll('.bottom_nav__item').forEach(elem => elem.classList.remove('bottom_nav__item--active'))
- document.querySelector(`.bottom_nav__item[href="#/${pageId}"]`).classList.add('bottom_nav__item--active')
- getRef(target)?.animate([
- {
- transform: 'translateY(1rem)',
- opacity: 0,
- },
- {
- transform: 'none',
- opacity: 1,
- },
- ],
- {
- duration: 300,
- easing: 'ease'
- })
- pagesData.lastPage = target
- if (!pagesData.openedPages.includes(target)) {
- pagesData.openedPages.push(target)
- }
+ document.querySelectorAll('.mobile-page').forEach(elem => elem.classList.add('hide-on-mobile'))
+ pagesData.lastPage = pageId
+ if (!pagesData.openedPages.includes(pageId)) {
+ pagesData.openedPages.push(pageId)
}
}
}
@@ -732,26 +708,62 @@
}
}
+ const checkEntry = debounce(e => {
+ const contentCard = e.target.closest('.content-card')
+ const contentArea = contentCard.querySelector('.content__area')
+ const uid = contentCard.dataset.uid
+ const isUniqueEntry = contentArea.dataset.type === 'origin'
+ contentArea.querySelectorAll('[style=""]').forEach((el) => {
+ el.removeAttribute('style')
+ })
+ const clean = DOMPurify.sanitize(contentArea.innerHTML.split('\n').map(v => v.trim()).filter(v => v));
+ if (clean === '' || clean === '
') {
+ contentCard.querySelector('.submit-entry').classList.add('hide-completely')
+ } else {
+ const hash = Crypto.SHA256(clean)
+ let previousHash
+ if (!isUniqueEntry) {
+ ({ hash: previousHash = '' } = getIterationDetails(uid))
+ } else {
+ previousHash = ''
+ }
+ if (previousHash !== hash)
+ contentCard.querySelector('.submit-entry').classList.remove('hide-completely')
+ else
+ contentCard.querySelector('.submit-entry').classList.add('hide-completely')
+ }
+
+ }, 300)
+ getRef('article_wrapper').addEventListener('input', e => {
+ if (e.target.closest('.content__area')) {
+ checkEntry(e)
+ }
+ })
getRef('article_wrapper').addEventListener('click', e => {
if (e.target.closest('.submit-entry')) {
const contentCard = e.target.closest('.content-card')
const contentArea = contentCard.querySelector('.content__area')
const uid = contentCard.dataset.uid
const isUniqueEntry = contentArea.dataset.type === 'origin'
+ const parentSection = contentCard.closest('.article-section')
+ const sectionID = parentSection.dataset.sectionId
contentArea.querySelectorAll('[style=""]').forEach((el) => {
el.removeAttribute('style')
})
const clean = DOMPurify.sanitize(contentArea.innerHTML.split('\n').map(v => v.trim()).filter(v => v));
- // const clean = contentArea.innerText.trim();
if (clean === '') return
const hash = Crypto.SHA256(clean)
- let previousVersion, contributors
- if (!isUniqueEntry)
- ({ data: previousVersion, contributors, hash: previousHash } = getIterationDetails(uid))
+ let previousVersion, previousHash
+ if (!isUniqueEntry) {
+ ({ data: previousVersion, hash: previousHash = '' } = getIterationDetails(uid))
+ } else {
+ previousHash = ''
+ }
if (previousHash !== hash) {
+ const timestamp = Date.now()
const entry = {
- section: contentCard.closest('.article-section').dataset.sectionId,
+ section: sectionID,
origin: isUniqueEntry ? floCrypto.randString(16, true) : uid,
data: isUniqueEntry ? clean : getDiff(previousVersion, clean),
hash
@@ -759,21 +771,26 @@
floCloudAPI.sendGeneralData(entry, `${currentArticle.id}_gd`)
.then((res) => {
console.log(res)
+ e.target.closest('.submit-entry').classList.add('hide-completely')
notify('sent data', 'success')
- if (isUniqueEntry)
+ if (isUniqueEntry) {
contentArea.innerHTML = ''
- else {
-
+ currentArticle.sections[sectionID].uniqueEntries.push(entry.origin)
+ currentArticle.uniqueEntries[entry.origin] = { iterations: [{ ...entry, timestamp }] }
+ parentSection.firstElementChild.after(render.contentCard(entry.origin))
+ } else {
+ currentArticle.uniqueEntries[entry.origin].iterations.push({ ...entry, timestamp })
}
})
} else {
notify("Duplicate entry!", 'error')
}
} else if (e.target.closest('.version-history-button')) {
- if (isHistoryPanelOpen)
+ const entryUid = e.target.closest('.content-card').dataset.uid
+ if (versionHistory.isOpen && entryUid === versionHistory.entryUid)
hideVersionHistory()
else
- showVersionHistory(e.target.closest('.content-card').dataset.uid)
+ showVersionHistory(entryUid)
}
})
getRef('article_wrapper').addEventListener("paste", e => {
@@ -786,11 +803,28 @@
event.preventDefault();
})
+ getRef('current_article_title').addEventListener("change", e => {
+ floGlobals.appObjects.cc.articleList[currentArticle.id].title = e.target.value.trim()
+ floCloudAPI.updateObjectData('cc')
+ .then((res) => {
+ notify('Renamed article', 'success')
+ })
+ .catch(err => console.error(err))
+ })
+ getRef('article_wrapper').addEventListener("change", e => {
+ if (e.target.classList.contains('heading')) {
+ floGlobals.appObjects[currentArticle.id].sections[e.target.dataset.index].title = e.target.value.trim()
+ floCloudAPI.updateObjectData(currentArticle.id)
+ .then((res) => {
+ notify('Updated heading', 'success')
+ })
+ .catch(err => console.error(err))
+ }
+ })
getRef('article_wrapper').addEventListener("focusin", e => {
if (e.target.closest('.content__area')) {
- document.addEventListener('selectionchange', detectFormatting)
-
const target = e.target.closest('.content__area')
+ document.addEventListener('selectionchange', detectFormatting)
if (target.childNodes[0] === undefined) {
target.innerHTML = `
`
}
@@ -799,17 +833,9 @@
})
}
})
- getRef('article_wrapper').addEventListener("dblclick", e => {
- if (e.target.closest('.heading')) {
- const target = e.target.closest('.heading')
- if (!target.isContentEditable) {
- target.contentEditable = true
- target.focus()
- }
- }
- })
getRef('article_wrapper').addEventListener("focusout", e => {
if (e.target.closest('.content__area')) {
+ const target = e.target.closest('.content__area')
normalizeText(e.target.closest('.content__area'))
document.removeEventListener('selectionchange', detectFormatting)
const selection = window.getSelection()
@@ -817,12 +843,6 @@
getRef('text_toolbar').classList.add('hide-completely')
childObserver.disconnect()
}
- } else if (e.target.closest('.heading')) {
- const target = e.target.closest('.heading')
- if (target.isContentEditable) {
- floGlobals.appObjects[currentArticle.id].sections[target.dataset.index].title = target.textContent.trim()
- target.contentEditable = false
- }
}
})
const childObserver = new MutationObserver((mutations, observer) => {
@@ -846,17 +866,38 @@