0 |
From 6b4412d816329acf1be741db005732e3cdcbb9f3 Mon Sep 17 00:00:00 2001 |
1 |
From: Jaidyn Ann <10477760+JadedCtrl@users.noreply.github.com> |
2 |
Date: Sat, 12 Aug 2023 12:36:26 -0500 |
3 |
Subject: [PATCH] =?UTF-8?q?Subtenon=20de=20subpa=C4=9Doj?= |
4 |
MIME-Version: 1.0 |
5 |
Content-Type: text/plain; charset=UTF-8 |
6 |
Content-Transfer-Encoding: 8bit |
7 |
|
8 |
»Subpaĝo« estas neŝanĝanta HTML-dosiero, kiu |
9 |
povas montriĝi kiel kartopaĝo en Pleroma |
10 |
ĉe /paĝoj/$io. |
11 |
Simple kreu HTML-ajn dosierojn ĉe /static/static/*! |
12 |
--- |
13 |
src/boot/routes.js | 3 + |
14 |
.../links_dynamically/links_dynamically.js | 41 +++++++++++ |
15 |
.../links_dynamically/links_dynamically.vue | 11 +++ |
16 |
src/components/subpage/subpage.js | 54 +++++++++++++++ |
17 |
src/components/subpage/subpage.vue | 69 +++++++++++++++++++ |
18 |
5 files changed, 178 insertions(+) |
19 |
create mode 100644 src/components/links_dynamically/links_dynamically.js |
20 |
create mode 100644 src/components/links_dynamically/links_dynamically.vue |
21 |
create mode 100644 src/components/subpage/subpage.js |
22 |
create mode 100644 src/components/subpage/subpage.vue |
23 |
|
24 |
diff --git a/src/boot/routes.js b/src/boot/routes.js |
25 |
index 2dc900e7..b67ad9e7 100644 |
26 |
--- a/src/boot/routes.js |
27 |
+++ b/src/boot/routes.js |
28 |
@@ -9,6 +9,7 @@ import DMs from 'components/dm_timeline/dm_timeline.vue' |
29 |
import ChatList from 'components/chat_list/chat_list.vue' |
30 |
import Chat from 'components/chat/chat.vue' |
31 |
import UserProfile from 'components/user_profile/user_profile.vue' |
32 |
+import SubPage from 'components/subpage/subpage.vue' |
33 |
import Search from 'components/search/search.vue' |
34 |
import Registration from 'components/registration/registration.vue' |
35 |
import PasswordReset from 'components/password_reset/password_reset.vue' |
36 |
@@ -79,6 +80,8 @@ export default (store) => { |
37 |
{ name: 'about', path: '/about', component: About }, |
38 |
{ name: 'announcements', path: '/announcements', component: AnnouncementsPage }, |
39 |
{ name: 'user-profile', path: '/users/:name', component: UserProfile }, |
40 |
+ { name: 'subpage-index', path: '/pa%C4%9Doj', component: SubPage }, |
41 |
+ { name: 'subpage', path: '/pa%C4%9Doj/:page', component: SubPage }, |
42 |
{ name: 'legacy-user-profile', path: '/:name', component: UserProfile }, |
43 |
{ name: 'lists', path: '/lists', component: Lists }, |
44 |
{ name: 'lists-timeline', path: '/lists/:id', component: ListsTimeline }, |
45 |
diff --git a/src/components/links_dynamically/links_dynamically.js b/src/components/links_dynamically/links_dynamically.js |
46 |
new file mode 100644 |
47 |
index 00000000..9a36f6f6 |
48 |
--- /dev/null |
49 |
+++ b/src/components/links_dynamically/links_dynamically.js |
50 |
@@ -0,0 +1,41 @@ |
51 |
+const LinksDynamically = { |
52 |
+ props: [ |
53 |
+ 'content' |
54 |
+ ], |
55 |
+ // Make sure that any internal links are handled by the router (most notably for intra-subpage links). |
56 |
+ // Borrowed from a very lovely man by the name of Dennis Reimann: |
57 |
+ // https://web.archive.org/web/20230607095633/https://dennisreimann.de/articles/delegating-html-links-to-vue-router.html |
58 |
+ mounted () { |
59 |
+ window.addEventListener('click', event => { |
60 |
+ // ensure we use the link, in case the click has been received by a subelement |
61 |
+ let { target } = event |
62 |
+ while (target && target.tagName !== 'A') target = target.parentNode |
63 |
+ // handle only links that do not reference external resources |
64 |
+ if (target && target.matches("a:not([href*='://'])") && target.href) { |
65 |
+ // some sanity checks taken from vue-router: |
66 |
+ // https://github.com/vuejs/vue-router/blob/dev/src/components/link.js#L106 |
67 |
+ const { altKey, ctrlKey, metaKey, shiftKey, button, defaultPrevented } = event |
68 |
+ // don't handle with control keys |
69 |
+ if (metaKey || altKey || ctrlKey || shiftKey) return |
70 |
+ // don't handle when preventDefault called |
71 |
+ if (defaultPrevented) return |
72 |
+ // don't handle right clicks |
73 |
+ if (button !== undefined && button !== 0) return |
74 |
+ // don't handle if `target="_blank"` |
75 |
+ if (target && target.getAttribute) { |
76 |
+ const linkTarget = target.getAttribute('target') |
77 |
+ if (/\b_blank\b/i.test(linkTarget)) return |
78 |
+ } |
79 |
+ // don't handle same page links/anchors |
80 |
+ const url = new URL(target.href) |
81 |
+ const to = url.pathname |
82 |
+ if (window.location.pathname !== to && event.preventDefault) { |
83 |
+ event.preventDefault() |
84 |
+ this.$router.push(to) |
85 |
+ } |
86 |
+ } |
87 |
+ }) |
88 |
+ } |
89 |
+} |
90 |
+ |
91 |
+export default LinksDynamically |
92 |
diff --git a/src/components/links_dynamically/links_dynamically.vue b/src/components/links_dynamically/links_dynamically.vue |
93 |
new file mode 100644 |
94 |
index 00000000..efcf7f94 |
95 |
--- /dev/null |
96 |
+++ b/src/components/links_dynamically/links_dynamically.vue |
97 |
@@ -0,0 +1,11 @@ |
98 |
+<template> |
99 |
+ <!-- eslint-disable vue/no-v-html --> |
100 |
+ <div |
101 |
+ class="dynamic-content" |
102 |
+ @click="handleClicks" |
103 |
+ v-html="content" |
104 |
+ /> |
105 |
+ <!-- eslint-enable vue/no-v-html --> |
106 |
+</template> |
107 |
+ |
108 |
+<script src="./links_dynamically.js"></script> |
109 |
diff --git a/src/components/subpage/subpage.js b/src/components/subpage/subpage.js |
110 |
new file mode 100644 |
111 |
index 00000000..73b6c68a |
112 |
--- /dev/null |
113 |
+++ b/src/components/subpage/subpage.js |
114 |
@@ -0,0 +1,54 @@ |
115 |
+import LinksDynamically from '../links_dynamically/links_dynamically.vue' |
116 |
+ |
117 |
+// Wow, I really don’t know how to write JS! Nor use Vue! |
118 |
+// Hopefully this goes OK! ^^ |
119 |
+const SubPage = { |
120 |
+ components: { |
121 |
+ LinksDynamically |
122 |
+ }, |
123 |
+ data () { |
124 |
+ return { |
125 |
+ content: 'Serĉante paĝon…', |
126 |
+ title: 'Paĝo', |
127 |
+ page: '', |
128 |
+ error: false |
129 |
+ } |
130 |
+ }, |
131 |
+ methods: { |
132 |
+ async switchPage (page) { |
133 |
+ // Reset status… |
134 |
+ this.title = 'Paĝo' |
135 |
+ this.content = 'Serĉante paĝon…' |
136 |
+ this.page = page || 'index' |
137 |
+ |
138 |
+ // Fetch & parse the page’s content. |
139 |
+ const response = await fetch('/static/paĝoj/' + this.page + '.html') |
140 |
+ const htmlStr = await response.text() |
141 |
+ const htmlDom = new DOMParser().parseFromString(htmlStr, 'text/html') |
142 |
+ |
143 |
+ // Set the panel name & remove its corresponding header from HTML. |
144 |
+ const firstChild = htmlDom.body.firstElementChild |
145 |
+ if (/^[Hh][0-9]/.test(firstChild.tagName)) { |
146 |
+ this.title = firstChild.innerHTML |
147 |
+ firstChild.remove() |
148 |
+ } |
149 |
+ |
150 |
+ // Actually set the panel’s content. |
151 |
+ this.content = htmlDom.body.innerHTML |
152 |
+ |
153 |
+ if (!response.ok || firstChild.tagName.toLowerCase() === 'noscript') { |
154 |
+ this.error = true |
155 |
+ } |
156 |
+ } |
157 |
+ }, |
158 |
+ created () { |
159 |
+ this.switchPage(this.$route.params.page) |
160 |
+ }, |
161 |
+ watch: { |
162 |
+ '$route.params.page': function (newPage) { |
163 |
+ this.switchPage(newPage) |
164 |
+ } |
165 |
+ } |
166 |
+} |
167 |
+ |
168 |
+export default SubPage |
169 |
diff --git a/src/components/subpage/subpage.vue b/src/components/subpage/subpage.vue |
170 |
new file mode 100644 |
171 |
index 00000000..b2b1fa6d |
172 |
--- /dev/null |
173 |
+++ b/src/components/subpage/subpage.vue |
174 |
@@ -0,0 +1,70 @@ |
175 |
+<template> |
176 |
+ <div> |
177 |
+ <div class="panel panel-default"> |
178 |
+ <div class="panel-heading timeline-heading base02-background"> |
179 |
+ <div |
180 |
+ v-if="error" |
181 |
+ class="title" |
182 |
+ > |
183 |
+ Eraro 404 — Paĝo ne ekzistas! |
184 |
+ </div> |
185 |
+ <div |
186 |
+ v-else |
187 |
+ class="title" |
188 |
+ > |
189 |
+ {{ title }} |
190 |
+ </div> |
191 |
+ <router-link |
192 |
+ class="pagelist-icon" |
193 |
+ to="./" |
194 |
+ > |
195 |
+ Paĝoj ↸ |
196 |
+ </router-link> |
197 |
+ </div> |
198 |
+ <div |
199 |
+ v-if="error" |
200 |
+ class="panel-body" |
201 |
+ > |
202 |
+ <div class="page-content"> |
203 |
+ <h4>La paĝo »{{ page }}« ne ekzistas!</h4> |
204 |
+ <p>Ĉu vi certas, ke ne mistajpis la retadreson?</p> |
205 |
+ <p>Krome, eblas ke foriĝis (aŭ neniam fariĝis) tiu paĝo. Tiuokaze, bedaŭron!</p> |
206 |
+ <p> |
207 |
+ Vi eble volas reviziti la |
208 |
+ <router-link to="./"> |
209 |
+ paĝoliston |
210 |
+ </router-link>. |
211 |
+ </p> |
212 |
+ </div> |
213 |
+ <img |
214 |
+ class="error-image" |
215 |
+ src="/x_x/404.png" |
216 |
+ > |
217 |
+ </div> |
218 |
+ <div |
219 |
+ v-else |
220 |
+ class="panel-body" |
221 |
+ > |
222 |
+ <div class="page-content"> |
223 |
+ <LinksDynamically :content="content" /> |
224 |
+ </div> |
225 |
+ </div> |
226 |
+ </div> |
227 |
+ </div> |
228 |
+</template> |
229 |
+ |
230 |
+<script src="./subpage.js"></script> |
231 |
+ |
232 |
+<style lang="scss"> |
233 |
+.page-content { |
234 |
+ margin: 1em; |
235 |
+} |
236 |
+.error-image { |
237 |
+ display: table-cell; |
238 |
+ vertical-align: bottom; |
239 |
+} |
240 |
+.pagelist-icon { |
241 |
+ text-align: right; |
242 |
+ margin-left: auto; |
243 |
+} |
244 |
+</style> |
245 |
-- |
246 |
2.42.0 |
247 |
|