diff --git a/src/Blocks/Footnote/FootnotesBlockView.jsx b/src/Blocks/Footnote/FootnotesBlockView.jsx index 08c9629..cc8d304 100644 --- a/src/Blocks/Footnote/FootnotesBlockView.jsx +++ b/src/Blocks/Footnote/FootnotesBlockView.jsx @@ -3,13 +3,13 @@ import { openAccordionOrTabIfContainsFootnoteReference, getAllBlocksAndSlateFields, makeFootnoteListOfUniqueItems, - makeFootnote, } from '@eeacms/volto-slate-footnote/editor/utils'; import './less/public.less'; import { UniversalLink } from '@plone/volto/components'; const alphabet = 'abcdefghijklmnopqrstuvwxyz'; +const urlRegex = /https?:\/\/[^\s]+/g; /** * @summary The React component that displays the list of footnotes inserted @@ -19,6 +19,7 @@ const alphabet = 'abcdefghijklmnopqrstuvwxyz'; * @param {Object} props Contains the properties `data` and `properties` as * received from the Volto form. */ + const FootnotesBlockView = (props) => { const { data, properties, tabData, content } = props; const { title, global, placeholder = 'Footnotes' } = data; @@ -75,6 +76,30 @@ const FootnotesBlockView = (props) => { startList = citationIndice; } + const renderTextWithLinks = (text) => { + if (!text) return null; + const parts = text.split(urlRegex); + const links = text.match(urlRegex); + let result = []; + + parts.forEach((part, index) => { + result.push({part}); + + if (links && links[index]) { + result.push( + + {links[index]} + , + ); + } + }); + + return result; + }; return (

{title}

@@ -85,16 +110,19 @@ const FootnotesBlockView = (props) => { const { uid, footnote, zoteroId, parentUid } = note; const { refs } = note; const refsList = refs ? Object.keys(refs) : null; + + // const history = createBrowserHistory(); + // const api = new Api(); + // const store = configureStore(window.__data, history, api); + const footnoteText = !footnote + ? '' + : footnote.replace('', ''); return (
  • -
    +
    {renderTextWithLinks(footnoteText)}
    {refsList ? ( <> {/** some footnotes are never parent so we need the parent to reference */} diff --git a/src/editor/render.jsx b/src/editor/render.jsx index 8b690af..671619f 100644 --- a/src/editor/render.jsx +++ b/src/editor/render.jsx @@ -15,9 +15,8 @@ import { UniversalLink } from '@plone/volto/components'; * @param {string} footnote * @returns {string} formatted footnote */ -const makeFootnote = (footnote) => { - return footnote ? footnote.replace('', '') : ''; -}; + +const urlRegex = /https?:\/\/[^\s]+/g; export const FootnoteElement = (props) => { const { attributes, children, element, mode, extras } = props; @@ -37,7 +36,7 @@ export const FootnoteElement = (props) => { const notesObjResult = isEmpty(metadata) ? makeFootnoteListOfUniqueItems(storeBlocks) : makeFootnoteListOfUniqueItems(blocks); - // will cosider zotero citations and footnote + // will consider zotero citations and footnote // notesObjResult contains all zotero/footnote as unique, and contain refs for other zotero/footnote const indiceIfZoteroId = data.extra ? [ @@ -52,6 +51,29 @@ export const FootnoteElement = (props) => { : // no extra citations (no multiples) `[${Object.keys(notesObjResult).indexOf(zoteroId) + 1}]`; + const renderTextWithLinks = (text) => { + if (!text) return null; + const parts = text.split(urlRegex); + const links = text.match(urlRegex); + let result = []; + + parts.forEach((part, index) => { + result.push({part}); + if (links && links[index]) { + result.push( + + {links[index]} + , + ); + } + }); + + return result; + }; const citationIndice = zoteroId // ZOTERO ? indiceIfZoteroId : // FOOTNOTES @@ -76,13 +98,17 @@ export const FootnoteElement = (props) => { Object.keys(notesObjResult).find( (noteKey) => notesObjResult[noteKey].uid === uid, ) || - // if not found in parent, search in refs, it might be a footnote references multiple times + // if not found in parent, search in refs, it might be a footnote referenced multiple times Object.keys(notesObjResult).find( (noteKey) => notesObjResult[noteKey].uid === uid || (notesObjResult[noteKey].refs && notesObjResult[noteKey].refs[uid]), ); + const footnoteText = !data.footnote + ? '' + : data.footnote.replace('', ''); + return ( <> {mode === 'view' ? ( @@ -109,7 +135,6 @@ export const FootnoteElement = (props) => { openAccordionOrTabIfContainsFootnoteReference( @@ -120,37 +145,34 @@ export const FootnoteElement = (props) => { > -
    {' '} + {renderTextWithLinks(footnoteText)} {data.extra && - data.extra.map((item) => ( - - openAccordionOrTabIfContainsFootnoteReference( - `#footnote-${item.zoteroId || item.uid}`, - ) - } - key={`#footnote-${item.zoteroId || item.uid}`} - > - - -
    {' '} - - - - ))} + data.extra.map((item) => { + const footnoteText = !item.footnote + ? '' + : item.footnote.replace('', ''); + + return ( + + openAccordionOrTabIfContainsFootnoteReference( + `#footnote-${item.zoteroId || item.uid}`, + ) + } + key={`#footnote-${item.zoteroId || item.uid}`} + > + + + {renderTextWithLinks(footnoteText)} + + + + ); + })} @@ -173,7 +195,6 @@ export const FootnoteElement = (props) => { openAccordionOrTabIfContainsFootnoteReference( @@ -184,18 +205,13 @@ export const FootnoteElement = (props) => { > -
    {' '} + {renderTextWithLinks(footnoteText)} {data.extra && data.extra.map((item) => ( openAccordionOrTabIfContainsFootnoteReference( @@ -206,11 +222,7 @@ export const FootnoteElement = (props) => { > -
    {' '} + {renderTextWithLinks(item.footnote)} diff --git a/src/editor/utils.js b/src/editor/utils.js index ba3350f..5a6dedc 100644 --- a/src/editor/utils.js +++ b/src/editor/utils.js @@ -1,15 +1,6 @@ import config from '@plone/volto/registry'; import { Node } from 'slate'; import { getAllBlocks } from '@plone/volto-slate/utils'; - -/** - * remove from the string - * @param {*} footnote - xml format - * @returns string - */ -export const makeFootnote = (footnote) => { - return footnote ? footnote.replace('', '') : ''; -}; /** * retrive all slate children of nested objects * @param {object} path - the keys that we want to extract the slate children from diff --git a/src/editor/utils.test.js b/src/editor/utils.test.js index 022990f..02970d0 100644 --- a/src/editor/utils.test.js +++ b/src/editor/utils.test.js @@ -1,5 +1,4 @@ import { - makeFootnote, openAccordionOrTabIfContainsFootnoteReference, getAllBlocksAndSlateFields, } from './utils'; @@ -9,19 +8,6 @@ jest.mock('@plone/volto-slate/utils', () => ({ getAllBlocks: jest.fn(), })); -describe('makeFootnote', () => { - it('should remove xml version string from footnote', () => { - const xmlString = 'Test text'; - const expectedResult = 'Test text'; - expect(makeFootnote(xmlString)).toEqual(expectedResult); - }); - - it('should return empty string when footnote is null or undefined', () => { - expect(makeFootnote(null)).toEqual(''); - expect(makeFootnote(undefined)).toEqual(''); - }); -}); - describe('openAccordionOrTabIfContainsFootnoteReference', () => { it('should open accordion if it contains footnote reference', () => { document.body.innerHTML = `