* Placeholder color contrast @ WCAG 2.0 level AA * Trailing whitespace removed. * Remove redundant labels. * Logo is a link in mobile, if not-embedded; otherwise, span. Fix link labels. * HREF mandatory on A; menu behaves like a popup button. * Hide icons from screen readers. * About icon id keyboard-operarable and is labeled. * Note about inaccessible modal. * Missing closing tag. * Fix nesting/indentation. * Fix nesting/indentation; add missing closing tag. * Trailing whitespace removed. * Don't use NAV landmark for non-nav; add heading for page structure. * Hide icon. * Load archive form's buttons visibly receive keyboard focus. * Trailing whitespace removed. * "Hide" header button is keyboard-operable, and more-verbosely labeled for screenreader users. * Don't use NAV landmark for non-nav; add heading for page structure. * Sort order announced to screen reader users. * Trailing whitespace removed. * Delete button only a button when it can be pressed; announce in progress deletion. * Trailing whitespace removed. * Use a NAV landmark for replay controls. * Remove "menu" role, to avoid having to implement arrow key support https://www.w3.org/WAI/GL/wiki/Using_ARIA_menus * Hide icons. * Label buttons. * Links in disguise as buttons need HREF, and to respond to spacebar. * Re-dub "main menu" to distinguish from replay menu * Replay nav buttons visually get keyboard focus. * Trailing whitespace removed. * Hiding icons; button labels; links-as-buttons are operable. * Use type=search for additional clarity. * Add appropriate landmarks and a heading for structure and clarity. * Tab selection is a nav, and is keyboard operable. * Indentation; missing closing tag. * Trailing whitespace removed. * Title iframe. * Not a navigation. * Per discussion, rename tab to "URLs" (label only; route etc. the same while experimenting). * Announce when expanded/collapsed. * Remove "menu" to avoid having to implement expected keyboard support. * Use correct heading level when in sidebar and when main. * Trailing whitespace removed. * Semantic markup of table; headings and captions; link-buttons are keyboard operable. * Skip links for keyboard users. * Title iframe; hide icon. * Just a list, not an aside. * Not an article. * Remove trailing whitespace. * Make each page in the list a heading. * link-buttons are keyboard operable. * Use semantic list for page list. * Announce changes to search results. * More wayfinding tweaks. * Landmark and heading for replay. * Dynamic page titles. * Remove redundant labels from main landmarks. * additional tweaks after rebase - add 'role' to each of the tabs, dependent if sidebar or not - add 'role=main' for replay - add sr-only headers to each tab * fix typos * remaining tweaks: - url-resources: fix sorter getting moved into notification - url-resources: fix border for mobile view - add screenreader labels to expand/hide buttons * Show hover effect on focus. * Wrap the whole sidebar is role=complementary, including the tab navigation. * Make buttons keyboard operable; fix typos. * Programmatically associate sidebar toggle button with sidebar. * Per discusson, try calling this "URLs" * Different heading levels for sidebar and main. * Announce changes to search results. * Correct dynamic page title, whe not in sidebar. * Remove hyperlink focus decoration; reveal obscured focus indicator. * Focus on replay, when replay changes. * Make buttons keyboard operable. * Move spacebar helper to misc instead of duplicating. * Bump compiled assets. * Use disabled attribute to match css; update label to describe new sidebar. * Adjust replay focus styles. * Adjust replay nav button focus, so visuals onclick in Chrome are less prominent. * Put wordmark with logo on non-embed desktop, so that logo and wordmark make a single link. Co-authored-by: Ilya Kreymer <ikreymer@gmail.com>
157 lines
4.2 KiB
JavaScript
157 lines
4.2 KiB
JavaScript
import { LitElement, html, css } from 'lit-element';
|
|
import { wrapCss } from './misc';
|
|
|
|
import fasUpload from '@fortawesome/fontawesome-free/svgs/solid/upload.svg';
|
|
|
|
|
|
// ===========================================================================
|
|
class Chooser extends LitElement
|
|
{
|
|
constructor() {
|
|
super();
|
|
|
|
this.fileDisplayName = "";
|
|
this.file = null;
|
|
}
|
|
|
|
onChooseFile(event) {
|
|
if (event.currentTarget.files.length === 0) {
|
|
return;
|
|
}
|
|
|
|
this.file = event.currentTarget.files[0];
|
|
// file.path only available in electron app
|
|
this.fileDisplayName = "file://" + (this.file.path || this.file.name);
|
|
this.requestUpdate();
|
|
}
|
|
|
|
onStartLoad(event) {
|
|
event.preventDefault();
|
|
|
|
const loadInfo = {sourceUrl: this.fileDisplayName};
|
|
|
|
if (this.file) {
|
|
loadInfo.isFile = true;
|
|
// file.path only available in electron app
|
|
if (this.file.path) {
|
|
const url = new URL(__APP_FILE_SERVE_PREFIX__);
|
|
url.searchParams.set("filename", this.file.path);
|
|
loadInfo.loadUrl = url.href;
|
|
} else {
|
|
loadInfo.loadUrl = URL.createObjectURL(this.file);
|
|
loadInfo.blob = this.file;
|
|
}
|
|
loadInfo.size = this.file.size;
|
|
loadInfo.noCache = this.file.path !== undefined;
|
|
loadInfo.name = this.fileDisplayName;
|
|
}
|
|
|
|
this.dispatchEvent(new CustomEvent("load-start", {detail: loadInfo}));
|
|
|
|
return false;
|
|
}
|
|
|
|
onInput(event) {
|
|
this.fileDisplayName = event.currentTarget.value;
|
|
|
|
if (this.file && this.fileDisplayName && this.fileDisplayName.startsWith("file://")) {
|
|
this.file = null;
|
|
this.fileDisplayName = "";
|
|
}
|
|
}
|
|
|
|
static get styles() {
|
|
return wrapCss(css`
|
|
:host {
|
|
min-width: 0;
|
|
}
|
|
.extra-padding {
|
|
padding: 2em;
|
|
}
|
|
.less-padding {
|
|
padding-top: 1.0em;
|
|
padding-bottom: 1.0em;
|
|
}
|
|
div.field.has-addons {
|
|
flex: auto;
|
|
}
|
|
.panel-heading {
|
|
background-color: #cff3ff;
|
|
}
|
|
form {
|
|
flex-grow: 1;
|
|
flex-shrink: 0;
|
|
}
|
|
p.control.is-expanded {
|
|
width: min-content;
|
|
}
|
|
input.input.file-name:invalid {
|
|
border: 1px dashed red;
|
|
}
|
|
input.input.file-name {
|
|
border-width: 1px;
|
|
margin-left: -1px;
|
|
max-width: 100%;
|
|
}
|
|
@media screen and (max-width: 1023px) {
|
|
.file-icon {
|
|
margin-right: 0px;
|
|
}
|
|
}
|
|
|
|
@media screen and (max-width: 768px) {
|
|
#filename {
|
|
border-bottom-right-radius: 4px;
|
|
border-top-right-radius: 4px;
|
|
}
|
|
}
|
|
`);
|
|
};
|
|
|
|
render() {
|
|
return html`
|
|
<section class="section less-padding">
|
|
<div class="panel">
|
|
<h2 class="panel-heading">Load Web Archive</h2>
|
|
<div class="extra-padding panel-block file has-name">
|
|
<form class="content is-flex" @submit="${this.onStartLoad}">
|
|
<label class="file-label">
|
|
<input class="file-input"
|
|
@click="${(e) => e.currentTarget.value = null}"
|
|
@change=${this.onChooseFile} type="file" id="fileupload" name="fileupload">
|
|
<span class="file-cta">
|
|
<span class="file-icon">
|
|
<fa-icon size="0.9em" .svg=${fasUpload} aria-hidden="true"></fa-icon>
|
|
</span>
|
|
<span class="file-label is-hidden-touch">
|
|
Choose File...
|
|
</span>
|
|
</span>
|
|
</label>
|
|
|
|
<div class="field has-addons">
|
|
<p class="control is-expanded">
|
|
<input class="file-name input" type="text"
|
|
name="filename" id="filename"
|
|
pattern="((file|http|https|s3):\/\/.*\.(warc|warc.gz|zip|wacz|har|wbn))|(googledrive:\/\/.+)"
|
|
.value="${this.fileDisplayName}"
|
|
@input="${this.onInput}"
|
|
autocomplete="off"
|
|
placeholder="Enter a URL or click 'Choose File' to select a WARC, WACZ, HAR or WBN archive source">
|
|
</p>
|
|
<div class="control">
|
|
<button type="submit" class="button is-hidden-mobile is-primary">Load</button>
|
|
</div>
|
|
</div>
|
|
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</section>`;
|
|
}
|
|
}
|
|
|
|
customElements.define("wr-chooser", Chooser);
|
|
|
|
export { Chooser };
|