~jadedctrl/jam-xwx-moe

~jadedctrl/jam-xwx-moe/pleroma-fe/flikaĵoj/0001-Subtenon-de-subpa-oj.patch
 ..
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