mirror of
https://github.com/jzillmann/pdf-to-markdown.git
synced 2025-01-23 14:08:47 +01:00
Un-Grouping switch
This commit is contained in:
parent
37622577c9
commit
c60bd3f737
@ -4,6 +4,7 @@ import Item from '../Item';
|
||||
import Page, { asPages } from './Page';
|
||||
import ChangeIndex from './ChangeIndex';
|
||||
import ChangeTracker from './ChangeTracker';
|
||||
import ItemGroup from './ItemGroup';
|
||||
|
||||
export default class StageResult {
|
||||
constructor(
|
||||
@ -20,6 +21,47 @@ export default class StageResult {
|
||||
return items;
|
||||
}, []);
|
||||
}
|
||||
|
||||
selectPages(relevantChangesOnly: boolean, groupItems: boolean, pinnedPage?: number): Page[] {
|
||||
let result: Page[];
|
||||
|
||||
// Ungroup pages
|
||||
if (!groupItems && this.descriptor?.debug?.itemMerger) {
|
||||
result = this.pagesWithUnpackedItems();
|
||||
} else {
|
||||
result = this.pages;
|
||||
}
|
||||
|
||||
// Filter to pinned page
|
||||
if (Number.isInteger(pinnedPage)) {
|
||||
result = result.filter((page) => page.index === pinnedPage);
|
||||
}
|
||||
|
||||
// Filter out item (groups) with no changes
|
||||
if (relevantChangesOnly && !this.descriptor.debug?.showAll === true) {
|
||||
result = result.map(
|
||||
(page) =>
|
||||
({
|
||||
...page,
|
||||
itemGroups: page.itemGroups.filter((itemGroup) => this.changes.hasChanged(itemGroup.top)),
|
||||
} as Page),
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
pagesWithUnpackedItems(): Page[] {
|
||||
return this.pages.map(
|
||||
(page) =>
|
||||
({
|
||||
...page,
|
||||
itemGroups: new Array<ItemGroup>().concat(
|
||||
...page.itemGroups.map((itemGroup) => itemGroup.unpacked().map((item) => new ItemGroup(item))),
|
||||
),
|
||||
} as Page),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function initialStage(inputSchema: string[], inputItems: Item[]): StageResult {
|
||||
|
@ -1,8 +1,4 @@
|
||||
import ItemMerger from '../debug/ItemMerger';
|
||||
import Item from '../Item';
|
||||
import ItemGroup from '../debug/ItemGroup';
|
||||
import Page from '../debug/Page';
|
||||
import ChangeTracker from '../debug/ChangeTracker';
|
||||
|
||||
type KeyExtractor = (item: Item) => any;
|
||||
type PageItemTransformer = (page: number, items: Item[]) => Item[];
|
||||
|
207
core/test/debug/StageResults.test.ts
Normal file
207
core/test/debug/StageResults.test.ts
Normal file
@ -0,0 +1,207 @@
|
||||
import StageResult from 'src/debug/StageResult';
|
||||
import { toDescriptor } from 'src/TransformDescriptor';
|
||||
import ChangeTracker from 'src/debug/ChangeTracker';
|
||||
import AnnotatedColumn from 'src/debug/AnnotatedColumn';
|
||||
import Page, { asPages } from 'src/debug/Page';
|
||||
import { items } from '../testItems';
|
||||
import LineItemMerger from 'src/debug/LineItemMerger';
|
||||
import ItemGroup from 'src/debug/ItemGroup';
|
||||
|
||||
test('itemsUnpacked', async () => {
|
||||
const tracker = new ChangeTracker();
|
||||
const itemMerger = new LineItemMerger(false);
|
||||
const descriptor = toDescriptor({ debug: { itemMerger } });
|
||||
const schema: AnnotatedColumn[] = [{ name: 'A' }];
|
||||
const flatItems = [
|
||||
...items(0, [
|
||||
{ idx: 0, line: 1 },
|
||||
{ idx: 1, line: 1 },
|
||||
{ idx: 2, line: 2 },
|
||||
]),
|
||||
...items(1, [{ idx: 3, line: 1 }]),
|
||||
...items(2, [
|
||||
{ idx: 4, line: 1 },
|
||||
{ idx: 5, line: 1 },
|
||||
]),
|
||||
];
|
||||
const pages = asPages(tracker, flatItems, itemMerger);
|
||||
const result = new StageResult(descriptor, schema, pages, tracker, []);
|
||||
|
||||
expect(result.itemsUnpacked().map((item) => item.data['idx'])).toEqual([0, 1, 2, 3, 4, 5]);
|
||||
});
|
||||
|
||||
describe('select pages', () => {
|
||||
function groupElements(page: Page, elementName: string) {
|
||||
return page.itemGroups.map((group) => group.unpacked().map((item) => item.data['idx']));
|
||||
}
|
||||
test('Changes on group level', async () => {
|
||||
const tracker = new ChangeTracker();
|
||||
const itemMerger = new LineItemMerger(true);
|
||||
const descriptor = toDescriptor({ debug: { itemMerger } });
|
||||
const schema: AnnotatedColumn[] = [{ name: 'A' }];
|
||||
const flatItems = [
|
||||
...items(0, [
|
||||
{ idx: 0, line: 1 },
|
||||
{ idx: 1, line: 1 },
|
||||
{ idx: 2, line: 2 },
|
||||
]),
|
||||
...items(1, [{ idx: 3, line: 1 }]),
|
||||
...items(2, [
|
||||
{ idx: 4, line: 1 },
|
||||
{ idx: 5, line: 1 },
|
||||
]),
|
||||
];
|
||||
const pages = asPages(tracker, flatItems, itemMerger);
|
||||
const result = new StageResult(descriptor, schema, pages, tracker, []);
|
||||
|
||||
const allGrouped = result.selectPages(false, true);
|
||||
expect(allGrouped.map((page) => page.index)).toEqual([0, 1, 2]);
|
||||
expect(groupElements(allGrouped[0], 'idx')).toEqual([[0, 1], [2]]);
|
||||
expect(groupElements(allGrouped[1], 'idx')).toEqual([[3]]);
|
||||
expect(groupElements(allGrouped[2], 'idx')).toEqual([[4, 5]]);
|
||||
|
||||
const relevantGrouped = result.selectPages(true, true);
|
||||
expect(relevantGrouped.map((page) => page.index)).toEqual([0, 1, 2]);
|
||||
expect(groupElements(relevantGrouped[0], 'idx')).toEqual([[0, 1]]);
|
||||
expect(groupElements(relevantGrouped[1], 'idx')).toEqual([]);
|
||||
expect(groupElements(relevantGrouped[2], 'idx')).toEqual([[4, 5]]);
|
||||
|
||||
const relevantUnpacked = result.selectPages(true, false);
|
||||
expect(relevantUnpacked.map((page) => page.index)).toEqual([0, 1, 2]);
|
||||
expect(groupElements(relevantUnpacked[0], 'idx')).toEqual([]);
|
||||
expect(groupElements(relevantUnpacked[1], 'idx')).toEqual([]);
|
||||
expect(groupElements(relevantUnpacked[2], 'idx')).toEqual([]);
|
||||
|
||||
const allUnpacked = result.selectPages(false, false);
|
||||
expect(allUnpacked.map((page) => page.index)).toEqual([0, 1, 2]);
|
||||
expect(groupElements(allUnpacked[0], 'idx')).toEqual([[0], [1], [2]]);
|
||||
expect(groupElements(allUnpacked[1], 'idx')).toEqual([[3]]);
|
||||
expect(groupElements(allUnpacked[2], 'idx')).toEqual([[4], [5]]);
|
||||
|
||||
const allGroupedWithPin = result.selectPages(false, true, 0);
|
||||
expect(allGroupedWithPin.map((page) => page.index)).toEqual([0]);
|
||||
expect(groupElements(allGroupedWithPin[0], 'idx')).toEqual([[0, 1], [2]]);
|
||||
|
||||
const relevantGroupedWithPin = result.selectPages(true, true, 0);
|
||||
expect(relevantGroupedWithPin.map((page) => page.index)).toEqual([0]);
|
||||
expect(groupElements(relevantGroupedWithPin[0], 'idx')).toEqual([[0, 1]]);
|
||||
|
||||
const relevantUnpackedWithPin = result.selectPages(true, false, 0);
|
||||
expect(relevantUnpackedWithPin.map((page) => page.index)).toEqual([0]);
|
||||
expect(groupElements(relevantUnpackedWithPin[0], 'idx')).toEqual([]);
|
||||
|
||||
const allUnpackedWithPin = result.selectPages(false, false, 0);
|
||||
expect(allUnpackedWithPin.map((page) => page.index)).toEqual([0]);
|
||||
expect(groupElements(allUnpackedWithPin[0], 'idx')).toEqual([[0], [1], [2]]);
|
||||
});
|
||||
|
||||
test('Changes on element level', async () => {
|
||||
const tracker = new ChangeTracker();
|
||||
const itemMerger = new LineItemMerger(false);
|
||||
const descriptor = toDescriptor({ debug: { itemMerger } });
|
||||
const schema: AnnotatedColumn[] = [{ name: 'A' }];
|
||||
const flatItems = [
|
||||
...items(0, [
|
||||
{ idx: 0, line: 1 },
|
||||
{ idx: 1, line: 1 },
|
||||
{ idx: 2, line: 2 },
|
||||
]),
|
||||
...items(1, [{ idx: 3, line: 1 }]),
|
||||
...items(2, [
|
||||
{ idx: 4, line: 1 },
|
||||
{ idx: 5, line: 1 },
|
||||
{ idx: 6, line: 2 },
|
||||
]),
|
||||
];
|
||||
tracker.trackAddition(flatItems[3]);
|
||||
tracker.trackAddition(flatItems[5]);
|
||||
const pages = asPages(tracker, flatItems, itemMerger);
|
||||
const result = new StageResult(descriptor, schema, pages, tracker, []);
|
||||
|
||||
const allGrouped = result.selectPages(false, true);
|
||||
expect(allGrouped.map((page) => page.index)).toEqual([0, 1, 2]);
|
||||
expect(groupElements(allGrouped[0], 'idx')).toEqual([[0, 1], [2]]);
|
||||
expect(groupElements(allGrouped[1], 'idx')).toEqual([[3]]);
|
||||
expect(groupElements(allGrouped[2], 'idx')).toEqual([[4, 5], [6]]);
|
||||
|
||||
const relevantGrouped = result.selectPages(true, true);
|
||||
expect(relevantGrouped.map((page) => page.index)).toEqual([0, 1, 2]);
|
||||
expect(groupElements(relevantGrouped[0], 'idx')).toEqual([]);
|
||||
expect(groupElements(relevantGrouped[1], 'idx')).toEqual([[3]]);
|
||||
expect(groupElements(relevantGrouped[2], 'idx')).toEqual([[4, 5]]);
|
||||
|
||||
const relevantUnpacked = result.selectPages(true, false);
|
||||
expect(relevantUnpacked.map((page) => page.index)).toEqual([0, 1, 2]);
|
||||
expect(groupElements(relevantUnpacked[0], 'idx')).toEqual([]);
|
||||
expect(groupElements(relevantUnpacked[1], 'idx')).toEqual([[3]]);
|
||||
expect(groupElements(relevantUnpacked[2], 'idx')).toEqual([[5]]);
|
||||
|
||||
const allUnpacked = result.selectPages(false, false);
|
||||
expect(allUnpacked.map((page) => page.index)).toEqual([0, 1, 2]);
|
||||
expect(groupElements(allUnpacked[0], 'idx')).toEqual([[0], [1], [2]]);
|
||||
expect(groupElements(allUnpacked[1], 'idx')).toEqual([[3]]);
|
||||
expect(groupElements(allUnpacked[2], 'idx')).toEqual([[4], [5], [6]]);
|
||||
|
||||
const allGroupedWithPin = result.selectPages(false, true, 2);
|
||||
expect(allGroupedWithPin.map((page) => page.index)).toEqual([2]);
|
||||
expect(groupElements(allGroupedWithPin[0], 'idx')).toEqual([[4, 5], [6]]);
|
||||
|
||||
const relevantGroupedWithPin = result.selectPages(true, true, 2);
|
||||
expect(relevantGroupedWithPin.map((page) => page.index)).toEqual([2]);
|
||||
expect(groupElements(relevantGroupedWithPin[0], 'idx')).toEqual([[4, 5]]);
|
||||
|
||||
const relevantUnpackedWithPin = result.selectPages(true, false, 2);
|
||||
expect(relevantUnpackedWithPin.map((page) => page.index)).toEqual([2]);
|
||||
expect(groupElements(relevantUnpackedWithPin[0], 'idx')).toEqual([[5]]);
|
||||
|
||||
const allUnpackedWithPin = result.selectPages(false, false, 2);
|
||||
expect(allUnpackedWithPin.map((page) => page.index)).toEqual([2]);
|
||||
expect(groupElements(allUnpackedWithPin[0], 'idx')).toEqual([[4], [5], [6]]);
|
||||
});
|
||||
|
||||
test('showAll - grouped', async () => {
|
||||
const tracker = new ChangeTracker();
|
||||
const itemMerger = new LineItemMerger(false);
|
||||
const descriptor = toDescriptor({ debug: { itemMerger, showAll: true } });
|
||||
const schema: AnnotatedColumn[] = [{ name: 'A' }];
|
||||
const flatItems = [
|
||||
...items(0, [
|
||||
{ idx: 0, line: 1 },
|
||||
{ idx: 1, line: 1 },
|
||||
{ idx: 2, line: 2 },
|
||||
]),
|
||||
...items(1, [{ idx: 3, line: 1 }]),
|
||||
...items(2, [
|
||||
{ idx: 4, line: 1 },
|
||||
{ idx: 5, line: 1 },
|
||||
]),
|
||||
];
|
||||
const pages = asPages(tracker, flatItems, itemMerger);
|
||||
const result = new StageResult(descriptor, schema, pages, tracker, []);
|
||||
|
||||
const relevantGrouped = result.selectPages(true, true);
|
||||
expect(relevantGrouped.map((page) => page.index)).toEqual([0, 1, 2]);
|
||||
expect(groupElements(relevantGrouped[0], 'idx')).toEqual([[0, 1], [2]]);
|
||||
expect(groupElements(relevantGrouped[1], 'idx')).toEqual([[3]]);
|
||||
expect(groupElements(relevantGrouped[2], 'idx')).toEqual([[4, 5]]);
|
||||
});
|
||||
|
||||
test('showAll - grouped', async () => {
|
||||
const tracker = new ChangeTracker();
|
||||
const descriptor = toDescriptor({ debug: { showAll: true } });
|
||||
const schema: AnnotatedColumn[] = [{ name: 'A' }];
|
||||
const flatItems = [
|
||||
...items(0, [{ idx: 0 }, { idx: 1 }, { idx: 2 }]),
|
||||
...items(1, [{ idx: 3 }]),
|
||||
...items(2, [{ idx: 4 }, { idx: 5 }]),
|
||||
];
|
||||
const pages = asPages(tracker, flatItems);
|
||||
const result = new StageResult(descriptor, schema, pages, tracker, []);
|
||||
|
||||
const relevantGrouped = result.selectPages(true, true);
|
||||
expect(relevantGrouped.map((page) => page.index)).toEqual([0, 1, 2]);
|
||||
expect(groupElements(relevantGrouped[0], 'idx')).toEqual([[0], [1], [2]]);
|
||||
expect(groupElements(relevantGrouped[1], 'idx')).toEqual([[3]]);
|
||||
expect(groupElements(relevantGrouped[2], 'idx')).toEqual([[4], [5]]);
|
||||
});
|
||||
});
|
@ -1,11 +1,13 @@
|
||||
<script>
|
||||
import { slide } from 'svelte/transition';
|
||||
import { linear } from 'svelte/easing';
|
||||
import Icon from 'fa-svelte';
|
||||
import { faMapPin as pin } from '@fortawesome/free-solid-svg-icons/faMapPin';
|
||||
import { BookOpen, ArrowLeft, ArrowRight } from 'svelte-hero-icons';
|
||||
|
||||
import type Debugger from '@core/Debugger';
|
||||
|
||||
import slideH from '../svelte/slideH';
|
||||
import Popup from '../components/Popup.svelte';
|
||||
import PageSelectionPopup from './PageSelectionPopup.svelte';
|
||||
import Checkbox from '../components/Checkbox.svelte';
|
||||
@ -18,14 +20,17 @@
|
||||
const stageNames = debug.stageNames;
|
||||
let pinnedPage: number;
|
||||
let onlyRelevantItems = true;
|
||||
let groupingEnabled = true;
|
||||
|
||||
$: canNext = $debugStage + 1 < stageNames.length;
|
||||
$: canPrev = $debugStage > 0;
|
||||
$: stageResult = debug.stageResults($debugStage);
|
||||
$: supportsGrouping = !!stageResult.descriptor?.debug?.itemMerger;
|
||||
$: supportsRelevanceFiltering = !stageResult.descriptor?.debug?.showAll;
|
||||
$: pageIsPinned = !isNaN(pinnedPage);
|
||||
$: pagesNumbers = new Set(stageResult.pages.map((page) => page.index));
|
||||
$: maxPage = Math.max(...pagesNumbers);
|
||||
$: visiblePages = pageIsPinned ? stageResult.pages.filter((page) => page.index === pinnedPage) : stageResult.pages;
|
||||
$: visiblePages = stageResult.selectPages(onlyRelevantItems, groupingEnabled, pinnedPage);
|
||||
</script>
|
||||
|
||||
<div class="mx-4">
|
||||
@ -37,7 +42,7 @@
|
||||
<div class="controls py-2">
|
||||
<div class="flex items-center space-x-2">
|
||||
{#if pageIsPinned}
|
||||
<span on:click={() => (pinnedPage = undefined)} transition:slide>
|
||||
<span on:click={() => (pinnedPage = undefined)} transition:slideH={{ duration: 180, easing: linear }}>
|
||||
<Icon class="text-xs hover:text-green-700 hover:opacity-25 cursor-pointer opacity-75" icon={pin} />
|
||||
</span>
|
||||
{/if}
|
||||
@ -82,7 +87,16 @@
|
||||
</Popup>
|
||||
</span>
|
||||
<div class="w-full flex flex-row-reverse space-x-2 space-x-reverse text-sm">
|
||||
<Checkbox name="Relevant Items" bind:enabled={onlyRelevantItems} />
|
||||
{#if supportsGrouping}
|
||||
<span class="inline-flex" transition:slideH={{ duration: 700 }}>
|
||||
<Checkbox name="Grouped" bind:enabled={groupingEnabled} />
|
||||
</span>
|
||||
{/if}
|
||||
{#if supportsRelevanceFiltering}
|
||||
<span class="inline-flex" transition:slideH={{ duration: 700 }}>
|
||||
<Checkbox name="Relevant Items" bind:enabled={onlyRelevantItems} />
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -97,15 +111,33 @@
|
||||
</ul>
|
||||
|
||||
<!-- Items -->
|
||||
<ItemTable
|
||||
fontMap={debug.fontMap}
|
||||
schema={stageResult.schema}
|
||||
pages={visiblePages}
|
||||
{maxPage}
|
||||
{pageIsPinned}
|
||||
showAllAsRelevant={stageResult.descriptor?.debug?.showAll}
|
||||
bind:onlyRelevantItems
|
||||
changes={stageResult.changes} />
|
||||
{#if visiblePages.find((page) => page.itemGroups.length > 0)}
|
||||
<ItemTable
|
||||
fontMap={debug.fontMap}
|
||||
schema={stageResult.schema}
|
||||
pages={visiblePages}
|
||||
{maxPage}
|
||||
{pageIsPinned}
|
||||
changes={stageResult.changes} />
|
||||
{:else}
|
||||
<div class="flex space-x-1 items-center justify-center text-xl">
|
||||
<div>No visible changes from the transformation.</div>
|
||||
{#if supportsRelevanceFiltering && onlyRelevantItems}
|
||||
<div>Disabled the</div>
|
||||
<div class="font-bold cursor-pointer hover:underline" on:click={() => (onlyRelevantItems = false)}>
|
||||
relevance filter
|
||||
</div>
|
||||
<div>?</div>
|
||||
{/if}
|
||||
{#if supportsGrouping && !groupingEnabled}
|
||||
<div>Enable</div>
|
||||
<div class="font-bold cursor-pointer hover:underline" on:click={() => (groupingEnabled = true)}>
|
||||
grouping
|
||||
</div>
|
||||
<div>?</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
@ -16,8 +16,6 @@
|
||||
export let pages: Page[];
|
||||
export let maxPage: number;
|
||||
export let pageIsPinned: boolean;
|
||||
export let onlyRelevantItems: boolean;
|
||||
export let showAllAsRelevant = false;
|
||||
export let changes: ChangeIndex;
|
||||
let maxItemsToRenderInOneLoad = 200;
|
||||
let renderedMaxPage = 0;
|
||||
@ -79,7 +77,7 @@
|
||||
{/if}
|
||||
|
||||
<!-- Page items -->
|
||||
{#each page.itemGroups.filter((group) => showAllAsRelevant || !onlyRelevantItems || changes.hasChanged(group.top)) as itemGroup, itemIdx}
|
||||
{#each page.itemGroups as itemGroup, itemIdx}
|
||||
<tr
|
||||
class:expandable={itemGroup.hasMany()}
|
||||
class:expanded={expandedItemGroup && isExpanded(page.index, itemIdx)}
|
||||
@ -171,23 +169,12 @@
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{#if onlyRelevantItems && changes.changeCount() === 0}
|
||||
<div class="flex space-x-1 items-center justify-center text-xl">
|
||||
<div>No changes from the transformation.</div>
|
||||
<div>Want to see</div>
|
||||
<div class="font-bold cursor-pointer hover:underline" on:click={() => (onlyRelevantItems = false)}>
|
||||
all items
|
||||
</div>
|
||||
<div>?</div>
|
||||
</div>
|
||||
{:else}
|
||||
{#if !pageIsPinned}
|
||||
{#if renderedMaxPage < pages.length}
|
||||
<span use:inView on:intersect={({ detail }) => detail && calculateNextPageToRenderTo()} />
|
||||
<div class="my-6 text-center text-2xl">...</div>
|
||||
{:else}
|
||||
<div class="my-6 text-center text-2xl">FIN!</div>
|
||||
{/if}
|
||||
{#if !pageIsPinned}
|
||||
{#if renderedMaxPage < pages.length}
|
||||
<span use:inView on:intersect={({ detail }) => detail && calculateNextPageToRenderTo()} />
|
||||
<div class="my-6 text-center text-2xl">...</div>
|
||||
{:else}
|
||||
<div class="my-6 text-center text-2xl">FIN!</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
@ -249,6 +236,6 @@
|
||||
margin-right: 15px;
|
||||
right: 100%;
|
||||
with: 200px;
|
||||
z-index: 4;
|
||||
z-index: 1;
|
||||
}
|
||||
</style>
|
||||
|
42
ui/src/svelte/slideH.ts
Normal file
42
ui/src/svelte/slideH.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { backInOut as easing } from 'svelte/easing';
|
||||
|
||||
const defaultOptions = {
|
||||
delay: 0,
|
||||
duration: 400,
|
||||
easing,
|
||||
};
|
||||
|
||||
/**
|
||||
* Slide the element horizontally, across the X-axis.
|
||||
* @param node
|
||||
* @param options
|
||||
*/
|
||||
export default function slideH(node: HTMLElement, options: object) {
|
||||
const mergedOptions = { ...defaultOptions, ...options };
|
||||
|
||||
const style = getComputedStyle(node);
|
||||
const opacity = +style.opacity;
|
||||
const width = parseFloat(style.width);
|
||||
const padding_left = parseFloat(style.paddingLeft);
|
||||
const padding_right = parseFloat(style.paddingRight);
|
||||
const margin_left = parseFloat(style.marginLeft);
|
||||
const margin_right = parseFloat(style.marginRight);
|
||||
const border_left_width = parseFloat(style.borderLeftWidth);
|
||||
const border_right_width = parseFloat(style.borderRightWidth);
|
||||
|
||||
return {
|
||||
delay: mergedOptions.delay,
|
||||
duration: mergedOptions.duration,
|
||||
easing: mergedOptions.easing,
|
||||
css: (t: number) =>
|
||||
`overflow: hidden;` +
|
||||
`opacity: ${Math.min(t * 20, 1) * opacity};` +
|
||||
`width: ${t * width}px;` +
|
||||
`padding-left: ${t * padding_left}px;` +
|
||||
`padding-right: ${t * padding_right}px;` +
|
||||
`margin-left: ${t * margin_left}px;` +
|
||||
`margin-right: ${t * margin_right}px;` +
|
||||
`border-left-width: ${t * border_left_width}px;` +
|
||||
`border-right-width: ${t * border_right_width}px;`,
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user