You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-11-23 22:36:32 +02:00
This commit is contained in:
@@ -9,6 +9,7 @@ import InteropService from './InteropService';
|
|||||||
import InteropService_Importer_OneNote from './InteropService_Importer_OneNote';
|
import InteropService_Importer_OneNote from './InteropService_Importer_OneNote';
|
||||||
import { JSDOM } from 'jsdom';
|
import { JSDOM } from 'jsdom';
|
||||||
import { ImportModuleOutputFormat } from './types';
|
import { ImportModuleOutputFormat } from './types';
|
||||||
|
import HtmlToMd from '../../HtmlToMd';
|
||||||
|
|
||||||
const instructionMessage = `
|
const instructionMessage = `
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
@@ -26,6 +27,21 @@ const removeItemIds = (body: string) => {
|
|||||||
return body.replace(/:\/[a-z0-9]{32}/g, ':/id-here');
|
return body.replace(/:\/[a-z0-9]{32}/g, ':/id-here');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const removeDefaultCss = (body: string) => {
|
||||||
|
const defaultCssStart = body.indexOf('/*** Start default CSS ***/');
|
||||||
|
const endMarker = '/*** End default CSS ***/';
|
||||||
|
const defaultCssEnd = body.indexOf(endMarker);
|
||||||
|
if (defaultCssEnd === -1 || defaultCssStart === -1) return body;
|
||||||
|
|
||||||
|
const before = body.substring(0, defaultCssStart);
|
||||||
|
const after = body.substring(defaultCssEnd + endMarker.length);
|
||||||
|
return [before, '/* (For testing: Removed default CSS) */', after].join('\n');
|
||||||
|
};
|
||||||
|
|
||||||
|
const normalizeNoteForSnapshot = (body: string) => {
|
||||||
|
return removeItemIds(removeDefaultCss(body));
|
||||||
|
};
|
||||||
|
|
||||||
// This file is ignored if not running in CI. Look at onenote-converter/README.md and jest.config.js for more information
|
// This file is ignored if not running in CI. Look at onenote-converter/README.md and jest.config.js for more information
|
||||||
describe('InteropService_Importer_OneNote', () => {
|
describe('InteropService_Importer_OneNote', () => {
|
||||||
let tempDir: string;
|
let tempDir: string;
|
||||||
@@ -68,7 +84,7 @@ describe('InteropService_Importer_OneNote', () => {
|
|||||||
|
|
||||||
expectWithInstructions(mainNote.title).toBe('Page title');
|
expectWithInstructions(mainNote.title).toBe('Page title');
|
||||||
expectWithInstructions(mainNote.markup_language).toBe(MarkupToHtml.MARKUP_LANGUAGE_HTML);
|
expectWithInstructions(mainNote.markup_language).toBe(MarkupToHtml.MARKUP_LANGUAGE_HTML);
|
||||||
expectWithInstructions(mainNote.body).toMatchSnapshot(mainNote.title);
|
expectWithInstructions(normalizeNoteForSnapshot(mainNote.body)).toMatchSnapshot(mainNote.title);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should preserve indentation of subpages in Section page', async () => {
|
it('should preserve indentation of subpages in Section page', async () => {
|
||||||
@@ -121,7 +137,7 @@ describe('InteropService_Importer_OneNote', () => {
|
|||||||
expectWithInstructions(notes.filter(n => n.parent_id === parentSection.id).length).toBe(6);
|
expectWithInstructions(notes.filter(n => n.parent_id === parentSection.id).length).toBe(6);
|
||||||
|
|
||||||
for (const note of notes) {
|
for (const note of notes) {
|
||||||
expectWithInstructions(note.body).toMatchSnapshot(note.title);
|
expectWithInstructions(normalizeNoteForSnapshot(note.body)).toMatchSnapshot(note.title);
|
||||||
}
|
}
|
||||||
BaseModel.setIdGenerator(originalIdGenerator);
|
BaseModel.setIdGenerator(originalIdGenerator);
|
||||||
});
|
});
|
||||||
@@ -186,7 +202,9 @@ describe('InteropService_Importer_OneNote', () => {
|
|||||||
const originalIdGenerator = BaseModel.setIdGenerator(() => String(idx++));
|
const originalIdGenerator = BaseModel.setIdGenerator(() => String(idx++));
|
||||||
const notes = await importNote(`${supportDir}/onenote/bug_broken_character.zip`);
|
const notes = await importNote(`${supportDir}/onenote/bug_broken_character.zip`);
|
||||||
|
|
||||||
expectWithInstructions(notes.find(n => n.title === 'Action research - Wikipedia').body).toMatchSnapshot();
|
expectWithInstructions(
|
||||||
|
normalizeNoteForSnapshot(notes.find(n => n.title === 'Action research - Wikipedia').body),
|
||||||
|
).toMatchSnapshot();
|
||||||
|
|
||||||
BaseModel.setIdGenerator(originalIdGenerator);
|
BaseModel.setIdGenerator(originalIdGenerator);
|
||||||
});
|
});
|
||||||
@@ -197,7 +215,7 @@ describe('InteropService_Importer_OneNote', () => {
|
|||||||
const notes = await importNote(`${supportDir}/onenote/remove_hyperlink_on_title.zip`);
|
const notes = await importNote(`${supportDir}/onenote/remove_hyperlink_on_title.zip`);
|
||||||
|
|
||||||
for (const note of notes) {
|
for (const note of notes) {
|
||||||
expectWithInstructions(note.body).toMatchSnapshot(note.title);
|
expectWithInstructions(normalizeNoteForSnapshot(note.body)).toMatchSnapshot(note.title);
|
||||||
}
|
}
|
||||||
BaseModel.setIdGenerator(originalIdGenerator);
|
BaseModel.setIdGenerator(originalIdGenerator);
|
||||||
});
|
});
|
||||||
@@ -217,7 +235,7 @@ describe('InteropService_Importer_OneNote', () => {
|
|||||||
const notes = await importNote(`${supportDir}/onenote/hyperlink_marker_as_first_character.zip`);
|
const notes = await importNote(`${supportDir}/onenote/hyperlink_marker_as_first_character.zip`);
|
||||||
|
|
||||||
for (const note of notes) {
|
for (const note of notes) {
|
||||||
expectWithInstructions(note.body).toMatchSnapshot(note.title);
|
expectWithInstructions(normalizeNoteForSnapshot(note.body)).toMatchSnapshot(note.title);
|
||||||
}
|
}
|
||||||
BaseModel.setIdGenerator(originalIdGenerator);
|
BaseModel.setIdGenerator(originalIdGenerator);
|
||||||
});
|
});
|
||||||
@@ -230,7 +248,7 @@ describe('InteropService_Importer_OneNote', () => {
|
|||||||
expectWithInstructions(notes.length).toBe(2);
|
expectWithInstructions(notes.length).toBe(2);
|
||||||
|
|
||||||
for (const note of notes) {
|
for (const note of notes) {
|
||||||
expectWithInstructions(note.body).toMatchSnapshot(note.title);
|
expectWithInstructions(normalizeNoteForSnapshot(note.body)).toMatchSnapshot(note.title);
|
||||||
}
|
}
|
||||||
BaseModel.setIdGenerator(originalIdGenerator);
|
BaseModel.setIdGenerator(originalIdGenerator);
|
||||||
});
|
});
|
||||||
@@ -243,7 +261,7 @@ describe('InteropService_Importer_OneNote', () => {
|
|||||||
expectWithInstructions(notes.length).toBe(2);
|
expectWithInstructions(notes.length).toBe(2);
|
||||||
|
|
||||||
for (const note of notes) {
|
for (const note of notes) {
|
||||||
expectWithInstructions(note.body).toMatchSnapshot(note.title);
|
expectWithInstructions(normalizeNoteForSnapshot(note.body)).toMatchSnapshot(note.title);
|
||||||
}
|
}
|
||||||
BaseModel.setIdGenerator(originalIdGenerator);
|
BaseModel.setIdGenerator(originalIdGenerator);
|
||||||
});
|
});
|
||||||
@@ -253,11 +271,11 @@ describe('InteropService_Importer_OneNote', () => {
|
|||||||
|
|
||||||
// InkBias bug
|
// InkBias bug
|
||||||
const note1Content = notes.find(n => n.title === 'Marketing Funnel & Training').body;
|
const note1Content = notes.find(n => n.title === 'Marketing Funnel & Training').body;
|
||||||
expect(removeItemIds(note1Content)).toMatchSnapshot();
|
expect(normalizeNoteForSnapshot(note1Content)).toMatchSnapshot();
|
||||||
|
|
||||||
// EntityGuid
|
// EntityGuid
|
||||||
const note2Content = notes.find(n => n.title === 'Decrease support costs').body;
|
const note2Content = notes.find(n => n.title === 'Decrease support costs').body;
|
||||||
expect(removeItemIds(note2Content)).toMatchSnapshot();
|
expect(normalizeNoteForSnapshot(note2Content)).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support directly importing .one files', async () => {
|
it('should support directly importing .one files', async () => {
|
||||||
@@ -277,7 +295,16 @@ describe('InteropService_Importer_OneNote', () => {
|
|||||||
it('should support importing .one files that contain checkboxes', async () => {
|
it('should support importing .one files that contain checkboxes', async () => {
|
||||||
const notes = await importNote(`${supportDir}/onenote/checkboxes_and_unicode.one`);
|
const notes = await importNote(`${supportDir}/onenote/checkboxes_and_unicode.one`);
|
||||||
expectWithInstructions(
|
expectWithInstructions(
|
||||||
removeItemIds(notes.find(n => n.title.startsWith('Test Todo')).body),
|
normalizeNoteForSnapshot(notes.find(n => n.title.startsWith('Test Todo')).body),
|
||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should correctly convert imported notes to Markdown', async () => {
|
||||||
|
const notes = await importNote(`${supportDir}/onenote/checkboxes_and_unicode.one`);
|
||||||
|
const checklistNote = notes.find(n => n.title.startsWith('Test Todo'));
|
||||||
|
const converter = new HtmlToMd();
|
||||||
|
const markdown = converter.parse(checklistNote.body);
|
||||||
|
|
||||||
|
expect(markdown).toMatchSnapshot('Test Todo: As Markdown');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -104,19 +104,9 @@ exports[`InteropService_Importer_OneNote should be able to create notes from cor
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>title</title>
|
<title>title</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; font-weight: normal; }
|
|
||||||
table, tr, td { border-color: #A3A3A3; }
|
|
||||||
ul, ol { padding: 0; }
|
|
||||||
.title .outline-element { display: inline; }
|
|
||||||
.title .outline-element:nth-child(2) { margin-left: 10px !important; }
|
|
||||||
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
|
||||||
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
|
||||||
.ink-text { top: 0; left: 0; }
|
|
||||||
.note-tag-icon { position: relative; }
|
|
||||||
|
|
||||||
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
/* (For testing: Removed default CSS) */
|
||||||
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
|
||||||
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -138,25 +128,41 @@ exports[`InteropService_Importer_OneNote should be able to create notes from cor
|
|||||||
</html>"
|
</html>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`InteropService_Importer_OneNote should correctly convert imported notes to Markdown: Test Todo: As Markdown 1`] = `
|
||||||
|
" Test Todo : cases à cocher lien vers doc sur partage
|
||||||
|
|
||||||
|
Test Todo : cases à cocher lien vers doc sur partage
|
||||||
|
|
||||||
|
jeudi 23 octobre 2025
|
||||||
|
|
||||||
|
09:24
|
||||||
|
|
||||||
|
## Todo HBA
|
||||||
|
|
||||||
|
- [x] Rédiger carnet MS-OneNote jeu d'essai (case cochée)
|
||||||
|
- [ ] Transmettre aux dev Joplin (case non cochée)
|
||||||
|
- [x] Exporter le carnet en \\*.packageone (case cochée)
|
||||||
|
- [ ] Exporter des page en \\*.one (case non cochée)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Todo Team appli
|
||||||
|
|
||||||
|
- [ ] Rédiger compte-rendu réunion de service
|
||||||
|
- [ ] Rédiger présentation service Joplin et fonctionnalités complémentaires associée à JBS
|
||||||
|
la doc sur le partage : [\\\\\\\\mondomaine.local\\\\partage\\\\DSI\\\\Projets Techniques 2025\\\\Remplacement Office\\\\JOPLIN_Alternatives_OneNote\\\\formation](file:///\\\\mondomaine.local\\partage\\DSI\\Projets%20Techniques%202025\\Remplacement%20Office\\JOPLIN_Alternatives_OneNote\\formation)
|
||||||
|
- [x] Documenter configuration synchro JBS saml pour un utilisateur (case cochée)"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`InteropService_Importer_OneNote should expect notes to be rendered the same: A page can have any width it wants 1`] = `
|
exports[`InteropService_Importer_OneNote should expect notes to be rendered the same: A page can have any width it wants 1`] = `
|
||||||
"<!DOCTYPE HTML>
|
"<!DOCTYPE HTML>
|
||||||
<html lang="en"><head>
|
<html lang="en"><head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>A page can have any width it wants?</title>
|
<title>A page can have any width it wants?</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; font-weight: normal; }
|
|
||||||
table, tr, td { border-color: #A3A3A3; }
|
|
||||||
ul, ol { padding: 0; }
|
|
||||||
.title .outline-element { display: inline; }
|
|
||||||
.title .outline-element:nth-child(2) { margin-left: 10px !important; }
|
|
||||||
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
|
||||||
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
|
||||||
.ink-text { top: 0; left: 0; }
|
|
||||||
.note-tag-icon { position: relative; }
|
|
||||||
|
|
||||||
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
/* (For testing: Removed default CSS) */
|
||||||
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
|
||||||
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -186,19 +192,9 @@ exports[`InteropService_Importer_OneNote should expect notes to be rendered the
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>A page with a lot of svgs</title>
|
<title>A page with a lot of svgs</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; font-weight: normal; }
|
|
||||||
table, tr, td { border-color: #A3A3A3; }
|
|
||||||
ul, ol { padding: 0; }
|
|
||||||
.title .outline-element { display: inline; }
|
|
||||||
.title .outline-element:nth-child(2) { margin-left: 10px !important; }
|
|
||||||
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
|
||||||
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
|
||||||
.ink-text { top: 0; left: 0; }
|
|
||||||
.note-tag-icon { position: relative; }
|
|
||||||
|
|
||||||
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
/* (For testing: Removed default CSS) */
|
||||||
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
|
||||||
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -226,19 +222,9 @@ exports[`InteropService_Importer_OneNote should expect notes to be rendered the
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>A page with text and drawing above it</title>
|
<title>A page with text and drawing above it</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; font-weight: normal; }
|
|
||||||
table, tr, td { border-color: #A3A3A3; }
|
|
||||||
ul, ol { padding: 0; }
|
|
||||||
.title .outline-element { display: inline; }
|
|
||||||
.title .outline-element:nth-child(2) { margin-left: 10px !important; }
|
|
||||||
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
|
||||||
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
|
||||||
.ink-text { top: 0; left: 0; }
|
|
||||||
.note-tag-icon { position: relative; }
|
|
||||||
|
|
||||||
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
/* (For testing: Removed default CSS) */
|
||||||
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
|
||||||
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -272,19 +258,9 @@ exports[`InteropService_Importer_OneNote should expect notes to be rendered the
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>A simple filename</title>
|
<title>A simple filename</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; font-weight: normal; }
|
|
||||||
table, tr, td { border-color: #A3A3A3; }
|
|
||||||
ul, ol { padding: 0; }
|
|
||||||
.title .outline-element { display: inline; }
|
|
||||||
.title .outline-element:nth-child(2) { margin-left: 10px !important; }
|
|
||||||
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
|
||||||
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
|
||||||
.ink-text { top: 0; left: 0; }
|
|
||||||
.note-tag-icon { position: relative; }
|
|
||||||
|
|
||||||
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
/* (For testing: Removed default CSS) */
|
||||||
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
|
||||||
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -312,19 +288,9 @@ exports[`InteropService_Importer_OneNote should expect notes to be rendered the
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Page with more than one font size</title>
|
<title>Page with more than one font size</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; font-weight: normal; }
|
|
||||||
table, tr, td { border-color: #A3A3A3; }
|
|
||||||
ul, ol { padding: 0; }
|
|
||||||
.title .outline-element { display: inline; }
|
|
||||||
.title .outline-element:nth-child(2) { margin-left: 10px !important; }
|
|
||||||
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
|
||||||
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
|
||||||
.ink-text { top: 0; left: 0; }
|
|
||||||
.note-tag-icon { position: relative; }
|
|
||||||
|
|
||||||
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
/* (For testing: Removed default CSS) */
|
||||||
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
|
||||||
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -462,19 +428,9 @@ exports[`InteropService_Importer_OneNote should expect notes to be rendered the
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>text</title>
|
<title>text</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; font-weight: normal; }
|
|
||||||
table, tr, td { border-color: #A3A3A3; }
|
|
||||||
ul, ol { padding: 0; }
|
|
||||||
.title .outline-element { display: inline; }
|
|
||||||
.title .outline-element:nth-child(2) { margin-left: 10px !important; }
|
|
||||||
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
|
||||||
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
|
||||||
.ink-text { top: 0; left: 0; }
|
|
||||||
.note-tag-icon { position: relative; }
|
|
||||||
|
|
||||||
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
/* (For testing: Removed default CSS) */
|
||||||
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
|
||||||
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -814,19 +770,9 @@ exports[`InteropService_Importer_OneNote should ignore broken characters at the
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Action research - Wikipedia</title>
|
<title>Action research - Wikipedia</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; font-weight: normal; }
|
|
||||||
table, tr, td { border-color: #A3A3A3; }
|
|
||||||
ul, ol { padding: 0; }
|
|
||||||
.title .outline-element { display: inline; }
|
|
||||||
.title .outline-element:nth-child(2) { margin-left: 10px !important; }
|
|
||||||
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
|
||||||
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
|
||||||
.ink-text { top: 0; left: 0; }
|
|
||||||
.note-tag-icon { position: relative; }
|
|
||||||
|
|
||||||
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
/* (For testing: Removed default CSS) */
|
||||||
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
|
||||||
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
|
||||||
|
|
||||||
.list-0 li { padding-left: 10px; }
|
.list-0 li { padding-left: 10px; }
|
||||||
.list-0 li::marker { content: '•'; font-family: Georgia; }
|
.list-0 li::marker { content: '•'; font-family: Georgia; }
|
||||||
@@ -887,19 +833,9 @@ exports[`InteropService_Importer_OneNote should import a simple OneNote notebook
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Page title</title>
|
<title>Page title</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; font-weight: normal; }
|
|
||||||
table, tr, td { border-color: #A3A3A3; }
|
|
||||||
ul, ol { padding: 0; }
|
|
||||||
.title .outline-element { display: inline; }
|
|
||||||
.title .outline-element:nth-child(2) { margin-left: 10px !important; }
|
|
||||||
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
|
||||||
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
|
||||||
.ink-text { top: 0; left: 0; }
|
|
||||||
.note-tag-icon { position: relative; }
|
|
||||||
|
|
||||||
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
/* (For testing: Removed default CSS) */
|
||||||
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
|
||||||
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -1031,19 +967,9 @@ exports[`InteropService_Importer_OneNote should remove hyperlink from title: Tip
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Tips from a Pro: Using Trees for Dramatic Landscape Photography</title>
|
<title>Tips from a Pro: Using Trees for Dramatic Landscape Photography</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; font-weight: normal; }
|
|
||||||
table, tr, td { border-color: #A3A3A3; }
|
|
||||||
ul, ol { padding: 0; }
|
|
||||||
.title .outline-element { display: inline; }
|
|
||||||
.title .outline-element:nth-child(2) { margin-left: 10px !important; }
|
|
||||||
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
|
||||||
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
|
||||||
.ink-text { top: 0; left: 0; }
|
|
||||||
.note-tag-icon { position: relative; }
|
|
||||||
|
|
||||||
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
/* (For testing: Removed default CSS) */
|
||||||
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
|
||||||
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -1072,19 +998,9 @@ exports[`InteropService_Importer_OneNote should remove hyperlink from title: wik
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>wikipedia link</title>
|
<title>wikipedia link</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; font-weight: normal; }
|
|
||||||
table, tr, td { border-color: #A3A3A3; }
|
|
||||||
ul, ol { padding: 0; }
|
|
||||||
.title .outline-element { display: inline; }
|
|
||||||
.title .outline-element:nth-child(2) { margin-left: 10px !important; }
|
|
||||||
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
|
||||||
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
|
||||||
.ink-text { top: 0; left: 0; }
|
|
||||||
.note-tag-icon { position: relative; }
|
|
||||||
|
|
||||||
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
/* (For testing: Removed default CSS) */
|
||||||
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
|
||||||
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -1113,19 +1029,9 @@ exports[`InteropService_Importer_OneNote should remove hyperlink from title: 风
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>风景 (Web view)</title>
|
<title>风景 (Web view)</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; font-weight: normal; }
|
|
||||||
table, tr, td { border-color: #A3A3A3; }
|
|
||||||
ul, ol { padding: 0; }
|
|
||||||
.title .outline-element { display: inline; }
|
|
||||||
.title .outline-element:nth-child(2) { margin-left: 10px !important; }
|
|
||||||
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
|
||||||
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
|
||||||
.ink-text { top: 0; left: 0; }
|
|
||||||
.note-tag-icon { position: relative; }
|
|
||||||
|
|
||||||
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
/* (For testing: Removed default CSS) */
|
||||||
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
|
||||||
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -1154,19 +1060,9 @@ exports[`InteropService_Importer_OneNote should remove hyperlink from title: 风
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>风景</title>
|
<title>风景</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; font-weight: normal; }
|
|
||||||
table, tr, td { border-color: #A3A3A3; }
|
|
||||||
ul, ol { padding: 0; }
|
|
||||||
.title .outline-element { display: inline; }
|
|
||||||
.title .outline-element:nth-child(2) { margin-left: 10px !important; }
|
|
||||||
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
|
||||||
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
|
||||||
.ink-text { top: 0; left: 0; }
|
|
||||||
.note-tag-icon { position: relative; }
|
|
||||||
|
|
||||||
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
/* (For testing: Removed default CSS) */
|
||||||
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
|
||||||
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -1194,19 +1090,9 @@ exports[`InteropService_Importer_OneNote should render audio as links to resourc
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>My title</title>
|
<title>My title</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; font-weight: normal; }
|
|
||||||
table, tr, td { border-color: #A3A3A3; }
|
|
||||||
ul, ol { padding: 0; }
|
|
||||||
.title .outline-element { display: inline; }
|
|
||||||
.title .outline-element:nth-child(2) { margin-left: 10px !important; }
|
|
||||||
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
|
||||||
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
|
||||||
.ink-text { top: 0; left: 0; }
|
|
||||||
.note-tag-icon { position: relative; }
|
|
||||||
|
|
||||||
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
/* (For testing: Removed default CSS) */
|
||||||
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
|
||||||
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -1337,19 +1223,9 @@ exports[`InteropService_Importer_OneNote should render links properly by ignorin
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Is Mexico safe for shooting Street Photography?</title>
|
<title>Is Mexico safe for shooting Street Photography?</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; font-weight: normal; }
|
|
||||||
table, tr, td { border-color: #A3A3A3; }
|
|
||||||
ul, ol { padding: 0; }
|
|
||||||
.title .outline-element { display: inline; }
|
|
||||||
.title .outline-element:nth-child(2) { margin-left: 10px !important; }
|
|
||||||
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
|
||||||
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
|
||||||
.ink-text { top: 0; left: 0; }
|
|
||||||
.note-tag-icon { position: relative; }
|
|
||||||
|
|
||||||
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
/* (For testing: Removed default CSS) */
|
||||||
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
|
||||||
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -1476,27 +1352,17 @@ exports[`InteropService_Importer_OneNote should support importing .one files tha
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Test Todo : cases à cocher lien vers doc sur partage</title>
|
<title>Test Todo : cases à cocher lien vers doc sur partage</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; font-weight: normal; }
|
|
||||||
table, tr, td { border-color: #A3A3A3; }
|
|
||||||
ul, ol { padding: 0; }
|
|
||||||
.title .outline-element { display: inline; }
|
|
||||||
.title .outline-element:nth-child(2) { margin-left: 10px !important; }
|
|
||||||
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
|
||||||
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
|
||||||
.ink-text { top: 0; left: 0; }
|
|
||||||
.note-tag-icon { position: relative; }
|
|
||||||
|
|
||||||
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
/* (For testing: Removed default CSS) */
|
||||||
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
|
||||||
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
|
||||||
|
|
||||||
.icon-0 > svg, .icon-0 > img { fill: #4673b7; height: 20px; left: -25px; width: 20px; }
|
|
||||||
.icon-1 > svg, .icon-1 > img { fill: #4673b7; height: 20px; left: -25px; width: 20px; }
|
.icon-0 > svg, .icon-0 > img { fill: #4673b7; }
|
||||||
.icon-2 > svg, .icon-2 > img { fill: #4673b7; height: 20px; left: -25px; width: 20px; }
|
.icon-1 > svg, .icon-1 > img { fill: #4673b7; }
|
||||||
.icon-3 > svg, .icon-3 > img { fill: #4673b7; height: 20px; left: -25px; width: 20px; }
|
.icon-2 > svg, .icon-2 > img { fill: #4673b7; }
|
||||||
.icon-4 > svg, .icon-4 > img { fill: #4673b7; height: 20px; left: -25px; width: 20px; }
|
.icon-3 > svg, .icon-3 > img { fill: #4673b7; }
|
||||||
.icon-5 > svg, .icon-5 > img { fill: #4673b7; height: 20px; left: -25px; width: 20px; }
|
.icon-4 > svg, .icon-4 > img { fill: #4673b7; }
|
||||||
.icon-6 > svg, .icon-6 > img { fill: #4673b7; height: 20px; left: -25px; width: 20px; }
|
.icon-5 > svg, .icon-5 > img { fill: #4673b7; }
|
||||||
|
.icon-6 > svg, .icon-6 > img { fill: #4673b7; }
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
@@ -1506,23 +1372,23 @@ exports[`InteropService_Importer_OneNote should support importing .one files tha
|
|||||||
</div><div class="container-outline"><div class="outline-element" style="margin-left: 0px;"><span style="color: rgb(118,118,118); font-family: Calibri; font-size: 10pt; line-height: 16px;">jeudi 23 octobre 2025</span></div>
|
</div><div class="container-outline"><div class="outline-element" style="margin-left: 0px;"><span style="color: rgb(118,118,118); font-family: Calibri; font-size: 10pt; line-height: 16px;">jeudi 23 octobre 2025</span></div>
|
||||||
<div class="outline-element" style="margin-left: 0px;"><span style="color: rgb(118,118,118); font-family: Calibri; font-size: 10pt; line-height: 16px;">09:24</span></div>
|
<div class="outline-element" style="margin-left: 0px;"><span style="color: rgb(118,118,118); font-family: Calibri; font-size: 10pt; line-height: 16px;">09:24</span></div>
|
||||||
</div></div><div class="container-outline" style="left: 48px; position: absolute; top: 115px; width: 720px;"><div class="outline-element" style="margin-left: 0px;"><h2 style="color: rgb(46,117,181); font-family: Calibri; font-size: 14pt; line-height: 22px;">Todo HBA</h2></div>
|
</div></div><div class="container-outline" style="left: 48px; position: absolute; top: 115px; width: 720px;"><div class="outline-element" style="margin-left: 0px;"><h2 style="color: rgb(46,117,181); font-family: Calibri; font-size: 14pt; line-height: 22px;">Todo HBA</h2></div>
|
||||||
<div class="outline-element" style="margin-left: 0px;"><p style="font-family: Calibri; font-size: 11pt; line-height: 17px;"><span class="note-tag-icon icon-0"><img alt="Checked" src=":/id-here">
|
<ul class="tagged-list"><li class="outline-element" style="margin-left: 0px;"><span style="font-family: Calibri; font-size: 11pt; line-height: 17px;"><span aria-checked="true" aria-disabled="true" class="note-tag-icon icon-0 -checkbox -large" role="checkbox"><img alt="Checked" src=":/id-here">
|
||||||
</span>Rédiger carnet MS-OneNote jeu d'essai (case cochée)</p></div>
|
</span>Rédiger carnet MS-OneNote jeu d'essai (case cochée)</span></li>
|
||||||
<div class="outline-element" style="margin-left: 0px;"><p style="font-family: Calibri; font-size: 11pt; line-height: 17px;"><span class="note-tag-icon icon-1"><img class="checkbox-icon" alt="Unchecked" src=":/id-here">
|
<li class="outline-element" style="margin-left: 0px;"><span style="font-family: Calibri; font-size: 11pt; line-height: 17px;"><span aria-checked="false" aria-disabled="true" class="note-tag-icon icon-1 -checkbox -large" role="checkbox"><img class="checkbox-icon" alt="Unchecked" src=":/id-here">
|
||||||
</span>Transmettre aux dev Joplin (case non cochée)</p></div><div class="outline-element" style="margin-left: 36px;"><p style="font-family: Calibri; font-size: 11pt; line-height: 17px;"><span class="note-tag-icon icon-2"><img alt="Checked" src=":/id-here">
|
</span>Transmettre aux dev Joplin (case non cochée)</span><ul class="tagged-list"><li class="outline-element" style="margin-left: 36px;"><span style="font-family: Calibri; font-size: 11pt; line-height: 17px;"><span aria-checked="true" aria-disabled="true" class="note-tag-icon icon-2 -checkbox -large" role="checkbox"><img alt="Checked" src=":/id-here">
|
||||||
</span>Exporter le carnet en *.packageone (case cochée)</p></div>
|
</span>Exporter le carnet en *.packageone (case cochée)</span></li>
|
||||||
<div class="outline-element" style="margin-left: 36px;"><p style="font-family: Calibri; font-size: 11pt; line-height: 17px;"><span class="note-tag-icon icon-3"><img class="checkbox-icon" alt="Unchecked" src=":/id-here">
|
<li class="outline-element" style="margin-left: 36px;"><span style="font-family: Calibri; font-size: 11pt; line-height: 17px;"><span aria-checked="false" aria-disabled="true" class="note-tag-icon icon-3 -checkbox -large" role="checkbox"><img class="checkbox-icon" alt="Unchecked" src=":/id-here">
|
||||||
</span>Exporter des page en *.one (case non cochée)</p></div>
|
</span>Exporter des page en *.one (case non cochée)</span></li>
|
||||||
|
</ul></li>
|
||||||
<div class="outline-element" style="margin-left: 0px;"><p style="font-family: Calibri; font-size: 11pt; line-height: 17px;"> </p></div>
|
</ul><div class="outline-element" style="margin-left: 0px;"><p style="font-family: Calibri; font-size: 11pt; line-height: 17px;"> </p></div>
|
||||||
<div class="outline-element" style="margin-left: 0px;"><h2 style="color: rgb(46,117,181); font-family: Calibri; font-size: 14pt; line-height: 22px;">Todo Team appli</h2></div>
|
<div class="outline-element" style="margin-left: 0px;"><h2 style="color: rgb(46,117,181); font-family: Calibri; font-size: 14pt; line-height: 22px;">Todo Team appli</h2></div>
|
||||||
<div class="outline-element" style="margin-left: 0px;"><p style="font-family: Calibri; font-size: 11pt; line-height: 17px;"><span class="note-tag-icon icon-4"><img class="checkbox-icon" alt="Unchecked" src=":/id-here">
|
<ul class="tagged-list"><li class="outline-element" style="margin-left: 0px;"><span style="font-family: Calibri; font-size: 11pt; line-height: 17px;"><span aria-checked="false" aria-disabled="true" class="note-tag-icon icon-4 -checkbox -large" role="checkbox"><img class="checkbox-icon" alt="Unchecked" src=":/id-here">
|
||||||
</span>Rédiger compte-rendu réunion de service</p></div>
|
</span>Rédiger compte-rendu réunion de service</span></li>
|
||||||
<div class="outline-element" style="margin-left: 0px;"><p style="font-family: Calibri; font-size: 11pt; line-height: 17px;"><span class="note-tag-icon icon-5"><img class="checkbox-icon" alt="Unchecked" src=":/id-here">
|
<li class="outline-element" style="margin-left: 0px;"><span style="font-family: Calibri; font-size: 11pt; line-height: 17px;"><span aria-checked="false" aria-disabled="true" class="note-tag-icon icon-5 -checkbox -large" role="checkbox"><img class="checkbox-icon" alt="Unchecked" src=":/id-here">
|
||||||
</span>Rédiger présentation service Joplin et fonctionnalités complémentaires associée à JBS<br>la doc sur le partage : <a href="file:///\\\\mondomaine.local\\partage\\DSI\\Projets%20Techniques%202025\\Remplacement%20Office\\JOPLIN_Alternatives_OneNote\\formation" style="">\\\\mondomaine.local\\partage\\DSI\\Projets Techniques 2025\\Remplacement Office\\JOPLIN_Alternatives_OneNote\\formation</a> </p></div><div class="outline-element" style="margin-left: 36px;"><p style="font-family: Calibri; font-size: 11pt; line-height: 17px;"><span class="note-tag-icon icon-6"><img alt="Checked" src=":/id-here">
|
</span>Rédiger présentation service Joplin et fonctionnalités complémentaires associée à JBS<br>la doc sur le partage : <a href="file:///\\\\mondomaine.local\\partage\\DSI\\Projets%20Techniques%202025\\Remplacement%20Office\\JOPLIN_Alternatives_OneNote\\formation" style="">\\\\mondomaine.local\\partage\\DSI\\Projets Techniques 2025\\Remplacement Office\\JOPLIN_Alternatives_OneNote\\formation</a> </span><ul class="tagged-list"><li class="outline-element" style="margin-left: 36px;"><span style="font-family: Calibri; font-size: 11pt; line-height: 17px;"><span aria-checked="true" aria-disabled="true" class="note-tag-icon icon-6 -checkbox -large" role="checkbox"><img alt="Checked" src=":/id-here">
|
||||||
</span>Documenter configuration synchro JBS saml pour un utilisateur (case cochée)</p></div>
|
</span>Documenter configuration synchro JBS saml pour un utilisateur (case cochée)</span></li>
|
||||||
|
</ul></li>
|
||||||
</div>
|
</ul></div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
if (window.parent !== null) {
|
if (window.parent !== null) {
|
||||||
@@ -1539,19 +1405,9 @@ exports[`InteropService_Importer_OneNote should use default value for EntityGuid
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Marketing Funnel & Training</title>
|
<title>Marketing Funnel & Training</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; font-weight: normal; }
|
|
||||||
table, tr, td { border-color: #A3A3A3; }
|
|
||||||
ul, ol { padding: 0; }
|
|
||||||
.title .outline-element { display: inline; }
|
|
||||||
.title .outline-element:nth-child(2) { margin-left: 10px !important; }
|
|
||||||
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
|
||||||
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
|
||||||
.ink-text { top: 0; left: 0; }
|
|
||||||
.note-tag-icon { position: relative; }
|
|
||||||
|
|
||||||
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
/* (For testing: Removed default CSS) */
|
||||||
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
|
||||||
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -1586,19 +1442,9 @@ exports[`InteropService_Importer_OneNote should use default value for EntityGuid
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Decrease support costs</title>
|
<title>Decrease support costs</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; font-weight: normal; }
|
|
||||||
table, tr, td { border-color: #A3A3A3; }
|
|
||||||
ul, ol { padding: 0; }
|
|
||||||
.title .outline-element { display: inline; }
|
|
||||||
.title .outline-element:nth-child(2) { margin-left: 10px !important; }
|
|
||||||
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
|
||||||
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
|
||||||
.ink-text { top: 0; left: 0; }
|
|
||||||
.note-tag-icon { position: relative; }
|
|
||||||
|
|
||||||
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
/* (For testing: Removed default CSS) */
|
||||||
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
|
||||||
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -18,13 +18,17 @@ impl<'a> Renderer<'a> {
|
|||||||
let mut list_end = None;
|
let mut list_end = None;
|
||||||
|
|
||||||
for (element, parent_level, current_level) in elements {
|
for (element, parent_level, current_level) in elements {
|
||||||
if !in_list && self.is_list(element) {
|
if !in_list && self.is_onenote_list(element) {
|
||||||
let tags = self.list_tags(element);
|
let tags = self.list_tags(element);
|
||||||
let list_start = tags.0;
|
let list_start = tags.0;
|
||||||
list_end = Some(tags.1);
|
list_end = Some(tags.1);
|
||||||
|
|
||||||
contents.push_str(&list_start);
|
contents.push_str(&list_start);
|
||||||
in_list = true;
|
in_list = true;
|
||||||
|
} else if !in_list && self.is_tag_list(element) {
|
||||||
|
contents.push_str("<ul class=\"tagged-list\">");
|
||||||
|
list_end = Some("</ul>".into());
|
||||||
|
in_list = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if in_list && !self.is_list(element) {
|
if in_list && !self.is_list(element) {
|
||||||
@@ -176,7 +180,15 @@ impl<'a> Renderer<'a> {
|
|||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_onenote_list(&self, element: &OutlineElement) -> bool {
|
||||||
|
!element.list_contents().is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_tag_list(&self, element: &OutlineElement) -> bool {
|
||||||
|
self.has_note_tag(element)
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn is_list(&self, element: &OutlineElement) -> bool {
|
pub(crate) fn is_list(&self, element: &OutlineElement) -> bool {
|
||||||
element.list_contents().first().is_some()
|
self.is_onenote_list(element) || self.is_tag_list(element)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::page::Renderer;
|
use crate::page::Renderer;
|
||||||
use crate::utils::StyleSet;
|
use crate::utils::{AttributeSet, StyleSet};
|
||||||
use parser::contents::{NoteTag, OutlineElement};
|
use parser::contents::{NoteTag, OutlineElement};
|
||||||
use parser::property::common::ColorRef;
|
use parser::property::common::ColorRef;
|
||||||
use parser::property::note_tag::{ActionItemStatus, NoteTagShape};
|
use parser::property::note_tag::{ActionItemStatus, NoteTagShape};
|
||||||
@@ -45,6 +45,35 @@ enum IconSize {
|
|||||||
Large,
|
Large,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct NoteTagIcon {
|
||||||
|
html: Cow<'static, str>,
|
||||||
|
size: IconSize,
|
||||||
|
styles: StyleSet,
|
||||||
|
is_checkbox: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(Cow<'static, str>, IconSize)> for NoteTagIcon {
|
||||||
|
fn from((html, size): (Cow<'static, str>, IconSize)) -> Self {
|
||||||
|
Self {
|
||||||
|
html,
|
||||||
|
size,
|
||||||
|
styles: StyleSet::new(),
|
||||||
|
is_checkbox: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(Cow<'static, str>, IconSize, StyleSet)> for NoteTagIcon {
|
||||||
|
fn from((html, size, styles): (Cow<'static, str>, IconSize, StyleSet)) -> Self {
|
||||||
|
Self {
|
||||||
|
html,
|
||||||
|
size,
|
||||||
|
styles,
|
||||||
|
is_checkbox: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> Renderer<'a> {
|
impl<'a> Renderer<'a> {
|
||||||
pub(crate) fn render_with_note_tags(
|
pub(crate) fn render_with_note_tags(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -63,6 +92,55 @@ impl<'a> Renderer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_note_tag_class_names(&mut self, icon: &NoteTagIcon) -> Vec<String> {
|
||||||
|
let mut icon_classes = vec!["note-tag-icon".to_string()];
|
||||||
|
|
||||||
|
if icon.styles.len() > 0 {
|
||||||
|
let class = self.gen_class("icon");
|
||||||
|
icon_classes.push(class.to_string());
|
||||||
|
|
||||||
|
self.global_styles
|
||||||
|
// Select both `svg` and `img`: `svg`s may be replaced with `img` later in the import process:
|
||||||
|
.insert(
|
||||||
|
format!(".{} > svg, .{} > img", class, class),
|
||||||
|
icon.styles.clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if icon.is_checkbox {
|
||||||
|
icon_classes.push("-checkbox".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
if icon.size == IconSize::Large {
|
||||||
|
icon_classes.push("-large".into());
|
||||||
|
} else if icon.size == IconSize::Normal {
|
||||||
|
icon_classes.push("-normal".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
icon_classes
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_note_tag_attrs(
|
||||||
|
&mut self,
|
||||||
|
icon: &NoteTagIcon,
|
||||||
|
status: ActionItemStatus,
|
||||||
|
class_names: &[String],
|
||||||
|
) -> AttributeSet {
|
||||||
|
let mut attrs = AttributeSet::new();
|
||||||
|
attrs.set("class", class_names.join(" "));
|
||||||
|
|
||||||
|
if icon.is_checkbox {
|
||||||
|
attrs.set("role", "checkbox".into());
|
||||||
|
attrs.set(
|
||||||
|
"aria-checked",
|
||||||
|
if status.completed() { "true" } else { "false" }.into(),
|
||||||
|
);
|
||||||
|
attrs.set("aria-disabled", "true".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
attrs
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn render_note_tags(&mut self, note_tags: &[NoteTag]) -> Option<(String, StyleSet)> {
|
pub(crate) fn render_note_tags(&mut self, note_tags: &[NoteTag]) -> Option<(String, StyleSet)> {
|
||||||
let mut markup = String::new();
|
let mut markup = String::new();
|
||||||
let mut styles = StyleSet::new();
|
let mut styles = StyleSet::new();
|
||||||
@@ -82,24 +160,12 @@ impl<'a> Renderer<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if def.shape() != NoteTagShape::NoIcon {
|
if def.shape() != NoteTagShape::NoIcon {
|
||||||
let (icon, icon_style) =
|
let icon = self.note_tag_icon(def.shape(), note_tag.item_status());
|
||||||
self.note_tag_icon(def.shape(), note_tag.item_status());
|
let icon_classes = self.build_note_tag_class_names(&icon);
|
||||||
let mut icon_classes = vec!["note-tag-icon".to_string()];
|
let attrs =
|
||||||
|
self.get_note_tag_attrs(&icon, note_tag.item_status(), &icon_classes);
|
||||||
|
|
||||||
if icon_style.len() > 0 {
|
markup.push_str(&format!("<span {}>{}</span>", attrs, icon.html,));
|
||||||
let class = self.gen_class("icon");
|
|
||||||
icon_classes.push(class.to_string());
|
|
||||||
|
|
||||||
self.global_styles
|
|
||||||
// Select both `svg` and `img`: `svg`s may be replaced with `img` later in the import process:
|
|
||||||
.insert(format!(".{} > svg, .{} > img", class, class), icon_style);
|
|
||||||
}
|
|
||||||
|
|
||||||
markup.push_str(&format!(
|
|
||||||
"<span class=\"{}\">{}</span>",
|
|
||||||
icon_classes.join(" "),
|
|
||||||
icon
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,291 +181,197 @@ impl<'a> Renderer<'a> {
|
|||||||
.any(|text| !text.note_tags().is_empty())
|
.any(|text| !text.note_tags().is_empty())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn note_tag_icon(
|
fn note_tag_icon(&self, shape: NoteTagShape, status: ActionItemStatus) -> NoteTagIcon {
|
||||||
&self,
|
|
||||||
shape: NoteTagShape,
|
|
||||||
status: ActionItemStatus,
|
|
||||||
) -> (Cow<'static, str>, StyleSet) {
|
|
||||||
let mut style = StyleSet::new();
|
|
||||||
|
|
||||||
match shape {
|
match shape {
|
||||||
NoteTagShape::GreenCheckBox => self.icon_checkbox(status, style, COLOR_GREEN),
|
NoteTagShape::GreenCheckBox => self.icon_checkbox(status, COLOR_GREEN),
|
||||||
NoteTagShape::YellowCheckBox => self.icon_checkbox(status, style, COLOR_YELLOW),
|
NoteTagShape::YellowCheckBox => self.icon_checkbox(status, COLOR_YELLOW),
|
||||||
NoteTagShape::BlueCheckBox => self.icon_checkbox(status, style, COLOR_BLUE),
|
NoteTagShape::BlueCheckBox => self.icon_checkbox(status, COLOR_BLUE),
|
||||||
NoteTagShape::GreenStarCheckBox => {
|
NoteTagShape::GreenStarCheckBox => self.icon_checkbox_with_star(status, COLOR_GREEN),
|
||||||
self.icon_checkbox_with_star(status, style, COLOR_GREEN)
|
NoteTagShape::YellowStarCheckBox => self.icon_checkbox_with_star(status, COLOR_YELLOW),
|
||||||
}
|
NoteTagShape::BlueStarCheckBox => self.icon_checkbox_with_star(status, COLOR_BLUE),
|
||||||
NoteTagShape::YellowStarCheckBox => {
|
|
||||||
self.icon_checkbox_with_star(status, style, COLOR_YELLOW)
|
|
||||||
}
|
|
||||||
NoteTagShape::BlueStarCheckBox => {
|
|
||||||
self.icon_checkbox_with_star(status, style, COLOR_BLUE)
|
|
||||||
}
|
|
||||||
NoteTagShape::GreenExclamationCheckBox => {
|
NoteTagShape::GreenExclamationCheckBox => {
|
||||||
self.icon_checkbox_with_exclamation(status, style, COLOR_GREEN)
|
self.icon_checkbox_with_exclamation(status, COLOR_GREEN)
|
||||||
}
|
}
|
||||||
NoteTagShape::YellowExclamationCheckBox => {
|
NoteTagShape::YellowExclamationCheckBox => {
|
||||||
self.icon_checkbox_with_exclamation(status, style, COLOR_YELLOW)
|
self.icon_checkbox_with_exclamation(status, COLOR_YELLOW)
|
||||||
}
|
}
|
||||||
NoteTagShape::BlueExclamationCheckBox => {
|
NoteTagShape::BlueExclamationCheckBox => {
|
||||||
self.icon_checkbox_with_exclamation(status, style, COLOR_BLUE)
|
self.icon_checkbox_with_exclamation(status, COLOR_BLUE)
|
||||||
}
|
}
|
||||||
NoteTagShape::GreenRightArrowCheckBox => {
|
NoteTagShape::GreenRightArrowCheckBox => {
|
||||||
self.icon_checkbox_with_right_arrow(status, style, COLOR_GREEN)
|
self.icon_checkbox_with_right_arrow(status, COLOR_GREEN)
|
||||||
}
|
}
|
||||||
NoteTagShape::YellowRightArrowCheckBox => {
|
NoteTagShape::YellowRightArrowCheckBox => {
|
||||||
self.icon_checkbox_with_right_arrow(status, style, COLOR_YELLOW)
|
self.icon_checkbox_with_right_arrow(status, COLOR_YELLOW)
|
||||||
}
|
}
|
||||||
NoteTagShape::BlueRightArrowCheckBox => {
|
NoteTagShape::BlueRightArrowCheckBox => {
|
||||||
self.icon_checkbox_with_right_arrow(status, style, COLOR_BLUE)
|
self.icon_checkbox_with_right_arrow(status, COLOR_BLUE)
|
||||||
}
|
}
|
||||||
NoteTagShape::YellowStar => {
|
NoteTagShape::YellowStar => {
|
||||||
|
let mut style = StyleSet::new();
|
||||||
style.set("fill", COLOR_YELLOW.to_string());
|
style.set("fill", COLOR_YELLOW.to_string());
|
||||||
|
|
||||||
(
|
(Cow::from(ICON_STAR), IconSize::Normal, style).into()
|
||||||
Cow::from(ICON_STAR),
|
|
||||||
self.icon_style(IconSize::Normal, style),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NoteTagShape::QuestionMark => (
|
NoteTagShape::QuestionMark => (Cow::from(ICON_QUESTION_MARK), IconSize::Normal).into(),
|
||||||
Cow::from(ICON_QUESTION_MARK),
|
|
||||||
self.icon_style(IconSize::Normal, style),
|
|
||||||
),
|
|
||||||
|
|
||||||
NoteTagShape::HighPriority => (
|
NoteTagShape::HighPriority => (Cow::from(ICON_ERROR), IconSize::Normal).into(),
|
||||||
Cow::from(ICON_ERROR),
|
NoteTagShape::ContactInformation => (Cow::from(ICON_PHONE), IconSize::Normal).into(),
|
||||||
self.icon_style(IconSize::Normal, style),
|
|
||||||
),
|
|
||||||
NoteTagShape::ContactInformation => (
|
|
||||||
Cow::from(ICON_PHONE),
|
|
||||||
self.icon_style(IconSize::Normal, style),
|
|
||||||
),
|
|
||||||
|
|
||||||
NoteTagShape::LightBulb => (
|
NoteTagShape::LightBulb => (Cow::from(ICON_LIGHT_BULB), IconSize::Normal).into(),
|
||||||
Cow::from(ICON_LIGHT_BULB),
|
|
||||||
self.icon_style(IconSize::Normal, style),
|
|
||||||
),
|
|
||||||
|
|
||||||
NoteTagShape::Home => (
|
NoteTagShape::Home => (Cow::from(ICON_HOME), IconSize::Normal).into(),
|
||||||
Cow::from(ICON_HOME),
|
NoteTagShape::CommentBubble => (Cow::from(ICON_BUBBLE), IconSize::Normal).into(),
|
||||||
self.icon_style(IconSize::Normal, style),
|
|
||||||
),
|
|
||||||
NoteTagShape::CommentBubble => (
|
|
||||||
Cow::from(ICON_BUBBLE),
|
|
||||||
self.icon_style(IconSize::Normal, style),
|
|
||||||
),
|
|
||||||
|
|
||||||
NoteTagShape::AwardRibbon => (
|
NoteTagShape::AwardRibbon => (Cow::from(ICON_AWARD), IconSize::Normal).into(),
|
||||||
Cow::from(ICON_AWARD),
|
|
||||||
self.icon_style(IconSize::Normal, style),
|
|
||||||
),
|
|
||||||
|
|
||||||
NoteTagShape::BlueCheckBox1 => self.icon_checkbox_with_1(status, style, COLOR_BLUE),
|
NoteTagShape::BlueCheckBox1 => self.icon_checkbox_with_1(status, COLOR_BLUE),
|
||||||
|
|
||||||
NoteTagShape::BlueCheckBox2 => self.icon_checkbox_with_2(status, style, COLOR_BLUE),
|
NoteTagShape::BlueCheckBox2 => self.icon_checkbox_with_2(status, COLOR_BLUE),
|
||||||
|
|
||||||
NoteTagShape::BlueCheckBox3 => self.icon_checkbox_with_3(status, style, COLOR_BLUE),
|
NoteTagShape::BlueCheckBox3 => self.icon_checkbox_with_3(status, COLOR_BLUE),
|
||||||
|
|
||||||
NoteTagShape::BlueCheckMark => self.icon_checkmark(style, COLOR_BLUE),
|
NoteTagShape::BlueCheckMark => self.icon_checkmark(COLOR_BLUE),
|
||||||
NoteTagShape::BlueCircle => self.icon_circle(style, COLOR_BLUE),
|
NoteTagShape::BlueCircle => self.icon_circle(COLOR_BLUE),
|
||||||
|
|
||||||
NoteTagShape::GreenCheckBox1 => self.icon_checkbox_with_1(status, style, COLOR_GREEN),
|
NoteTagShape::GreenCheckBox1 => self.icon_checkbox_with_1(status, COLOR_GREEN),
|
||||||
|
|
||||||
NoteTagShape::GreenCheckBox2 => self.icon_checkbox_with_2(status, style, COLOR_GREEN),
|
NoteTagShape::GreenCheckBox2 => self.icon_checkbox_with_2(status, COLOR_GREEN),
|
||||||
|
|
||||||
NoteTagShape::GreenCheckBox3 => self.icon_checkbox_with_3(status, style, COLOR_GREEN),
|
NoteTagShape::GreenCheckBox3 => self.icon_checkbox_with_3(status, COLOR_GREEN),
|
||||||
|
|
||||||
NoteTagShape::GreenCheckMark => self.icon_checkmark(style, COLOR_GREEN),
|
NoteTagShape::GreenCheckMark => self.icon_checkmark(COLOR_GREEN),
|
||||||
NoteTagShape::GreenCircle => self.icon_circle(style, COLOR_GREEN),
|
NoteTagShape::GreenCircle => self.icon_circle(COLOR_GREEN),
|
||||||
|
|
||||||
NoteTagShape::YellowCheckBox1 => self.icon_checkbox_with_1(status, style, COLOR_YELLOW),
|
NoteTagShape::YellowCheckBox1 => self.icon_checkbox_with_1(status, COLOR_YELLOW),
|
||||||
|
|
||||||
NoteTagShape::YellowCheckBox2 => self.icon_checkbox_with_2(status, style, COLOR_YELLOW),
|
NoteTagShape::YellowCheckBox2 => self.icon_checkbox_with_2(status, COLOR_YELLOW),
|
||||||
|
|
||||||
NoteTagShape::YellowCheckBox3 => self.icon_checkbox_with_3(status, style, COLOR_YELLOW),
|
NoteTagShape::YellowCheckBox3 => self.icon_checkbox_with_3(status, COLOR_YELLOW),
|
||||||
|
|
||||||
NoteTagShape::YellowCheckMark => self.icon_checkmark(style, COLOR_YELLOW),
|
NoteTagShape::YellowCheckMark => self.icon_checkmark(COLOR_YELLOW),
|
||||||
NoteTagShape::YellowCircle => self.icon_circle(style, COLOR_YELLOW),
|
NoteTagShape::YellowCircle => self.icon_circle(COLOR_YELLOW),
|
||||||
|
|
||||||
NoteTagShape::BluePersonCheckBox => {
|
NoteTagShape::BluePersonCheckBox => self.icon_checkbox_with_person(status, COLOR_BLUE),
|
||||||
self.icon_checkbox_with_person(status, style, COLOR_BLUE)
|
|
||||||
}
|
|
||||||
NoteTagShape::YellowPersonCheckBox => {
|
NoteTagShape::YellowPersonCheckBox => {
|
||||||
self.icon_checkbox_with_person(status, style, COLOR_YELLOW)
|
self.icon_checkbox_with_person(status, COLOR_YELLOW)
|
||||||
}
|
}
|
||||||
NoteTagShape::GreenPersonCheckBox => {
|
NoteTagShape::GreenPersonCheckBox => {
|
||||||
self.icon_checkbox_with_person(status, style, COLOR_GREEN)
|
self.icon_checkbox_with_person(status, COLOR_GREEN)
|
||||||
}
|
}
|
||||||
NoteTagShape::BlueFlagCheckBox => {
|
NoteTagShape::BlueFlagCheckBox => self.icon_checkbox_with_flag(status, COLOR_BLUE),
|
||||||
self.icon_checkbox_with_flag(status, style, COLOR_BLUE)
|
NoteTagShape::RedFlagCheckBox => self.icon_checkbox_with_flag(status, COLOR_RED),
|
||||||
}
|
NoteTagShape::GreenFlagCheckBox => self.icon_checkbox_with_flag(status, COLOR_GREEN),
|
||||||
NoteTagShape::RedFlagCheckBox => self.icon_checkbox_with_flag(status, style, COLOR_RED),
|
NoteTagShape::RedSquare => self.icon_square(COLOR_RED),
|
||||||
NoteTagShape::GreenFlagCheckBox => {
|
NoteTagShape::YellowSquare => self.icon_square(COLOR_YELLOW),
|
||||||
self.icon_checkbox_with_flag(status, style, COLOR_GREEN)
|
NoteTagShape::BlueSquare => self.icon_square(COLOR_BLUE),
|
||||||
}
|
NoteTagShape::GreenSquare => self.icon_square(COLOR_GREEN),
|
||||||
NoteTagShape::RedSquare => self.icon_square(style, COLOR_RED),
|
NoteTagShape::OrangeSquare => self.icon_square(COLOR_ORANGE),
|
||||||
NoteTagShape::YellowSquare => self.icon_square(style, COLOR_YELLOW),
|
NoteTagShape::PinkSquare => self.icon_square(COLOR_PINK),
|
||||||
NoteTagShape::BlueSquare => self.icon_square(style, COLOR_BLUE),
|
NoteTagShape::EMailMessage => (Cow::from(ICON_EMAIL), IconSize::Normal).into(),
|
||||||
NoteTagShape::GreenSquare => self.icon_square(style, COLOR_GREEN),
|
|
||||||
NoteTagShape::OrangeSquare => self.icon_square(style, COLOR_ORANGE),
|
|
||||||
NoteTagShape::PinkSquare => self.icon_square(style, COLOR_PINK),
|
|
||||||
NoteTagShape::EMailMessage => (
|
|
||||||
Cow::from(ICON_EMAIL),
|
|
||||||
self.icon_style(IconSize::Normal, style),
|
|
||||||
),
|
|
||||||
|
|
||||||
NoteTagShape::Contact => (
|
NoteTagShape::Contact => (Cow::from(ICON_CONTACT), IconSize::Normal).into(),
|
||||||
Cow::from(ICON_CONTACT),
|
|
||||||
self.icon_style(IconSize::Normal, style),
|
|
||||||
),
|
|
||||||
|
|
||||||
NoteTagShape::MusicalNote => (
|
NoteTagShape::MusicalNote => (Cow::from(ICON_MUSIC), IconSize::Normal).into(),
|
||||||
Cow::from(ICON_MUSIC),
|
NoteTagShape::MovieClip => (Cow::from(ICON_FILM), IconSize::Normal).into(),
|
||||||
self.icon_style(IconSize::Normal, style),
|
|
||||||
),
|
|
||||||
NoteTagShape::MovieClip => (
|
|
||||||
Cow::from(ICON_FILM),
|
|
||||||
self.icon_style(IconSize::Normal, style),
|
|
||||||
),
|
|
||||||
|
|
||||||
NoteTagShape::HyperlinkGlobe => (
|
NoteTagShape::HyperlinkGlobe => (Cow::from(ICON_LINK), IconSize::Normal).into(),
|
||||||
Cow::from(ICON_LINK),
|
|
||||||
self.icon_style(IconSize::Normal, style),
|
|
||||||
),
|
|
||||||
|
|
||||||
NoteTagShape::Padlock => (
|
NoteTagShape::Padlock => (Cow::from(ICON_LOCK), IconSize::Normal).into(),
|
||||||
Cow::from(ICON_LOCK),
|
NoteTagShape::OpenBook => (Cow::from(ICON_BOOK), IconSize::Normal).into(),
|
||||||
self.icon_style(IconSize::Normal, style),
|
|
||||||
),
|
|
||||||
NoteTagShape::OpenBook => (
|
|
||||||
Cow::from(ICON_BOOK),
|
|
||||||
self.icon_style(IconSize::Normal, style),
|
|
||||||
),
|
|
||||||
|
|
||||||
NoteTagShape::BlankPaperWithLines => (
|
NoteTagShape::BlankPaperWithLines => (Cow::from(ICON_PAPER), IconSize::Normal).into(),
|
||||||
Cow::from(ICON_PAPER),
|
|
||||||
self.icon_style(IconSize::Normal, style),
|
|
||||||
),
|
|
||||||
|
|
||||||
NoteTagShape::Pen => (
|
NoteTagShape::Pen => (Cow::from(ICON_PEN), IconSize::Normal).into(),
|
||||||
Cow::from(ICON_PEN),
|
|
||||||
self.icon_style(IconSize::Normal, style),
|
|
||||||
),
|
|
||||||
|
|
||||||
shape => self.icon_fallback(style, shape),
|
shape => self.icon_fallback(shape),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_fallback(&self, style: StyleSet, shape: NoteTagShape) -> (Cow<'static, str>, StyleSet) {
|
fn icon_fallback(&self, shape: NoteTagShape) -> NoteTagIcon {
|
||||||
log_warn!("Unsupported icon type: {:?}", shape);
|
log_warn!("Unsupported icon type: {:?}", shape);
|
||||||
|
|
||||||
(
|
(Cow::from(ICON_QUESTION_MARK), IconSize::Normal).into()
|
||||||
Cow::from(ICON_QUESTION_MARK),
|
|
||||||
self.icon_style(IconSize::Normal, style),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_checkbox(
|
fn icon_checkbox(&self, status: ActionItemStatus, color: &'static str) -> NoteTagIcon {
|
||||||
&self,
|
let mut styles = StyleSet::new();
|
||||||
status: ActionItemStatus,
|
styles.set("fill", color.to_string());
|
||||||
mut style: StyleSet,
|
|
||||||
color: &'static str,
|
|
||||||
) -> (Cow<'static, str>, StyleSet) {
|
|
||||||
style.set("fill", color.to_string());
|
|
||||||
|
|
||||||
if status.completed() {
|
let html = if status.completed() {
|
||||||
(
|
Cow::from(ICON_CHECKBOX_COMPLETE)
|
||||||
Cow::from(ICON_CHECKBOX_COMPLETE),
|
|
||||||
self.icon_style(IconSize::Large, style),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
(
|
Cow::from(ICON_CHECKBOX_EMPTY)
|
||||||
Cow::from(ICON_CHECKBOX_EMPTY),
|
};
|
||||||
self.icon_style(IconSize::Large, style),
|
|
||||||
)
|
NoteTagIcon {
|
||||||
|
html,
|
||||||
|
size: IconSize::Large,
|
||||||
|
styles,
|
||||||
|
is_checkbox: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_checkbox_with_person(
|
fn icon_checkbox_with_person(
|
||||||
&self,
|
&self,
|
||||||
status: ActionItemStatus,
|
status: ActionItemStatus,
|
||||||
style: StyleSet,
|
|
||||||
color: &'static str,
|
color: &'static str,
|
||||||
) -> (Cow<'static, str>, StyleSet) {
|
) -> NoteTagIcon {
|
||||||
self.icon_checkbox_with(status, style, color, ICON_PERSON)
|
self.icon_checkbox_with(status, color, ICON_PERSON)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_checkbox_with_right_arrow(
|
fn icon_checkbox_with_right_arrow(
|
||||||
&self,
|
&self,
|
||||||
status: ActionItemStatus,
|
status: ActionItemStatus,
|
||||||
style: StyleSet,
|
|
||||||
color: &'static str,
|
color: &'static str,
|
||||||
) -> (Cow<'static, str>, StyleSet) {
|
) -> NoteTagIcon {
|
||||||
self.icon_checkbox_with(status, style, color, ICON_ARROW_RIGHT)
|
self.icon_checkbox_with(status, color, ICON_ARROW_RIGHT)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_checkbox_with_star(
|
fn icon_checkbox_with_star(
|
||||||
&self,
|
&self,
|
||||||
status: ActionItemStatus,
|
status: ActionItemStatus,
|
||||||
style: StyleSet,
|
|
||||||
color: &'static str,
|
color: &'static str,
|
||||||
) -> (Cow<'static, str>, StyleSet) {
|
) -> NoteTagIcon {
|
||||||
self.icon_checkbox_with(status, style, color, ICON_STAR)
|
self.icon_checkbox_with(status, color, ICON_STAR)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_checkbox_with_flag(
|
fn icon_checkbox_with_flag(
|
||||||
&self,
|
&self,
|
||||||
status: ActionItemStatus,
|
status: ActionItemStatus,
|
||||||
style: StyleSet,
|
|
||||||
color: &'static str,
|
color: &'static str,
|
||||||
) -> (Cow<'static, str>, StyleSet) {
|
) -> NoteTagIcon {
|
||||||
self.icon_checkbox_with(status, style, color, ICON_FLAG)
|
self.icon_checkbox_with(status, color, ICON_FLAG)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_checkbox_with_1(
|
fn icon_checkbox_with_1(&self, status: ActionItemStatus, color: &'static str) -> NoteTagIcon {
|
||||||
&self,
|
self.icon_checkbox_with(status, color, "<span class=\"content\">1</span>")
|
||||||
status: ActionItemStatus,
|
|
||||||
style: StyleSet,
|
|
||||||
color: &'static str,
|
|
||||||
) -> (Cow<'static, str>, StyleSet) {
|
|
||||||
self.icon_checkbox_with(status, style, color, "<span class=\"content\">1</span>")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_checkbox_with_2(
|
fn icon_checkbox_with_2(&self, status: ActionItemStatus, color: &'static str) -> NoteTagIcon {
|
||||||
&self,
|
self.icon_checkbox_with(status, color, "<span class=\"content\">2</span>")
|
||||||
status: ActionItemStatus,
|
|
||||||
style: StyleSet,
|
|
||||||
color: &'static str,
|
|
||||||
) -> (Cow<'static, str>, StyleSet) {
|
|
||||||
self.icon_checkbox_with(status, style, color, "<span class=\"content\">2</span>")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_checkbox_with_3(
|
fn icon_checkbox_with_3(&self, status: ActionItemStatus, color: &'static str) -> NoteTagIcon {
|
||||||
&self,
|
self.icon_checkbox_with(status, color, "<span class=\"content\">3</span>")
|
||||||
status: ActionItemStatus,
|
|
||||||
style: StyleSet,
|
|
||||||
color: &'static str,
|
|
||||||
) -> (Cow<'static, str>, StyleSet) {
|
|
||||||
self.icon_checkbox_with(status, style, color, "<span class=\"content\">3</span>")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_checkbox_with_exclamation(
|
fn icon_checkbox_with_exclamation(
|
||||||
&self,
|
&self,
|
||||||
status: ActionItemStatus,
|
status: ActionItemStatus,
|
||||||
style: StyleSet,
|
|
||||||
color: &'static str,
|
color: &'static str,
|
||||||
) -> (Cow<'static, str>, StyleSet) {
|
) -> NoteTagIcon {
|
||||||
self.icon_checkbox_with(status, style, color, "<span class=\"content\">!</span>")
|
self.icon_checkbox_with(status, color, "<span class=\"content\">!</span>")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_checkbox_with(
|
fn icon_checkbox_with(
|
||||||
&self,
|
&self,
|
||||||
status: ActionItemStatus,
|
status: ActionItemStatus,
|
||||||
mut style: StyleSet,
|
|
||||||
color: &'static str,
|
color: &'static str,
|
||||||
secondary_icon: &'static str,
|
secondary_icon: &'static str,
|
||||||
) -> (Cow<'static, str>, StyleSet) {
|
) -> NoteTagIcon {
|
||||||
|
let mut style = StyleSet::new();
|
||||||
style.set("fill", color.to_string());
|
style.set("fill", color.to_string());
|
||||||
|
|
||||||
let mut content = String::new();
|
let mut content = String::new();
|
||||||
@@ -414,75 +386,37 @@ impl<'a> Renderer<'a> {
|
|||||||
secondary_icon
|
secondary_icon
|
||||||
));
|
));
|
||||||
|
|
||||||
(Cow::from(content), self.icon_style(IconSize::Large, style))
|
NoteTagIcon {
|
||||||
}
|
html: Cow::from(content),
|
||||||
|
size: IconSize::Large,
|
||||||
fn icon_checkmark(
|
styles: style,
|
||||||
&self,
|
is_checkbox: true,
|
||||||
mut style: StyleSet,
|
|
||||||
color: &'static str,
|
|
||||||
) -> (Cow<'static, str>, StyleSet) {
|
|
||||||
style.set("fill", color.to_string());
|
|
||||||
|
|
||||||
(
|
|
||||||
Cow::from(ICON_CHECK_MARK),
|
|
||||||
self.icon_style(IconSize::Large, style),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn icon_circle(
|
|
||||||
&self,
|
|
||||||
mut style: StyleSet,
|
|
||||||
color: &'static str,
|
|
||||||
) -> (Cow<'static, str>, StyleSet) {
|
|
||||||
style.set("fill", color.to_string());
|
|
||||||
|
|
||||||
(
|
|
||||||
Cow::from(ICON_CIRCLE),
|
|
||||||
self.icon_style(IconSize::Normal, style),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn icon_square(
|
|
||||||
&self,
|
|
||||||
mut style: StyleSet,
|
|
||||||
color: &'static str,
|
|
||||||
) -> (Cow<'static, str>, StyleSet) {
|
|
||||||
style.set("fill", color.to_string());
|
|
||||||
|
|
||||||
(
|
|
||||||
Cow::from(ICON_SQUARE),
|
|
||||||
self.icon_style(IconSize::Large, style),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn icon_style(&self, size: IconSize, mut style: StyleSet) -> StyleSet {
|
|
||||||
match size {
|
|
||||||
IconSize::Normal => {
|
|
||||||
style.set("height", "16px".to_string());
|
|
||||||
style.set("width", "16px".to_string());
|
|
||||||
}
|
|
||||||
IconSize::Large => {
|
|
||||||
style.set("height", "20px".to_string());
|
|
||||||
style.set("width", "20px".to_string());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match (self.in_list, size) {
|
fn icon_checkmark(&self, color: &'static str) -> NoteTagIcon {
|
||||||
(false, IconSize::Normal) => {
|
let mut style = StyleSet::new();
|
||||||
style.set("left", "-23px".to_string());
|
style.set("fill", color.to_string());
|
||||||
}
|
|
||||||
(false, IconSize::Large) => {
|
|
||||||
style.set("left", "-25px".to_string());
|
|
||||||
}
|
|
||||||
(true, IconSize::Normal) => {
|
|
||||||
style.set("left", "-38px".to_string());
|
|
||||||
}
|
|
||||||
(true, IconSize::Large) => {
|
|
||||||
style.set("left", "-40px".to_string());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
style
|
NoteTagIcon {
|
||||||
|
is_checkbox: true,
|
||||||
|
html: Cow::from(ICON_CHECK_MARK),
|
||||||
|
size: IconSize::Large,
|
||||||
|
styles: style,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn icon_circle(&self, color: &'static str) -> NoteTagIcon {
|
||||||
|
let mut style = StyleSet::new();
|
||||||
|
style.set("fill", color.to_string());
|
||||||
|
|
||||||
|
(Cow::from(ICON_CIRCLE), IconSize::Normal, style).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn icon_square(&self, color: &'static str) -> NoteTagIcon {
|
||||||
|
let mut style = StyleSet::new();
|
||||||
|
style.set("fill", color.to_string());
|
||||||
|
|
||||||
|
(Cow::from(ICON_SQUARE), IconSize::Large, style).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ impl<'a> Renderer<'a> {
|
|||||||
let is_list = self.is_list(element);
|
let is_list = self.is_list(element);
|
||||||
|
|
||||||
let mut attrs = AttributeSet::new();
|
let mut attrs = AttributeSet::new();
|
||||||
attrs.set("class", "outline-element".to_string());
|
attrs.set("class", "outline-element".into());
|
||||||
|
|
||||||
let mut styles = StyleSet::new();
|
let mut styles = StyleSet::new();
|
||||||
styles.set("margin-left", px(indent_width as f32));
|
styles.set("margin-left", px(indent_width as f32));
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ impl<'a> Renderer<'a> {
|
|||||||
fn table_cell_level(&self, elements: &[OutlineElement]) -> u8 {
|
fn table_cell_level(&self, elements: &[OutlineElement]) -> u8 {
|
||||||
let needs_nesting = elements
|
let needs_nesting = elements
|
||||||
.iter()
|
.iter()
|
||||||
.any(|element| self.is_list(element) || self.has_note_tag(element));
|
.any(|element| self.is_list(element));
|
||||||
|
|
||||||
if needs_nesting { 2 } else { 1 }
|
if needs_nesting { 2 } else { 1 }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>{{ name }}</title>
|
<title>{{ name }}</title>
|
||||||
<style>
|
<style>
|
||||||
|
/*** Start default CSS ***/
|
||||||
* { margin: 0; padding: 0; font-weight: normal; }
|
* { margin: 0; padding: 0; font-weight: normal; }
|
||||||
table, tr, td { border-color: #A3A3A3; }
|
table, tr, td { border-color: #A3A3A3; }
|
||||||
ul, ol { padding: 0; }
|
ul, ol { padding: 0; }
|
||||||
@@ -12,11 +13,31 @@
|
|||||||
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
.container-outline { font-family: Calibri, sans-serif; font-size: 6pt; }
|
||||||
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
.ink-text, .ink-space { display: inline-block; position: relative; vertical-align: bottom; }
|
||||||
.ink-text { top: 0; left: 0; }
|
.ink-text { top: 0; left: 0; }
|
||||||
.note-tag-icon { position: relative; }
|
|
||||||
|
/* Icons */
|
||||||
|
.note-tag-icon {
|
||||||
|
position: relative;
|
||||||
|
--note-tag-left: -23px;
|
||||||
|
--note-tag-width: 16px;
|
||||||
|
--note-tag-height: 16px;
|
||||||
|
}
|
||||||
|
.note-tag-icon.-large {
|
||||||
|
--note-tag-left: -25px;
|
||||||
|
--note-tag-width: 20px;
|
||||||
|
--note-tag-height: 20px;
|
||||||
|
}
|
||||||
|
.note-tag-icon > img, .note-tag-icon > svg {
|
||||||
|
width: var(--note-tag-width);
|
||||||
|
height: var(--note-tag-height);
|
||||||
|
left: var(--note-tag-left);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tagged-list { list-style: none; padding-left: 0; }
|
||||||
{# Select both SVGs and IMGs: Joplin post-processes the converter's output, converting SVGs to IMGs. #}
|
{# Select both SVGs and IMGs: Joplin post-processes the converter's output, converting SVGs to IMGs. #}
|
||||||
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
.note-tag-icon > svg, .note-tag-icon > img { position: absolute; }
|
||||||
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
.icon-secondary > svg, .icon-secondary > img { position: absolute; fill: black; filter: drop-shadow(0 0 2px white); height: 12px; top: -1px; }
|
||||||
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
.icon-secondary > .content { position: absolute; color: black; filter: drop-shadow(0 0 2px white); font-size: 10px; color: black; top: -1px; user-select: none; }
|
||||||
|
/*** End default CSS ***/
|
||||||
|
|
||||||
{% for entry in global_styles -%}
|
{% for entry in global_styles -%}
|
||||||
{{ entry.0 }} { {{ entry.1 }} }
|
{{ entry.0 }} { {{ entry.1 }} }
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ pub(crate) fn px(inches: f32) -> String {
|
|||||||
format!("{}px", (inches * 48.0).round())
|
format!("{}px", (inches * 48.0).round())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub(crate) struct AttributeSet(HashMap<&'static str, String>);
|
pub(crate) struct AttributeSet(HashMap<&'static str, String>);
|
||||||
|
|
||||||
impl AttributeSet {
|
impl AttributeSet {
|
||||||
@@ -21,6 +22,12 @@ impl AttributeSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<const N: usize> From<[(&'static str, String); N]> for AttributeSet {
|
||||||
|
fn from(data: [(&'static str, String); N]) -> Self {
|
||||||
|
Self(data.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for AttributeSet {
|
impl Display for AttributeSet {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
|
|||||||
@@ -3,15 +3,20 @@ export default function taskListItems (turndownService) {
|
|||||||
filter: function (node) {
|
filter: function (node) {
|
||||||
const parent = node.parentNode;
|
const parent = node.parentNode;
|
||||||
const grandparent = parent.parentNode;
|
const grandparent = parent.parentNode;
|
||||||
return node.type === 'checkbox' && (
|
const grandparentIsListItem = !!grandparent && grandparent.nodeName === 'LI';
|
||||||
|
return (node.type === 'checkbox' || node.role === 'checkbox') && (
|
||||||
parent.nodeName === 'LI'
|
parent.nodeName === 'LI'
|
||||||
// Handles the case where the label contains the checkbox. For example,
|
// Handles the case where the label contains the checkbox. For example,
|
||||||
// <label><input ...> ...label text...</label>
|
// <label><input ...> ...label text...</label>
|
||||||
|| (parent.nodeName === 'LABEL' && grandparent && grandparent.nodeName === 'LI')
|
|| (parent.nodeName === 'LABEL' && grandparentIsListItem)
|
||||||
|
// Handles the case where the input is contained within a <span>
|
||||||
|
// <li><span><input ...></span></li>
|
||||||
|
|| (parent.nodeName === 'SPAN' && grandparentIsListItem)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
replacement: function (content, node) {
|
replacement: function (content, node) {
|
||||||
return (node.checked ? '[x]' : '[ ]') + ' '
|
const checked = node.nodeName === 'INPUT' ? node.checked : node.getAttribute('aria-checked') === 'true';
|
||||||
|
return (checked ? '[x]' : '[ ]') + ' '
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -864,8 +864,12 @@ function joplinCheckboxInfo(liNode) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Should handle both <ul class='joplin-checklist'><li>...</li></ul>
|
||||||
|
// and <ul><li class='joplin-checklist-item'>...</li></ul>. The second is present
|
||||||
|
// in certain types of imported notes.
|
||||||
const parentChecklist = findParent(liNode, 'class', 'joplin-checklist');
|
const parentChecklist = findParent(liNode, 'class', 'joplin-checklist');
|
||||||
if (parentChecklist) {
|
const currentChecklist = liNode.classList.contains('joplin-checklist-item');
|
||||||
|
if (parentChecklist || currentChecklist) {
|
||||||
return {
|
return {
|
||||||
checked: !!liNode.classList && liNode.classList.contains('checked'),
|
checked: !!liNode.classList && liNode.classList.contains('checked'),
|
||||||
renderingType: 2,
|
renderingType: 2,
|
||||||
|
|||||||
Reference in New Issue
Block a user