Skip to content

Commit

Permalink
[FEATURE] Add support for deeplinks of extension keys
Browse files Browse the repository at this point in the history
  • Loading branch information
eliashaeussler committed Aug 15, 2024
1 parent 6d50039 commit 0a65329
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 21 deletions.
24 changes: 3 additions & 21 deletions assets/js/badge/provider/badgeProviderToggle.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/

import BadgeProvider from './badgeProvider';
import Url from '../../url';

/**
* BadgeProviderToggle.
Expand All @@ -37,7 +38,7 @@ export default class BadgeProviderToggle {
this.inputs = this.locateInputs();
this.providers = this.buildProviders();

const preselectedProvider = BadgeProviderToggle.getProviderFromUrl();
const preselectedProvider = Url.getFromHash('provider');
this.setActiveProvider(preselectedProvider);
if (preselectedProvider !== null) {
this.hideButtonPings();
Expand Down Expand Up @@ -118,7 +119,7 @@ export default class BadgeProviderToggle {
}

// Apply provider as URL fragment
window.location.hash = activeProvider;
Url.setInHash('provider', activeProvider);

// Apply "checked" state of all input elements
[...this.inputs].forEach((el) => {
Expand Down Expand Up @@ -158,25 +159,6 @@ export default class BadgeProviderToggle {
});
}

/**
* Get provider identifier from URL fragment.
*
* @returns {string|null} Provider identifier or `NULL` if no URL fragment is set or if it's empty
*/
static getProviderFromUrl() {
let { hash } = window.location;

if (hash === null || hash.length === 0) {
return null;
}

if (hash.startsWith('#')) {
hash = hash.substr(1);
}

return hash;
}

static getButtonLabel(button) {
return button.querySelector('.badge-providers-button-label');
}
Expand Down
23 changes: 23 additions & 0 deletions assets/js/badge/tryOut.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import BadgeProviderToggle from './provider/badgeProviderToggle';
import Clipboard from '../clipboard';
import CodeTabs from './codeTabs';
import LazyLoad from './lazyLoad';
import Url from '../url';

/**
* TryOut.
Expand All @@ -35,6 +36,7 @@ export default class TryOut {
backdrop: 'static',
backdropClasses: 'bg-gray-900 bg-opacity-50 dark:bg-opacity-80 fixed inset-0 z-40',
onShow: () => this.showModal(),
onHide: () => this.hideModal(),
};

options;
Expand All @@ -49,6 +51,8 @@ export default class TryOut {

output;

extensionKeyInput;

modal;

constructor(trigger, options) {
Expand All @@ -72,6 +76,13 @@ export default class TryOut {
this.modal.toggle();
}
});

// Preselect extension from url
const preselectedExtension = Url.getFromHash('extension');
if (preselectedExtension !== null) {
this.modal.show();
this.applyTemplate(preselectedExtension);
}
}

/**
Expand All @@ -87,12 +98,20 @@ export default class TryOut {
};
}

/**
* Hide try-out modal.
*/
hideModal() {
Url.deleteFromHash('extension');
}

/**
* Read and store try-out template section.
*/
readTemplate() {
this.template = document.querySelector('#try-out-template').innerHTML;
this.output = document.querySelector('#try-out-output');
this.extensionKeyInput = document.querySelector('#try-out-extension-key');
}

/**
Expand All @@ -103,6 +122,7 @@ export default class TryOut {
applyTemplate(extensionKey) {
this.output.classList.remove('hidden');
this.output.innerHTML = this.template.replaceAll('EXTENSION_KEY', extensionKey);
this.extensionKeyInput.value = extensionKey;

// Connect badge provider toggles
const badgeProviderToggle = new BadgeProviderToggle('#try-out-modal .badge-providers-button');
Expand Down Expand Up @@ -143,5 +163,8 @@ export default class TryOut {

// Connect lazy-loading for badges
LazyLoad.connect(this.element);

// Store in URL
Url.setInHash('extension', extensionKey);
}
}
84 changes: 84 additions & 0 deletions assets/js/url.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* This file is part of the Symfony project "eliashaeussler/typo3-badges".
*
* Copyright (C) 2024 Elias Häußler <elias@haeussler.dev>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

/**
* Url.
*
* @author Elias Häußler <elias@haeussler.dev>
* @license GPL-3.0-or-later
*/
export default class Url {
/**
* Read given parameter value from url hash.
*
* @param name {string} Name of the parameter inside url hash
* @returns {string} Value of given parameter from url hash
*/
static getFromHash(name) {
const searchParams = Url.parseHash();

return searchParams.get(name);
}

/**
* Store given parameter in url hash.
*
* @param name {string} Name of the parameter to store in url hash
* @param value {string} Value of the parameter to store in url hash
*/
static setInHash(name, value) {
const searchParams = Url.parseHash();

searchParams.set(name, value);

window.location.hash = searchParams.toString();
}

/**
* Delete given parameter from url hash.
*
* @param name {string} Name of the parameter to delete from url hash
*/
static deleteFromHash(name) {
const searchParams = Url.parseHash();

searchParams.delete(name);

window.location.hash = searchParams.toString();
}

/**
* Parse url hash into URLSearchParams object.
*
* @returns {URLSearchParams} Object of parsed parameters from url hash
*/
static parseHash() {
let { hash } = window.location;

if (hash === null || hash.length === 0) {
return new URLSearchParams();
}

if (hash.startsWith('#')) {
hash = hash.substr(1);
}

return new URLSearchParams(hash);
}
}

0 comments on commit 0a65329

Please sign in to comment.