test: harden visual resource rendering
This commit is contained in:
@@ -94,11 +94,8 @@ const page: OneNotePageDto = {
|
|||||||
|
|
||||||
describe('PageReader structured content', () => {
|
describe('PageReader structured content', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.stubGlobal('URL', {
|
vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:local-image');
|
||||||
...URL,
|
vi.spyOn(URL, 'revokeObjectURL').mockImplementation(() => undefined);
|
||||||
createObjectURL: vi.fn(() => 'blob:local-image'),
|
|
||||||
revokeObjectURL: vi.fn(),
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders semantic formatting, links, tables, and a signed image resource', async () => {
|
it('renders semantic formatting, links, tables, and a signed image resource', async () => {
|
||||||
|
|||||||
@@ -426,15 +426,20 @@ function ImageView({
|
|||||||
|
|
||||||
function InkView({ ink }: { ink: OneNoteInkBlock }) {
|
function InkView({ ink }: { ink: OneNoteInkBlock }) {
|
||||||
const box = ink.boundingBox ?? boundingBoxFromInk(ink.strokes);
|
const box = ink.boundingBox ?? boundingBoxFromInk(ink.strokes);
|
||||||
const padding = Math.max(
|
const widestStroke = ink.strokes.reduce(
|
||||||
140,
|
(widest, stroke) => Math.max(widest, stroke.width ?? 0),
|
||||||
...ink.strokes.map((stroke) => stroke.width ?? 0)
|
0
|
||||||
);
|
);
|
||||||
|
const padding = Math.max(140, Math.min(1_000_000, widestStroke));
|
||||||
const viewBox = box
|
const viewBox = box
|
||||||
? `${box.x - padding / 2} ${box.y - padding / 2} ${Math.max(box.width + padding, 1)} ${Math.max(box.height + padding, 1)}`
|
? `${box.x - padding / 2} ${box.y - padding / 2} ${Math.max(box.width + padding, 1)} ${Math.max(box.height + padding, 1)}`
|
||||||
: '0 0 1 1';
|
: '0 0 1 1';
|
||||||
const width = box ? Math.max((box.width + padding) / (2540 / 96), 1) : 1;
|
const width = box
|
||||||
const height = box ? Math.max((box.height + padding) / (2540 / 96), 1) : 1;
|
? Math.min(Math.max((box.width + padding) / (2540 / 96), 1), 10_000)
|
||||||
|
: 1;
|
||||||
|
const height = box
|
||||||
|
? Math.min(Math.max((box.height + padding) / (2540 / 96), 1), 10_000)
|
||||||
|
: 1;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="onenote-ink" style={layoutStyle(ink.layout)}>
|
<div className="onenote-ink" style={layoutStyle(ink.layout)}>
|
||||||
@@ -452,7 +457,10 @@ function InkView({ ink }: { ink: OneNoteInkBlock }) {
|
|||||||
d={inkPath(stroke)}
|
d={inkPath(stroke)}
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke={inkColor(stroke.color)}
|
stroke={inkColor(stroke.color)}
|
||||||
strokeWidth={Math.max(stroke.width ?? 140, 1)}
|
strokeWidth={Math.min(
|
||||||
|
Math.max(stroke.width ?? 140, 1),
|
||||||
|
1_000_000
|
||||||
|
)}
|
||||||
strokeOpacity={
|
strokeOpacity={
|
||||||
stroke.transparency === undefined
|
stroke.transparency === undefined
|
||||||
? undefined
|
? undefined
|
||||||
|
|||||||
@@ -121,6 +121,75 @@ describe('OneNote rich-content model', () => {
|
|||||||
).toBeUndefined();
|
).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('retains an embedded-file node as a downloadable lazy resource', () => {
|
||||||
|
const guid = '{22222222-2222-2222-2222-222222222222}';
|
||||||
|
const attachmentId = id(guid, 1);
|
||||||
|
const containerId = id(guid, 2);
|
||||||
|
const payload = Uint8Array.of(1, 2, 3, 4);
|
||||||
|
const attachment = object(
|
||||||
|
attachmentId,
|
||||||
|
JCID.EmbeddedFileNode,
|
||||||
|
{
|
||||||
|
...emptyProps(),
|
||||||
|
objectIds: [compact(2)],
|
||||||
|
properties: {
|
||||||
|
entries: [
|
||||||
|
referenceEntry(PROPERTY.EmbeddedFileContainer, 'one'),
|
||||||
|
bytesEntry(
|
||||||
|
PROPERTY.EmbeddedFileName,
|
||||||
|
Buffer.from('report.txt', 'utf16le')
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
guid
|
||||||
|
);
|
||||||
|
const container = object(
|
||||||
|
containerId,
|
||||||
|
JCID.EmbeddedFileContainer,
|
||||||
|
emptyProps(),
|
||||||
|
guid
|
||||||
|
);
|
||||||
|
container.fileData = {
|
||||||
|
referenceKind: 'embedded',
|
||||||
|
dataReference: '<ifndf>{22222222-2222-2222-2222-222222222222}',
|
||||||
|
extension: '.txt',
|
||||||
|
blob: { source: payload, offset: 0, size: payload.length },
|
||||||
|
};
|
||||||
|
const resources = new Map();
|
||||||
|
const space: ObjectSpace = {
|
||||||
|
id: id(guid, 0),
|
||||||
|
roots: new Map(),
|
||||||
|
objects: new Map([
|
||||||
|
[exGuidKey(attachment.id), attachment],
|
||||||
|
[exGuidKey(container.id), container],
|
||||||
|
]),
|
||||||
|
};
|
||||||
|
|
||||||
|
const blocks = parseContentObjects([attachmentId], {
|
||||||
|
space,
|
||||||
|
limits: { ...DEFAULT_ONENOTE_PARSER_LIMITS },
|
||||||
|
diagnostics: [],
|
||||||
|
resources,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(blocks).toEqual([
|
||||||
|
expect.objectContaining({
|
||||||
|
kind: 'attachment',
|
||||||
|
filename: 'report.txt',
|
||||||
|
size: 4,
|
||||||
|
resourceId: exGuidKey(containerId),
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
expect(resources.get(exGuidKey(containerId))).toMatchObject({
|
||||||
|
kind: 'attachment',
|
||||||
|
extension: 'txt',
|
||||||
|
mediaType: 'text/plain',
|
||||||
|
availability: 'available',
|
||||||
|
size: 4,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('bounds aggregate ink point expansion', () => {
|
it('bounds aggregate ink point expansion', () => {
|
||||||
const model = parseOneNoteSectionContent(fixture, {
|
const model = parseOneNoteSectionContent(fixture, {
|
||||||
limits: { maxInkPoints: 100 },
|
limits: { maxInkPoints: 100 },
|
||||||
|
|||||||
Reference in New Issue
Block a user