@lexho111/plainblog 0.6.5 → 0.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/Article.js +1 -1
  2. package/Blog.js +64 -14
  3. package/Formatter.js +5 -7
  4. package/package.json +1 -1
  5. package/public/index.html +2 -2
  6. package/public/main-LAI5FAZI.js +7 -0
  7. package/public/main-SKL6R4NB.js +7 -0
  8. package/public/scripts.min.js +2 -2
  9. package/public/styles-I55BTQOK.css +1 -0
  10. package/public/styles.min.css +2 -2
  11. package/src/fetchData.js +50 -26
  12. package/src/styles.css +97 -41
  13. package/.vscode/settings.json +0 -2
  14. package/blog_test_empty.db +0 -0
  15. package/blog_test_load.db +0 -0
  16. package/coverage/clover.xml +0 -1051
  17. package/coverage/coverage-final.json +0 -20
  18. package/coverage/lcov-report/base.css +0 -224
  19. package/coverage/lcov-report/block-navigation.js +0 -87
  20. package/coverage/lcov-report/favicon.png +0 -0
  21. package/coverage/lcov-report/index.html +0 -161
  22. package/coverage/lcov-report/package/Article.js.html +0 -406
  23. package/coverage/lcov-report/package/Blog.js.html +0 -2674
  24. package/coverage/lcov-report/package/Formatter.js.html +0 -379
  25. package/coverage/lcov-report/package/build-scripts.js.html +0 -247
  26. package/coverage/lcov-report/package/build-styles.js.html +0 -367
  27. package/coverage/lcov-report/package/index.html +0 -191
  28. package/coverage/lcov-report/package/model/APIModel.js.html +0 -190
  29. package/coverage/lcov-report/package/model/ArrayList.js.html +0 -382
  30. package/coverage/lcov-report/package/model/ArrayListHashMap.js.html +0 -379
  31. package/coverage/lcov-report/package/model/BinarySearchTree.js.html +0 -856
  32. package/coverage/lcov-report/package/model/BinarySearchTreeHashMap.js.html +0 -346
  33. package/coverage/lcov-report/package/model/DataModel.js.html +0 -325
  34. package/coverage/lcov-report/package/model/DatabaseModel.js.html +0 -235
  35. package/coverage/lcov-report/package/model/FileAdapter.js.html +0 -397
  36. package/coverage/lcov-report/package/model/FileList.js.html +0 -244
  37. package/coverage/lcov-report/package/model/FileModel.js.html +0 -361
  38. package/coverage/lcov-report/package/model/SequelizeAdapter.js.html +0 -538
  39. package/coverage/lcov-report/package/model/SqliteAdapter.js.html +0 -247
  40. package/coverage/lcov-report/package/model/datastructures/ArrayList.js.html +0 -439
  41. package/coverage/lcov-report/package/model/datastructures/ArrayListHashMap.js.html +0 -196
  42. package/coverage/lcov-report/package/model/datastructures/BinarySearchTree.js.html +0 -916
  43. package/coverage/lcov-report/package/model/datastructures/BinarySearchTreeHashMap.js.html +0 -355
  44. package/coverage/lcov-report/package/model/datastructures/FileList.js.html +0 -244
  45. package/coverage/lcov-report/package/model/datastructures/index.html +0 -176
  46. package/coverage/lcov-report/package/model/index.html +0 -206
  47. package/coverage/lcov-report/package/utilities.js.html +0 -511
  48. package/coverage/lcov-report/prettify.css +0 -1
  49. package/coverage/lcov-report/prettify.js +0 -2
  50. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  51. package/coverage/lcov-report/sorter.js +0 -210
  52. package/coverage/lcov.info +0 -2078
  53. package/eslint.config.js +0 -27
  54. package/jest.config.js +0 -15
  55. package/plainblog - Verkn/303/274pfung.lnk +0 -0
  56. package/public/main-EXNUAFJ6.js +0 -6
  57. package/public/styles-OPUTW5UJ.css +0 -1
@@ -1,2 +1,2 @@
1
- let isLoading=!1;function debounce(t,n=300){let a;return(...e)=>{clearTimeout(a),a=setTimeout(()=>{t.apply(this,e)},n)}}async function handleScroll(){isLoading||document.documentElement.scrollHeight-window.innerHeight-window.scrollY<100&&await loadMore()}async function loadMore(){console.log("load more");var e=document.getElementById("articles"),t=Array.from(e.querySelectorAll("article"));let n=NaN;for(let e=t.length-1;0<=e;e--){var a=t[e].getAttribute("data-date");if(a){a=parseInt(a,10);if(!isNaN(a)){n=a;break}}}if(console.log("lastTimestamp "+n),isNaN(n))window.removeEventListener("scroll",handleScroll);else{var e=n,l=(isLoading=!0,`/api/articles?enddate=${e}&limit=51`);console.log("load more "+l),console.log("endDate: "+new Date(e));try{var o=await fetch(l);if(o.ok){var i=(await o.json()).articles||[];if(0<i.length){let e=0;var r,d=document.createDocumentFragment();for(r of i)fillWithContent(r.title,r.content,r.createdAt,r.id,d)&&e++;document.getElementById("articles").appendChild(d),e<50&&window.removeEventListener("scroll",handleScroll)}else window.removeEventListener("scroll",handleScroll)}}catch(e){console.error("Failed to load articles:",e)}isLoading=!1}}function getFormattedDate(e){return e.getFullYear()+`/${String(e.getMonth()+1).padStart(2,"0")}/${String(e.getDate()).padStart(2,"0")} ${String(e.getHours()).padStart(2,"0")}:`+String(e.getMinutes()).padStart(2,"0")}function fillWithContent(n,a,e,l,t){if(l&&document.querySelector(`#articles > article[data-id='${l}']`))return console.log("article found. not adding it."),console.log(l+` ${n} `+e),!1;let o=document.createElement("article");var i,r,d,c,e=new Date(e),s=(null!=l&&o.setAttribute("data-id",l),o.setAttribute("data-date",e.getTime()),document.createElement("h2")),m=document.createElement("span"),u=document.createElement("p");function g(e){var t;"delete"===e?confirm("Delete this article?")&&fetch("/api/articles?id="+l,{method:"DELETE"}).then(e=>{e.ok?o.remove():alert("Error: "+e.statusText)}):"edit"===e&&(e=prompt("New Title",n),t=prompt("New Content",a),e)&&t&&fetch("/api/articles?id="+l,{method:"PUT",body:JSON.stringify({title:e,content:t})}).then(e=>{e.ok?window.location.reload():alert("Error: "+e.statusText)})}return null!==document.querySelector('a[href="/logout"]')&&(i=document.createElement("div"),r=document.createElement("div"),d=document.createElement("div"),c=document.createElement("div"),i.setAttribute("class","buttons"),r.setAttribute("class","btn edit"),d.setAttribute("class","btn delete"),c.setAttribute("class","btn light"),r.textContent="edit",d.textContent="delete",c.textContent="something",i.appendChild(r),i.appendChild(d),i.appendChild(c),r.addEventListener("click",()=>g("edit")),d.addEventListener("click",()=>g("delete")),o.appendChild(i)),s.textContent=n,m.textContent=getFormattedDate(e),u.textContent=a,o.appendChild(s),o.appendChild(m),o.appendChild(u),(t||document.getElementById("articles")).appendChild(o),!0}document.addEventListener("DOMContentLoaded",()=>{window.addEventListener("scroll",handleScroll);var e=document.getElementById("search");e&&e.addEventListener("input",debounce(async e=>{e=e.target.value;if(0<e.length){var e=await(await fetch("/api/articles?q="+encodeURIComponent(e))).json(),n=document.getElementById("articles");n.innerHTML="";let t=document.createDocumentFragment();(e.articles?e.articles.slice(0,50):[]).forEach(e=>fillWithContent(e.title,e.content,e.createdAt,e.id,t)),n.appendChild(t)}else window.location.reload()},300))});
2
- /* source-hash: e7678417f28d953daf75ab7eecffc4a7fc43d7fb2932904a992d8edb0ae8f426 */
1
+ let isLoading=!1;function debounce(t,n=300){let a;return(...e)=>{clearTimeout(a),a=setTimeout(()=>{t.apply(this,e)},n)}}async function handleScroll(){isLoading||document.documentElement.scrollHeight-window.innerHeight-window.scrollY<100&&await loadMore()}async function loadMore(){console.log("load more");var e=document.getElementById("articles"),t=Array.from(e.querySelectorAll("article"));let n=NaN;for(let e=t.length-1;0<=e;e--){var a=t[e].getAttribute("data-date");if(a){a=parseInt(a,10);if(!isNaN(a)){n=a;break}}}if(console.log("lastTimestamp "+n),isNaN(n))window.removeEventListener("scroll",handleScroll);else{var e=n,l=(isLoading=!0,`/api/articles?enddate=${e}&limit=51`);console.log("load more "+l),console.log("endDate: "+new Date(e));try{var o=await fetch(l);if(o.ok){var i=(await o.json()).articles||[];if(0<i.length){let e=0;var r,d=document.createDocumentFragment();for(r of i)fillWithContent(r.title,r.content,r.createdAt,r.id,d)&&e++;document.getElementById("articles").appendChild(d),e<50&&window.removeEventListener("scroll",handleScroll)}else window.removeEventListener("scroll",handleScroll)}}catch(e){console.error("Failed to load articles:",e)}isLoading=!1}}function getFormattedDate(e){return e.getFullYear()+`/${String(e.getMonth()+1).padStart(2,"0")}/${String(e.getDate()).padStart(2,"0")} ${String(e.getHours()).padStart(2,"0")}:`+String(e.getMinutes()).padStart(2,"0")}async function handleArticleAction(e,t,n,a,l){var o;"delete"===e?confirm("Delete this article?")&&((o=await fetch("/api/articles?id="+t,{method:"DELETE"})).ok?l.remove():alert("Error: "+o.statusText)):"edit"===e&&(l=prompt("New Title",n),o=prompt("New Content",a),l)&&o&&((e=await fetch("/api/articles?id="+t,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({title:l,content:o})})).ok?window.location.reload():alert("Error: "+e.statusText))}function fillWithContent(a,l,e,o,t){if(o&&document.querySelector(`#articles > article[data-id='${o}']`))return console.log("article found. not adding it."),console.log(o+` ${a} `+e),!1;let i=document.createElement("article");var e=new Date(e),n=(null!=o&&i.setAttribute("data-id",o),i.setAttribute("data-date",e.getTime()),document.createElement("h2")),r=document.createElement("span"),d=document.createElement("p");if(null!==document.querySelector('a[href="/logout"]')){let n=document.createElement("div");var c=document.createElement("div"),s=document.createElement("div"),m=document.createElement("div");n.setAttribute("class","buttons"),c.setAttribute("class","btn edit"),s.setAttribute("class","btn delete"),m.setAttribute("class","btn light"),c.textContent="edit",s.textContent="delete",m.textContent="something else",n.appendChild(c),n.appendChild(s),n.appendChild(m),[{label:"edit",type:"edit",class:"btn edit"},{label:"delete",type:"delete",class:"btn delete"},{label:"something else",type:"other",class:"btn light"}].forEach(e=>{var t=document.createElement("div");t.className=e.class,t.textContent=e.label,t.addEventListener("click",()=>handleArticleAction(e.type,o,a,l,i)),n.appendChild(t)}),i.appendChild(n)}return n.textContent=a,r.textContent=getFormattedDate(e),d.textContent=l,i.appendChild(n),i.appendChild(r),i.appendChild(d),(t||document.getElementById("articles")).appendChild(i),!0}document.addEventListener("DOMContentLoaded",()=>{window.addEventListener("scroll",handleScroll);var e=document.getElementById("search");e&&e.addEventListener("input",debounce(async e=>{e=e.target.value;if(0<e.length){var e=await(await fetch("/api/articles?q="+encodeURIComponent(e))).json(),n=document.getElementById("articles");n.innerHTML="";let t=document.createDocumentFragment();(e.articles?e.articles.slice(0,50):[]).forEach(e=>fillWithContent(e.title,e.content,e.createdAt,e.id,t)),n.appendChild(t)}else window.location.reload()},300))});
2
+ /* source-hash: 1fffde3e00f56a4fe51e53474262fcf2482e14e10c8acd05b62e87eee32ce5a3 */
@@ -0,0 +1 @@
1
+ :root{--blue: hsl(224, 100%, 41%);--yellow: hsl(53, 100%, 50%);--orange: hsl(44, 100%, 50%);--poisongreen: hsl(88, 100%, 50%);--green: hsl(85, 100%, 40%);--pink: hsl(303, 100%, 40%);--basecolor: var(--orange);--primary: var(--basecolor);--primary-inverted: rgb(from var(--primary) calc(1 - r) calc(1 - g) calc(1 - b) );--header_bg: var(--basecolor);--header_darker: hsl(from var(--primary) h s l / .4);--header_darker_high-contrast: hsl(from var(--primary) h s l);--gray: rgba(255, 255, 255, .3);--darkgray: rgba(54, 54, 54, .5);--white: #fefefe;--white_darker: #eeeeee;--red: hsla(0, 100%, 38%, .7);--black: black;--contrast_text: rgb( from var(--header_darker) clamp(0, (r * .299 + g * .587 + b * .114 - 128) * -1000, 255) clamp(0, (r * .299 + g * .587 + b * .114 - 128) * -1000, 255) clamp(0, (r * .299 + g * .587 + b * .114 - 128) * -1000, 255) );--text-primary: var(--black);--text-secondary: var(--white)}html,body{margin:0}body{color:var(--text-primary);background:var(--white_darker);font-family:Arial,sans-serif}header{background-color:var(--header_darker)}header h1{color:var(--header_darker_high-contrast);text-shadow:1px 1px black,-1px -1px black,1px -1px black,-1px 1px black}.article-card{background-color:var(--white)}label{display:block;margin-bottom:.5rem}input,textarea{width:100%;padding:.5rem;box-sizing:border-box}button{padding:.5rem 1rem;cursor:pointer}.btn{background-color:var(--primary);border:none;color:var(--text-secondary);font-size:1rem;font-weight:500;text-decoration:none;cursor:pointer;padding:.5rem 1rem;border-radius:4px;width:fit-content;border:1px solid var(--white);box-shadow:3px 2px 2px var(--darkgray)}.btn:hover{color:#000;background-color:#fff;border:2px solid var(--black)}.btn-secondary{background-color:var(--darkgray)}.btn-text{background-color:var(--header_darker)}.btn-text:hover{background-color:var(--white);color:#0034c2b3;border:2px solid black;font-weight:700}.btn-danger{background-color:var(--red)}.btn-danger:hover{background-color:var(--white);color:#c20000b3;border:2px solid var(--black);font-weight:700}.btn-electric{padding:15px 30px;cursor:pointer;overflow:hidden;display:inline-block;font-weight:900;font-size:1.5rem;color:#000;animation:wackel-color 2.5s infinite}@keyframes wackel-color{0%,19.9%,22.1%,24.9%,60.1%,62.9%,to{color:#000;filter:drop-shadow(0 0 0px transparent)}20%,22%,25%,60%,63%{color:#fff;filter:drop-shadow(0 0 2px rgba(0,0,0,.5))}}@keyframes wackel-jitter{0%{transform:translate(0)}25%{transform:translate(-1.5px,.5px)}50%{transform:translate(1.5px,-.5px)}75%{transform:translate(-.5px,-1.5px)}to{transform:translate(0)}}.inverted{background-color:var(--white);color:var(--black);font-weight:700}.inverted:hover{background-color:hsl(from var(--primary) hsl / .2);color:var(--black);font-weight:700;border:2px solid var(--white)}.main-nav{background-color:var(--header_bg)}.nav-brand .brand-link{color:var(--mainfont)}.brand-link:hover{color:var(--primary-inverted)}.form-group{margin-bottom:1rem}.error-message{color:red;font-size:.875rem;margin-top:.25rem}.error{color:red}@media print{.no-print,nav,footer,button{display:none!important}body{font-size:12pt;color:#000;background:#fff}header h1{color:#000}}.glow{text-shadow:0 0 .1em,0 0 .3em}
@@ -1,2 +1,2 @@
1
- body{font-family:Arial,sans-serif}h1{color:#333}:root{--black:#111;--clearwhite:#fefefe;--white:#eee;--darkgray:rgba(54,54,54,.5);--text-primary:var(--black);--text-secondary:var(--clearwhite)}body,html{margin:0}body{background:var(--white_darker);color:var(--text-primary);font-family:Arial}nav{margin-top:10px}#header h1,.box,nav{margin-left:10px}.grid{border:0 solid #000;display:grid;gap:.25rem;grid-template-columns:1fr}.grid article{border:2px solid #a9a9a9;border-radius:4px;margin-bottom:10px;min-width:0;overflow-wrap:break-word;padding:.4rem}.grid article h2{color:#353535;margin-bottom:5px}.grid article .datetime{color:#757575;margin:0}.grid article p{margin-bottom:0;margin-top:10px}article a,article a:visited,h1{color:#696969}h2{border:0 solid #000;margin-top:0}nav a{color:#3b40c1;font-size:20px;text-decoration:underline}nav a:visited{color:#3b40c1;text-decoration-color:#3b40c1}#wrapper{max-width:500px;width:100%}.buttons{align-items:center;border:2px solid #000;display:flex;gap:5px;list-style:none;margin:0;padding:15px}.btn{border:none;border:1px solid var(--text-primary);border-radius:4px;box-shadow:3px 2px 2px var(--darkgray);color:var(--text-secondary);cursor:pointer;font-size:1rem;font-weight:500;padding:.5rem 1rem;text-decoration:none;width:-moz-fit-content;width:fit-content}.btn:hover{background-color:#fff;border:2px solid var(--black);color:#000}.light{background:var(--clearwhite);color:var(--black)}.hide-image{display:none}@media screen and (max-width:1000px){*{font-size:4vw}#wrapper{box-sizing:border-box;max-width:100%;padding:0 10px;width:100%}}.buttons{border:0 solid #000;height:25px;margin-bottom:0;width:100%}.button{border:1px solid #000;cursor:pointer;float:left;height:19px;padding:2px;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100px}.button:focus{outline:2px solid orange}.edit{background-color:blue}.delete{background-color:red}
2
- /* source-hash: defca3bf20a3a5a58be1bf92a0013577c6aaf2474d28976f2f42bd5480cf41cc */
1
+ body{font-family:Arial,sans-serif}h1{color:#333}:root{--black:#111;--clearwhite:#fefefe;--white:#eee;--darkgray:rgba(54,54,54,.5);--text-primary:var(--black);--text-secondary:var(--clearwhite)}body,html{margin:0}html{font-size:clamp(1rem,1.5vw + .5rem,1.25rem)}body{background:var(--white_darker);color:var(--text-primary);font-family:Arial}nav{margin-top:10px}#header h1,nav{margin-left:25px}form{font-size:clamp(1rem,1.5vw + .5rem,1.25rem)}button,form input,form textarea{font-size:90%}button{width:-moz-fit-content;width:fit-content;field-sizing:content;padding:10px}.form_element{display:block;margin-bottom:10px;padding:4px}.wide{width:100%}.password{width:250px}.new_title{padding:10px}.new_content{height:500px;padding:10px;resize:none}#search{float:right;font-size:100%;margin:5px}.articles{border:0 solid #000;display:grid;gap:.25rem;grid-template-columns:1fr;max-width:800px}.articles article{border:2px solid #a9a9a9;border-radius:4px;margin-bottom:10px;min-width:0;overflow-wrap:break-word;padding:.4rem}.articles article h2{color:#353535;margin-bottom:5px}.articles article .datetime{color:#757575;margin:0}.articles article p{margin-bottom:0;margin-top:10px}article a,article a:visited,h1{color:#696969}h2{border:0 solid #000;margin-top:0}nav a{color:#3b40c1;font-size:20px;text-decoration:underline}nav a:visited{color:#3b40c1;text-decoration-color:#3b40c1}.loginform{margin-left:25px}#wrapper{margin-left:5px;max-width:1200px;padding:0 20px}#wrapper,.buttons{box-sizing:border-box;width:100%}.buttons{align-items:center;border:0 solid #000;display:flex;gap:5px;height:25px;list-style:none;margin:0 0 16px;padding:15px 15px 15px 0}.box{margin-left:25px}.btn{border:none;border:1px solid var(--text-primary);border-radius:0;box-shadow:3px 2px 2px var(--darkgray);color:var(--text-primary);cursor:pointer;font-size:1rem;font-weight:500;padding:.25rem .5rem;text-decoration:none;width:-moz-fit-content;width:fit-content}.btn:hover{background-color:#fff;border:2px solid var(--black);color:#000}.light{background:var(--clearwhite);color:var(--black)}.light:hover{background:var(--black);color:var(--clearwhite)}.hide-image{display:none}@media screen and (min-width:1000px){#wrapper{font-size:.75rem;margin:0 auto;max-width:1400px;padding:0 40px;width:90%}}.edit{background-color:blue}.delete,.edit{color:var(--clearwhite)}.delete{background-color:red}
2
+ /* source-hash: 4fcd9901ab776e735cba281aaa4865ed96f897dd0aa4eaef774dee803966b720 */
package/src/fetchData.js CHANGED
@@ -137,6 +137,37 @@ function getFormattedDate(date) {
137
137
  const minutes = String(date.getMinutes()).padStart(2, "0");
138
138
  return `${year}/${month}/${day} ${hours}:${minutes}`;
139
139
  }
140
+ async function handleArticleAction(
141
+ type,
142
+ id,
143
+ currentTitle,
144
+ currentContent,
145
+ element,
146
+ ) {
147
+ if (type === "delete") {
148
+ if (!confirm("Delete this article?")) return;
149
+
150
+ const res = await fetch(`/api/articles?id=${id}`, { method: "DELETE" });
151
+ if (res.ok) {
152
+ element.remove();
153
+ } else {
154
+ alert(`Error: ${res.statusText}`);
155
+ }
156
+ } else if (type === "edit") {
157
+ const title = prompt("New Title", currentTitle);
158
+ const content = prompt("New Content", currentContent);
159
+ if (!title || !content) return;
160
+
161
+ const res = await fetch(`/api/articles?id=${id}`, {
162
+ method: "PUT",
163
+ headers: { "Content-Type": "application/json" },
164
+ body: JSON.stringify({ title, content }),
165
+ });
166
+
167
+ if (res.ok) window.location.reload();
168
+ else alert(`Error: ${res.statusText}`);
169
+ }
170
+ }
140
171
  function fillWithContent(title, content, date, id, targetContainer) {
141
172
  if (id) {
142
173
  // Check if an article with this ID already exists in the container.
@@ -169,37 +200,30 @@ function fillWithContent(title, content, date, id, targetContainer) {
169
200
  somethingButton.setAttribute("class", "btn light");
170
201
  editButton.textContent = "edit";
171
202
  deleteButton.textContent = "delete";
172
- somethingButton.textContent = "something";
203
+ somethingButton.textContent = "something else";
173
204
  buttons.appendChild(editButton);
174
205
  buttons.appendChild(deleteButton);
175
206
  buttons.appendChild(somethingButton);
176
207
 
177
- editButton.addEventListener("click", () => handleAction("edit"));
178
- deleteButton.addEventListener("click", () => handleAction("delete"));
179
- article.appendChild(buttons);
180
- }
208
+ const actions = [
209
+ { label: "edit", type: "edit", class: "btn edit" },
210
+ { label: "delete", type: "delete", class: "btn delete" },
211
+ { label: "something else", type: "other", class: "btn light" },
212
+ ];
181
213
 
182
- function handleAction(button) {
183
- if (button === "delete") {
184
- if (confirm("Delete this article?")) {
185
- fetch("/api/articles?id=" + id, { method: "DELETE" }).then((res) => {
186
- if (res.ok) article.remove();
187
- else alert("Error: " + res.statusText);
188
- });
189
- }
190
- } else if (button === "edit") {
191
- const newTitle = prompt("New Title", title);
192
- const newContent = prompt("New Content", content);
193
- if (newTitle && newContent) {
194
- fetch("/api/articles?id=" + id, {
195
- method: "PUT",
196
- body: JSON.stringify({ title: newTitle, content: newContent }),
197
- }).then((res) => {
198
- if (res.ok) window.location.reload();
199
- else alert("Error: " + res.statusText);
200
- });
201
- }
202
- }
214
+ actions.forEach((action) => {
215
+ const btn = document.createElement("div");
216
+ btn.className = action.class;
217
+ btn.textContent = action.label;
218
+
219
+ // Attach the single summarized handler
220
+ btn.addEventListener("click", () =>
221
+ handleArticleAction(action.type, id, title, content, article),
222
+ );
223
+
224
+ buttons.appendChild(btn);
225
+ });
226
+ article.appendChild(buttons);
203
227
  }
204
228
 
205
229
  heading.textContent = title;
package/src/styles.css CHANGED
@@ -11,6 +11,9 @@ html,
11
11
  body {
12
12
  margin: 0;
13
13
  }
14
+ html {
15
+ font-size: clamp(1rem, 1.5vw + 0.5rem, 1.25rem);
16
+ }
14
17
  body {
15
18
  color: var(--text-primary);
16
19
  background: var(--white_darker);
@@ -21,18 +24,66 @@ nav {
21
24
  }
22
25
  nav,
23
26
  #header h1 {
24
- margin-left: 10px;
27
+ margin-left: 25px;
25
28
  }
26
- .box {
27
- margin-left: 10px;
29
+
30
+ form {
31
+ font-size: clamp(1rem, 1.5vw + 0.5rem, 1.25rem);
32
+ }
33
+
34
+ form input,
35
+ form textarea,
36
+ button {
37
+ font-size: 90%;
38
+ }
39
+
40
+ button {
41
+ width: fit-content;
42
+ field-sizing: content;
43
+ padding: 10px;
44
+ }
45
+
46
+ .form_element {
47
+ display: block;
48
+ margin-bottom: 10px;
49
+ padding: 4px;
50
+ }
51
+
52
+ .wide {
53
+ width: 100%;
54
+ }
55
+
56
+ .password {
57
+ width: 250px;
58
+ }
59
+
60
+ .new_title {
61
+ padding: 10px;
62
+ }
63
+
64
+ .new_content {
65
+ height: 500px;
66
+ resize: none;
67
+ padding: 10px;
68
+ }
69
+
70
+ #search {
71
+ float: right;
72
+ margin: 5px;
73
+ font-size: 100%;
28
74
  }
29
- .grid {
75
+
76
+ hr {
77
+ }
78
+
79
+ .articles {
30
80
  border: 0 solid #000;
31
81
  display: grid;
32
82
  gap: 0.25rem;
33
83
  grid-template-columns: 1fr;
84
+ max-width: 800px;
34
85
  }
35
- .grid article {
86
+ .articles article {
36
87
  border: 0 solid #ccc;
37
88
  border-radius: 4px;
38
89
  min-width: 0;
@@ -41,17 +92,17 @@ nav,
41
92
  margin-bottom: 10px;
42
93
  border: 2px solid darkgray;
43
94
  }
44
- .grid article h2 {
95
+ .articles article h2 {
45
96
  color: rgb(53, 53, 53);
46
97
  margin-bottom: 5px;
47
98
  }
48
99
 
49
- .grid article .datetime {
100
+ .articles article .datetime {
50
101
  margin: 0;
51
102
  color: rgb(117, 117, 117);
52
103
  }
53
104
 
54
- .grid article p {
105
+ .articles article p {
55
106
  margin-top: 10px;
56
107
  margin-bottom: 0;
57
108
  }
@@ -84,30 +135,47 @@ nav a:visited {
84
135
  text-decoration-color: #3b40c1;
85
136
  }
86
137
 
138
+ .loginform {
139
+ margin-left: 25px;
140
+ }
141
+
87
142
  #wrapper {
88
- max-width: 500px;
143
+ max-width: 1200px; /* Limits width on big PC screens */
144
+ /*margin: 0 auto; /* Centers the layout on PC */
145
+ padding: 0 20px; /* Consistent spacing on edges */
89
146
  width: 100%;
147
+ margin-left: 5px;
148
+ box-sizing: border-box;
90
149
  }
91
150
 
92
151
  .buttons {
152
+ box-sizing: border-box; /* This ensures 100% width includes the 15px padding */
93
153
  display: flex;
94
154
  align-items: center;
95
- gap: 5px; /* This creates uniform space between the items only */
155
+ gap: 5px;
96
156
  list-style: none;
97
157
  margin: 0;
158
+ margin-bottom: 16px;
98
159
  padding: 15px;
99
- border: 2px solid black;
160
+ padding-left: 0px;
161
+ border: 0px solid black;
162
+ width: 100%; /* Now 100% will respect the parent's boundaries */
163
+ height: 25px;
164
+ }
165
+
166
+ .box {
167
+ margin-left: 25px;
100
168
  }
101
169
 
102
170
  .btn {
103
171
  border: none;
104
- color: var(--text-secondary);
172
+ color: var(--text-primary);
105
173
  font-size: 1rem;
106
174
  font-weight: 500;
107
175
  text-decoration: none;
108
176
  cursor: pointer;
109
- padding: 0.5rem 1rem;
110
- border-radius: 4px;
177
+ padding: 0.25rem 0.5rem;
178
+ border-radius: 0px;
111
179
  width: fit-content;
112
180
  border: 1px solid var(--text-primary);
113
181
  box-shadow: 3px 2px 2px var(--darkgray);
@@ -124,44 +192,32 @@ nav a:visited {
124
192
  background: var(--clearwhite);
125
193
  }
126
194
 
195
+ .light:hover {
196
+ color: var(--clearwhite);
197
+ background: var(--black);
198
+ }
199
+
127
200
  .hide-image {
128
201
  display: none;
129
202
  }
130
203
 
131
- /* Mobile Layout (screens smaller than 1000px) */
132
- @media screen and (max-width: 1000px) {
133
- * {
134
- font-size: 4vw;
135
- }
204
+ /* 2. DESKTOP ADJUSTMENTS (Screens larger than 1000px) */
205
+ @media screen and (min-width: 1000px) {
136
206
  #wrapper {
137
- max-width: 100%;
138
- width: 100%;
139
- padding: 0 10px; /* Prevents text from touching the edges */
140
- box-sizing: border-box;
207
+ width: 90%; /* Gives some breathing room on large monitors */
208
+ max-width: 1400px; /* Prevents it from getting absurdly wide */
209
+ padding: 0 40px;
210
+ margin: 0 auto;
211
+ /*zoom: 0.75; /* Reduces the entire layout to 80% of its current size */
212
+ font-size: 0.75rem; /* Instead of zoom, use a smaller base font size if you want things "smaller" */
141
213
  }
142
214
  }
143
215
 
144
- .buttons {
145
- width: 100%;
146
- height: 25px;
147
- border: 0px solid black;
148
- margin-bottom: 0px;
149
- }
150
- .button {
151
- border: 1px solid black;
152
- width: 100px;
153
- height: 19px;
154
- float: left;
155
- padding: 2px;
156
- cursor: pointer;
157
- user-select: none; /* Prevents text selection on double-click */
158
- }
159
- .button:focus {
160
- outline: 2px solid orange; /* Vital for keyboard accessibility */
161
- }
162
216
  .edit {
217
+ color: var(--clearwhite);
163
218
  background-color: blue;
164
219
  }
165
220
  .delete {
221
+ color: var(--clearwhite);
166
222
  background-color: red;
167
223
  }
@@ -1,2 +0,0 @@
1
- {
2
- }
Binary file
package/blog_test_load.db DELETED
Binary file