9 Commits
Author SHA1 Message Date
Solninja A 981f6da829 Revamp popup settings 2025-01-27 17:26:25 +10:00
SolninjaA f38086593b Add Firefox Add-Ons link to README.md 2025-01-27 15:49:01 +10:00
SolninjaA fdb3f44f3b Create CODE_OF_CONDUCT.md 2025-01-27 15:37:13 +10:00
SolninjaA 74c0645136 Merge pull request #2 from SolninjaA/all-contributors/add-DarioDarko
docs: add DarioDarko as a contributor for code
2025-01-27 15:29:44 +10:00
allcontributors[bot] 9f88ba7a45 docs: update .all-contributorsrc 2025-01-27 05:28:38 +00:00
allcontributors[bot] 1aa4aa75fe docs: update README.md 2025-01-27 05:28:37 +00:00
SolninjaA d0c3386b58 Update .all-contributorsrc 2025-01-27 15:27:59 +10:00
Solninja A 538b799bab Add all contributors RC 2025-01-27 15:22:18 +10:00
SolninjaA fc8dac1c9f Add all contributors bot in README.md 2025-01-27 15:15:42 +10:00
9 changed files with 268 additions and 12 deletions

No files matched your search

+23
View File
@@ -0,0 +1,23 @@
{
"projectName": "Chhoto-URL-Extension",
"projectOwner": "SolninjaA",
"repoType": "github",
"repoHost": "https://github.com",
"files": [
"README.md"
],
"contributors": [
{
"login": "DarioDarko",
"name": "DarioDarko",
"avatar_url": "https://avatars.githubusercontent.com/u/154679092?v=4",
"profile": "https://github.com/DarioDarko",
"contributions": [
"code"
]
}
],
"commitType": "docs",
"commitConvention": "angular",
"contributorsPerLine": 7
}
+128
View File
@@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
code-of-conduct-report@happy-mochi.com.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
+20 -2
View File
@@ -39,9 +39,9 @@ environment:
```
## Installation
*This extension will be published to extension stores in the near future*
<a href="https://addons.mozilla.org/en-US/firefox/addon/chhoto-url/" target="_blank"><img alt="Firefox icon" src="https://imgur.com/ihXsdDO.png" width="64" height="64"></a>
Once you have installed the extension, either through an extension store or [from source](#installing-from-source), you must configure the extension.
Once you have installed the extension, either through an extension store (see icons above) or [from source](#installing-from-source), you must configure the extension.
### Firefox
1. Right-click on the Chhoto URL extension icon (![Chhoto URL extension icon](icons/chhoto-url-16.png)). If the extension is not pinned, the Chhoto URL extension icon will be under this highlighted icon:
@@ -100,6 +100,24 @@ This extension only communicates to the Chhoto URL server instance you configure
4. Navigate to the cloned repository folder
5. Click "Select"
## Contributors
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tbody>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DarioDarko"><img src="https://avatars.githubusercontent.com/u/154679092?v=4?s=100" width="100px;" alt="DarioDarko"/><br /><sub><b>DarioDarko</b></sub></a><br /><a href="https://github.com/SolninjaA/Chhoto-URL-Extension/commits?author=DarioDarko" title="Code">💻</a></td>
</tr>
</tbody>
</table>
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
## Acknowledgements
This project was inspired by and modified from Edward Shen's [Shlink extension][shlink-extension]. Modifications include:
1. Rewriting the backend code to contact a Chhoto URL server, rather than a Shlink server.
+2 -2
View File
@@ -345,6 +345,6 @@ browser.contextMenus.create({
});
// Run code when the context menu is clicked
browser.contextMenus.onClicked.addListener( () => {
browser.windows.create({url: "/popup/popup.html", type: "popup"});
browser.contextMenus.onClicked.addListener( (info) => {
browser.windows.create({url: `/popup/popup.html?url=${info.pageUrl}`, type: "popup"});
});
+1 -1
View File
@@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "Chhoto URL",
"version": "1.2.0",
"version": "1.3.0",
"description": "An unofficial extension for shortening URLs using the Chhoto URL API. Requires a Chhoto URL instance.",
"icons": {
"16": "icons/chhoto-url-16.png",
+10
View File
@@ -150,6 +150,16 @@
<p id="message2" class="note">Inputted value is not a number.</p>
</div>
<div class="settings checkbox">
<h2>Popup Settings</h2>
<label>
Automatically insert long URL into the popup
<input type="checkbox" id="auto-insert-popup">
<p class="note">This will only autofill the long URL if the page's protocol is supported (see the allowed protocols setting).</p>
</label>
</div>
<script type="application/javascript" src="/lib/browser-polyfill.min.js"></script>
<script type="application/javascript" src="/options/options.js"></script>
</body>
+25 -1
View File
@@ -40,6 +40,7 @@ const generateWithTitleEle = document.getElementById("generate-with-title");
const titleWordLimitLabelEle = document.getElementById("title-word-limit-label");
const titleWordLimitEle = document.getElementById("title-word-limit");
const message2Ele = document.getElementById("message2");
const autoInsertPopupEle = document.getElementById("auto-insert-popup");
// Get the browser storage
const browserStorage = browser.storage.local;
@@ -164,7 +165,21 @@ titleWordLimitEle.oninput = (event) => {
};
}
function setCurrentChoice({ chhotoHost, chhotoKey, allowedProtocols, generateWithTitle, titleWordLimit }) {
// Automatically insert long URL into popup
autoInsertPopupEle.onclick = () => {
// Get browser storage
browserStorage.get("autoInsertPopup").then(({ autoInsertPopup }) => {
// Get value
autoInsertPopup = autoInsertPopupEle.checked;
// Save value
browserStorage.set({ autoInsertPopup });
});
};
function setCurrentChoice({ chhotoHost, chhotoKey, allowedProtocols, generateWithTitle, titleWordLimit, autoInsertPopup }) {
hostKeyEle.value = chhotoHost || "";
apiKeyEle.value = chhotoKey || "";
@@ -191,16 +206,25 @@ function setCurrentChoice({ chhotoHost, chhotoKey, allowedProtocols, generateWit
browserStorage.set({ titleWordLimit: titleWordLimit });
}
// If autoInsertPopup is undefined, set the default value
if (autoInsertPopup === undefined) {
autoInsertPopup = false;
browserStorage.set({ autoInsertPopup: autoInsertPopup });
}
// Initialize a list of protocols that are allowed if unset. This needs
// to be synced with the initialization code in background.js#validateURL.
allowedProtocols = new Set(allowedProtocols);
// Update the checkboxes to display the correct value
AllowHttpEle.checked = allowedProtocols.has("http:");
AllowHttpsEle.checked = allowedProtocols.has("https:");
AllowFileEle.checked = allowedProtocols.has("file:");
AllowFtpEle.checked = allowedProtocols.has("ftp:");
generateWithTitleEle.checked = generateWithTitle;
autoInsertPopupEle.checked = autoInsertPopup;
// Set default display
let display = "none";
+7 -5
View File
@@ -34,7 +34,7 @@
cursor: pointer;
}
#generate {
.generate-button {
border: black 1px solid;
border-radius: 7px;
background-color: white;
@@ -45,7 +45,7 @@
}
#close:hover,
#generate:hover {
.generate-button:hover {
background-color: #bbb;
}
@@ -61,7 +61,7 @@
}
input {
min-width: 150px;
min-width: 250px;
min-height: 17px;
padding: 5px;
border: 2px solid black;
@@ -96,10 +96,11 @@
<button id="close" type="button">&#10006; Close</button>
<form id="generate">
<div class="generate">
<label>
Short URL
<input required type="text" id="shorturl" placeholder="interesting-short-url">
<input autofocus required type="text" id="shorturl" placeholder="interesting-short-url">
<p id="message"></p>
</label>
</div>
@@ -112,10 +113,11 @@
</div>
<div class="generate">
<label>
<input id="generate" type="button" value="Shorten!">
<input class="generate-button" type="submit" value="Shorten!">
<p id="message3">Error: Required fields are missing.</p>
</label>
</div>
</form>
<script type="application/javascript" src="/lib/browser-polyfill.min.js"></script>
+52 -1
View File
@@ -41,6 +41,56 @@ const generateEle = document.querySelector("#generate");
let shorturl;
let longurl;
const requestParams = new URLSearchParams(window.location.search);
const requestValue = requestParams.get('url');
/**
* Automatically insert the long URL, if enabled
*/
// If a URL was passed in the request
if (requestValue) {
browser.storage.local.get().then(( data ) => {
if (data.autoInsertPopup !== undefined && data.autoInsertPopup) {
let allowedProtocols;
// Initialize a list of protocols that are allowed if unset.
if (data.allowedProtocols === undefined) {
allowedProtocols = new Set();
allowedProtocols.add("http:");
allowedProtocols.add("https:");
allowedProtocols.add("ftp:");
allowedProtocols.add("file:");
browser.storage.local.set({ allowedProtocols: Array(...allowedProtocols) });
} else {
allowedProtocols = data.allowedProtocols;
allowedProtocols = new Set(allowedProtocols);
}
// Try and catch structure
try {
// Define the URL
const url = new URL(requestValue);
// Ensure the URL has a valid protocol
if (allowedProtocols.size > 0 && !allowedProtocols.has(url.protocol)) {
throw new Error("The URL is invalid");
};
////// If anything beyond this point is trigerred, the URL protocol is valid. //////
// Reassign the long url
longURLEle.value = url;
longurl = url;
} catch (error) {
console.log(`Error while auto inserting the long URL - ${error}`);
};
};
});
};
// Close function
async function close() {
try {
const windowId = (await browser.windows.getCurrent()).id;
@@ -162,7 +212,8 @@ function sendRequest(page) {
}
// If the generate button was clicked
generateEle.addEventListener("click", () => {
generateEle.addEventListener("submit", (event) => {
event.preventDefault();
// Ensure both fields have been filled out, and the long URL is valid
if ( shorturl !== undefined && longurl !== undefined && !message2Ele.classList.contains("warning") ) {