@@ -19,7 +19,7 @@ if (typeof $localize === 'undefined') {
1919
2020// All user-visible strings. Values are replaced per-locale by the Angular localize pipeline at build time.
2121const STRINGS = {
22- unnamedProfile : $localize `:@@printView.unnamedProfile:Unnamed ORCID profile ` ,
22+ unnamedProfile : $localize `:@@printView.unnamedProfile:Name is private ` ,
2323 orcidIdAlt : $localize `:@@printView.orcidIdAlt:ORCID iD` ,
2424 biography : $localize `:@@printView.biography:Biography` ,
2525 personalInformation : $localize `:@@printView.personalInformation:Personal information` ,
@@ -54,6 +54,7 @@ const STRINGS = {
5454 loadingRecord : $localize `:@@printView.loadingRecord:Loading ORCID record...` ,
5555 recordNotFound : $localize `:@@printView.recordNotFound:Record data was not found in ORCID response.` ,
5656 redirectingToPrimary : $localize `:@@printView.redirectingToPrimary:Redirecting to primary ORCID record…` ,
57+ orcidPrintView : $localize `:@@printView.orcidPrintView:ORCID Print view` ,
5758}
5859
5960const ORCID_REGEX = / \b \d { 4 } - \d { 4 } - \d { 4 } - \d { 3 } [ \d X ] \b / i
@@ -266,6 +267,11 @@ function jsonOrcidUri(orcidIdentifier) {
266267 return uri || ( path ? `https://orcid.org/${ path } ` : '' )
267268}
268269
270+ function setTitle ( recordJson , chosenName ) {
271+ const orcidId = jsonText ( recordJson ?. [ 'orcid-identifier' ] ?. path )
272+ document . title = `${ chosenName } (${ orcidId } ) - ${ STRINGS . orcidPrintView } `
273+ }
274+
269275function renderIdentityFromJson ( recordJson ) {
270276 const person = recordJson ?. person
271277 const name = person ?. name
@@ -275,6 +281,9 @@ function renderIdentityFromJson(recordJson) {
275281 const fullName = [ given , family ] . filter ( Boolean ) . join ( ' ' )
276282 const chosenName = credit || fullName || STRINGS . unnamedProfile
277283
284+ // Set the page title
285+ setTitle ( recordJson , chosenName )
286+
278287 const container = document . createElement ( 'article' )
279288 container . className = 'cv-container'
280289 container . setAttribute ( 'aria-label' , `${ chosenName } ORCID profile` )
@@ -287,6 +296,11 @@ function renderIdentityFromJson(recordJson) {
287296 const otherNames = jsonList ( person ?. [ 'other-names' ] ?. [ 'other-name' ] )
288297 . map ( ( n ) => jsonText ( n ?. content ) )
289298 . filter ( Boolean )
299+
300+ if ( credit && fullName ) {
301+ otherNames . unshift ( fullName )
302+ }
303+
290304 if ( otherNames . length ) {
291305 const namesLine = document . createElement ( 'p' )
292306 namesLine . className = 'other-names'
@@ -409,7 +423,7 @@ function renderPersonalInfoFromJson(recordJson, container) {
409423 const lines = externalIds . map ( ( entry ) => {
410424 const label = entry . type || 'Identifier'
411425 const value = entry . value || entry . url || ''
412- return textLineNode ( label , value , entry . url )
426+ return otherIdsTextNode ( label , value , entry . url )
413427 } )
414428 appendList ( block , lines )
415429 blocks . push ( block )
@@ -475,6 +489,32 @@ function textLineNode(label, value, url) {
475489 }
476490 return wrapper
477491}
492+
493+ function otherIdsTextNode ( label , value , url ) {
494+ const wrapper = document . createElement ( 'p' )
495+ wrapper . className = 'line'
496+ if ( label ) {
497+ const prefix = document . createElement ( 'span' )
498+ prefix . className = 'line-label'
499+ prefix . textContent = `${ label } : `
500+ wrapper . appendChild ( prefix )
501+ }
502+
503+ wrapper . appendChild ( document . createTextNode ( value ) )
504+
505+ const safeUrl = sanitizeUrl ( url )
506+ if ( safeUrl ) {
507+ wrapper . appendChild ( document . createTextNode ( ' ' ) )
508+ const a = document . createElement ( 'a' )
509+ a . href = safeUrl
510+ a . target = '_blank'
511+ a . rel = 'noopener noreferrer'
512+ a . textContent = safeUrl
513+ wrapper . appendChild ( a )
514+ }
515+ return wrapper
516+ }
517+
478518function safeTextNode ( value ) {
479519 return ( value || '' ) . replace ( / \s + / g, ' ' ) . trim ( )
480520}
@@ -564,7 +604,9 @@ function composeActivityEntryFromJson(entry, opts = {}) {
564604 idRel && idRel . toLowerCase ( ) !== 'self'
565605 ? `${ idRel } ${ idType } `
566606 : idType || STRINGS . identifier
567- wrapper . appendChild ( textLineNode ( label , idValue || idUrl || '' , idUrl ) )
607+ wrapper . appendChild (
608+ otherIdsTextNode ( label , idValue || idUrl || '' , idUrl )
609+ )
568610 } )
569611 }
570612
@@ -650,10 +692,12 @@ function renderEducationsAndQualifications(activities, section) {
650692}
651693
652694function renderWorks ( activities , section ) {
695+ const workSummaries = [ ]
653696 // Works: activities-summary.works.group[].work-summary[]
654- const workSummaries = ( activities ?. works ?. group || [ ] ) . flatMap (
655- ( g ) => g ?. [ 'work-summary' ] || [ ]
656- )
697+ for ( const group of activities ?. works ?. group || [ ] ) {
698+ workSummaries . push ( group [ 'work-summary' ] [ 0 ] )
699+ }
700+
657701 hasContent = false
658702 hasContent =
659703 renderActivityGroupFromJson ( section , STRINGS . works , workSummaries , ( w ) =>
@@ -771,30 +815,36 @@ function renderProfessionalActivities(activities, section) {
771815}
772816
773817function renderFundings ( activities , section ) {
774- // Fundings: activitiesSummary.fundings.group[].activities[]
775- const fundings = ( activities ?. fundings ?. group || [ ] ) . flatMap (
776- ( g ) => g ?. [ 'funding-summary' ] || [ ]
777- )
818+ const fundingSummaries = [ ]
819+ for ( const group of activities ?. fundings ?. group || [ ] ) {
820+ fundingSummaries . push ( group [ 'funding-summary' ] [ 0 ] )
821+ }
822+
778823 hasContent = false
779824 hasContent =
780- renderActivityGroupFromJson ( section , STRINGS . fundings , fundings , ( f ) =>
781- composeActivityEntryFromJson ( f , { title : jsonText ( f ?. title ?. title ) } )
825+ renderActivityGroupFromJson (
826+ section ,
827+ STRINGS . fundings ,
828+ fundingSummaries ,
829+ ( f ) =>
830+ composeActivityEntryFromJson ( f , { title : jsonText ( f ?. title ?. title ) } )
782831 ) || hasContent
783832 return hasContent
784833}
785834
786835function renderResearchResources ( activities , section ) {
787836 // Research resources: activities.research-resources.group.research-resource-summary
788- const researchResources = (
789- activities ?. [ 'research-resources' ] ?. group || [ ]
790- ) . flatMap ( ( g ) => g ?. [ 'research-resource-summary' ] || [ ] )
837+ const researchResourceSummaries = [ ]
838+ for ( const group of activities ?. [ 'research-resources' ] ?. group || [ ] ) {
839+ researchResourceSummaries . push ( group [ 'research-resource-summary' ] [ 0 ] )
840+ }
791841
792842 hasContent = false
793843 hasContent =
794844 renderActivityGroupFromJson (
795845 section ,
796846 STRINGS . researchResources ,
797- researchResources ,
847+ researchResourceSummaries ,
798848 ( r ) =>
799849 composeActivityEntryFromJson ( r , {
800850 title :
@@ -839,7 +889,10 @@ function renderPeerReviews(activities, section) {
839889 for ( publication of sortedPublications || [ ] ) {
840890 const numberOfPublications = peerReviewsPerPublication . get ( publication )
841891 const li = document . createElement ( 'li' )
842- li . textContent = publication + '(' + numberOfPublications + ')'
892+ const strong = document . createElement ( 'strong' )
893+ strong . textContent = publication
894+ li . appendChild ( strong )
895+ li . appendChild ( document . createTextNode ( ' (' + numberOfPublications + ')' ) )
843896 list . appendChild ( li )
844897 }
845898 block . appendChild ( list )
0 commit comments