Added tab-content-service base class
This commit is contained in:
parent
12da6f7776
commit
3cc3652275
54
content.js
54
content.js
@ -2,7 +2,8 @@ class MessagingService {
|
|||||||
|
|
||||||
async GetHyperlinkNodes(sender, callback) {
|
async GetHyperlinkNodes(sender, callback) {
|
||||||
const a = this;
|
const a = this;
|
||||||
const nodes = await document.body.getElementsByTagName("a");
|
const nodes = await document.querySelectorAll("a");
|
||||||
|
|
||||||
let result = [];
|
let result = [];
|
||||||
|
|
||||||
for (let i=0; i<nodes.length; i++) {
|
for (let i=0; i<nodes.length; i++) {
|
||||||
@ -18,16 +19,13 @@ class MessagingService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// for (let i=0; i<result.length; i++) {
|
|
||||||
// result[i].occurrence = result.filter(item => JSON.stringify(item) === JSON.stringify(result[i])).length;
|
|
||||||
// }
|
|
||||||
|
|
||||||
await callback(result);
|
await callback(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
async GetImageNodes(sender, callback) {
|
async GetImageNodes(sender, callback) {
|
||||||
const a = this;
|
const a = this;
|
||||||
const nodes = await document.body.getElementsByTagName("img");
|
const nodes = await document.querySelectorAll("img");
|
||||||
|
|
||||||
let result = [];
|
let result = [];
|
||||||
|
|
||||||
for (let i=0; i<nodes.length; i++) {
|
for (let i=0; i<nodes.length; i++) {
|
||||||
@ -49,6 +47,41 @@ class MessagingService {
|
|||||||
callback(document.location.href);
|
callback(document.location.href);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async GetMetaNodes(sender, callback) {
|
||||||
|
const a = this;
|
||||||
|
const nodes = await document.querySelectorAll("meta");
|
||||||
|
|
||||||
|
let result = [];
|
||||||
|
|
||||||
|
for (let i=0; i<nodes.length; i++) {
|
||||||
|
result.push({
|
||||||
|
content: (nodes[i].getAttribute("content") ?? ""),
|
||||||
|
name: (nodes[i].getAttribute("name") ?? ""),
|
||||||
|
httpEquiv: (nodes[i].getAttribute("http-equiv") ?? ""),
|
||||||
|
occurrence: 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await callback(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
async GetScriptNodes(sender, callback) {
|
||||||
|
const a = this;
|
||||||
|
const nodes = await document.querySelectorAll("script");
|
||||||
|
|
||||||
|
let result = [];
|
||||||
|
|
||||||
|
for (let i=0; i<nodes.length; i++) {
|
||||||
|
result.push({
|
||||||
|
src: (nodes[i].getAttribute("src") ?? ""),
|
||||||
|
type: (nodes[i].getAttribute("type") ?? ""),
|
||||||
|
occurrence: 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await callback(result);
|
||||||
|
}
|
||||||
|
|
||||||
#encodeHtml(htmlContent) {
|
#encodeHtml(htmlContent) {
|
||||||
const map = {
|
const map = {
|
||||||
"&": "&",
|
"&": "&",
|
||||||
@ -79,12 +112,3 @@ chrome.runtime.onMessage.addListener(async function(request, sender, callback) {
|
|||||||
await messageService[request.event](sender, callback);
|
await messageService[request.event](sender, callback);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// var optHideWatchedVideos = new Promise(function(resolve) {
|
|
||||||
// chrome.storage.local.get(['switch1'], function(result) {
|
|
||||||
// resolve(result.switch1);
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
|
File diff suppressed because one or more lines are too long
192
popup.html
192
popup.html
@ -21,12 +21,32 @@
|
|||||||
<button class="nav-link active" id="nav-home-tab" data-bs-toggle="tab" data-bs-target="#nav-home" type="button" role="tab" aria-controls="nav-home" aria-selected="true">Home</button>
|
<button class="nav-link active" id="nav-home-tab" data-bs-toggle="tab" data-bs-target="#nav-home" type="button" role="tab" aria-controls="nav-home" aria-selected="true">Home</button>
|
||||||
<button class="nav-link" id="nav-hyperlinks-tab" data-bs-toggle="tab" data-bs-target="#nav-hyperlinks" type="button" role="tab" aria-controls="nav-hyperlinks" aria-selected="false">Hyperlinks</button>
|
<button class="nav-link" id="nav-hyperlinks-tab" data-bs-toggle="tab" data-bs-target="#nav-hyperlinks" type="button" role="tab" aria-controls="nav-hyperlinks" aria-selected="false">Hyperlinks</button>
|
||||||
<button class="nav-link" id="nav-images-tab" data-bs-toggle="tab" data-bs-target="#nav-images" type="button" role="tab" aria-controls="nav-images" aria-selected="false">Images</button>
|
<button class="nav-link" id="nav-images-tab" data-bs-toggle="tab" data-bs-target="#nav-images" type="button" role="tab" aria-controls="nav-images" aria-selected="false">Images</button>
|
||||||
<button class="nav-link" id="nav-disabled-tab" data-bs-toggle="tab" data-bs-target="#nav-disabled" type="button" role="tab" aria-controls="nav-disabled" aria-selected="false" disabled>Disabled</button>
|
<button class="nav-link" id="nav-scripts-tab" data-bs-toggle="tab" data-bs-target="#nav-scripts" type="button" role="tab" aria-controls="nav-scripts" aria-selected="false">Scripts</button>
|
||||||
|
<button class="nav-link" id="nav-metas-tab" data-bs-toggle="tab" data-bs-target="#nav-metas" type="button" role="tab" aria-controls="nav-metas" aria-selected="false">Metas</button>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="tab-content" id="nav-tabContent">
|
<div class="tab-content" id="nav-tabContent">
|
||||||
<div class="tab-pane fade show active" id="nav-home" role="tabpanel" aria-labelledby="nav-home-tab" tabindex="0">...</div>
|
<div class="tab-pane fade show active" id="nav-home" role="tabpanel" aria-labelledby="nav-home-tab" tabindex="0">
|
||||||
<div class="tab-pane py-3 fade" id="nav-hyperlinks" role="tabpanel" aria-labelledby="nav-hyperlinks-tab" tabindex="0">
|
|
||||||
|
<div class="container-fluid py-4">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<img src="./icon128.png" class="mx-auto d-block" alt="Logo" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12 text-center">
|
||||||
|
<h3>Peji Inspektor</h3>
|
||||||
|
<p>
|
||||||
|
Peji Inspektor is a browser extension for finding nodes on a web page.
|
||||||
|
These nodes (or tags) can be filtered and searched to find hyperlinks, images and other assets.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="tab-pane py-3 fade" id="nav-hyperlinks" role="tabpanel" aria-labelledby="nav-hyperlinks-tab" tabindex="1">
|
||||||
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="pt-2 pb-2 mb-2 border-bottom">
|
<div class="pt-2 pb-2 mb-2 border-bottom">
|
||||||
@ -34,11 +54,11 @@
|
|||||||
<label for="textBox1" class="col-sm-2 col-form-label fw-bold">Search</label>
|
<label for="textBox1" class="col-sm-2 col-form-label fw-bold">Search</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<div class="input-group input-group-sm">
|
<div class="input-group input-group-sm">
|
||||||
<input type="text" class="form-control" role="textbox" id="textBox1" />
|
<input type="text" class="form-control" id="textBox1" />
|
||||||
|
|
||||||
<select class="form-select pe-0 input-group-text" name="comboBox1">
|
<select class="form-select pe-0 input-group-text">
|
||||||
<option value="anchor">Anchor</option>
|
<option value="text">Anchor</option>
|
||||||
<option value="link" selected>Link</option>
|
<option value="href" selected>Link</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<button type="button" class="btn btn-secondary input-group-text">✕</button>
|
<button type="button" class="btn btn-secondary input-group-text">✕</button>
|
||||||
@ -50,7 +70,7 @@
|
|||||||
<div class="col-5">
|
<div class="col-5">
|
||||||
<div class="input-group input-group-sm">
|
<div class="input-group input-group-sm">
|
||||||
<button class="btn btn-primary" type="button">Load Results</button>
|
<button class="btn btn-primary" type="button">Load Results</button>
|
||||||
<select class="form-select" name="comboBox2">
|
<select class="form-select">
|
||||||
<option value="table" selected>Table</option>
|
<option value="table" selected>Table</option>
|
||||||
<option value="csv">CSV</option>
|
<option value="csv">CSV</option>
|
||||||
<option value="links">Links</option>
|
<option value="links">Links</option>
|
||||||
@ -82,22 +102,13 @@
|
|||||||
<div class="row pb-2 mb-2 border-bottom"></div>
|
<div class="row pb-2 mb-2 border-bottom"></div>
|
||||||
|
|
||||||
<div class="row pt-2 mb-2">
|
<div class="row pt-2 mb-2">
|
||||||
<div class="col px-0">
|
<div class="col px-0" role="results"></div>
|
||||||
|
|
||||||
<table class="table table-bordered table-hover table-sm table-striped">
|
|
||||||
<thead></thead>
|
|
||||||
<tbody></tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<textarea class="form-control font-monospace text-sm px-1 py-1" rows="16"></textarea>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-pane fade" id="nav-images" role="tabpanel" aria-labelledby="nav-images-tab" tabindex="0">
|
<div class="tab-pane py-3 fade" id="nav-images" role="tabpanel" aria-labelledby="nav-images-tab" tabindex="2">
|
||||||
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="pt-2 pb-2 mb-2 border-bottom">
|
<div class="pt-2 pb-2 mb-2 border-bottom">
|
||||||
@ -105,9 +116,9 @@
|
|||||||
<label for="textBox2" class="col-sm-2 col-form-label fw-bold">Search</label>
|
<label for="textBox2" class="col-sm-2 col-form-label fw-bold">Search</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<div class="input-group input-group-sm">
|
<div class="input-group input-group-sm">
|
||||||
<input type="text" class="form-control" role="textbox" id="textBox2" />
|
<input type="text" class="form-control" id="textBox2" />
|
||||||
|
|
||||||
<select class="form-select pe-0 input-group-text" name="comboBox1">
|
<select class="form-select pe-0 input-group-text">
|
||||||
<option value="alt">Alternative Text</option>
|
<option value="alt">Alternative Text</option>
|
||||||
<option value="src" selected>Source</option>
|
<option value="src" selected>Source</option>
|
||||||
</select>
|
</select>
|
||||||
@ -121,7 +132,7 @@
|
|||||||
<div class="col-5">
|
<div class="col-5">
|
||||||
<div class="input-group input-group-sm">
|
<div class="input-group input-group-sm">
|
||||||
<button class="btn btn-primary" type="button">Load Results</button>
|
<button class="btn btn-primary" type="button">Load Results</button>
|
||||||
<select class="form-select" name="comboBox2">
|
<select class="form-select">
|
||||||
<option value="table" selected>Table</option>
|
<option value="table" selected>Table</option>
|
||||||
<option value="csv">CSV</option>
|
<option value="csv">CSV</option>
|
||||||
<option value="links">Links</option>
|
<option value="links">Links</option>
|
||||||
@ -153,22 +164,137 @@
|
|||||||
<div class="row pb-2 mb-2 border-bottom"></div>
|
<div class="row pb-2 mb-2 border-bottom"></div>
|
||||||
|
|
||||||
<div class="row pt-2 mb-2">
|
<div class="row pt-2 mb-2">
|
||||||
<div class="col px-0">
|
<div class="col px-0"role="results"></div>
|
||||||
|
|
||||||
<table class="table table-bordered table-hover table-sm table-striped">
|
|
||||||
<thead></thead>
|
|
||||||
<tbody></tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<textarea class="form-control font-monospace text-sm px-1 py-1" rows="16"></textarea>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-pane fade" id="nav-disabled" role="tabpanel" aria-labelledby="nav-disabled-tab" tabindex="0">...</div>
|
<div class="tab-pane py-3 fade" id="nav-scripts" role="tabpanel" aria-labelledby="nav-scripts-tab" tabindex="3">
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="pt-2 pb-2 mb-2 border-bottom">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<label for="textBox3" class="col-sm-2 col-form-label fw-bold">Search</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<div class="input-group input-group-sm">
|
||||||
|
<input type="text" class="form-control" id="textBox3" />
|
||||||
|
|
||||||
|
<select class="form-select pe-0 input-group-text">
|
||||||
|
<option value="type">Type</option>
|
||||||
|
<option value="src" selected>Source</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-secondary input-group-text">✕</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-2 mb-2">
|
||||||
|
<div class="col-2"></div>
|
||||||
|
<div class="col-5">
|
||||||
|
<div class="input-group input-group-sm">
|
||||||
|
<button class="btn btn-primary" type="button">Load Results</button>
|
||||||
|
<select class="form-select">
|
||||||
|
<option value="table" selected>Table</option>
|
||||||
|
<option value="csv">CSV</option>
|
||||||
|
<option value="links">Links</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-5 px-0">
|
||||||
|
<div class="pt-2" role="label"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="fw-bold clearfix cursor-pointer" data-bs-toggle="collapse" data-bs-target="#collapsPanel5" aria-expanded="false" aria-controls="collapsPanel5">⯈ Options</div>
|
||||||
|
<div class="row pb-2 mb-2 border-bottom collapse" id="collapsPanel5">
|
||||||
|
<div class="col-sm-2"></div>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<div class="row px-0" role="options"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="fw-bold clearfix cursor-pointer" data-bs-toggle="collapse" data-bs-target="#collapsPanel6" aria-expanded="false" aria-controls="collapsPanel6">⯈ Filters</div>
|
||||||
|
<div class="row collapse" id="collapsPanel6">
|
||||||
|
<div class="col-sm-2"></div>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<div class="row px-0" role="filters"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row pb-2 mb-2 border-bottom"></div>
|
||||||
|
|
||||||
|
<div class="row pt-2 mb-2">
|
||||||
|
<div class="col px-0"role="results"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="tab-pane py-3 fade" id="nav-metas" role="tabpanel" aria-labelledby="nav-metas-tab" tabindex="3">
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="pt-2 pb-2 mb-2 border-bottom">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<label for="textBox3" class="col-sm-2 col-form-label fw-bold">Search</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<div class="input-group input-group-sm">
|
||||||
|
<input type="text" class="form-control" id="textBox3" />
|
||||||
|
|
||||||
|
<select class="form-select pe-0 input-group-text">
|
||||||
|
<option value="content">Content</option>
|
||||||
|
<option value="name" selected>Name</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-secondary input-group-text">✕</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-2 mb-2">
|
||||||
|
<div class="col-2"></div>
|
||||||
|
<div class="col-5">
|
||||||
|
<div class="input-group input-group-sm">
|
||||||
|
<button type="button" class="btn btn-primary">Load Results</button>
|
||||||
|
<select class="form-select">
|
||||||
|
<option value="table" selected>Table</option>
|
||||||
|
<option value="csv">CSV</option>
|
||||||
|
<option value="links">Links</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-5 px-0">
|
||||||
|
<div class="pt-2" role="label"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="fw-bold clearfix cursor-pointer" data-bs-toggle="collapse" data-bs-target="#collapsPanel7" aria-expanded="false" aria-controls="collapsPanel7">⯈ Options</div>
|
||||||
|
<div class="row pb-2 mb-2 border-bottom collapse" id="collapsPanel7">
|
||||||
|
<div class="col-sm-2"></div>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<div class="row px-0" role="options"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="fw-bold clearfix cursor-pointer" data-bs-toggle="collapse" data-bs-target="#collapsPanel8" aria-expanded="false" aria-controls="collapsPanel8">⯈ Filters</div>
|
||||||
|
<div class="row collapse" id="collapsPanel8">
|
||||||
|
<div class="col-sm-2"></div>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<div class="row px-0" role="filters"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row pb-2 mb-2 border-bottom"></div>
|
||||||
|
|
||||||
|
<div class="row pt-2 mb-2">
|
||||||
|
<div class="col px-0"role="results"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,17 +1,23 @@
|
|||||||
// src/popup.js
|
// src/popup.js
|
||||||
import PopupService from './popup/popup-service.js';
|
import PopupService from './popup/popup-service.js';
|
||||||
import AContentService from './popup/acontent-service.js';
|
import AContentService from './popup/a-content-service.js';
|
||||||
import ImgContentService from './popup/imgcontent-service.js';
|
import ImgContentService from './popup/img-content-service.js';
|
||||||
|
import ScriptContentService from './popup/script-content-service.js';
|
||||||
|
import MetaContentService from './popup/meta-content-service.js';
|
||||||
|
|
||||||
|
|
||||||
const popupService = new PopupService();
|
const popupService = new PopupService();
|
||||||
const aContentService = new AContentService(popupService);
|
const aContentService = new AContentService(popupService);
|
||||||
const imgContentService = new ImgContentService(popupService);
|
const imgContentService = new ImgContentService(popupService);
|
||||||
|
const scriptContentService = new ScriptContentService(popupService);
|
||||||
|
const metaContentService = new MetaContentService(popupService);
|
||||||
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", async function(event) {
|
document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
|
|
||||||
aContentService.InitialiseComponents();
|
aContentService.InitialiseComponents();
|
||||||
imgContentService.InitialiseComponents();
|
imgContentService.InitialiseComponents();
|
||||||
|
scriptContentService.InitialiseComponents();
|
||||||
|
metaContentService.InitialiseComponents();
|
||||||
|
|
||||||
});
|
});
|
280
src/src/popup/a-content-service.js
Normal file
280
src/src/popup/a-content-service.js
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
import '../../../literyz-js/extensions.dist.js';
|
||||||
|
|
||||||
|
import TabContentService from './tab-content-service.js';
|
||||||
|
|
||||||
|
|
||||||
|
class AContentService extends TabContentService {
|
||||||
|
|
||||||
|
constructor(popupService) {
|
||||||
|
super(popupService);
|
||||||
|
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
a._containerId = "nav-hyperlinks";
|
||||||
|
a._optionsCol1 = [
|
||||||
|
{ id: 1, text: "Show Anchor as HTML", checked: false },
|
||||||
|
{ id: 4, text: "Resolve Relative URL", checked: false }
|
||||||
|
];
|
||||||
|
a._optionsCol2 = [
|
||||||
|
{ id: 3, text: "Sort By Anchor Text", checked: true },
|
||||||
|
{ id: 2, text: "Trim Anchor Text", checked: true }
|
||||||
|
];
|
||||||
|
a._filtersCol1 = [
|
||||||
|
{ id: 12, text: "Hide External Links", checked: true },
|
||||||
|
{ id: 5, text: "Hide Duplicates", checked: true },
|
||||||
|
{ id: 14, text: "Hide Blank Anchors", checked: true },
|
||||||
|
{ id: 15, text: "Hide Blank Links", checked: true },
|
||||||
|
{ id: 11, text: "Hide Fragments", checked: true },
|
||||||
|
{ id: 13, text: "Hide Mailto/Tel", checked: true },
|
||||||
|
{ id: 16, text: "Hide Javascript", checked: true }
|
||||||
|
];
|
||||||
|
a._filtersCol2 = [
|
||||||
|
{ id: 6, text: "Show Title", checked: true },
|
||||||
|
{ id: 7, text: "Show Target", checked: false },
|
||||||
|
{ id: 8, text: "Show Rel", checked: false },
|
||||||
|
{ id: 9, text: "Show Type", checked: false },
|
||||||
|
{ id: 10, text: "Show Count", checked: false }
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async _retrieveResult() {
|
||||||
|
return await this._popupService.GetHyperlinks();
|
||||||
|
}
|
||||||
|
|
||||||
|
async _filterResult(items) {
|
||||||
|
const a = this;
|
||||||
|
const currentUrl = await a._popupService.GetLocation();
|
||||||
|
const currentHostname = (new URL(currentUrl)).hostname;
|
||||||
|
|
||||||
|
let result = [];
|
||||||
|
|
||||||
|
for (let i=0; i<items.length; i++) {
|
||||||
|
const item = items[i];
|
||||||
|
|
||||||
|
// Hide fragments
|
||||||
|
if (a._getCheckBox(11)) {
|
||||||
|
if (item.href.startsWith("#")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide Blank Links
|
||||||
|
if (a._getCheckBox(15)) {
|
||||||
|
if (String.isNullOrWhitespace(item.href)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide mailto/tel
|
||||||
|
if (a._getCheckBox(13)) {
|
||||||
|
if (item.href.toLowerCase().startsWith("telno:") || item.href.toLowerCase().startsWith("mailto:")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide javascript
|
||||||
|
if (a._getCheckBox(16)) {
|
||||||
|
if (item.href.toLowerCase().startsWith("javascript:")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const absoluteUrl = new URL(item.href, currentUrl);
|
||||||
|
|
||||||
|
// Hide external links
|
||||||
|
if (a._getCheckBox(12)) {
|
||||||
|
if (currentHostname != absoluteUrl.hostname) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show anchor as html
|
||||||
|
let text = (a._getCheckBox(1) ? item.innerHTML : item.innerText);
|
||||||
|
|
||||||
|
// Hide Blank Anchors
|
||||||
|
if (a._getCheckBox(14)) {
|
||||||
|
if (String.isNullOrWhitespace(text)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve relative url
|
||||||
|
const href = (a._getCheckBox(4) ? absoluteUrl.href : item.href);
|
||||||
|
|
||||||
|
// Trim anchor text
|
||||||
|
if (a._getCheckBox(2)) {
|
||||||
|
text = text.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search term
|
||||||
|
if (!String.isNullOrWhitespace(a._textBox1.value)) {
|
||||||
|
if (a._getComboBox(1) == "href") {
|
||||||
|
if (!href.toLowerCase().includes(a._textBox1.value.toLowerCase())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!text.toLowerCase().includes(a._textBox1.value.toLowerCase())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push({
|
||||||
|
text: text,
|
||||||
|
href: href,
|
||||||
|
title: (a._getCheckBox(6) ? item.title : ""),
|
||||||
|
target: (a._getCheckBox(7) ? item.target : ""),
|
||||||
|
rel: (a._getCheckBox(8) ? item.rel : ""),
|
||||||
|
type: (a._getCheckBox(9) ? item.type : ""),
|
||||||
|
occurrence: ""
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show occurrence
|
||||||
|
if (a._getCheckBox(10)) {
|
||||||
|
// Calc occurrences, store in cache
|
||||||
|
let occurrenceCache = [];
|
||||||
|
for (let i=0; i<result.length; i++) {
|
||||||
|
const occurrence = result.filter(item => JSON.stringify(item) === JSON.stringify(result[i])).length;
|
||||||
|
|
||||||
|
occurrenceCache.push(occurrence);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update result with occurrence
|
||||||
|
for (let i=0; i<result.length; i++) {
|
||||||
|
result[i].occurrence = occurrenceCache[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide duplicates
|
||||||
|
if (a._getCheckBox(5)) {
|
||||||
|
result = result.distinct();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort by anchor text
|
||||||
|
if (a._getCheckBox(3)) {
|
||||||
|
result = result.orderBy("text");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderTable(results) {
|
||||||
|
const a = this;
|
||||||
|
const table = a._generateTable();
|
||||||
|
|
||||||
|
a._setHtml(a._panel3, table);
|
||||||
|
|
||||||
|
const thead = a._panel3.querySelectorAll("thead")[0];
|
||||||
|
const tbody = a._panel3.querySelectorAll("tbody")[0];
|
||||||
|
|
||||||
|
// Write thead
|
||||||
|
thead.innerHTML = "<tr>" + a.#generateTableHeader() + "</tr>";
|
||||||
|
|
||||||
|
// Write tbody
|
||||||
|
for (let i=0; i<results.length; i++) {
|
||||||
|
const item = results[i];
|
||||||
|
|
||||||
|
let row = [ item.text, item.href ];
|
||||||
|
|
||||||
|
if (a._getCheckBox(6)) {
|
||||||
|
row.push(item.title);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a._getCheckBox(7)) {
|
||||||
|
row.push(item.target);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a._getCheckBox(8)) {
|
||||||
|
row.push(item.rel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a._getCheckBox(9)) {
|
||||||
|
row.push(item.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a._getCheckBox(10)) {
|
||||||
|
row.push(item.occurrence);
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody.innerHTML += a.GenerateRow(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderCSV(results) {
|
||||||
|
const a = this;
|
||||||
|
const textarea = a._generateTextarea();
|
||||||
|
|
||||||
|
a._setHtml(a._panel3, textarea);
|
||||||
|
|
||||||
|
const tbody = a._panel3.querySelectorAll("textarea")[0];
|
||||||
|
|
||||||
|
for (let i=0; i<results.length; i++) {
|
||||||
|
const item = results[i];
|
||||||
|
|
||||||
|
let row = [ item.text, item.href ];
|
||||||
|
|
||||||
|
if (a._getCheckBox(6)) {
|
||||||
|
row.push(item.title);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a._getCheckBox(7)) {
|
||||||
|
row.push(item.target);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a._getCheckBox(8)) {
|
||||||
|
row.push(item.rel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a._getCheckBox(9)) {
|
||||||
|
row.push(item.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a._getCheckBox(10)) {
|
||||||
|
row.push(item.occurrence);
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody.value += a.GenerateCSVLine("\t", row);
|
||||||
|
tbody.value += "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderLinks(results) {
|
||||||
|
const a = this;
|
||||||
|
const textarea = a._generateTextarea();
|
||||||
|
|
||||||
|
a._setHtml(a._panel3, textarea);
|
||||||
|
|
||||||
|
const tbody = a._panel3.querySelectorAll("textarea")[0];
|
||||||
|
|
||||||
|
for (let i=0; i<results.length; i++) {
|
||||||
|
const item = results[i];
|
||||||
|
|
||||||
|
tbody.value += a.GenerateCSVLine("\t", [ item.href ]);
|
||||||
|
tbody.value += "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#generateTableHeader() {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
const columns1 = [
|
||||||
|
"Anchor Text",
|
||||||
|
"Address"
|
||||||
|
];
|
||||||
|
const columns2 = [
|
||||||
|
{ id: 6, name: "Title" },
|
||||||
|
{ id: 7, name: "Target" },
|
||||||
|
{ id: 8, name: "Rel" },
|
||||||
|
{ id: 9, name: "Type" },
|
||||||
|
{ id: 10, name: "Count" }
|
||||||
|
];
|
||||||
|
|
||||||
|
return a._generateTableHeader(columns1, columns2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default AContentService;
|
@ -1,502 +0,0 @@
|
|||||||
import '../../../literyz-js/extensions.dist.js';
|
|
||||||
|
|
||||||
import ContentService from './content-service.js';
|
|
||||||
|
|
||||||
|
|
||||||
class AContentService extends ContentService {
|
|
||||||
#containerPanel = null;
|
|
||||||
#popupService = null;
|
|
||||||
|
|
||||||
|
|
||||||
constructor(popupService) {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.#popupService = popupService;
|
|
||||||
}
|
|
||||||
|
|
||||||
InitialiseComponents() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
a.Clear();
|
|
||||||
|
|
||||||
a.#initialiseComponents_Options();
|
|
||||||
a.#initialiseComponents_Filters();
|
|
||||||
|
|
||||||
a.Button1.addEventListener('click', async function (e) {
|
|
||||||
a.Button2.disabled = true;
|
|
||||||
|
|
||||||
a.TextBox1.value = "";
|
|
||||||
|
|
||||||
await a.Search();
|
|
||||||
|
|
||||||
a.Button2.disabled = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
a.Button2.addEventListener('click', async function (e) {
|
|
||||||
a.Button2.disabled = true;
|
|
||||||
|
|
||||||
await a.Search();
|
|
||||||
|
|
||||||
a.Button2.disabled = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#initialiseComponents_Options() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
let col1 = "";
|
|
||||||
col1 += a.GenerateCheckBox(1, "Show Anchor as HTML", false);
|
|
||||||
col1 += a.GenerateCheckBox(4, "Resolve Relative URL", false);
|
|
||||||
|
|
||||||
let col2 = "";
|
|
||||||
col2 += a.GenerateCheckBox(3, "Sort By Anchor Text", true);
|
|
||||||
col2 += a.GenerateCheckBox(2, "Trim Anchor Text", true);
|
|
||||||
|
|
||||||
let html = a.GenerateCols(col1, col2);
|
|
||||||
|
|
||||||
a.SetHtml(a.Panel1, html);
|
|
||||||
}
|
|
||||||
|
|
||||||
#initialiseComponents_Filters() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
let col1 = "";
|
|
||||||
col1 += a.GenerateCheckBox(12, "Hide External Links", true);
|
|
||||||
col1 += a.GenerateCheckBox(5, "Hide Duplicates", true);
|
|
||||||
col1 += a.GenerateCheckBox(14, "Hide Blank Anchors", true);
|
|
||||||
col1 += a.GenerateCheckBox(15, "Hide Blank Links", true);
|
|
||||||
col1 += a.GenerateCheckBox(11, "Hide Fragments", true);
|
|
||||||
col1 += a.GenerateCheckBox(13, "Hide Mailto/Tel", true);
|
|
||||||
col1 += a.GenerateCheckBox(16, "Hide Javascript", true);
|
|
||||||
|
|
||||||
let col2 = "";
|
|
||||||
col2 += a.GenerateCheckBox(6, "Show Title", true);
|
|
||||||
col2 += a.GenerateCheckBox(7, "Show Target", false);
|
|
||||||
col2 += a.GenerateCheckBox(8, "Show Rel", false);
|
|
||||||
col2 += a.GenerateCheckBox(9, "Show Type", false);
|
|
||||||
col2 += a.GenerateCheckBox(10, "Show Count", false);
|
|
||||||
|
|
||||||
let html = a.GenerateCols(col1, col2);
|
|
||||||
|
|
||||||
a.SetHtml(a.Panel2, html);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
get Button1() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.Container.querySelectorAll("button")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
get Button2() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.Container.querySelectorAll("button")[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
get Container() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.#containerPanel == null) {
|
|
||||||
a.#containerPanel = document.getElementById("nav-hyperlinks");
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.#containerPanel;
|
|
||||||
}
|
|
||||||
|
|
||||||
get Label1() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.Container.querySelectorAll("[role='label']")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
get MemoBox1() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.Container.querySelectorAll("textarea")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
get Panel1() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.Container.querySelectorAll("div[role='options']")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
get Panel2() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.Container.querySelectorAll("div[role='filters']")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
get Table1() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.Container.querySelectorAll("table")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
get TextBox1() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.Container.querySelectorAll("input[role='textbox']")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Clear() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
a.Table1.style.display = 'none';
|
|
||||||
a.MemoBox1.style.display = 'none';
|
|
||||||
|
|
||||||
a.SetHtml(a.Panel1, "");
|
|
||||||
a.SetHtml(a.Panel2, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
async Search() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
a.Label1.innerText = "";
|
|
||||||
|
|
||||||
a.Table1.style.display = 'none';
|
|
||||||
a.MemoBox1.style.display = 'none';
|
|
||||||
|
|
||||||
const result = await a.#popupService.GetHyperlinks();
|
|
||||||
const totalCount = result.length;
|
|
||||||
|
|
||||||
const newResults = await a.#filterResult(result.copy());
|
|
||||||
|
|
||||||
if (newResults.length == totalCount) {
|
|
||||||
a.Label1.innerText = "Showing " + totalCount + " result" + (totalCount == 1 ? "" : "s");
|
|
||||||
} else {
|
|
||||||
a.Label1.innerText = "Showing " + newResults.length + " of " + totalCount + " result" + (totalCount == 1 ? "" : "s");
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (a.#getComboBox(2)) {
|
|
||||||
case "table":
|
|
||||||
a.#renderTable(newResults);
|
|
||||||
break;
|
|
||||||
case "csv":
|
|
||||||
a.#renderCSV(newResults);
|
|
||||||
break;
|
|
||||||
case "links":
|
|
||||||
a.#renderLinks(newResults);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async #filterResult(items) {
|
|
||||||
const a = this;
|
|
||||||
const currentUrl = await a.#popupService.GetLocation();
|
|
||||||
const currentHostname = (new URL(currentUrl)).hostname;
|
|
||||||
|
|
||||||
let result = [];
|
|
||||||
|
|
||||||
for (let i=0; i<items.length; i++) {
|
|
||||||
const item = items[i];
|
|
||||||
|
|
||||||
// Hide fragments
|
|
||||||
if (a.#getCheckBox(11)) {
|
|
||||||
if (item.href.startsWith("#")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide blank links
|
|
||||||
if (a.#getCheckBox(15)) {
|
|
||||||
if (String.isNullOrWhitespace(item.href)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide mailto/tel
|
|
||||||
if (a.#getCheckBox(13)) {
|
|
||||||
if (item.href.toLowerCase().startsWith("telno:") || item.href.toLowerCase().startsWith("mailto:")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide javascript
|
|
||||||
if (a.#getCheckBox(16)) {
|
|
||||||
if (item.href.toLowerCase().startsWith("javascript:")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const absoluteUrl = new URL(item.href, currentUrl);
|
|
||||||
|
|
||||||
// Hide external links
|
|
||||||
if (a.#getCheckBox(12)) {
|
|
||||||
if (currentHostname != absoluteUrl.hostname) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show anchor as html
|
|
||||||
let text = (a.#getCheckBox(1) ? item.innerHTML : item.innerText);
|
|
||||||
|
|
||||||
// Hide blank anchors
|
|
||||||
if (a.#getCheckBox(14)) {
|
|
||||||
if (String.isNullOrWhitespace(text)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve relative url
|
|
||||||
const href = (a.#getCheckBox(4) ? absoluteUrl.href : item.href);
|
|
||||||
|
|
||||||
// Trim anchor text
|
|
||||||
if (a.#getCheckBox(2)) {
|
|
||||||
text = text.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search term
|
|
||||||
if (!String.isNullOrWhitespace(a.TextBox1.value)) {
|
|
||||||
if (a.#getComboBox(1) == "anchor") {
|
|
||||||
if (!text.toLowerCase().includes(a.TextBox1.value.toLowerCase())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!href.toLowerCase().includes(a.TextBox1.value.toLowerCase())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result.push({
|
|
||||||
text: text,
|
|
||||||
href: href,
|
|
||||||
title: (a.#getCheckBox(6) ? item.title : ""),
|
|
||||||
target: (a.#getCheckBox(7) ? item.target : ""),
|
|
||||||
rel: (a.#getCheckBox(8) ? item.rel : ""),
|
|
||||||
type: (a.#getCheckBox(9) ? item.type : ""),
|
|
||||||
occurrence: ""
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show occurrence
|
|
||||||
if (a.#getCheckBox(10)) {
|
|
||||||
// Calc occurrences, store in cache
|
|
||||||
let occurrenceCache = [];
|
|
||||||
for (let i=0; i<result.length; i++) {
|
|
||||||
const occurrence = result.filter(item => JSON.stringify(item) === JSON.stringify(result[i])).length;
|
|
||||||
|
|
||||||
occurrenceCache.push(occurrence);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update result with occurrence
|
|
||||||
for (let i=0; i<result.length; i++) {
|
|
||||||
result[i].occurrence = occurrenceCache[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide duplicates
|
|
||||||
if (a.#getCheckBox(5)) {
|
|
||||||
result = result.distinct();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort by anchor text
|
|
||||||
if (a.#getCheckBox(3)) {
|
|
||||||
result = result.orderBy("text");
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#generateTHeader() {
|
|
||||||
const a = this;
|
|
||||||
const columns = [
|
|
||||||
{ id: 6, name: "Title" },
|
|
||||||
{ id: 7, name: "Target" },
|
|
||||||
{ id: 8, name: "Rel" },
|
|
||||||
{ id: 9, name: "Type" },
|
|
||||||
{ id: 10, name: "Count" }
|
|
||||||
];
|
|
||||||
|
|
||||||
let html = "";
|
|
||||||
html += "<th>Anchor Text</th>";
|
|
||||||
html += "<th>Address</th>";
|
|
||||||
|
|
||||||
for (let i=0; i<columns.length; i++) {
|
|
||||||
if (a.#getCheckBox(columns[i].id)) {
|
|
||||||
html += "<th>" + columns[i].name + "</th>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
#getCheckBox(num) {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = a.Container.querySelectorAll("input[name='checkbox" + num + "']");
|
|
||||||
if (result.length <= 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result[0].checked;
|
|
||||||
}
|
|
||||||
|
|
||||||
#getComboBox(num) {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = a.Container.querySelectorAll("select[name='comboBox" + num + "']");
|
|
||||||
if (result.length <= 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return result[0].value;
|
|
||||||
}
|
|
||||||
|
|
||||||
#getRadioGroup(num) {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = a.Container.querySelectorAll("input[name='radioGroup" + num + "']:checked");
|
|
||||||
if (result.length <= 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return result[0].value;
|
|
||||||
}
|
|
||||||
|
|
||||||
#renderTable(results) {
|
|
||||||
const a = this;
|
|
||||||
const thead = a.Table1.querySelectorAll("thead")[0];
|
|
||||||
const tbody = a.Table1.querySelectorAll("tbody")[0];
|
|
||||||
|
|
||||||
thead.innerHTML = "";
|
|
||||||
tbody.innerHTML = "";
|
|
||||||
|
|
||||||
a.Table1.style.display = 'table';
|
|
||||||
|
|
||||||
// Write thead
|
|
||||||
thead.innerHTML = "<tr>" + a.#generateTHeader() + "</tr>";
|
|
||||||
|
|
||||||
// Write tbody
|
|
||||||
for (let i=0; i<results.length; i++) {
|
|
||||||
const item = results[i];
|
|
||||||
|
|
||||||
let row = [ item.text, item.href ];
|
|
||||||
|
|
||||||
if (a.#getCheckBox(6)) {
|
|
||||||
row.push(item.title);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a.#getCheckBox(7)) {
|
|
||||||
row.push(item.target);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a.#getCheckBox(8)) {
|
|
||||||
row.push(item.rel);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a.#getCheckBox(9)) {
|
|
||||||
row.push(item.type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a.#getCheckBox(10)) {
|
|
||||||
row.push(item.occurrence);
|
|
||||||
}
|
|
||||||
|
|
||||||
tbody.innerHTML += a.GenerateRow(row);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#renderCSV(results) {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
a.MemoBox1.value = "";
|
|
||||||
a.MemoBox1.style.display = 'inline-block';
|
|
||||||
|
|
||||||
for (let i=0; i<results.length; i++) {
|
|
||||||
const item = results[i];
|
|
||||||
|
|
||||||
let row = [ item.text, item.href ];
|
|
||||||
|
|
||||||
if (a.#getCheckBox(6)) {
|
|
||||||
row.push(item.title);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a.#getCheckBox(7)) {
|
|
||||||
row.push(item.target);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a.#getCheckBox(8)) {
|
|
||||||
row.push(item.rel);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a.#getCheckBox(9)) {
|
|
||||||
row.push(item.type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a.#getCheckBox(10)) {
|
|
||||||
row.push(item.occurrence);
|
|
||||||
}
|
|
||||||
|
|
||||||
a.MemoBox1.value += a.GenerateCSVLine("\t", row);
|
|
||||||
a.MemoBox1.value += "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#renderLinks(results) {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
a.MemoBox1.value = "";
|
|
||||||
a.MemoBox1.style.display = 'inline-block';
|
|
||||||
|
|
||||||
for (let i=0; i<results.length; i++) {
|
|
||||||
const item = results[i];
|
|
||||||
|
|
||||||
a.MemoBox1.value += a.GenerateCSVLine("\t", [ item.href ]);
|
|
||||||
a.MemoBox1.value += "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default AContentService;
|
|
@ -1,27 +1,72 @@
|
|||||||
// import '../references/extensions.dist.js';
|
// import '../references/extensions.dist.js';
|
||||||
|
|
||||||
class ContentService {
|
class ContentService {
|
||||||
|
_popupService = null;
|
||||||
|
|
||||||
|
_containerId = null;
|
||||||
|
|
||||||
|
|
||||||
|
constructor(popupService) {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
a._popupService = popupService;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
get Container() {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
return document.getElementById(a._containerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get Panel1() {
|
||||||
|
// return this.#getElement("div[role='options']", 1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// get Panel2() {
|
||||||
|
// return this.#getElement("div[role='filters']", 1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// get Panel3() {
|
||||||
|
// return this.#getElement("div[role='results']", 1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// Clear(clearAll) {
|
||||||
|
// const a = this;
|
||||||
|
// const label1 = a._getLabel(1);
|
||||||
|
|
||||||
|
// label1.innerText = "";
|
||||||
|
|
||||||
|
// if (Boolean.isTrue(clearAll)) {
|
||||||
|
// a._setHtml(a.Panel1, "");
|
||||||
|
// a._setHtml(a.Panel2, "");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// a._setHtml(a.Panel3, "");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// async Search() {
|
||||||
|
// const a = this;
|
||||||
|
|
||||||
|
// a.Clear(false);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
GenerateCheckBox(num, label, checked) {
|
GenerateCheckBox(num, label, checked) {
|
||||||
|
const randId = Math.randomN(100001, 999999);
|
||||||
|
const id = "checkbox" + randId;
|
||||||
|
const name = "checkbox" + num;
|
||||||
|
|
||||||
let html = "";
|
let html = "";
|
||||||
html += "<div class=\"form-check form-switch\">";
|
html += "<div class=\"form-check form-switch\">";
|
||||||
html += "<input class=\"form-check-input\" type=\"checkbox\" role=\"switch\" id=\"checkbox" + num + "\" name=\"checkbox" + num + "\" " + (checked ? "checked" : "") + ">";
|
html += "<input class=\"form-check-input\" type=\"checkbox\" role=\"switch\" id=\"" + id + "\" name=\"" + name + "\" " + (checked ? "checked" : "") + ">";
|
||||||
html += "<label class=\"form-check-label\" for=\"checkbox" + num + "\">" + label + "</label>";
|
html += "<label class=\"form-check-label\" for=\"" + id + "\">" + label + "</label>";
|
||||||
html += "</div>";
|
html += "</div>";
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
GenerateCols(...args) {
|
|
||||||
let html = "";
|
|
||||||
|
|
||||||
for (let i=0; i<args.length; i++) {
|
|
||||||
html += "<div class=\"col\">" + args[i] + "</div>";
|
|
||||||
}
|
|
||||||
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
GenerateCSVLine(delimiter, ...args) {
|
GenerateCSVLine(delimiter, ...args) {
|
||||||
const a = this;
|
const a = this;
|
||||||
|
|
||||||
@ -43,15 +88,17 @@ class ContentService {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
GenerateRadioBox(groupNo, num, label, value, checked) {
|
// GenerateRadioBox(groupNo, num, label, value, checked) {
|
||||||
let html = "";
|
// const randId = Math.randomN(100001, 999999);
|
||||||
html += "<div class=\"form-check\">";
|
|
||||||
html += "<input class=\"form-check-input\" type=\"radio\" name=\"radioGroup" + groupNo + "\" id=\"radioBox" + num + "\" value=\"" + value + "\" " + (checked ? "checked" : "") + ">";
|
|
||||||
html += "<label class=\"form-check-label\" for=\"radioBox" + num + "\">" + label + "</label>";
|
|
||||||
html += "</div>";
|
|
||||||
|
|
||||||
return html;
|
// let html = "";
|
||||||
}
|
// html += "<div class=\"form-check\">";
|
||||||
|
// html += "<input class=\"form-check-input\" type=\"radio\" name=\"radioGroup" + groupNo + "\" id=\"radioBox" + randId + "\" value=\"" + value + "\" " + (checked ? "checked" : "") + ">";
|
||||||
|
// html += "<label class=\"form-check-label\" for=\"radioBox" + randId + "\">" + label + "</label>";
|
||||||
|
// html += "</div>";
|
||||||
|
|
||||||
|
// return html;
|
||||||
|
// }
|
||||||
|
|
||||||
GenerateRow(...args) {
|
GenerateRow(...args) {
|
||||||
const a = this;
|
const a = this;
|
||||||
@ -64,17 +111,113 @@ class ContentService {
|
|||||||
|
|
||||||
let result = "";
|
let result = "";
|
||||||
for (let i=0; i<args.length; i++) {
|
for (let i=0; i<args.length; i++) {
|
||||||
result = result + a.GenerateRowCell(args[i]);
|
result = result + a._generateTableCell(args[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return "<tr>" + result + "</tr>";
|
return "<tr>" + result + "</tr>";
|
||||||
}
|
}
|
||||||
|
|
||||||
GenerateRowCell(value) {
|
|
||||||
|
|
||||||
|
_generateCheckBoxPanel(col1, col2) {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
let colContent1 = "";
|
||||||
|
let colContent2 = "";
|
||||||
|
|
||||||
|
for (let i=0; i<col1.length; i++) {
|
||||||
|
colContent1 += a.GenerateCheckBox(col1[i].id, col1[i].text, col1[i].checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i=0; i<col2.length; i++) {
|
||||||
|
colContent2 += a.GenerateCheckBox(col2[i].id, col2[i].text, col2[i].checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
return a.#generateCols(colContent1, colContent2);
|
||||||
|
}
|
||||||
|
|
||||||
|
_generateTextarea() {
|
||||||
|
let html = "";
|
||||||
|
html += "<textarea class=\"form-control font-monospace text-sm px-1 py-1\" rows=\"16\"></textarea>";
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
_generateTable() {
|
||||||
|
let html = "";
|
||||||
|
html += "<table class=\"table table-bordered table-hover table-sm table-striped\">";
|
||||||
|
html += "<thead></thead>";
|
||||||
|
html += "<tbody></tbody>";
|
||||||
|
html += "</table>";
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
_generateTableCell(value) {
|
||||||
return "<td class=\"\"><input type=\"text\" class=\"display\" readonly=\"readonly\" value=\"" + value + "\" /></td>";
|
return "<td class=\"\"><input type=\"text\" class=\"display\" readonly=\"readonly\" value=\"" + value + "\" /></td>";
|
||||||
}
|
}
|
||||||
|
|
||||||
SetHtml(element, htmlContent) {
|
_generateTableHeader(fixedColumns, conditionalColumns) {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
let html = "";
|
||||||
|
for (let i=0; i<fixedColumns.length; i++) {
|
||||||
|
html += "<th>" + fixedColumns[i] + "</th>";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i=0; i<conditionalColumns.length; i++) {
|
||||||
|
if (!a._getCheckBox(conditionalColumns[i].id)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
html += "<th>" + conditionalColumns[i].name + "</th>";
|
||||||
|
}
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_getButton(num) {
|
||||||
|
return this.#getElement("button", num);
|
||||||
|
}
|
||||||
|
|
||||||
|
_getCheckBox(id) {
|
||||||
|
const a = this;
|
||||||
|
const name = "checkbox" + id;
|
||||||
|
|
||||||
|
const el = this.#getElement("input[type='checkbox'][name='" + name + "']", 1);
|
||||||
|
if (el == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return el.checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
_getComboBox(num) {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
const el = a.#getElement("select", num);
|
||||||
|
if (el == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return el.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
_getLabel(num) {
|
||||||
|
return this.#getElement("[role='label']", num);
|
||||||
|
}
|
||||||
|
|
||||||
|
_getPanel(name, num) {
|
||||||
|
return this.#getElement("div[role='" + name + "']", num);
|
||||||
|
}
|
||||||
|
|
||||||
|
_getTextBox(num) {
|
||||||
|
return this.#getElement("input[type='text']", num);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_setHtml(element, htmlContent) {
|
||||||
if (element == null) {
|
if (element == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -82,6 +225,36 @@ class ContentService {
|
|||||||
element.innerHTML = htmlContent;
|
element.innerHTML = htmlContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#generateCols(...args) {
|
||||||
|
let html = "";
|
||||||
|
|
||||||
|
for (let i=0; i<args.length; i++) {
|
||||||
|
html += "<div class=\"col\">" + args[i] + "</div>";
|
||||||
|
}
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
#getElement(nodeName, num) {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
if (a.Container == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nodes = a.Container.querySelectorAll(nodeName);
|
||||||
|
if (nodes.length <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodes.length > num) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodes[(num - 1)];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
233
src/src/popup/img-content-service.js
Normal file
233
src/src/popup/img-content-service.js
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
import TabContentService from './tab-content-service.js';
|
||||||
|
|
||||||
|
|
||||||
|
class ImgContentService extends TabContentService {
|
||||||
|
|
||||||
|
constructor(popupService) {
|
||||||
|
super(popupService);
|
||||||
|
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
a._containerId = "nav-images";
|
||||||
|
a._optionsCol1 = [
|
||||||
|
{ id: 203, text: "Sort By Source URL", checked: true },
|
||||||
|
{ id: 204, text: "Resolve Relative URL", checked: false }
|
||||||
|
];
|
||||||
|
a._optionsCol2 = [
|
||||||
|
{ id: 202, text: "Trim Alternate Text", checked: true }
|
||||||
|
];
|
||||||
|
a._filtersCol1 = [
|
||||||
|
{ id: 212, text: "Hide External Links", checked: false },
|
||||||
|
{ id: 205, text: "Hide Duplicates", checked: true },
|
||||||
|
{ id: 214, text: "Hide Blank Alternate Text", checked: false },
|
||||||
|
{ id: 215, text: "Hide Blank Source URL", checked: true }
|
||||||
|
];
|
||||||
|
a._filtersCol2 = [
|
||||||
|
{ id: 206, text: "Show Alternative Text", checked: true },
|
||||||
|
{ id: 207, text: "Show Source Set", checked: false },
|
||||||
|
{ id: 208, text: "Show Image Map", checked: false },
|
||||||
|
{ id: 210, text: "Show Count", checked: false }
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async _retrieveResult() {
|
||||||
|
return await this._popupService.GetImages();
|
||||||
|
}
|
||||||
|
|
||||||
|
async _filterResult(items) {
|
||||||
|
const a = this;
|
||||||
|
const currentUrl = await a._popupService.GetLocation();
|
||||||
|
const currentHostname = (new URL(currentUrl)).hostname;
|
||||||
|
|
||||||
|
let result = [];
|
||||||
|
|
||||||
|
for (let i=0; i<items.length; i++) {
|
||||||
|
const item = items[i];
|
||||||
|
|
||||||
|
// Hide source
|
||||||
|
if (a._getCheckBox(215)) {
|
||||||
|
if (String.isNullOrWhitespace(item.src)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const absoluteUrl = new URL(item.src, currentUrl);
|
||||||
|
|
||||||
|
// Hide external links
|
||||||
|
if (a._getCheckBox(212)) {
|
||||||
|
if (currentHostname != absoluteUrl.hostname) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide blank alternative text
|
||||||
|
if (a._getCheckBox(214)) {
|
||||||
|
if (String.isNullOrWhitespace(item.alt)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve source
|
||||||
|
const src = (a._getCheckBox(204) ? absoluteUrl.href : item.src);
|
||||||
|
const alt = (a._getCheckBox(202) ? item.alt.trim() : item.alt);
|
||||||
|
|
||||||
|
// Search term
|
||||||
|
if (!String.isNullOrWhitespace(a._textBox1.value)) {
|
||||||
|
if (a._getComboBox(1) == "src") {
|
||||||
|
if (!src.toLowerCase().includes(a._textBox1.value.toLowerCase())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!alt.toLowerCase().includes(a._textBox1.value.toLowerCase())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push({
|
||||||
|
src: src,
|
||||||
|
alt: (a._getCheckBox(206) ? alt : ""),
|
||||||
|
srcset: (a._getCheckBox(207) ? item.srcset : ""),
|
||||||
|
usemap: (a._getCheckBox(208) ? item.usemap : ""),
|
||||||
|
occurrence: ""
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show occurrence
|
||||||
|
if (a._getCheckBox(210)) {
|
||||||
|
// Calc occurrences, store in cache
|
||||||
|
let occurrenceCache = [];
|
||||||
|
for (let i=0; i<result.length; i++) {
|
||||||
|
const occurrence = result.filter(item => JSON.stringify(item) === JSON.stringify(result[i])).length;
|
||||||
|
|
||||||
|
occurrenceCache.push(occurrence);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update result with occurrence
|
||||||
|
for (let i=0; i<result.length; i++) {
|
||||||
|
result[i].occurrence = occurrenceCache[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide duplicates
|
||||||
|
if (a._getCheckBox(205)) {
|
||||||
|
result = result.distinct();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort by source
|
||||||
|
if (a._getCheckBox(203)) {
|
||||||
|
result = result.orderBy("src");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderTable(results) {
|
||||||
|
const a = this;
|
||||||
|
const table = a._generateTable();
|
||||||
|
|
||||||
|
a._setHtml(a._panel3, table);
|
||||||
|
|
||||||
|
const thead = a._panel3.querySelectorAll("thead")[0];
|
||||||
|
const tbody = a._panel3.querySelectorAll("tbody")[0];
|
||||||
|
|
||||||
|
// Write thead
|
||||||
|
thead.innerHTML = "<tr>" + a.#generateTableHeader() + "</tr>";
|
||||||
|
|
||||||
|
// Write tbody
|
||||||
|
for (let i=0; i<results.length; i++) {
|
||||||
|
const item = results[i];
|
||||||
|
|
||||||
|
let row = [ item.src ];
|
||||||
|
|
||||||
|
if (a._getCheckBox(206)) {
|
||||||
|
row.push(item.alt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a._getCheckBox(207)) {
|
||||||
|
row.push(item.srcset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a._getCheckBox(208)) {
|
||||||
|
row.push(item.usemap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a._getCheckBox(210)) {
|
||||||
|
row.push(item.occurrence);
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody.innerHTML += a.GenerateRow(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderCSV(results) {
|
||||||
|
const a = this;
|
||||||
|
const textarea = a._generateTextarea();
|
||||||
|
|
||||||
|
a._setHtml(a._panel3, textarea);
|
||||||
|
|
||||||
|
const tbody = a._panel3.querySelectorAll("textarea")[0];
|
||||||
|
|
||||||
|
for (let i=0; i<results.length; i++) {
|
||||||
|
const item = results[i];
|
||||||
|
|
||||||
|
let row = [ item.src ];
|
||||||
|
|
||||||
|
if (a._getCheckBox(206)) {
|
||||||
|
row.push(item.alt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a._getCheckBox(207)) {
|
||||||
|
row.push(item.srcset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a._getCheckBox(208)) {
|
||||||
|
row.push(item.usemap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a._getCheckBox(210)) {
|
||||||
|
row.push(item.occurrence);
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody.value += a.GenerateCSVLine("\t", row);
|
||||||
|
tbody.value += "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderLinks(results) {
|
||||||
|
const a = this;
|
||||||
|
const textarea = a._generateTextarea();
|
||||||
|
|
||||||
|
a._setHtml(a._panel3, textarea);
|
||||||
|
|
||||||
|
const tbody = a._panel3.querySelectorAll("textarea")[0];
|
||||||
|
|
||||||
|
for (let i=0; i<results.length; i++) {
|
||||||
|
const item = results[i];
|
||||||
|
|
||||||
|
tbody.value += a.GenerateCSVLine("\t", [ item.src ]);
|
||||||
|
tbody.value += "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#generateTableHeader() {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
const columns1 = [
|
||||||
|
"Source"
|
||||||
|
];
|
||||||
|
const columns2 = [
|
||||||
|
{ id: 206, name: "Alternative Text" },
|
||||||
|
{ id: 207, name: "Source Set" },
|
||||||
|
{ id: 208, name: "Image Map" },
|
||||||
|
{ id: 210, name: "Count" }
|
||||||
|
];
|
||||||
|
|
||||||
|
return a._generateTableHeader(columns1, columns2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default ImgContentService;
|
@ -1,444 +0,0 @@
|
|||||||
import '../../../literyz-js/extensions.dist.js';
|
|
||||||
|
|
||||||
import ContentService from './content-service.js';
|
|
||||||
|
|
||||||
|
|
||||||
class ImgContentService extends ContentService {
|
|
||||||
#containerPanel = null;
|
|
||||||
#popupService = null;
|
|
||||||
|
|
||||||
|
|
||||||
constructor(popupService) {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.#popupService = popupService;
|
|
||||||
}
|
|
||||||
|
|
||||||
InitialiseComponents() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
a.Clear();
|
|
||||||
|
|
||||||
a.#initialiseComponents_Options();
|
|
||||||
a.#initialiseComponents_Filters();
|
|
||||||
|
|
||||||
a.Button1.addEventListener('click', async function (e) {
|
|
||||||
a.Button2.disabled = true;
|
|
||||||
|
|
||||||
a.TextBox1.value = "";
|
|
||||||
|
|
||||||
await a.Search();
|
|
||||||
|
|
||||||
a.Button2.disabled = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
a.Button2.addEventListener('click', async function (e) {
|
|
||||||
a.Button2.disabled = true;
|
|
||||||
|
|
||||||
await a.Search();
|
|
||||||
|
|
||||||
a.Button2.disabled = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#initialiseComponents_Options() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
let col1 = "";
|
|
||||||
col1 += a.GenerateCheckBox(203, "Sort By Source URL", true);
|
|
||||||
col1 += a.GenerateCheckBox(204, "Resolve Relative URL", false);
|
|
||||||
|
|
||||||
let col2 = "";
|
|
||||||
col2 += a.GenerateCheckBox(202, "Trim Alternate Text", true);
|
|
||||||
|
|
||||||
let html = a.GenerateCols(col1, col2);
|
|
||||||
|
|
||||||
a.SetHtml(a.Panel1, html);
|
|
||||||
}
|
|
||||||
|
|
||||||
#initialiseComponents_Filters() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
let col1 = "";
|
|
||||||
col1 += a.GenerateCheckBox(212, "Hide External Links", false);
|
|
||||||
col1 += a.GenerateCheckBox(205, "Hide Duplicates", true);
|
|
||||||
col1 += a.GenerateCheckBox(214, "Hide Blank Alternate Text", false);
|
|
||||||
col1 += a.GenerateCheckBox(215, "Hide Blank Source URL", true);
|
|
||||||
|
|
||||||
let col2 = "";
|
|
||||||
col2 += a.GenerateCheckBox(206, "Show Alternative Text", true);
|
|
||||||
col2 += a.GenerateCheckBox(207, "Show Source Set", false);
|
|
||||||
col2 += a.GenerateCheckBox(208, "Show Image Map", false);
|
|
||||||
// col2 += a.GenerateCheckBox(209, "Show Width", false);
|
|
||||||
// col2 += a.GenerateCheckBox(210, "Show Height", false);
|
|
||||||
col2 += a.GenerateCheckBox(210, "Show Count", false);
|
|
||||||
|
|
||||||
let html = a.GenerateCols(col1, col2);
|
|
||||||
|
|
||||||
a.SetHtml(a.Panel2, html);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
get Button1() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.Container.querySelectorAll("button")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
get Button2() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.Container.querySelectorAll("button")[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
get Container() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.#containerPanel == null) {
|
|
||||||
a.#containerPanel = document.getElementById("nav-images");
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.#containerPanel;
|
|
||||||
}
|
|
||||||
|
|
||||||
get Label1() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.Container.querySelectorAll("[role='label']")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
get MemoBox1() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.Container.querySelectorAll("textarea")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
get Panel1() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.Container.querySelectorAll("div[role='options']")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
get Panel2() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.Container.querySelectorAll("div[role='filters']")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
get Table1() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.Container.querySelectorAll("table")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
get TextBox1() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.Container.querySelectorAll("input[role='textbox']")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Clear() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
a.Table1.style.display = 'none';
|
|
||||||
a.MemoBox1.style.display = 'none';
|
|
||||||
|
|
||||||
a.SetHtml(a.Panel1, "");
|
|
||||||
a.SetHtml(a.Panel2, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
async Search() {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
a.Label1.innerText = "";
|
|
||||||
|
|
||||||
a.Table1.style.display = 'none';
|
|
||||||
a.MemoBox1.style.display = 'none';
|
|
||||||
|
|
||||||
const result = await a.#popupService.GetImages();
|
|
||||||
const totalCount = result.length;
|
|
||||||
|
|
||||||
const newResults = await a.#filterResult(result.copy());
|
|
||||||
|
|
||||||
if (newResults.length == totalCount) {
|
|
||||||
a.Label1.innerText = "Showing " + totalCount + " result" + (totalCount == 1 ? "" : "s");
|
|
||||||
} else {
|
|
||||||
a.Label1.innerText = "Showing " + newResults.length + " of " + totalCount + " result" + (totalCount == 1 ? "" : "s");
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (a.#getComboBox(2)) {
|
|
||||||
case "table":
|
|
||||||
a.#renderTable(newResults);
|
|
||||||
break;
|
|
||||||
case "csv":
|
|
||||||
a.#renderCSV(newResults);
|
|
||||||
break;
|
|
||||||
case "links":
|
|
||||||
a.#renderLinks(newResults);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async #filterResult(items) {
|
|
||||||
const a = this;
|
|
||||||
const currentUrl = await a.#popupService.GetLocation();
|
|
||||||
const currentHostname = (new URL(currentUrl)).hostname;
|
|
||||||
|
|
||||||
let result = [];
|
|
||||||
|
|
||||||
for (let i=0; i<items.length; i++) {
|
|
||||||
const item = items[i];
|
|
||||||
|
|
||||||
// Hide source
|
|
||||||
if (a.#getCheckBox(215)) {
|
|
||||||
if (String.isNullOrWhitespace(item.src)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const absoluteUrl = new URL(item.src, currentUrl);
|
|
||||||
|
|
||||||
// Hide external links
|
|
||||||
if (a.#getCheckBox(212)) {
|
|
||||||
if (currentHostname != absoluteUrl.hostname) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide blank alternative text
|
|
||||||
if (a.#getCheckBox(214)) {
|
|
||||||
if (String.isNullOrWhitespace(item.alt)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve source
|
|
||||||
const src = (a.#getCheckBox(204) ? absoluteUrl.href : item.src);
|
|
||||||
const alt = (a.#getCheckBox(202) ? item.alt.trim() : item.alt);
|
|
||||||
|
|
||||||
// Search term
|
|
||||||
if (!String.isNullOrWhitespace(a.TextBox1.value)) {
|
|
||||||
if (a.#getComboBox(201) == "alt") {
|
|
||||||
if (!alt.toLowerCase().includes(a.TextBox1.value.toLowerCase())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!src.toLowerCase().includes(a.TextBox1.value.toLowerCase())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result.push({
|
|
||||||
src: src,
|
|
||||||
alt: (a.#getCheckBox(206) ? alt : ""),
|
|
||||||
srcset: (a.#getCheckBox(207) ? item.srcset : ""),
|
|
||||||
usemap: (a.#getCheckBox(208) ? item.usemap : ""),
|
|
||||||
occurrence: ""
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show occurrence
|
|
||||||
if (a.#getCheckBox(210)) {
|
|
||||||
// Calc occurrences, store in cache
|
|
||||||
let occurrenceCache = [];
|
|
||||||
for (let i=0; i<result.length; i++) {
|
|
||||||
const occurrence = result.filter(item => JSON.stringify(item) === JSON.stringify(result[i])).length;
|
|
||||||
|
|
||||||
occurrenceCache.push(occurrence);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update result with occurrence
|
|
||||||
for (let i=0; i<result.length; i++) {
|
|
||||||
result[i].occurrence = occurrenceCache[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide duplicates
|
|
||||||
if (a.#getCheckBox(205)) {
|
|
||||||
result = result.distinct();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort by source
|
|
||||||
if (a.#getCheckBox(203)) {
|
|
||||||
result = result.orderBy("src");
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#generateTHeader() {
|
|
||||||
const a = this;
|
|
||||||
const columns = [
|
|
||||||
{ id: 206, name: "Alternative Text" },
|
|
||||||
{ id: 207, name: "Source Set" },
|
|
||||||
{ id: 208, name: "Image Map" },
|
|
||||||
{ id: 210, name: "Count" }
|
|
||||||
];
|
|
||||||
|
|
||||||
let html = "";
|
|
||||||
html += "<th>Source</th>";
|
|
||||||
|
|
||||||
for (let i=0; i<columns.length; i++) {
|
|
||||||
if (a.#getCheckBox(columns[i].id)) {
|
|
||||||
html += "<th>" + columns[i].name + "</th>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
#getCheckBox(num) {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = a.Container.querySelectorAll("input[name='checkbox" + num + "']");
|
|
||||||
if (result.length <= 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result[0].checked;
|
|
||||||
}
|
|
||||||
|
|
||||||
#getComboBox(num) {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
if (a.Container == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = a.Container.querySelectorAll("select[name='comboBox" + num + "']");
|
|
||||||
if (result.length <= 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return result[0].value;
|
|
||||||
}
|
|
||||||
|
|
||||||
#renderTable(results) {
|
|
||||||
const a = this;
|
|
||||||
const thead = a.Table1.querySelectorAll("thead")[0];
|
|
||||||
const tbody = a.Table1.querySelectorAll("tbody")[0];
|
|
||||||
|
|
||||||
thead.innerHTML = "";
|
|
||||||
tbody.innerHTML = "";
|
|
||||||
|
|
||||||
a.Table1.style.display = 'table';
|
|
||||||
|
|
||||||
// Write thead
|
|
||||||
thead.innerHTML = "<tr>" + a.#generateTHeader() + "</tr>";
|
|
||||||
|
|
||||||
// Write tbody
|
|
||||||
for (let i=0; i<results.length; i++) {
|
|
||||||
const item = results[i];
|
|
||||||
|
|
||||||
let row = [ item.src ];
|
|
||||||
|
|
||||||
if (a.#getCheckBox(206)) {
|
|
||||||
row.push(item.alt);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a.#getCheckBox(207)) {
|
|
||||||
row.push(item.srcset);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a.#getCheckBox(208)) {
|
|
||||||
row.push(item.usemap);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a.#getCheckBox(210)) {
|
|
||||||
row.push(item.occurrence);
|
|
||||||
}
|
|
||||||
|
|
||||||
tbody.innerHTML += a.GenerateRow(row);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#renderCSV(results) {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
a.MemoBox1.value = "";
|
|
||||||
a.MemoBox1.style.display = 'inline-block';
|
|
||||||
|
|
||||||
for (let i=0; i<results.length; i++) {
|
|
||||||
const item = results[i];
|
|
||||||
|
|
||||||
let row = [ item.src ];
|
|
||||||
|
|
||||||
if (a.#getCheckBox(206)) {
|
|
||||||
row.push(item.alt);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a.#getCheckBox(207)) {
|
|
||||||
row.push(item.srcset);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a.#getCheckBox(208)) {
|
|
||||||
row.push(item.usemap);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a.#getCheckBox(210)) {
|
|
||||||
row.push(item.occurrence);
|
|
||||||
}
|
|
||||||
|
|
||||||
a.MemoBox1.value += a.GenerateCSVLine("\t", row);
|
|
||||||
a.MemoBox1.value += "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#renderLinks(results) {
|
|
||||||
const a = this;
|
|
||||||
|
|
||||||
a.MemoBox1.value = "";
|
|
||||||
a.MemoBox1.style.display = 'inline-block';
|
|
||||||
|
|
||||||
for (let i=0; i<results.length; i++) {
|
|
||||||
const item = results[i];
|
|
||||||
|
|
||||||
a.MemoBox1.value += a.GenerateCSVLine("\t", [ item.src ]);
|
|
||||||
a.MemoBox1.value += "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default ImgContentService;
|
|
188
src/src/popup/meta-content-service.js
Normal file
188
src/src/popup/meta-content-service.js
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
import TabContentService from './tab-content-service.js';
|
||||||
|
|
||||||
|
|
||||||
|
class MetaContentService extends TabContentService {
|
||||||
|
|
||||||
|
constructor(popupService) {
|
||||||
|
super(popupService);
|
||||||
|
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
a._containerId = "nav-metas";
|
||||||
|
a._optionsCol1 = [
|
||||||
|
{ id: 303, text: "Sort By Name", checked: true }
|
||||||
|
];
|
||||||
|
a._optionsCol2 = [
|
||||||
|
{ id: 302, text: "Trim Content", checked: true }
|
||||||
|
];
|
||||||
|
a._filtersCol1 = [
|
||||||
|
{ id: 305, text: "Hide Duplicates", checked: true },
|
||||||
|
{ id: 314, text: "Hide Blank Name", checked: false },
|
||||||
|
{ id: 315, text: "Hide Blank Content", checked: true }
|
||||||
|
];
|
||||||
|
a._filtersCol2 = [
|
||||||
|
{ id: 310, text: "Show Count", checked: false }
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async _retrieveResult() {
|
||||||
|
return await this._popupService.GetMetas();
|
||||||
|
}
|
||||||
|
|
||||||
|
async _filterResult(items) {
|
||||||
|
const a = this;
|
||||||
|
const currentUrl = await a._popupService.GetLocation();
|
||||||
|
|
||||||
|
let result = [];
|
||||||
|
|
||||||
|
for (let i=0; i<items.length; i++) {
|
||||||
|
const item = items[i];
|
||||||
|
|
||||||
|
const content = (a._getCheckBox(302) ? item.content.trim() : item.content);
|
||||||
|
|
||||||
|
// Hide source
|
||||||
|
if (a._getCheckBox(315)) {
|
||||||
|
if (String.isNullOrWhitespace(content)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide blank type
|
||||||
|
if (a._getCheckBox(314)) {
|
||||||
|
if (String.isNullOrWhitespace(item.name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search term
|
||||||
|
if (!String.isNullOrWhitespace(a._textBox1.value)) {
|
||||||
|
if (a._getComboBox(1) == "name") {
|
||||||
|
if (!item.name.toLowerCase().includes(a._textBox1.value.toLowerCase())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!content.toLowerCase().includes(a._textBox1.value.toLowerCase())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push({
|
||||||
|
name: item.name,
|
||||||
|
content: content,
|
||||||
|
occurrence: ""
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show occurrence
|
||||||
|
if (a._getCheckBox(310)) {
|
||||||
|
// Calc occurrences, store in cache
|
||||||
|
let occurrenceCache = [];
|
||||||
|
for (let i=0; i<result.length; i++) {
|
||||||
|
const occurrence = result.filter(item => JSON.stringify(item) === JSON.stringify(result[i])).length;
|
||||||
|
|
||||||
|
occurrenceCache.push(occurrence);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update result with occurrence
|
||||||
|
for (let i=0; i<result.length; i++) {
|
||||||
|
result[i].occurrence = occurrenceCache[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide duplicates
|
||||||
|
if (a._getCheckBox(305)) {
|
||||||
|
result = result.distinct();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort by name
|
||||||
|
if (a._getCheckBox(303)) {
|
||||||
|
result = result.orderBy("name");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderTable(results) {
|
||||||
|
const a = this;
|
||||||
|
const table = a._generateTable();
|
||||||
|
|
||||||
|
a._setHtml(a._panel3, table);
|
||||||
|
|
||||||
|
const thead = a._panel3.querySelectorAll("thead")[0];
|
||||||
|
const tbody = a._panel3.querySelectorAll("tbody")[0];
|
||||||
|
|
||||||
|
// Write thead
|
||||||
|
thead.innerHTML = "<tr>" + a.#generateTableHeader() + "</tr>";
|
||||||
|
|
||||||
|
// Write tbody
|
||||||
|
for (let i=0; i<results.length; i++) {
|
||||||
|
const item = results[i];
|
||||||
|
|
||||||
|
let row = [ item.name, item.content ];
|
||||||
|
|
||||||
|
if (a._getCheckBox(310)) {
|
||||||
|
row.push(item.occurrence);
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody.innerHTML += a.GenerateRow(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderCSV(results) {
|
||||||
|
const a = this;
|
||||||
|
const textarea = a._generateTextarea();
|
||||||
|
|
||||||
|
a._setHtml(a._panel3, textarea);
|
||||||
|
|
||||||
|
const tbody = a._panel3.querySelectorAll("textarea")[0];
|
||||||
|
|
||||||
|
for (let i=0; i<results.length; i++) {
|
||||||
|
const item = results[i];
|
||||||
|
|
||||||
|
let row = [ item.name, item.content ];
|
||||||
|
|
||||||
|
if (a._getCheckBox(310)) {
|
||||||
|
row.push(item.occurrence);
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody.value += a.GenerateCSVLine("\t", row);
|
||||||
|
tbody.value += "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderLinks(results) {
|
||||||
|
const a = this;
|
||||||
|
const textarea = a._generateTextarea();
|
||||||
|
|
||||||
|
a._setHtml(a._panel3, textarea);
|
||||||
|
|
||||||
|
const tbody = a._panel3.querySelectorAll("textarea")[0];
|
||||||
|
|
||||||
|
for (let i=0; i<results.length; i++) {
|
||||||
|
const item = results[i];
|
||||||
|
|
||||||
|
tbody.value += a.GenerateCSVLine("\t", [ item.content ]);
|
||||||
|
tbody.value += "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#generateTableHeader() {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
const columns1 = [
|
||||||
|
"Name",
|
||||||
|
"Content"
|
||||||
|
];
|
||||||
|
const columns2 = [
|
||||||
|
{ id: 310, name: "Count" }
|
||||||
|
];
|
||||||
|
|
||||||
|
return a._generateTableHeader(columns1, columns2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default MetaContentService;
|
@ -17,7 +17,6 @@ class PopupService {
|
|||||||
resolve(payload.copy());
|
resolve(payload.copy());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async GetImages() {
|
async GetImages() {
|
||||||
@ -28,7 +27,16 @@ class PopupService {
|
|||||||
resolve(payload.copy());
|
resolve(payload.copy());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async GetScripts() {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
return new Promise(function(resolve) {
|
||||||
|
a.SendMessage("GetScriptNodes", async function(payload) {
|
||||||
|
resolve(payload.copy());
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async GetLocation() {
|
async GetLocation() {
|
||||||
@ -41,6 +49,16 @@ class PopupService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async GetMetas() {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
return new Promise(function(resolve) {
|
||||||
|
a.SendMessage("GetMetaNodes", async function(payload) {
|
||||||
|
resolve(payload.copy());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
211
src/src/popup/script-content-service.js
Normal file
211
src/src/popup/script-content-service.js
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
import TabContentService from './tab-content-service.js';
|
||||||
|
|
||||||
|
|
||||||
|
class ScriptContentService extends TabContentService {
|
||||||
|
|
||||||
|
constructor(popupService) {
|
||||||
|
super(popupService);
|
||||||
|
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
a._containerId = "nav-scripts";
|
||||||
|
a._optionsCol1 = [
|
||||||
|
{ id: 303, text: "Sort By Source URL", checked: true },
|
||||||
|
{ id: 304, text: "Resolve Relative URL", checked: false }
|
||||||
|
];
|
||||||
|
a._optionsCol2 = [
|
||||||
|
{ id: 302, text: "Trim Alternate Type", checked: true }
|
||||||
|
];
|
||||||
|
a._filtersCol1 = [
|
||||||
|
{ id: 312, text: "Hide External Links", checked: false },
|
||||||
|
{ id: 305, text: "Hide Duplicates", checked: true },
|
||||||
|
{ id: 314, text: "Hide Blank Type", checked: false },
|
||||||
|
{ id: 315, text: "Hide Blank Source URL", checked: true }
|
||||||
|
];
|
||||||
|
a._filtersCol2 = [
|
||||||
|
{ id: 306, text: "Show Type", checked: true },
|
||||||
|
{ id: 310, text: "Show Count", checked: false }
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async _retrieveResult() {
|
||||||
|
return await this._popupService.GetScripts();
|
||||||
|
}
|
||||||
|
|
||||||
|
async _filterResult(items) {
|
||||||
|
const a = this;
|
||||||
|
const currentUrl = await a._popupService.GetLocation();
|
||||||
|
const currentHostname = (new URL(currentUrl)).hostname;
|
||||||
|
|
||||||
|
let result = [];
|
||||||
|
|
||||||
|
for (let i=0; i<items.length; i++) {
|
||||||
|
const item = items[i];
|
||||||
|
|
||||||
|
// Hide source
|
||||||
|
if (a._getCheckBox(315)) {
|
||||||
|
if (String.isNullOrWhitespace(item.src)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const absoluteUrl = new URL(item.src, currentUrl);
|
||||||
|
|
||||||
|
// Hide external links
|
||||||
|
if (a._getCheckBox(312)) {
|
||||||
|
if (currentHostname != absoluteUrl.hostname) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide blank type
|
||||||
|
if (a._getCheckBox(314)) {
|
||||||
|
if (String.isNullOrWhitespace(item.type)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve source
|
||||||
|
const src = (a._getCheckBox(304) ? absoluteUrl.href : item.src);
|
||||||
|
const type = (a._getCheckBox(302) ? item.type.trim() : item.type);
|
||||||
|
|
||||||
|
// Search term
|
||||||
|
if (!String.isNullOrWhitespace(a._textBox1.value)) {
|
||||||
|
if (a._getComboBox(1) == "src") {
|
||||||
|
if (!src.toLowerCase().includes(a._textBox1.value.toLowerCase())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!type.toLowerCase().includes(a._textBox1.value.toLowerCase())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push({
|
||||||
|
src: src,
|
||||||
|
type: (a._getCheckBox(306) ? type : ""),
|
||||||
|
occurrence: ""
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show occurrence
|
||||||
|
if (a._getCheckBox(310)) {
|
||||||
|
// Calc occurrences, store in cache
|
||||||
|
let occurrenceCache = [];
|
||||||
|
for (let i=0; i<result.length; i++) {
|
||||||
|
const occurrence = result.filter(item => JSON.stringify(item) === JSON.stringify(result[i])).length;
|
||||||
|
|
||||||
|
occurrenceCache.push(occurrence);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update result with occurrence
|
||||||
|
for (let i=0; i<result.length; i++) {
|
||||||
|
result[i].occurrence = occurrenceCache[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide duplicates
|
||||||
|
if (a._getCheckBox(305)) {
|
||||||
|
result = result.distinct();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort by source
|
||||||
|
if (a._getCheckBox(303)) {
|
||||||
|
result = result.orderBy("src");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderTable(results) {
|
||||||
|
const a = this;
|
||||||
|
const table = a._generateTable();
|
||||||
|
|
||||||
|
a._setHtml(a._panel3, table);
|
||||||
|
|
||||||
|
const thead = a._panel3.querySelectorAll("thead")[0];
|
||||||
|
const tbody = a._panel3.querySelectorAll("tbody")[0];
|
||||||
|
|
||||||
|
// Write thead
|
||||||
|
thead.innerHTML = "<tr>" + a.#generateTableHeader() + "</tr>";
|
||||||
|
|
||||||
|
// Write tbody
|
||||||
|
for (let i=0; i<results.length; i++) {
|
||||||
|
const item = results[i];
|
||||||
|
|
||||||
|
let row = [ item.src ];
|
||||||
|
|
||||||
|
if (a._getCheckBox(306)) {
|
||||||
|
row.push(item.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a._getCheckBox(310)) {
|
||||||
|
row.push(item.occurrence);
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody.innerHTML += a.GenerateRow(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderCSV(results) {
|
||||||
|
const a = this;
|
||||||
|
const textarea = a._generateTextarea();
|
||||||
|
|
||||||
|
a._setHtml(a._panel3, textarea);
|
||||||
|
|
||||||
|
const tbody = a._panel3.querySelectorAll("textarea")[0];
|
||||||
|
|
||||||
|
for (let i=0; i<results.length; i++) {
|
||||||
|
const item = results[i];
|
||||||
|
|
||||||
|
let row = [ item.src ];
|
||||||
|
|
||||||
|
if (a._getCheckBox(306)) {
|
||||||
|
row.push(item.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a._getCheckBox(310)) {
|
||||||
|
row.push(item.occurrence);
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody.value += a.GenerateCSVLine("\t", row);
|
||||||
|
tbody.value += "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderLinks(results) {
|
||||||
|
const a = this;
|
||||||
|
const textarea = a._generateTextarea();
|
||||||
|
|
||||||
|
a._setHtml(a._panel3, textarea);
|
||||||
|
|
||||||
|
const tbody = a._panel3.querySelectorAll("textarea")[0];
|
||||||
|
|
||||||
|
for (let i=0; i<results.length; i++) {
|
||||||
|
const item = results[i];
|
||||||
|
|
||||||
|
tbody.value += a.GenerateCSVLine("\t", [ item.src ]);
|
||||||
|
tbody.value += "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#generateTableHeader() {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
const columns1 = [
|
||||||
|
"Source"
|
||||||
|
];
|
||||||
|
const columns2 = [
|
||||||
|
{ id: 306, name: "Type" },
|
||||||
|
{ id: 310, name: "Count" }
|
||||||
|
];
|
||||||
|
|
||||||
|
return a._generateTableHeader(columns1, columns2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default ScriptContentService;
|
129
src/src/popup/tab-content-service.js
Normal file
129
src/src/popup/tab-content-service.js
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
import ContentService from './content-service.js';
|
||||||
|
|
||||||
|
|
||||||
|
class TabContentService extends ContentService {
|
||||||
|
_button1 = null;
|
||||||
|
_button2 = null;
|
||||||
|
_label1 = null;
|
||||||
|
_panel1 = null;
|
||||||
|
_panel2 = null;
|
||||||
|
_panel3 = null;
|
||||||
|
_textBox1 = null;
|
||||||
|
|
||||||
|
_optionsCol1 = [];
|
||||||
|
_optionsCol2 = [];
|
||||||
|
_filtersCol1 = [];
|
||||||
|
_filtersCol2 = [];
|
||||||
|
|
||||||
|
|
||||||
|
constructor(popupService) {
|
||||||
|
super(popupService);
|
||||||
|
}
|
||||||
|
|
||||||
|
InitialiseComponents() {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
const buttons = a.Container.querySelectorAll("button");
|
||||||
|
a._button1 = buttons[0];
|
||||||
|
a._button2 = buttons[1];
|
||||||
|
a._label1 = a._getLabel(1);
|
||||||
|
a._panel1 = a._getPanel("options", 1);
|
||||||
|
a._panel2 = a._getPanel("filters", 1);
|
||||||
|
a._panel3 = a._getPanel("results", 1);
|
||||||
|
a._textBox1 = a._getTextBox(1);
|
||||||
|
|
||||||
|
a.Clear(true);
|
||||||
|
|
||||||
|
// Initialise options
|
||||||
|
const htmlContent1 = a._generateCheckBoxPanel(a._optionsCol1, a._optionsCol2);
|
||||||
|
|
||||||
|
a._setHtml(a._panel1, htmlContent1);
|
||||||
|
|
||||||
|
// Initialise filters
|
||||||
|
const htmlContent2 = a._generateCheckBoxPanel(a._filtersCol1, a._filtersCol2);
|
||||||
|
|
||||||
|
a._setHtml(a._panel2, htmlContent2);
|
||||||
|
|
||||||
|
// Events
|
||||||
|
a._button1.addEventListener('click', async function (e) {
|
||||||
|
a._button2.disabled = true;
|
||||||
|
|
||||||
|
a._textBox1.value = "";
|
||||||
|
|
||||||
|
await a.Search();
|
||||||
|
|
||||||
|
a._button2.disabled = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
a._button2.addEventListener('click', async function (e) {
|
||||||
|
a._button2.disabled = true;
|
||||||
|
|
||||||
|
await a.Search();
|
||||||
|
|
||||||
|
a._button2.disabled = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Clear(clearAll) {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
a._label1.innerText = "";
|
||||||
|
|
||||||
|
if (Boolean.isTrue(clearAll)) {
|
||||||
|
a._setHtml(a._panel1, "");
|
||||||
|
a._setHtml(a._panel2, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
a._setHtml(a._panel3, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
async Search() {
|
||||||
|
const a = this;
|
||||||
|
|
||||||
|
const result = await a._retrieveResult();
|
||||||
|
const totalCount = result.length;
|
||||||
|
|
||||||
|
const newResults = await a._filterResult(result.copy());
|
||||||
|
|
||||||
|
if (newResults.length == totalCount) {
|
||||||
|
a._label1.innerText = "Showing " + totalCount + " result" + (totalCount == 1 ? "" : "s");
|
||||||
|
} else {
|
||||||
|
a._label1.innerText = "Showing " + newResults.length + " of " + totalCount + " result" + (totalCount == 1 ? "" : "s");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (a._getComboBox(2)) {
|
||||||
|
case "table":
|
||||||
|
a._renderTable(newResults);
|
||||||
|
break;
|
||||||
|
case "csv":
|
||||||
|
a._renderCSV(newResults);
|
||||||
|
break;
|
||||||
|
case "links":
|
||||||
|
a._renderLinks(newResults);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async _retrieveResult() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
async _filterResult(result) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderTable(result) {
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderCSV(result) {
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderLinks(result) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default TabContentService;
|
Loading…
Reference in New Issue
Block a user