Skip to content

Commit

Permalink
Add Lazy Load Options (#107)
Browse files Browse the repository at this point in the history
  • Loading branch information
smashedr authored Oct 27, 2024
1 parent 6abe145 commit 392324b
Show file tree
Hide file tree
Showing 20 changed files with 391 additions and 159 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=cssnr_link-extractor&metric=alert_status&label=quality)](https://sonarcloud.io/summary/overall?id=cssnr_link-extractor)
[![GitHub Last Commit](https://img.shields.io/github/last-commit/cssnr/link-extractor?logo=github&logoColor=white&label=updated)](https://github.com/cssnr/link-extractor/graphs/commit-activity)
[![GitHub Top Language](https://img.shields.io/github/languages/top/cssnr/link-extractor?logo=htmx&logoColor=white)](https://github.com/cssnr/link-extractor)
[![GitHub Org Stars](https://img.shields.io/github/stars/cssnr?style=flat&logo=github&logoColor=white&label=org%20stars)](https://cssnr.github.io/)
[![Discord](https://img.shields.io/discord/899171661457293343?logo=discord&logoColor=white&label=discord&color=7289da)](https://discord.gg/wXy6m2X8wY)

# Link Extractor
Expand Down
Binary file added assets/lazy-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 21 additions & 3 deletions src/css/main.css
Original file line number Diff line number Diff line change
@@ -1,19 +1,37 @@
/* CSS for global */

:root,
[data-bs-theme='light'] {
--bs-emphasis-bg: var(--bs-white);
--bs-emphasis-bg-rgb: var(--bs-white-rgb);
}

[data-bs-theme='dark'] {
--bs-emphasis-bg: var(--bs-black);
--bs-emphasis-bg-rgb: var(--bs-black-rgb);
}

svg {
height: 1em;
width: 1em;
margin-bottom: 0.15em;
}

#toast-container {
z-index: 3;
}

#back-to-top {
position: fixed;
bottom: 64px;
right: 20px;
display: none;
z-index: 6;
z-index: 3;
}

#toast-container {
z-index: 5;
.text-ellipsis {
max-width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
5 changes: 5 additions & 0 deletions src/css/permissions.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/* CSS for permissions.html */

body {
min-width: 340px;
}
1 change: 1 addition & 0 deletions src/html/lazy.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
<link rel="icon" href="data:image/x-icon;," type="image/x-icon">
</head>
<body>

Expand Down
16 changes: 8 additions & 8 deletions src/html/links.html
Original file line number Diff line number Diff line change
Expand Up @@ -188,19 +188,19 @@ <h5 class="modal-title">Keyboard Shortcuts <i class="fa-regular fa-keyboard ms-2
</div>
</div> <!-- keybinds-modal -->

<button type="button" class="btn btn-outline-primary" id="back-to-top">
<i class="fa-regular fa-square-caret-up"></i>
</button> <!-- back-to-top -->

<div aria-live="polite" aria-atomic="true" class="">
<div id="toast-container" class="toast-container position-fixed bottom-0 end-0 p-3"></div>
</div> <!-- toast-container -->
</div> <!-- toast -->

<div class="d-none">
<div class="toast align-items-center border-0" role="alert" aria-live="assertive" aria-atomic="true" data-bs-delay="5000">
<div id="clones" class="d-none">
<div class="toast align-items-center border-0" role="alert" aria-live="assertive" aria-atomic="true" data-bs-delay="6000">
<div class="toast-body"></div>
</div>
</div> <!-- d-none -->

<button type="button" class="btn btn-outline-primary" id="back-to-top">
<i class="fa-regular fa-square-caret-up"></i>
</button> <!-- back-to-top -->
</div> <!-- clones -->

<script type="text/javascript" src="../dist/jquery/jquery.min.js"></script>
<script type="text/javascript" src="../dist/bootstrap/bootstrap.bundle.min.js"></script>
Expand Down
178 changes: 127 additions & 51 deletions src/html/options.html

Large diffs are not rendered by default.

15 changes: 8 additions & 7 deletions src/html/permissions.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@
<link rel="stylesheet" type="text/css" href="../dist/bootstrap/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="../dist/fontawesome/css/all.min.css">
<link rel="stylesheet" type="text/css" href="../css/main.css">
<link rel="stylesheet" type="text/css" href="../css/permissions.css">
<script type="text/javascript" src="../js/theme.js"></script>
</head>
<body class="h-100">

<div class="container-fluid p-3 h-100">
<div class="container-fluid py-0 py-sm-3 px-0 px-sm-3 h-100">
<div class="d-flex align-items-center h-100">
<div class="col-xl-6 col-md-8 col-12 m-auto">
<div class="card p-3 ">
<div class="col-12 col-md-10 col-lg-8 col-xxl-6 mx-auto">
<div class="card p-3">
<div class="d-flex justify-content-center align-items-center mb-2">
<img src="../images/logo48.png" class="me-2" height="48" width="48"
alt="Auto Auth" title="Auto Auth">
Expand Down Expand Up @@ -53,7 +54,7 @@ <h1>Link Extractor</h1>
<a class="link-body-emphasis text-decoration-none" target="_blank" rel="noopener"
href="https://link-extractor.cssnr.com/faq/">FAQ</a>
<span class="mx-2">&bull;</span>
<a class="link-body-emphasis text-decoration-none" target="_blank" rel="noopener"
<a class="link-body-emphasis text-decoration-none d-inline-block" target="_blank" rel="noopener"
href="https://link-extractor.cssnr.com/#support">Get Support</a>
</div>
</div> <!-- card -->
Expand All @@ -69,11 +70,11 @@ <h1>Link Extractor</h1>
<div id="toast-container" class="toast-container position-fixed bottom-0 end-0 p-3"></div>
</div> <!-- toast -->

<div class="d-none">
<div class="toast align-items-center border-0" role="alert" aria-live="assertive" aria-atomic="true" data-bs-delay="10000">
<div id="clones" class="d-none">
<div class="toast align-items-center border-0" role="alert" aria-live="assertive" aria-atomic="true" data-bs-delay="6000">
<div class="toast-body"></div>
</div>
</div> <!-- d-none -->
</div> <!-- clones -->

<script type="text/javascript" src="../dist/jquery/jquery.min.js"></script>
<script type="text/javascript" src="../dist/bootstrap/bootstrap.bundle.min.js"></script>
Expand Down
43 changes: 22 additions & 21 deletions src/html/popup.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,28 @@
</ul>
</div>
</div>

<form id="filter-form" class="my-0">
<label for="filter-input" class="visually-hidden"></label>
<input id="filter-input" class="form-control form-control-sm" type="text" placeholder="Quick Filter">
</form>

<button type="button" class="btn btn-sm btn-primary" data-filter="domains">
<i class="fa-solid fa-globe me-1"></i> Only Domains</button>

<button id="pdf-btn" type="button" class="btn btn-sm btn-outline-warning d-none"
data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Experimental Feature">
<i class="fa-solid fa-file-pdf me-1"></i> Extract from PDF
<i id="pdf-icon" class="fa-solid fa-flask" style="min-width: 22px;"></i></button>

<div id="no-file-access" class="alert alert-warning text-center p-1 my-0 d-none">
<span>Browser</span> does <b>not</b> allow access to files.
</div>

<div id="file-access" class="alert alert-warning text-center p-1 my-0 d-none">
PDF files require <a href="https://link-extractor.cssnr.com/faq/#fileAccess" class="alert-link">file access</a>.
</div>

<div id="pdf-perms" class="alert alert-warning text-center p-1 my-0 d-none">
PDF extraction needs <a href="#" class="alert-link grant-permissions">host permissions</a>.
</div>
Expand All @@ -97,38 +103,38 @@
<form id="options-form">
<div class="form-check form-switch">
<input class="form-check-input form-control" type="checkbox" role="switch" id="lazyLoad">
<label class="form-check-label me-1" for="lazyLoad">Lazy Load Opened Tabs</label>
<i class="fa-solid fa-circle-info" data-bs-toggle="tooltip" data-bs-placement="bottom"
<label class="form-check-label" for="lazyLoad">Lazy Load Opened Tabs</label>
<i class="fa-solid fa-circle-info p-1" data-bs-toggle="tooltip" data-bs-placement="bottom"
data-bs-title="Don't Load Tabs Until Clicked On"></i>
</div>
<div class="form-check form-switch">
<input class="form-check-input form-control" type="checkbox" role="switch" id="removeDuplicates">
<label class="form-check-label me-1" for="removeDuplicates">Remove Duplicate Links</label>
<i class="fa-solid fa-circle-info" data-bs-toggle="tooltip" data-bs-placement="bottom"
<label class="form-check-label" for="removeDuplicates">Remove Duplicate Links</label>
<i class="fa-solid fa-circle-info p-1" data-bs-toggle="tooltip" data-bs-placement="bottom"
data-bs-title="Filter Out Links with the same URL"></i>
</div>
<div class="form-check form-switch">
<input class="form-check-input me-2" type="checkbox" role="switch" id="defaultFilter">
<label class="form-check-label me-1" for="defaultFilter">Use Default Link Filtering</label>
<i class="fa-solid fa-circle-info" data-bs-toggle="tooltip" data-bs-placement="bottom"
<label class="form-check-label" for="defaultFilter">Use Default Link Filtering</label>
<i class="fa-solid fa-circle-info p-1" data-bs-toggle="tooltip" data-bs-placement="bottom"
data-bs-title="Filter Out Links Without ://"></i>
</div>
<div class="form-check form-switch">
<input class="form-check-input form-control" type="checkbox" role="switch" id="saveState">
<label class="form-check-label me-1" for="saveState">Save Links Page Options</label>
<i class="fa-solid fa-circle-info" data-bs-toggle="tooltip" data-bs-placement="bottom"
<label class="form-check-label" for="saveState">Save Links Page Options</label>
<i class="fa-solid fa-circle-info p-1" data-bs-toggle="tooltip" data-bs-placement="bottom"
data-bs-title="Remember Links Display, Columns, and Sorting"></i>
</div>
<div class="form-check form-switch">
<input class="form-check-input form-control" type="checkbox" role="switch" id="linksTruncate">
<label class="form-check-label me-1" for="linksTruncate">Truncate Long Links</label>
<i class="fa-solid fa-circle-info" data-bs-toggle="tooltip" data-bs-placement="bottom"
<label class="form-check-label" for="linksTruncate">Truncate Long Links</label>
<i class="fa-solid fa-circle-info p-1" data-bs-toggle="tooltip" data-bs-placement="bottom"
data-bs-title="Truncate Display of Long Links with Ellipsis"></i>
</div>
<div class="form-check form-switch">
<input class="form-check-input form-control" type="checkbox" role="switch" id="linksNoWrap">
<label class="form-check-label me-1" for="linksNoWrap">Don't Wrap Long Links</label>
<i class="fa-solid fa-circle-info" data-bs-toggle="tooltip" data-bs-placement="bottom"
<label class="form-check-label" for="linksNoWrap">Don't Wrap Long Links</label>
<i class="fa-solid fa-circle-info p-1" data-bs-toggle="tooltip" data-bs-placement="bottom"
data-bs-title="Force Long Links to Display on a Single Line"></i>
</div>
</form> <!-- options-form -->
Expand All @@ -143,23 +149,18 @@
<a class="btn btn-sm btn-outline-info" role="button" href="../html/options.html">
<i class="fa-solid fa-sliders me-1"></i> More Options</a>

<!-- <div class="d-flex justify-content-center align-items-center text-center small">-->
<!-- <img class="" src="../images/logo16.png" width="16" height="16" alt="Link Extractor" title="Link Extractor">-->
<!-- <a class="link-offset-2 link-underline link-underline-opacity-0 link-underline-opacity-75-hover mx-2" type="button" rel="noopener"-->
<!-- href="homepage_url">Link Extractor</a> v<span class="version"></span>-->
<!-- </div>-->
</div> <!-- d-grid -->
</div> <!-- container-fluid -->

<div aria-live="polite" aria-atomic="true" class="">
<div id="toast-container" class="toast-container position-fixed bottom-0 end-0 p-3"></div>
</div> <!-- toast-container -->
</div> <!-- toast -->

<div class="d-none">
<div class="toast align-items-center border-0" role="alert" aria-live="assertive" aria-atomic="true" data-bs-delay="5000">
<div id="clones" class="d-none">
<div class="toast align-items-center border-0" role="alert" aria-live="assertive" aria-atomic="true" data-bs-delay="6000">
<div class="toast-body small"></div>
</div>
</div> <!-- d-none -->
</div> <!-- clones -->

<script type="text/javascript" src="../dist/jquery/jquery.min.js"></script>
<script type="text/javascript" src="../dist/bootstrap/bootstrap.bundle.min.js"></script>
Expand Down
Binary file added src/images/lazy/icon-black.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/lazy/icon-red.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/lazy/icon-white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/lazy/icon-yellow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
103 changes: 84 additions & 19 deletions src/js/exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,32 +91,74 @@ export async function injectTab({
* @param {Object} options
*/
export function updateOptions(options) {
for (const [key, value] of Object.entries(options)) {
// console.debug(`${key}: ${value}`)
console.debug('updateOptions:', options)
for (let [key, value] of Object.entries(options)) {
// console.debug(`%c${key}: %c${value}`)
if (typeof value === 'undefined') {
console.warn('Value undefined for key:', key)
continue
}
// Option Key should be `radioXXX` and values should be the option IDs
if (key.startsWith('radio')) {
key = value //NOSONAR
value = true //NOSONAR
}
const el = document.getElementById(key)
if (el) {
if (typeof value === 'boolean') {
el.checked = value
} else {
el.value = value
}
el.classList.remove('is-invalid')
if (!el) {
continue
}
if (el.tagName !== 'INPUT') {
el.textContent = value.toString()
} else if (typeof value === 'boolean') {
el.checked = value
} else {
el.value = value
}
if (el.dataset.related) {
hideShowElement(`#${el.dataset.related}`, value)
}
}
}

/**
* Hide or Show Element with JQuery
* @function hideShowElement
* @param {String} selector
* @param {Boolean} [show]
* @param {String} [speed]
*/
function hideShowElement(selector, show, speed = 'fast') {
const element = $(`${selector}`)
// console.debug('hideShowElement:', show, element)
if (show) {
element.show(speed)
} else {
element.hide(speed)
}
}

/**
* Save Options Callback
* NOTE: Look into simplifying this function
* @function saveOptions
* @param {InputEvent} event
*/
export async function saveOptions(event) {
export async function saveOptions(event) /* NOSONAR */ {
console.debug('saveOptions:', event)
const { options } = await chrome.storage.sync.get(['options'])
let key = event.target?.id
// console.debug('%c ----- targets -----', 'color: Yellow')
// console.debug('event.currentTarget:', event.currentTarget)
// // console.debug('target:', target)
// console.debug('event.target:', event.target)
// console.debug('%c ----- targets -----', 'color: Yellow')
// target = event.currentTarget || target || event.target
const target = event.currentTarget || event.target
console.debug('target:', target)
let key = target.id
// console.debug('key:', key)
let value
if (['flags', 'reset-default'].includes(event.target.id)) {
key = 'flags'
const { options } = await chrome.storage.sync.get(['options'])
if (key === 'flags') {
// key = 'flags'
/** @type {HTMLInputElement} */
const element = document.getElementById(key)
let flags = element.value.toLowerCase().replace(/\s+/gm, '').split('')
Expand All @@ -132,17 +174,40 @@ export async function saveOptions(event) {
}
element.value = flags
value = flags
} else if (event.target.id === 'linksDisplay') {
value = parseInt(event.target.value)
} else if (event.target.type === 'checkbox') {
value = event.target.checked
// } else if (key.startsWith('reset-')) {
// key = target.dataset.target
// console.debug('key reset-:', key)
// /** @type {HTMLInputElement} */
// const element = document.getElementById(key)
// console.debug('element:', element)
// element.value = target.dataset.value
// value = target.dataset.value
} else if (target.dataset.target) {
key = target.dataset.target
console.debug('key dataset.target:', key)
const element = document.getElementById(key)
value = element.value
} else if (target.type === 'radio') {
key = target.name
console.debug('key radio:', key)
const radios = document.getElementsByName(key)
for (const input of radios) {
if (input.checked) {
value = input.id
break
}
}
} else if (target.type === 'checkbox') {
value = target.checked
} else {
value = event.target.value
value = target.value
}
if (value !== undefined) {
options[key] = value
console.log(`Set %c${key}:`, 'color: Khaki', value)
await chrome.storage.sync.set({ options })
} else {
console.warn(`No Value for key: ${key}`)
}
}

Expand Down
Loading

0 comments on commit 392324b

Please sign in to comment.