Some checks failed
📦 Build / build (push) Has been cancelled
🧪 CI Test / test shard (1/4) (push) Has been cancelled
🧪 CI Test / test shard (2/4) (push) Has been cancelled
🧪 CI Test / test shard (3/4) (push) Has been cancelled
🧪 CI Test / test shard (4/4) (push) Has been cancelled
🧪 CI Test / test (push) Has been cancelled
🧪 CI Test / eslint (push) Has been cancelled
🧪 CI Test / typecheck (push) Has been cancelled
🔫 Sync to Pro / dispatch-sync (push) Has been cancelled
🔮 Sync Mirror / sync (push) Has been cancelled
181 lines
6.5 KiB
TypeScript
181 lines
6.5 KiB
TypeScript
/**
|
|
* Copyright 2023-present DreamNum Co., Ltd.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
// @vitest-environment jsdom
|
|
|
|
import { describe, expect, it, vi } from 'vitest';
|
|
import {
|
|
resolveDocsTableLikeCustomBlockBleedViewport,
|
|
resolveDocsTableLikeCustomBlockContentHeight,
|
|
resolveDocsTableLikeCustomBlockContentWidth,
|
|
} from '../embed-docs-custom-block-bleed';
|
|
|
|
describe('resolveDocsTableLikeCustomBlockBleedViewport', () => {
|
|
it('keeps the viewport inside the block when content fits the block width', () => {
|
|
const boundary = createElementWithRect({ left: 100, right: 1200, width: 1100 });
|
|
const root = createElementWithRect({ left: 220, right: 1180, width: 960 });
|
|
boundary.style.overflow = 'hidden';
|
|
boundary.appendChild(root);
|
|
vi.spyOn(window, 'innerWidth', 'get').mockReturnValue(1800);
|
|
|
|
expect(resolveDocsTableLikeCustomBlockBleedViewport(root, 960)).toEqual({
|
|
bleedLeft: 0,
|
|
bleedRight: 0,
|
|
bleedWidth: 960,
|
|
contentWidth: 960,
|
|
virtualWidth: 960,
|
|
});
|
|
});
|
|
|
|
it('uses the clipping ancestor as the bleed boundary', () => {
|
|
const boundary = createElementWithRect({ left: 100, right: 1200, width: 1100 });
|
|
const root = createElementWithRect({ left: 220, right: 1180, width: 960 });
|
|
boundary.style.overflow = 'hidden';
|
|
boundary.appendChild(root);
|
|
vi.spyOn(window, 'innerWidth', 'get').mockReturnValue(1800);
|
|
|
|
expect(resolveDocsTableLikeCustomBlockBleedViewport(root, 1500)).toEqual({
|
|
bleedLeft: 110,
|
|
bleedRight: 10,
|
|
bleedWidth: 1080,
|
|
contentWidth: 1500,
|
|
virtualWidth: 1610,
|
|
});
|
|
});
|
|
|
|
it('falls back to the visual window when wide content has no clipping ancestor', () => {
|
|
const root = createElementWithRect({ left: 220, right: 1180, width: 960 });
|
|
document.body.appendChild(root);
|
|
vi.spyOn(window, 'innerWidth', 'get').mockReturnValue(1440);
|
|
|
|
expect(resolveDocsTableLikeCustomBlockBleedViewport(root, 1200)).toEqual({
|
|
bleedLeft: 210,
|
|
bleedRight: 250,
|
|
bleedWidth: 1420,
|
|
contentWidth: 1200,
|
|
virtualWidth: 1420,
|
|
});
|
|
});
|
|
|
|
it('converts measured screen geometry back to logical geometry at document scale', () => {
|
|
const root = createElementWithRect({ left: 440, right: 2360, width: 1920 });
|
|
document.body.appendChild(root);
|
|
vi.spyOn(window, 'innerWidth', 'get').mockReturnValue(2880);
|
|
|
|
expect(resolveDocsTableLikeCustomBlockBleedViewport(root, 1800, {
|
|
viewScale: 2,
|
|
})).toEqual({
|
|
bleedLeft: 215,
|
|
bleedRight: 255,
|
|
bleedWidth: 1430,
|
|
contentWidth: 1800,
|
|
virtualWidth: 2015,
|
|
});
|
|
});
|
|
|
|
it('uses authoritative render viewport bleed hints without expanding the layout root', () => {
|
|
const root = createElementWithRect({ left: 220, right: 1180, width: 960 });
|
|
document.body.appendChild(root);
|
|
vi.spyOn(window, 'innerWidth', 'get').mockReturnValue(1440);
|
|
|
|
expect(resolveDocsTableLikeCustomBlockBleedViewport(root, 1800, {
|
|
bleedLeft: 210,
|
|
bleedWidth: 1420,
|
|
})).toEqual({
|
|
bleedLeft: 210,
|
|
bleedRight: 250,
|
|
bleedWidth: 1420,
|
|
contentWidth: 1800,
|
|
virtualWidth: 2010,
|
|
});
|
|
});
|
|
|
|
it('keeps authoritative bleed hints while runtime content width has not caught up', () => {
|
|
const root = createElementWithRect({ left: 220, right: 1180, width: 960 });
|
|
|
|
expect(resolveDocsTableLikeCustomBlockBleedViewport(root, 960, {
|
|
bleedLeft: 210,
|
|
bleedWidth: 1420,
|
|
})).toEqual({
|
|
bleedLeft: 210,
|
|
bleedRight: 250,
|
|
bleedWidth: 1420,
|
|
contentWidth: 960,
|
|
virtualWidth: 1420,
|
|
});
|
|
});
|
|
|
|
it('does not bleed when authoritative content width fits the block', () => {
|
|
const root = createElementWithRect({ left: 220, right: 1180, width: 960 });
|
|
|
|
expect(resolveDocsTableLikeCustomBlockBleedViewport(root, 960, {
|
|
authoritativeContentWidth: true,
|
|
bleedLeft: 210,
|
|
bleedWidth: 1420,
|
|
})).toEqual({
|
|
bleedLeft: 0,
|
|
bleedRight: 0,
|
|
bleedWidth: 960,
|
|
contentWidth: 960,
|
|
virtualWidth: 960,
|
|
});
|
|
});
|
|
|
|
it('uses the full visible canvas bleed once content exceeds the page', () => {
|
|
const root = createElementWithRect({ left: 220, right: 1180, width: 960 });
|
|
|
|
expect(resolveDocsTableLikeCustomBlockBleedViewport(root, 1100, {
|
|
bleedLeft: 210,
|
|
bleedWidth: 1420,
|
|
})).toEqual({
|
|
bleedLeft: 210,
|
|
bleedRight: 250,
|
|
bleedWidth: 1420,
|
|
contentWidth: 1100,
|
|
virtualWidth: 1420,
|
|
});
|
|
});
|
|
|
|
it('prefers authoritative product content width over runtime DOM fallback', () => {
|
|
expect(resolveDocsTableLikeCustomBlockContentWidth(1600, 960)).toBe(1600);
|
|
expect(resolveDocsTableLikeCustomBlockContentWidth(undefined, 960)).toBe(960);
|
|
expect(resolveDocsTableLikeCustomBlockContentWidth(0, 960)).toBe(960);
|
|
});
|
|
|
|
it('prefers authoritative product content height over runtime DOM fallback', () => {
|
|
expect(resolveDocsTableLikeCustomBlockContentHeight(1200, 480)).toBe(1200);
|
|
expect(resolveDocsTableLikeCustomBlockContentHeight(undefined, 480)).toBe(480);
|
|
expect(resolveDocsTableLikeCustomBlockContentHeight(0, 480)).toBe(480);
|
|
});
|
|
});
|
|
|
|
function createElementWithRect(rect: { left: number; right: number; width: number }): HTMLElement {
|
|
const element = document.createElement('div');
|
|
element.getBoundingClientRect = () => ({
|
|
bottom: 0,
|
|
height: 0,
|
|
left: rect.left,
|
|
right: rect.right,
|
|
top: 0,
|
|
width: rect.width,
|
|
x: rect.left,
|
|
y: 0,
|
|
toJSON: () => rect,
|
|
});
|
|
|
|
return element;
|
|
}
|