|
29 | 29 | let platform; |
30 | 30 | let initError; |
31 | 31 | let firstGuide; |
32 | | - let windowHeight = 0; |
33 | 32 | let header; |
34 | 33 | let warn; |
35 | 34 | let err; |
|
42 | 41 | let installViewUserscriptError; |
43 | 42 | let showAll; |
44 | 43 | let allItems = []; |
45 | | - let resizeTimer; |
46 | 44 | let abort = false; |
47 | 45 |
|
48 | 46 | $: list = items.sort((a, b) => a.name.localeCompare(b.name)); |
49 | 47 |
|
50 | | - $: if (platform) document.body.classList.add(platform); |
51 | | -
|
52 | 48 | function getItemBackgroundColor(elements, index) { |
53 | 49 | if (elements.length < 2) return null; |
54 | 50 | if (elements.length % 2 === 0 && index % 2 === 0) return "light"; |
|
259 | 255 | // set toggle state |
260 | 256 | active = await settingsStorage.get("global_active"); |
261 | 257 |
|
262 | | - // set popup height |
263 | | - resize(); |
264 | | -
|
265 | 258 | // get matches |
266 | 259 | const currentTab = await browser.tabs.getCurrent(); |
267 | 260 | const url = currentTab.url; |
|
361 | 354 | window.location.reload(); |
362 | 355 | } |
363 | 356 |
|
364 | | - async function resize() { |
365 | | - if (!platform || platform === "macos") return; |
366 | | - clearTimeout(resizeTimer); |
367 | | - resizeTimer = setTimeout(async () => { |
368 | | - if (platform === "ipados") { |
369 | | - if (window.matchMedia("(max-width: 360px)").matches) { |
370 | | - // the popup window is no greater than 360px |
371 | | - // ensure body & main element have no leftover styling |
372 | | - main.removeAttribute("style"); |
373 | | - document.body.removeAttribute("style"); |
374 | | - return; |
375 | | - } |
376 | | - main.style.maxHeight = "unset"; |
377 | | - document.body.style.width = "100vw"; |
378 | | - } |
379 | | - // on ios and ipados (split view) programmatically set the height of the scrollable container |
380 | | - // first get the header height |
381 | | - const headerHeight = header.offsetHeight; |
382 | | - // then check if a warning or error is visible (ie. taking up height) |
383 | | - let addHeight = 0; |
384 | | - // if warn or error elements visible, also subtract that from applied height |
385 | | - if (warn) addHeight += warn.offsetHeight; |
386 | | - if (err) addHeight += err.offsetHeight; |
387 | | - windowHeight = window.outerHeight - (headerHeight + addHeight); |
388 | | - main.style.height = `${windowHeight}px`; |
389 | | - main.style.paddingBottom = `${headerHeight + addHeight}px`; |
390 | | - }, 25); |
391 | | - } |
392 | | -
|
| 357 | + /** @type {import("svelte/elements").UIEventHandler<Window>} */ |
| 358 | + // async function resizeHandler(event) { |
| 359 | + // if (platform !== "macos") { |
| 360 | + // const viewport = event.currentTarget.visualViewport; |
| 361 | + // console.debug(platform, viewport); |
| 362 | + // // add max limits after the window size has been rendered |
| 363 | + // // avoid display overflow when window shrinks dynamically |
| 364 | + // } |
| 365 | + // } |
| 366 | +
|
| 367 | + /** |
| 368 | + * Check if the current page contains a user script |
| 369 | + * @param {import("webextension-polyfill").Tabs.Tab} currentTab |
| 370 | + */ |
393 | 371 | async function installCheck(currentTab) { |
394 | 372 | // refetch script from URL to avoid tampered DOM content |
395 | 373 | let res; // fetch response |
|
472 | 450 |
|
473 | 451 | onMount(async () => { |
474 | 452 | await initialize(); |
475 | | - // run resize again for good measure |
476 | | - resize(); |
477 | 453 | }); |
478 | 454 |
|
479 | 455 | // handle native app messages |
|
491 | 467 | } |
492 | 468 | </script> |
493 | 469 |
|
494 | | -<svelte:window on:resize={resize} /> |
495 | | -<div class="header" bind:this={header}> |
496 | | - <IconButton |
497 | | - icon={iconOpen} |
498 | | - title={"Open save location"} |
499 | | - on:click={openSaveLocation} |
500 | | - {disabled} |
501 | | - /> |
502 | | - <IconButton |
503 | | - icon={iconUpdate} |
504 | | - notification={!!updates.length} |
505 | | - on:click={() => (showUpdates = true)} |
506 | | - title={"Show updates"} |
507 | | - {disabled} |
508 | | - /> |
509 | | - <IconButton |
510 | | - icon={iconRefresh} |
511 | | - on:click={refreshView} |
512 | | - title={"Refresh view"} |
513 | | - {disabled} |
514 | | - /> |
515 | | - <Toggle |
516 | | - checked={active} |
517 | | - title={"Toggle injection"} |
518 | | - on:click={toggleExtension} |
519 | | - {disabled} |
520 | | - /> |
521 | | -</div> |
522 | | -{#if !active} |
523 | | - <!-- <div class="warn" bind:this={warn}>Injection disabled</div> --> |
524 | | -{/if} |
525 | | -{#if showInstallPrompt} |
526 | | - <div class="warn" class:done={scriptInstalled} bind:this={warn}> |
527 | | - Userscript |
528 | | - {#if scriptChecking} |
529 | | - {showInstallPrompt} |
530 | | - {:else} |
531 | | - {scriptInstalled ? "Installed" : "Detected"}: |
532 | | - <button on:click={showInstallView}>{showInstallPrompt}</button> |
533 | | - {/if} |
534 | | - </div> |
535 | | -{/if} |
536 | | -{#if errorNotification} |
537 | | - <div class="error" bind:this={err}> |
538 | | - {errorNotification} |
539 | | - <IconButton |
540 | | - icon={iconClear} |
541 | | - on:click={() => (errorNotification = undefined)} |
542 | | - title={"Clear error"} |
543 | | - /> |
544 | | - </div> |
545 | | -{/if} |
546 | | -<div class="main {rowColors || ''}" bind:this={main}> |
547 | | - {#if loading} |
548 | | - <Loader abortClick={abortUpdates} {abort} /> |
549 | | - {:else if inactive} |
550 | | - <div class="none">Popup inactive on extension page</div> |
551 | | - {:else if firstGuide} |
552 | | - <div class="none"> |
553 | | - <p>Welcome, first use please: </p> |
554 | | - <button class="link" on:click={openContainingApp}> |
555 | | - Open Userscripts App |
556 | | - </button> |
557 | | - <p>to complete the initialization</p> |
558 | | - </div> |
559 | | - {:else if initError} |
560 | | - <div class="none"> |
561 | | - Something went wrong: |
562 | | - <button class="link" on:click={() => window.location.reload()}> |
563 | | - click to retry |
564 | | - </button> |
565 | | - </div> |
566 | | - {:else if items.length < 1} |
567 | | - <div class="none">No matched userscripts</div> |
568 | | - {:else} |
569 | | - <div class="items" class:disabled> |
570 | | - {#each list as item, i (item.filename)} |
571 | | - <PopupItem |
572 | | - background={getItemBackgroundColor(list, i)} |
573 | | - enabled={!item.disabled} |
574 | | - name={item.name} |
575 | | - subframe={item.subframe} |
576 | | - type={item.type} |
577 | | - request={!!item.request} |
578 | | - on:click={() => toggleItem(item)} |
579 | | - /> |
580 | | - {/each} |
581 | | - </div> |
582 | | - {/if} |
583 | | -</div> |
584 | | -{#if !inactive && platform === "macos"} |
585 | | - <div class="footer"> |
586 | | - <button class="link" on:click={gotoExtensionPage}> |
587 | | - Open Extension Page |
588 | | - </button> |
589 | | - </div> |
590 | | -{/if} |
591 | 470 | {#if showUpdates} |
592 | 471 | <View |
593 | 472 | headerTitle={"Updates"} |
|
630 | 509 | > |
631 | 510 | <AllItemsView {allItems} allItemsToggleItem={toggleItem} /> |
632 | 511 | </View> |
| 512 | +{:else} |
| 513 | + <div class="header" bind:this={header}> |
| 514 | + <div class="buttons"> |
| 515 | + <IconButton |
| 516 | + icon={iconOpen} |
| 517 | + title={"Open save location"} |
| 518 | + on:click={openSaveLocation} |
| 519 | + {disabled} |
| 520 | + /> |
| 521 | + <IconButton |
| 522 | + icon={iconUpdate} |
| 523 | + notification={!!updates.length} |
| 524 | + on:click={() => (showUpdates = true)} |
| 525 | + title={"Show updates"} |
| 526 | + {disabled} |
| 527 | + /> |
| 528 | + <IconButton |
| 529 | + icon={iconRefresh} |
| 530 | + on:click={refreshView} |
| 531 | + title={"Refresh view"} |
| 532 | + {disabled} |
| 533 | + /> |
| 534 | + <Toggle |
| 535 | + checked={active} |
| 536 | + title={"Toggle injection"} |
| 537 | + on:click={toggleExtension} |
| 538 | + {disabled} |
| 539 | + /> |
| 540 | + </div> |
| 541 | + {#if !active} |
| 542 | + <!-- <div class="warn" bind:this={warn}>Injection disabled</div> --> |
| 543 | + {/if} |
| 544 | + {#if showInstallPrompt} |
| 545 | + <div class="warn" class:done={scriptInstalled} bind:this={warn}> |
| 546 | + Userscript |
| 547 | + {#if scriptChecking} |
| 548 | + {showInstallPrompt} |
| 549 | + {:else} |
| 550 | + {scriptInstalled ? "Installed" : "Detected"}: |
| 551 | + <button on:click={showInstallView}>{showInstallPrompt}</button> |
| 552 | + {/if} |
| 553 | + </div> |
| 554 | + {/if} |
| 555 | + {#if errorNotification} |
| 556 | + <div class="error" bind:this={err}> |
| 557 | + {errorNotification} |
| 558 | + <IconButton |
| 559 | + icon={iconClear} |
| 560 | + on:click={() => (errorNotification = undefined)} |
| 561 | + title={"Clear error"} |
| 562 | + /> |
| 563 | + </div> |
| 564 | + {/if} |
| 565 | + </div> |
| 566 | + <div class="main {rowColors || ''}" bind:this={main}> |
| 567 | + {#if loading} |
| 568 | + <Loader abortClick={abortUpdates} {abort} /> |
| 569 | + {:else if inactive} |
| 570 | + <div class="none">Popup inactive on extension page</div> |
| 571 | + {:else if firstGuide} |
| 572 | + <div class="none"> |
| 573 | + <p>Welcome, first use please: </p> |
| 574 | + <button class="link" on:click={openContainingApp}> |
| 575 | + Open Userscripts App |
| 576 | + </button> |
| 577 | + <p>to complete the initialization</p> |
| 578 | + </div> |
| 579 | + {:else if initError} |
| 580 | + <div class="none"> |
| 581 | + Something went wrong: |
| 582 | + <button class="link" on:click={() => window.location.reload()}> |
| 583 | + click to retry |
| 584 | + </button> |
| 585 | + </div> |
| 586 | + {:else if items.length < 1} |
| 587 | + <div class="none">No matched userscripts</div> |
| 588 | + {:else} |
| 589 | + <div class="items" class:disabled> |
| 590 | + {#each list as item, i (item.filename)} |
| 591 | + <PopupItem |
| 592 | + background={getItemBackgroundColor(list, i)} |
| 593 | + enabled={!item.disabled} |
| 594 | + name={item.name} |
| 595 | + subframe={item.subframe} |
| 596 | + type={item.type} |
| 597 | + request={!!item.request} |
| 598 | + on:click={() => toggleItem(item)} |
| 599 | + /> |
| 600 | + {/each} |
| 601 | + </div> |
| 602 | + {/if} |
| 603 | + </div> |
| 604 | + {#if !inactive && platform === "macos"} |
| 605 | + <div class="footer"> |
| 606 | + <button class="link" on:click={gotoExtensionPage}> |
| 607 | + Open Extension Page |
| 608 | + </button> |
| 609 | + </div> |
| 610 | + {/if} |
633 | 611 | {/if} |
634 | 612 |
|
635 | 613 | <style> |
636 | 614 | .header { |
| 615 | + background-color: var(--color-bg-secondary); |
| 616 | + position: sticky; |
| 617 | + top: 0; |
| 618 | + z-index: 1; |
| 619 | + } |
| 620 | +
|
| 621 | + .header .buttons { |
637 | 622 | align-items: center; |
638 | 623 | border-bottom: 1px solid var(--color-black); |
639 | 624 | display: flex; |
640 | 625 | padding: 0.5rem 1rem calc(0.5rem - 1px) 1rem; |
641 | 626 | } |
642 | 627 |
|
643 | | - .header :global(button:nth-of-type(2)) { |
| 628 | + .header .buttons :global(button:nth-of-type(2)) { |
644 | 629 | margin: 0 auto 0 1rem; |
645 | 630 | } |
646 | 631 |
|
647 | | - .header :global(button:nth-of-type(3)) { |
| 632 | + .header .buttons :global(button:nth-of-type(3)) { |
648 | 633 | margin-right: 1rem; |
649 | 634 | } |
650 | 635 |
|
651 | | - .header :global(button:nth-of-type(1) svg) { |
| 636 | + .header .buttons :global(button:nth-of-type(1) svg) { |
652 | 637 | transform: scale(0.75); |
653 | 638 | } |
654 | 639 |
|
655 | | - .header :global(button:nth-of-type(2) svg) { |
| 640 | + .header .buttons :global(button:nth-of-type(2) svg) { |
656 | 641 | transform: scale(0.9); |
657 | 642 | } |
658 | 643 |
|
659 | | - .header :global(label) { |
660 | | - font-size: 1.25rem !important; |
| 644 | + .header .buttons :global(button:nth-of-type(4)) { |
| 645 | + --toggle-font-size: 1.25rem; |
661 | 646 | } |
662 | 647 |
|
663 | 648 | .error, |
|
702 | 687 | } |
703 | 688 |
|
704 | 689 | .main { |
| 690 | + flex-grow: 1; |
705 | 691 | min-height: 12.5rem; |
706 | 692 | overflow-y: auto; |
707 | 693 | position: relative; |
708 | 694 | } |
709 | 695 |
|
710 | | - :global(body:not(.ios) .main) { |
711 | | - max-height: 20rem; |
712 | | - } |
713 | | -
|
714 | 696 | .none { |
715 | 697 | font-weight: 600; |
716 | 698 | color: var(--text-color-disabled); |
|
0 commit comments