Skip to content

Commit a207a19

Browse files
rohan-goelobulat
andauthored
Added condition for link without title (#298)
* Added condition for link without title * Added default title * Added showProperty and defaultTitle * Added isTitleDefault * Simplify license utility functions and fix tests Co-authored-by: Travis CI <travis> Co-authored-by: Olga Bulat <obulat@gmail.com>
1 parent f74b8c5 commit a207a19

File tree

7 files changed

+232
-182
lines changed

7 files changed

+232
-182
lines changed

src/components/LicenseHTML.vue

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,30 @@ export default {
2020
...mapState(['attributionDetails', 'attributionType']),
2121
2222
htmlLicenseParagraph() {
23-
const isFull = this.attributionType === 'full'
24-
const { work, creator, license, paragraph } = generateHTML(this.attributionDetails, this.shortName, isFull)
23+
const useFullName = this.attributionType === 'full'
24+
25+
const { workTitle } = this.attributionDetails
26+
const isTitleDefault = !workTitle
27+
28+
const attributionDetails = {
29+
...this.attributionDetails,
30+
workTitle: workTitle || this.$t('license-use.richtext.workTitle')
31+
}
32+
const { work, creator, license } = generateHTML(attributionDetails, this.shortName, useFullName, isTitleDefault)
33+
2534
const licenseCodeSpan = this.$t('license-use.richtext.full-text', {
26-
workTitle: work || this.$t('license-use.richtext.workTitle'),
35+
workTitle: work,
2736
creator: creator,
2837
license: license,
2938
by: creator ? this.$t('license-use.richtext.by') : '',
3039
licenseMark: this.shortName === LICENSES.CC0.SHORT
3140
? this.$t('license-use.richtext.marked-text')
3241
: this.$t('license-use.richtext.licensed-text')
3342
})
34-
return `${paragraph}${licenseCodeSpan}</p>`
43+
const metadata = `xmlns:cc="http://creativecommons.org/ns#" ${isTitleDefault
44+
? ''
45+
: 'xmlns:dct="http://purl.org/dc/terms/"'}`
46+
return `<p ${metadata}>${licenseCodeSpan}</p>`
3547
}
3648
}
3749
}

src/utils/license-utilities.js

Lines changed: 81 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/** @typedef {{BY?: boolean, NC?: boolean, ND?: boolean, SA?: boolean}} LicenseAttributes */
22

3-
/** @typedef {('CC0 1.0'|'CC BY 4.0'|'CC BY-NC 4.0'|'CC BY-NC-ND 4.0'|'CC BY-NC-SA 4.0'|'CC BY-ND 4.0'|'CC BY-ND-SA 4.0')} ShortLicenseName
3+
/** @typedef {('CC0 1.0'|'CC BY 4.0'|'CC BY-SA 4.0'|'CC BY-NC 4.0'|'CC BY-ND 4.0'|'CC BY-NC-ND 4.0'|'CC BY-NC-SA 4.0')} ShortLicenseName
44
*/
55
/** @typedef {('CC0 1.0 Universal'|'Attribution 4.0 International'|'Attribution-ShareAlike 4.0 International'|'Attribution-NonCommercial-ShareAlike 4.0 International'|'Attribution-NonCommercial-NoDerivatives 4.0 International'|'Attribution-NoDerivatives 4.0 International')} FullLicenseName
66
*/
@@ -9,16 +9,24 @@ const CC0Attributes = LICENSES.CC0.ATTRIBUTES
99
const CCBYAttributes = LICENSES.CC_BY.ATTRIBUTES
1010
const defaultAttributes = { BY: undefined, NC: undefined, ND: undefined, SA: undefined }
1111

12+
const shortToSlug = {
13+
'CC0 1.0': 'CC0',
14+
'CC BY 4.0': 'CC_BY',
15+
'CC BY-ND 4.0': 'CC_BY_ND',
16+
'CC BY-SA 4.0': 'CC_BY_SA',
17+
'CC BY-NC 4.0': 'CC_BY_NC',
18+
'CC BY-NC-ND 4.0': 'CC_BY_NC_ND',
19+
'CC BY-NC-SA 4.0': 'CC_BY_NC_SA'
20+
}
21+
1222
/**
13-
* Convert short license name to attributes
14-
* @param {ShortLicenseName} shortLicenseName - name of the license with version number
15-
* @returns {LicenseAttributes|null}
23+
* Converts the short license name into slug that can be used to look up
24+
* license information in the LICENSES object
25+
* @param short
26+
* @returns {string}
1627
*/
17-
function shortToAttr(shortLicenseName) {
18-
const currentLicense = Object.values(LICENSES).find(license => {
19-
return license.SHORT === shortLicenseName
20-
})
21-
return currentLicense ? currentLicense.ATTRIBUTES : currentLicense
28+
const slugFromShort = (short) => {
29+
return shortToSlug[short]
2230
}
2331

2432
/**
@@ -43,20 +51,12 @@ function attrToShort(attr) {
4351
/**
4452
* Convert license attributes object to full license name
4553
* @param {LicenseAttributes} attr
46-
* @returns {string|undefined}
54+
* @returns {string|null}
4755
*/
4856
function attrToFull(attr) {
49-
if (attr.BY === undefined) { return undefined }
50-
if (!attr.BY) { return 'CC0 1.0 Universal' }
51-
let base = 'Attribution'
52-
if (attr.NC) { base += '-NonCommercial' }
53-
if (!attr.ND && attr.SA) {
54-
base += '-ShareAlike'
55-
} else if (attr.ND) {
56-
base += '-NoDerivatives'
57-
}
58-
base += ' 4.0 International'
59-
return base
57+
const slug = slugFromShort(attrToShort(attr))
58+
if (!slug) return null
59+
return LICENSES[slug].FULL
6060
}
6161

6262
const chooserRef = '?ref=chooser-v1'
@@ -69,13 +69,10 @@ const chooserRef = '?ref=chooser-v1'
6969
*/
7070
function licenseURL(attr, mode = 'web') {
7171
if (attr.BY === undefined) throw new Error('Cannot return URL when BY attribute is undefined')
72+
const slug = slugFromShort(attrToShort(attr))
73+
const url = LICENSES[slug].URL
7274
const linkRef = mode === 'web' ? chooserRef : ''
73-
if (attr.BY === false) {
74-
return `https://creativecommons.org/publicdomain/zero/1.0${linkRef}`
75-
}
76-
let short = attrToShort(attr).toLowerCase().slice(3)
77-
short = short.slice(0, short.length - 4)
78-
return `https://creativecommons.org/licenses/${short}/4.0${linkRef}`
75+
return `${url}${linkRef}`
7976
}
8077

8178
/**
@@ -169,83 +166,93 @@ const ICON_BASE_URL = 'https://mirrors.creativecommons.org/presskit/icons'
169166
* @returns {string}
170167
*/
171168
function generateCreatorCode(creatorName, creatorProfileUrl) {
172-
let creator = ''
173-
if (creatorName) {
174-
if (creatorProfileUrl) {
175-
const absoluteUrl = creatorProfileUrl.startsWith('http') ? creatorProfileUrl : `http://${creatorProfileUrl}`
176-
creator =
177-
`<a rel="cc:attributionURL dct:creator" property="cc:attributionName" href="${absoluteUrl}">${creatorName}</a>`
178-
} else {
179-
creator = `<span property="cc:attributionName">${creatorName}</span>`
180-
}
169+
if (!creatorName) {
170+
return ''
171+
}
172+
if (creatorProfileUrl) {
173+
const absoluteUrl = creatorProfileUrl.startsWith('http') ? creatorProfileUrl : `http://${creatorProfileUrl}`
174+
const linkMeta = 'rel="cc:attributionURL dct:creator" property="cc:attributionName"'
175+
return `<a ${linkMeta} href="${absoluteUrl}">${creatorName}</a>`
176+
} else {
177+
return `<span property="cc:attributionName">${creatorName}</span>`
181178
}
182-
return creator
183179
}
184180

185181
/**
186182
* Generate html for work title:
187-
* 1. If the work title is blank, event if work link is provided, return blank string
188-
* 2. If only work title is provided, return a span with proper metadata
189-
* 3. If both title and URL are provided, returns an 'a' element with proper data and metadata
190-
* @param {string} workTitle
183+
*
184+
* 1. If the user has not provided a work url:
185+
* a. Title is default: return title
186+
* b. Title is provided: return span with `dct:title` property
187+
*
188+
* 2. If the user has provided a work url:
189+
* Convert any url into absolute url by adding 'http://' to the beginning
190+
* Return anchor with 'dct:title' attribute if title is not default
191+
*
192+
* @param {string} title
191193
* @param {string} workUrl
194+
* @param {Boolean} isTitleDefault - true if the user hasn't provided a title, false otherwise
192195
* @returns {string}
193196
*/
194-
function generateWorkCode(workTitle, workUrl) {
195-
let workCode = ''
196-
if (workTitle) {
197-
if (workUrl) {
198-
const absoluteUrl = workUrl.startsWith('http') ? workUrl : `http://${workUrl}`
199-
workCode = `<a rel="cc:attributionURL" property="dct:title" href="${absoluteUrl}">${workTitle}</a>`
200-
} else {
201-
workCode = `<span property="dct:title">${workTitle}</span>`
202-
}
197+
function generateWorkCode(title, workUrl, isTitleDefault) {
198+
if (isTitleDefault && !workUrl) {
199+
return title
203200
}
204-
return workCode
201+
202+
const titleMeta = 'property="dct:title"'
203+
if (!workUrl) {
204+
return `<span ${titleMeta}>${title}</span>`
205+
}
206+
207+
const absoluteUrl = workUrl.startsWith('http') ? workUrl : `http://${workUrl}`
208+
return `<a ${isTitleDefault ? '' : titleMeta} rel="cc:attributionURL" href="${absoluteUrl}">${title}</a>`
205209
}
206210

207211
/**
208212
* Generates the html for the rich text license information, including license name,
209213
* link to the license deed, and license icons
210-
* @param {LicenseAttributes} licenseAttr
214+
* @param {array} licenseIcons
215+
* @param {string} licenseUrl
211216
* @param {ShortLicenseName|FullLicenseName} licenseName
212217
* @returns {string} HTML code for the license
213218
*/
214-
function generateLicenseCode(licenseAttr, licenseName) {
219+
function generateLicenseLink(licenseIcons, licenseUrl, licenseName) {
215220
const iconStyle = `style="${ICON_STYLE}"`
216221
const assetPathRef = '?ref=chooser-v1'
217-
const licenseIconsCode = ['cc', ...licenseIconsArr(licenseAttr)]
218-
.map(attr => `<img ${iconStyle} src="${ICON_BASE_URL}/${attr.toLowerCase()}.svg${assetPathRef}">`
219-
).join('')
222+
const iconSrc = (attr) => `${ICON_BASE_URL}/${attr.toLowerCase()}.svg${assetPathRef}`
223+
const icons = licenseIcons
224+
.map(attr => `<img ${iconStyle} src="${iconSrc(attr)}">`).join('')
220225

221-
return (`<a href="${licenseURL(licenseAttr)}" target="_blank"` +
222-
' rel="license noopener noreferrer" style="display:inline-block;">' +
223-
`${licenseName}${licenseIconsCode}</a>`)
226+
const linkHref = `href="${licenseUrl}${assetPathRef}"`
227+
const linkAttributes = 'target="_blank" rel="license noopener noreferrer"'
228+
const linkStyle = 'style="display:inline-block;"'
229+
return `<a ${linkHref} ${linkAttributes} ${linkStyle}>${licenseName}${icons}</a>`
224230
}
225231

226232
/**
227233
* Generate data for use in attribution HTML through i18n
228234
* @param attributionDetails
229235
* @param {ShortLicenseName} shortLicenseName
230-
* @param {Boolean} isFullName - Should the license name be full (short by default)
231-
* @returns {{creator: string, workTitle: string, licenseLink: string, htmlString: string}}
236+
* @param {Boolean} useFullName - Should the license name be full (short by default)
237+
* @param {Boolean} isTitleDefault
238+
* @returns {{creator: string, work: string, license: string}}
232239
*/
233-
function generateHTML(attributionDetails, shortLicenseName, isFullName = false) {
234-
const dataForHtmlGeneration = {}
235-
const { creatorName, creatorProfileUrl, workTitle, workUrl } = attributionDetails
236-
dataForHtmlGeneration.paragraph =
237-
`<p ${DCT_NAMESPACE.NAME}="${DCT_NAMESPACE.URI}"` +
238-
` ${CC_NAMESPACE.NAME}="${CC_NAMESPACE.URI}">`
239-
const licenseAttr = shortToAttr(shortLicenseName)
240-
const licenseName = isFullName ? attrToFull(licenseAttr) : shortLicenseName
241-
dataForHtmlGeneration.license = generateLicenseCode(licenseAttr, licenseName)
242-
dataForHtmlGeneration.creator = generateCreatorCode(creatorName, creatorProfileUrl)
243-
dataForHtmlGeneration.work = generateWorkCode(workTitle, workUrl)
244-
return dataForHtmlGeneration
240+
function generateHTML(attributionDetails, shortLicenseName, useFullName = false, isTitleDefault = true) {
241+
const data = {}
242+
const { creatorName, creatorProfileUrl, workUrl, workTitle } = attributionDetails
243+
244+
const licenseSlug = slugFromShort(shortLicenseName)
245+
const { ICONS: icons, URL: url, FULL: fullLicenseName } = LICENSES[licenseSlug]
246+
const licenseName = useFullName ? fullLicenseName : shortLicenseName
247+
248+
data.license = generateLicenseLink(icons, url, licenseName)
249+
data.creator = generateCreatorCode(creatorName, creatorProfileUrl)
250+
data.work = generateWorkCode(workTitle, workUrl, isTitleDefault)
251+
return data
245252
}
246253

247254
export {
248-
defaultAttributes, CC0Attributes, CCBYAttributes, shortToAttr, attrToShort,
255+
defaultAttributes, CC0Attributes, CCBYAttributes, attrToShort, slugFromShort,
249256
attrToFull, licenseURL, chooserRef, licenseSlug, licenseIconsArr, generateHTML, updateVisibleEnabledStatus,
250257
CC_NAMESPACE, DCT_NAMESPACE, LICENSES, ICON_STYLE, ICON_BASE_URL
251258
}

src/utils/licenses.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const LICENSES = {
1515
FULL: 'CC0 1.0 Universal',
1616
SHORT: 'CC0 1.0',
1717
SLUG: 'cc0',
18-
URL: 'https://creativecommons.org/publicdomain/zero/1.0',
18+
URL: 'http://creativecommons.org/publicdomain/zero/1.0',
1919
ICONS: ['cc', 'zero']
2020
},
2121
CC_BY: {
@@ -28,7 +28,7 @@ export const LICENSES = {
2828
FULL: 'Attribution 4.0 International',
2929
SHORT: 'CC BY 4.0',
3030
SLUG: 'cc-by',
31-
URL: 'https://creativecommons.org/licenses/by/4.0',
31+
URL: 'http://creativecommons.org/licenses/by/4.0/',
3232
ICONS: ['cc', 'by']
3333
},
3434
CC_BY_SA: {
@@ -41,7 +41,7 @@ export const LICENSES = {
4141
FULL: 'Attribution-ShareAlike 4.0 International',
4242
SHORT: 'CC BY-SA 4.0',
4343
SLUG: 'cc-by-sa',
44-
URL: 'https://creativecommons.org/licenses/by-sa/4.0',
44+
URL: 'http://creativecommons.org/licenses/by-sa/4.0/',
4545
ICONS: ['cc', 'by', 'sa']
4646
},
4747
CC_BY_NC: {
@@ -54,7 +54,7 @@ export const LICENSES = {
5454
FULL: 'Attribution-NonCommercial 4.0 International',
5555
SHORT: 'CC BY-NC 4.0',
5656
SLUG: 'cc-by-nc',
57-
URL: 'https://creativecommons.org/licenses/by-nc/4.0',
57+
URL: 'http://creativecommons.org/licenses/by-nc/4.0/',
5858
ICONS: ['cc', 'by', 'nc']
5959
},
6060
CC_BY_NC_SA: {
@@ -67,7 +67,7 @@ export const LICENSES = {
6767
FULL: 'Attribution-NonCommercial-ShareAlike 4.0 International',
6868
SHORT: 'CC BY-NC-SA 4.0',
6969
SLUG: 'cc-by-nc-sa',
70-
URL: 'https://creativecommons.org/licenses/by-nc-sa/4.0',
70+
URL: 'http://creativecommons.org/licenses/by-nc-sa/4.0/',
7171
ICONS: ['cc', 'by', 'nc', 'sa']
7272
},
7373
CC_BY_NC_ND: {
@@ -80,7 +80,7 @@ export const LICENSES = {
8080
FULL: 'Attribution-NonCommercial-NoDerivatives 4.0 International',
8181
SHORT: 'CC BY-NC-ND 4.0',
8282
SLUG: 'cc-by-nc-nd',
83-
URL: 'https://creativecommons.org/licenses/by-nc-nd/4.0',
83+
URL: 'http://creativecommons.org/licenses/by-nc-nd/4.0/',
8484
ICONS: ['cc', 'by', 'nc', 'nd']
8585
},
8686
CC_BY_ND: {
@@ -93,7 +93,7 @@ export const LICENSES = {
9393
FULL: 'Attribution-NoDerivatives 4.0 International',
9494
SHORT: 'CC BY-ND 4.0',
9595
SLUG: 'cc-by-nd',
96-
URL: 'https://creativecommons.org/licenses/by-nd/4.0',
96+
URL: 'http://creativecommons.org/licenses/by-nd/4.0/',
9797
ICONS: ['cc', 'by', 'nd']
9898
}
9999
}

tests/e2e/specs/LicenseDetailsCard.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ module.exports = {
1616
browser
1717
.assert.elementPresent('a[class="license-deed-link"]')
1818
.getAttribute('a[class="license-deed-link"]', 'href', function(result) {
19-
this.assert.equal(result.value, 'https://creativecommons.org/licenses/by-sa/4.0?ref=chooser-v1')
19+
this.assert.equal(result.value, 'http://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1')
2020
})
2121
}
2222
}

0 commit comments

Comments
 (0)