import { LitElement, html, css } from 'lit-element'; import { wrapCss, clickOnSpacebarPress } from './misc'; import { getReplayLink } from './pageutils'; import fasSearch from '@fortawesome/fontawesome-free/svgs/solid/search.svg'; import "keyword-mark-element/lib/keyword-mark.js"; // =========================================================================== class URLResources extends LitElement { static get filters() { return [ {name: "HTML", filter: ""}, //default {name: "Images", filter: "image/"}, {name: "Audio/Video", filter: "audio/,video/"}, {name: "PDF", filter: "application/pdf"}, {name: "Javascript", filter: "application/javascript,application/x-javascript"}, {name: "CSS", filter: "text/css"}, {name: "Fonts", filter: "font/,application/font-woff"}, {name: "Plain Text", filter: "text/plain"}, {name: "JSON", filter: "application/json"}, {name: "DASH/HLS", filter: "application/dash+xml,application/x-mpegURL,application/vnd.apple.mpegurl"}, {name: "All URLs", filter: "all"} ]; } static get sortKeys() { return [ { "key": "url", "name": "URL" }, { "key": "ts", "name": "Date" }, { "key": "mime", "name": "Mime Type", }, { "key": "status", "name": "Status" } ]; } constructor() { super(); this.collInfo = null; this.isSidebar = false; this.currMime = ""; this.query = ""; this.urlSearchType = ""; this.filteredResults = []; this.sortedResults = []; this.results = []; this.newQuery = null; this.tryMore = false; this.loading = false; this.sortKey = "url"; this.sortDesc = false; } static get properties() { return { collInfo: { type: Object }, isSidebar: { type: Boolean }, currMime: { type: String }, query: { type: String }, urlSearchType: { type: String }, filteredResults: { type: Array }, sortedResults: { type: Array }, loading: { type: Boolean }, sortKey: { type: String }, sortDesc: { type: Boolean } } } firstUpdated() { //this.doLoadResources(); if (this.urlSearchType === "") { this.urlSearchType = "prefix"; } } _timedUpdate() { if (this.newQuery !== null) { this.query = this.newQuery; this.newQuery = null; } } updated(changedProperties) { if (changedProperties.has("query") || changedProperties.has("urlSearchType") || changedProperties.has("currMime")) { this.doLoadResources(); const data = { query: this.query, urlSearchType: this.urlSearchType, currMime: this.currMime }; const replaceLoc = !changedProperties.has("currMime") && !changedProperties.has("urlSearchType"); this.dispatchEvent(new CustomEvent("coll-tab-nav", {detail: {replaceLoc, data}})); } if (changedProperties.has("sortKey") || changedProperties.has("sortDesc")) { this.filter(); } } async doLoadResources(isMore = false) { const count = 100; if (isMore && (!this.tryMore || !this.results.length)) { return; } if (this.loading) { return; } this.loading = true; let url = (this.urlSearchType !== "contains" ? this.query : ""); const prefix = url && this.urlSearchType === "prefix" ? 1 : 0; // optimization: if not starting with http, likely won't have a match here, so just add https:// if (url && !url.startsWith("http")) { url = "https://" + url; } let mime; switch (this.currMime) { case "all": mime = ""; break; case "": mime = "text/html,text/xhtml"; break; default: mime = this.currMime; } const params = new URLSearchParams({ mime, url, prefix, count }); if (isMore) { const last = this.results[this.results.length - 1]; params.set("fromMime", last.mime); params.set("fromUrl", last.url); params.set("fromTs", new Date(last.date).getTime()); } let resp = await fetch(`${this.collInfo.apiPrefix}/urls?${params.toString()}`); resp = await resp.json(); this.results = isMore ? this.results.concat(resp.urls) : resp.urls; // can be more than count if multiple mimes this.tryMore = (resp.urls.length >= count); this.filter(); this.loading = false; } onChangeTypeSearch(event) { this.currMime = event.currentTarget.value; } onChangeQuery(event) { this.newQuery = event.currentTarget.value; if (this._ival) { window.clearTimeout(this._ival); } this._ival = window.setTimeout(() => this._timedUpdate(), 250); } onClickUrlType(event) { this.urlSearchType = event.currentTarget.value; } filter() { const filteredResults = []; const filterText = (this.urlSearchType === "contains" ? this.query : ""); for (const result of this.results) { if (!filterText || result.url.indexOf(filterText) >= 0) { filteredResults.push(result); } } this.filteredResults = filteredResults; } onScroll(event) { const element = event.currentTarget; const diff = (element.scrollHeight - element.scrollTop) - element.clientHeight; if (this.tryMore && diff < 40) { this.doLoadResources(true); } } static get styles() { return wrapCss(css` :host { width: 100%; height: 100%; display: flex; min-width: 0px; flex-direction: column; } :host(.sidebar) .is-hidden-tablet { display: flex !important; } :host(.sidebar) .is-hidden-mobile { display: none !important; } :host(.sidebar) .level, :host(.sidebar) .level-left, :host(.sidebar) .level-right { display: block !important; } :host(.sidebar) .columns { display: flex !important; flex-direction: column; } :host(.sidebar) .column { width: 100% !important; } .notification { width: 100%; } .all-results { margin: 0 0 0 0.5em; display: flex; flex-direction: column; min-height: 0; } .main-scroll { flex-grow: 1; } .minihead { font-size: 10px; font-weight: bold; } .columns { margin: 0px; } thead { margin-bottom: 24px; } table th:not([align]) { text-align: left; } .result { border-bottom: 1px #dbdbdb solid; min-height: fit-content; } .results-head { border-bottom: 2px #dbdbdb solid; margin-right: 16px; min-height: fit-content; display: block; width: 100%; } .results-head a { color: black; } .all-results .column { word-break: break-word; } div.sort-header { padding: 10px; margin-bottom: 0px !important; min-height: fit-content; } .flex-auto { flex: auto; } .asc:after { content: "▼"; font-size: 0.75em; } .desc:after { content: "▲"; font-size: 0.75em; } .num-results { margin-left: 1em; font-style: italic; } `); } render() { return html`
| URL | Date | Mime Type | Status |
|---|---|---|---|
URL |
Date ${new Date(result.date).toLocaleString()} |
Mime Type ${result.mime} |
Status ${result.status} |
| No Results Found. | |||