Implement lint

This commit is contained in:
2026-08-27 12:45:30 +02:00
parent 171db88400
commit 17009b641f
41 changed files with 70402 additions and 580 deletions
+1 -1
View File
@@ -105,7 +105,7 @@ export default {
window.removeEventListener('hashchange', this.onBrowserHashChange);
this.mobileMediaQuery.removeEventListener('change', this.updateMobile);
}
}
};
</script>
<template>
<div id="main">
+8 -8
View File
@@ -43,7 +43,7 @@ export default {
for(const [sType, aoElems] of Object.entries(aoElemTypes)) {
this.elems[sType] = {};
for(const [iKey, oElem] of Object.entries(aoElems)) {
for(const oElem of Object.values(aoElems)) {
oElem.type = sType;
this.elems[sType][oElem.id] = oElem;
}
@@ -53,7 +53,7 @@ export default {
this.api.post('admin_create', {type: sType})
.then((aoNewElemTypes) => {
for(const [sType, aoNewElems] of Object.entries(aoNewElemTypes)) {
for(const [iKey, oNewElem] of Object.entries(aoNewElems)) {
for(const oNewElem of Object.values(aoNewElems)) {
oNewElem.type = sType;
this.elems[sType][oNewElem.id] = oNewElem;
this.addFeedback('success', this.l('admin.create_success'), {'create':sType});
@@ -114,7 +114,7 @@ export default {
.catch((oError) => {this.addFeedback('error', oError.desc_lang_text, {'update':'project'});});
}
}
}
};
</script>
<template>
<div id="admin">
@@ -134,7 +134,7 @@ export default {
</tr>
</thead>
<tbody>
<tr v-for="project in elems.project">
<tr v-for="project in elems.project" :key="project.id">
<td>{{ project.id }}</td>
<td><AdminInput :type="'text'" :name="'name'" :elem="project" /></td>
<td>{{ project.mode }}</td>
@@ -163,7 +163,7 @@ export default {
</tr>
</thead>
<tbody>
<tr v-for="feed in elems.feed">
<tr v-for="feed in elems.feed" :key="feed.id">
<td>{{ feed.id }}</td>
<td><AdminInput :type="'text'" :name="'ref_feed_id'" :elem="feed" /></td>
<td><AdminInput :type="'number'" :name="'id_spot'" :elem="feed" /></td>
@@ -189,7 +189,7 @@ export default {
</tr>
</thead>
<tbody>
<tr v-for="spot in elems.spot">
<tr v-for="spot in elems.spot" :key="spot.id">
<td>{{ spot.id }}</td>
<td>{{ spot.ref_spot_id }}</td>
<td>{{ spot.name }}</td>
@@ -212,7 +212,7 @@ export default {
</tr>
</thead>
<tbody>
<tr v-for="user in elems.user">
<tr v-for="user in elems.user" :key="user.id">
<td>{{ user.id }}</td>
<td class="left">{{ user.name }}</td>
<td class="left">{{ user.email }}</td>
@@ -228,7 +228,7 @@ export default {
<AppButton :classes="'refresh'" :text="l('project.update_messages')" :icon="'refresh'" @click="updateProject" />
</div>
<div id="feedback" class="feedback">
<p v-for="feedback in feedbacks" :class="feedback.type">{{ feedback.msg }}</p>
<p v-for="(feedback, index) in feedbacks" :key="index" :class="feedback.type">{{ feedback.msg }}</p>
</div>
</div>
</template>
+1 -1
View File
@@ -10,7 +10,7 @@
return this.elem[this.name];
}
}
}
};
</script>
<template>
+1 -1
View File
@@ -12,7 +12,7 @@ export default {
iconClasses: String,
iconSize: String
}
}
};
</script>
<template>
<button :class="classes"><AppIcon :icon="icon" :text="text" :classes="iconClasses" :size="iconSize" /></button>
+1 -1
View File
@@ -37,7 +37,7 @@ export default {
return this.transform || null;
}
}
}
};
</script>
<template>
+1 -1
View File
@@ -38,7 +38,7 @@ export default {
].filter(Boolean).join(' ');
}
}
}
};
</script>
<template>
+5 -5
View File
@@ -183,7 +183,7 @@ export default {
positionFromTop: 0,
resizeDuration: parseFloat(this.getStyleProperty('--trans-slow')),
hasVideo: true,
onMediaChange: async (oMedia) => {
onMediaChange: async(oMedia) => {
this.hash.items = [this.project.codename, 'media', oMedia.id];
if(oMedia.set == 'post-medias') {
(await this.feed.findPost('media', oMedia.id))?.panMapToMarker();
@@ -439,7 +439,7 @@ export default {
onMarkerClick(oEvent, oMarker) {
oEvent.preventDefault();
oEvent.stopPropagation();
switch (oMarker.type) {
switch(oMarker.type) {
case 'project':
this.hash.items = [oMarker.codename];
break;
@@ -448,7 +448,7 @@ export default {
}
},
onMarkerHover(oEvent, oMarker) {
switch (oMarker.type) {
switch(oMarker.type) {
case 'project':
if(oEvent.type == 'mouseenter') this.openProjectPopup(oMarker);
else this.closePopup();
@@ -651,7 +651,7 @@ export default {
getStyleProperty(sProperty) {
return getComputedStyle(this.$el).getPropertyValue(sProperty).trim();
},
isMarkerVisible(oLngLat){
isMarkerVisible(oLngLat) {
return !!this.map && this.map.getBounds().contains(oLngLat);
},
onPanelToggle(sPanel, bNewValue, iAnimDuration=500) {
@@ -674,7 +674,7 @@ export default {
this.settings = vPanel;
}
}
}
};
</script>
<template>
+2 -2
View File
@@ -55,7 +55,7 @@ export default {
manageLogin() {
if(this.loginLoading) return;
var regexEmail = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
let regexEmail = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if(!regexEmail.test(this.user.email)) this.feedbacks.push({type:'error', 'msg':this.lang.get('account.invalid_email')});
else if(this.settingPassword && this.password !== this.passwordConfirmation) this.feedbacks.push({type:'error', 'msg':this.lang.get('account.password_mismatch')});
else {
@@ -90,7 +90,7 @@ export default {
}
}
}
}
};
</script>
<template>
+2 -2
View File
@@ -215,7 +215,7 @@ export default {
return this.$el.getBoundingClientRect().width;
}
}
}
};
</script>
<template>
@@ -226,7 +226,7 @@ export default {
<ProjectPost v-else :options="{type: 'poster', relative_time: lang.get('post.new_message')}" />
</div>
<div v-if="project" v-show="!loadingPost" id="feed-posts">
<ProjectPost v-for="post in posts" :options="post" ref="posts" />
<ProjectPost v-for="post in posts" :key="post.ref" :options="post" ref="posts" />
</div>
<div id="feed-footer" v-if="loading">
<ProjectPost :options="{type: 'loading', headerless: true}" />
+1 -1
View File
@@ -4,7 +4,7 @@ export default {
options: Object
},
inject: ['lang']
}
};
</script>
<template>
+2 -2
View File
@@ -17,7 +17,7 @@ export default {
data() {
return {
title:''
}
};
},
inject: ['lang', 'isMobile'],
mounted() {
@@ -32,7 +32,7 @@ export default {
this.$refs.link.click();
}
}
}
};
</script>
<template>
+2 -2
View File
@@ -48,7 +48,7 @@ export default {
;
}
}
}
};
</script>
<template>
@@ -98,7 +98,7 @@ export default {
<div v-if="options.medias" class="section medias">
<appIcon v-if="options.type=='message'" icon="media" width="fixed" size="lg" :text="lang.get('media.nearby')" />
<div class="medias-list">
<projectMediaLink v-for="media in options?.medias" :options="media" :type="'marker'" />
<projectMediaLink v-for="media in options?.medias" :key="media.id_media" :options="media" :type="'marker'" />
</div>
</div>
</div>
+2 -1
View File
@@ -159,6 +159,7 @@
case 'media':
this.$refs.medialink.openMedia();
if(this.relatedMarker) return this.openMarkerPopup();
else return Promise.resolve();
default:
return Promise.resolve();
}
@@ -168,7 +169,7 @@
//Auto-adjust text area height
if(this.options.type == 'poster') autosize(this.$refs.post);
}
}
};
</script>
<template>
+1 -1
View File
@@ -27,7 +27,7 @@ export default {
(bDifferentTimeZone?sTime:null);
}
}
}
};
</script>
<template>
+2 -2
View File
@@ -83,7 +83,7 @@ export default {
return this.$el.getBoundingClientRect().width;
}
}
}
};
</script>
<template>
@@ -154,7 +154,7 @@ export default {
</div>
<div v-if="project?.id && !isMobile()" id="legend" class="panel-control panel-control-bottom">
<div class="panel-control-elem">
<div v-for="(color, hikeType) in hikes.colors" class="track">
<div v-for="(color, hikeType) in hikes.colors" :key="hikeType" class="track">
<span class="line" :style="'background-color:'+color+';'"></span>
<span class="desc">{{ lang.get('track.'+hikeType) }}</span>
</div>
+1 -1
View File
@@ -123,7 +123,7 @@ export default {
else this.addLog('upload.position.unsupported');
}
}
}
};
</script>
<template>
<div id="upload">
+3 -3
View File
@@ -2,7 +2,7 @@
export function copyTextToClipboard(text) {
if(!navigator.clipboard) {
var textArea = document.createElement('textarea');
let textArea = document.createElement('textarea');
textArea.value = text;
// Avoid scrolling to bottom
@@ -15,9 +15,9 @@ export function copyTextToClipboard(text) {
textArea.select();
try {
var successful = document.execCommand('copy');
let successful = document.execCommand('copy');
if(!successful) console.error('Fallback: Oops, unable to copy', text);
} catch (err) {
} catch(err) {
console.error('Fallback: Oops, unable to copy', err);
}
+53 -53
View File
@@ -37,7 +37,7 @@ export default class Lightbox {
}
init() {
if (document.readyState === 'loading') {
if(document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => {
this.build();
this.enable();
@@ -58,7 +58,7 @@ export default class Lightbox {
onBodyClick(event) {
const link = event.target.closest('a[data-lightbox], area[data-lightbox]');
if (!link) return;
if(!link) return;
event.preventDefault();
this.start(link);
}
@@ -68,7 +68,7 @@ export default class Lightbox {
}
build() {
if (!document.getElementById('lightbox')) {
if(!document.getElementById('lightbox')) {
const wrapper = document.createElement('div');
wrapper.innerHTML = `
<div id="lightboxOverlay" tabindex="-1" class="lightboxOverlay"></div>
@@ -129,21 +129,21 @@ export default class Lightbox {
this.overlay.addEventListener('click', () => this.end());
this.dataContainer.addEventListener('click', () => this.end());
this.lightbox.addEventListener('click', (event) => {
if (event.target === this.lightbox) this.end();
if(event.target === this.lightbox) this.end();
});
this.outerContainer.addEventListener('click', (event) => {
if (event.target === this.outerContainer) this.end();
if(event.target === this.outerContainer) this.end();
event.stopPropagation();
});
this.prev.addEventListener('click', (event) => {
event.preventDefault();
if (this.currentImageIndex === 0) this.changeImage(this.album.length - 1);
if(this.currentImageIndex === 0) this.changeImage(this.album.length - 1);
else this.changeImage(this.currentImageIndex - 1);
});
this.next.addEventListener('click', (event) => {
event.preventDefault();
if (this.currentImageIndex === this.album.length - 1) this.changeImage(0);
if(this.currentImageIndex === this.album.length - 1) this.changeImage(0);
else this.changeImage(this.currentImageIndex + 1);
});
@@ -157,7 +157,7 @@ export default class Lightbox {
this.end();
});
this.closeButton.addEventListener('keyup', (event) => {
if (event.key === 'Enter' || event.key === ' ') this.end();
if(event.key === 'Enter' || event.key === ' ') this.end();
});
this.nav.addEventListener('wheel', this.boundOnWheel, { passive: false });
@@ -184,13 +184,13 @@ export default class Lightbox {
const links = [...document.querySelectorAll(`${link.tagName}[data-lightbox="${CSS.escape(setName)}"]`)];
links.forEach((item, index) => {
this.addToAlbum(item);
if (item === link) imageNumber = index;
if(item === link) imageNumber = index;
});
this.fade(this.overlay, true, this.options.fadeDuration);
this.fade(this.lightbox, true, this.options.fadeDuration);
if (this.options.disableScrolling) document.body.classList.add('lb-disable-scrolling');
if(this.options.disableScrolling) document.body.classList.add('lb-disable-scrolling');
window.addEventListener('resize', this.boundOnResize);
this.changeImage(imageNumber);
@@ -217,15 +217,15 @@ export default class Lightbox {
refreshAlbum() {
const current = this.album[this.currentImageIndex];
if (!current?.set) return;
if(!current?.set) return;
const links = [...document.querySelectorAll(`a[data-lightbox="${CSS.escape(current.set)}"], area[data-lightbox="${CSS.escape(current.set)}"]`)];
if (!links.length) return;
if(!links.length) return;
const existingKeys = new Set(this.album.map((media) => this.getMediaKey(media)));
links.forEach((link) => {
const key = this.getLinkMediaKey(link);
if (existingKeys.has(key)) return;
if(existingKeys.has(key)) return;
this.addToAlbum(link);
existingKeys.add(key);
@@ -257,10 +257,10 @@ export default class Lightbox {
}
getDataContainerHeight(width = null) {
if (!this.dataContainer) return 0;
if(!this.dataContainer) return 0;
const currentWidth = this.dataContainer.style.width;
if (width !== null) this.dataContainer.style.width = `${width}px`;
if(width !== null) this.dataContainer.style.width = `${width}px`;
const height = Math.ceil(this.dataContainer.getBoundingClientRect().height || this.dataContainer.offsetHeight || 0);
this.dataContainer.style.width = currentWidth;
@@ -268,7 +268,7 @@ export default class Lightbox {
}
getMediaSize(media, maxWidth, maxHeight) {
if (media.width <= maxWidth && media.height <= maxHeight) {
if(media.width <= maxWidth && media.height <= maxHeight) {
return {
width: media.width,
height: media.height
@@ -278,7 +278,7 @@ export default class Lightbox {
const widthRatio = media.width / maxWidth;
const heightRatio = media.height / maxHeight;
if (widthRatio > heightRatio) {
if(widthRatio > heightRatio) {
return {
width: maxWidth,
height: Math.round(media.height / widthRatio)
@@ -296,12 +296,12 @@ export default class Lightbox {
const maxOuterHeight = Math.max(window.innerHeight - this.options.positionFromTop, 1);
let fittedSize = size;
for (let i = 0; i < 5; i++) {
for(let i = 0; i < 5; i++) {
const containerWidth = fittedSize.width + this.containerPadding.left + this.containerPadding.right + border.left + border.right;
const containerHeight = fittedSize.height + this.containerPadding.top + this.containerPadding.bottom + border.top + border.bottom;
const dataHeight = this.getDataContainerHeight(containerWidth);
const overflow = Math.ceil(containerHeight + dataHeight - maxOuterHeight);
if (overflow <= 0 || fittedSize.height <= 1) break;
if(overflow <= 0 || fittedSize.height <= 1) break;
const height = Math.max(fittedSize.height - overflow, 1);
fittedSize = {
@@ -328,7 +328,7 @@ export default class Lightbox {
changeImage(index) {
const media = this.album[index];
if (!media) return;
if(!media) return;
this.updateDetails(media, false);
this.hideElements([this.dataContainer]);
@@ -343,7 +343,7 @@ export default class Lightbox {
this.options.onMediaChange(media);
if (media.type === 'video') {
if(media.type === 'video') {
this.image.removeAttribute('src');
this.container.classList.add('lb-video-nav');
this.video.onloadedmetadata = () => {
@@ -360,7 +360,7 @@ export default class Lightbox {
this.image.alt = media.alt;
let width = this.image.naturalWidth;
let height = this.image.naturalHeight;
if (Math.abs(media.orientation) === 90 && width > height) {
if(Math.abs(media.orientation) === 90 && width > height) {
const tmp = width;
width = height;
height = tmp;
@@ -375,13 +375,13 @@ export default class Lightbox {
}
sizeOverlay() {
if (this.resizeTimer) clearTimeout(this.resizeTimer);
if (!this.album.length) return;
if(this.resizeTimer) clearTimeout(this.resizeTimer);
if(!this.album.length) return;
this.resizeTimer = window.setTimeout(() => {
const current = this.album[this.currentImageIndex];
if (!current) return;
if (current.type === 'image') this.changeImage(this.currentImageIndex);
if(!current) return;
if(current.type === 'image') this.changeImage(this.currentImageIndex);
else this.updateSize(this.currentImageIndex);
}, 200);
}
@@ -406,7 +406,7 @@ export default class Lightbox {
showImage() {
this.fade(this.loader, false, 0);
if (this.options.hasVideo && this.album[this.currentImageIndex].type === 'video') this.fade(this.video, true, this.options.imageFadeDuration);
if(this.options.hasVideo && this.album[this.currentImageIndex].type === 'video') this.fade(this.video, true, this.options.imageFadeDuration);
else this.fade(this.image, true, this.options.imageFadeDuration);
this.updateNav();
@@ -421,17 +421,17 @@ export default class Lightbox {
this.setVisible(this.next, false);
const alwaysShowNav = ('ontouchstart' in window) && this.options.alwaysShowNavOnTouchDevices;
if (this.album.length <= 1) return;
if(this.album.length <= 1) return;
if (this.options.wrapAround) {
if(this.options.wrapAround) {
this.setVisible(this.prev, true);
this.setVisible(this.next, true);
} else {
if (this.currentImageIndex > 0) this.setVisible(this.prev, true);
if (this.currentImageIndex < this.album.length - 1) this.setVisible(this.next, true);
if(this.currentImageIndex > 0) this.setVisible(this.prev, true);
if(this.currentImageIndex < this.album.length - 1) this.setVisible(this.next, true);
}
if (alwaysShowNav) {
if(alwaysShowNav) {
this.prev.style.opacity = '1';
this.next.style.opacity = '1';
} else {
@@ -441,19 +441,19 @@ export default class Lightbox {
}
updateDetails(media = this.album[this.currentImageIndex], show = true) {
if (!media) return;
if(!media) return;
if (media.title) {
if (this.options.sanitizeTitle) this.caption.textContent = media.title;
if(media.title) {
if(this.options.sanitizeTitle) this.caption.textContent = media.title;
else this.caption.innerHTML = media.title;
if (show) this.fade(this.caption, true, 200);
if(show) this.fade(this.caption, true, 200);
else this.setVisible(this.caption, true);
} else {
this.caption.textContent = '';
this.setVisible(this.caption, false);
}
if (show) {
if(show) {
this.fade(this.closeButton, true, 200);
this.outerContainer.classList.remove('animating');
this.fade(this.dataContainer, true, this.options.resizeDuration);
@@ -468,11 +468,11 @@ export default class Lightbox {
preloadNeighboringImages() {
const next = this.album[this.currentImageIndex + 1];
const prev = this.album[this.currentImageIndex - 1];
if (next && next.type === 'image') {
if(next && next.type === 'image') {
const preloadNext = new Image();
preloadNext.src = next.link;
}
if (prev && prev.type === 'image') {
if(prev && prev.type === 'image') {
const preloadPrev = new Image();
preloadPrev.src = prev.link;
}
@@ -490,25 +490,25 @@ export default class Lightbox {
}
keyboardAction(event) {
switch (event.key) {
switch(event.key) {
case 'Escape':
event.stopPropagation();
this.end();
break;
case 'ArrowLeft':
if (this.currentImageIndex !== 0) this.changeImage(this.currentImageIndex - 1);
else if (this.options.wrapAround && this.album.length > 1) this.changeImage(this.album.length - 1);
if(this.currentImageIndex !== 0) this.changeImage(this.currentImageIndex - 1);
else if(this.options.wrapAround && this.album.length > 1) this.changeImage(this.album.length - 1);
break;
case 'ArrowRight':
if (this.currentImageIndex !== this.album.length - 1) this.changeImage(this.currentImageIndex + 1);
else if (this.options.wrapAround && this.album.length > 1) this.changeImage(0);
if(this.currentImageIndex !== this.album.length - 1) this.changeImage(this.currentImageIndex + 1);
else if(this.options.wrapAround && this.album.length > 1) this.changeImage(0);
break;
}
}
onWheel(event) {
const media = this.album[this.currentImageIndex];
if (!media || media.type === 'video') return;
if(!media || media.type === 'video') return;
event.preventDefault();
const rect = this.image.getBoundingClientRect();
@@ -534,7 +534,7 @@ export default class Lightbox {
onDragStart(event) {
const scale = parseFloat(this.image.style.getPropertyValue('--scale') || '1');
if (scale <= 1) return;
if(scale <= 1) return;
this.gMouseDownOffsetX = event.clientX - parseFloat(this.image.style.getPropertyValue('--translate-x') || '0');
this.gMouseDownOffsetY = event.clientY - parseFloat(this.image.style.getPropertyValue('--translate-y') || '0');
@@ -582,7 +582,7 @@ export default class Lightbox {
}
setImageTransform(transform) {
if (!this.image) return;
if(!this.image) return;
this.image.style.setProperty('--scale', String(transform.scale));
this.image.style.setProperty('--translate-x', `${transform.translateX}px`);
this.image.style.setProperty('--translate-y', `${transform.translateY}px`);
@@ -595,17 +595,17 @@ export default class Lightbox {
}
setVisible(element, visible) {
if (!element) return;
if(!element) return;
element.style.visibility = visible ? 'visible' : 'hidden';
element.style.pointerEvents = visible ? '' : 'none';
}
fade(element, show, duration, done) {
if (!element) return;
if(!element) return;
const safeDuration = duration || 0;
element.style.transition = `opacity ${safeDuration}ms`;
if (show) {
if(show) {
this.setVisible(element, true);
requestAnimationFrame(() => {
element.style.opacity = element === this.overlay ? '0.8' : '1';
@@ -618,7 +618,7 @@ export default class Lightbox {
}, safeDuration);
}
if (typeof done === 'function') {
if(typeof done === 'function') {
window.setTimeout(done, safeDuration);
}
}
@@ -631,7 +631,7 @@ export default class Lightbox {
window.removeEventListener('resize', this.boundOnResize);
window.removeEventListener('mousemove', this.boundOnDragMove);
if(dispose){
if(dispose) {
this.disable();
if(this.resizeTimer) clearTimeout(this.resizeTimer);
window.removeEventListener('mouseup', this.boundOnDragEnd);
@@ -645,6 +645,6 @@ export default class Lightbox {
this.options.onClosing();
}
if (this.options.disableScrolling) document.body.classList.remove('lb-disable-scrolling');
if(this.options.disableScrolling) document.body.classList.remove('lb-disable-scrolling');
}
}