mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-31 12:19:31 +02:00
Field: fix wikiURL by URL encoding it - and slight refactors (#10165)
* Field: fix wikiURL by URL encoding it - and slight refactors * Field: fix wikiURL only encodeURIComponent instead of redundant full URL * Field: refactors function to generate wikiURL, ensures anchor part is also URI encoded, ensures the anchor ref is not encoded, adds unit tests * Field: refactors wikipedia URI encoding of the anchor logic, removes legacy anchorencode effort via try-catch that replaced percentage character with dots, adds unit further tests, reduces exessive inlining
This commit is contained in:
@@ -11,6 +11,8 @@ import { utilGetSetValue, utilNoAuto, utilRebind } from '../../util';
|
||||
|
||||
|
||||
export function uiFieldWikipedia(field, context) {
|
||||
const scheme = 'https://';
|
||||
const domain = 'wikipedia.org';
|
||||
const dispatch = d3_dispatch('change');
|
||||
const wikipedia = services.wikipedia;
|
||||
const wikidata = services.wikidata;
|
||||
@@ -132,7 +134,7 @@ export function uiFieldWikipedia(field, context) {
|
||||
link = link.enter()
|
||||
.append('button')
|
||||
.attr('class', 'form-field-button wiki-link')
|
||||
.attr('title', t('icons.view_on', { domain: 'wikipedia.org' }))
|
||||
.attr('title', t('icons.view_on', { domain }))
|
||||
.call(svgIcon('#iD-icon-out-link'))
|
||||
.merge(link);
|
||||
|
||||
@@ -280,24 +282,13 @@ export function uiFieldWikipedia(field, context) {
|
||||
const nativeLangName = tagLangInfo[1];
|
||||
utilGetSetValue(_langInput, nativeLangName);
|
||||
utilGetSetValue(_titleInput, tagArticleTitle + (anchor ? ('#' + anchor) : ''));
|
||||
if (anchor) {
|
||||
try {
|
||||
// Best-effort `anchorencode:` implementation
|
||||
anchor = encodeURIComponent(anchor.replace(/ /g, '_')).replace(/%/g, '.');
|
||||
} catch (e) {
|
||||
anchor = anchor.replace(/ /g, '_');
|
||||
}
|
||||
}
|
||||
_wikiURL = 'https://' + tagLang + '.wikipedia.org/wiki/' +
|
||||
tagArticleTitle.replace(/ /g, '_') + (anchor ? ('#' + anchor) : '');
|
||||
|
||||
// unrecognized value format
|
||||
_wikiURL = `${scheme}${tagLang}.${domain}/wiki/${wiki.encodePath(tagArticleTitle, anchor)}`;
|
||||
} else {
|
||||
utilGetSetValue(_titleInput, value);
|
||||
if (value && value !== '') {
|
||||
utilGetSetValue(_langInput, '');
|
||||
const defaultLangInfo = defaultLanguageInfo();
|
||||
_wikiURL = `https://${defaultLangInfo[2]}.wikipedia.org/w/index.php?fulltext=1&search=${value}`;
|
||||
_wikiURL = `${scheme}${defaultLangInfo[2]}.${domain}/w/index.php?fulltext=1&search=${value}`;
|
||||
} else {
|
||||
const shownOrDefaultLangInfo = language(true /* skipEnglishFallback */);
|
||||
utilGetSetValue(_langInput, shownOrDefaultLangInfo[1]);
|
||||
@@ -306,6 +297,18 @@ export function uiFieldWikipedia(field, context) {
|
||||
}
|
||||
}
|
||||
|
||||
wiki.encodePath = (tagArticleTitle, anchor) => {
|
||||
const underscoredTitle = tagArticleTitle.replace(/ /g, '_');
|
||||
const uriEncodedUnderscoredTitle = encodeURIComponent(underscoredTitle);
|
||||
const uriEncodedAnchorFragment = wiki.encodeURIAnchorFragment(anchor);
|
||||
return `${uriEncodedUnderscoredTitle}${uriEncodedAnchorFragment}`;
|
||||
};
|
||||
|
||||
wiki.encodeURIAnchorFragment = (anchor) => {
|
||||
if (!anchor) return '';
|
||||
const underscoredAnchor = anchor.replace(/ /g, '_');
|
||||
return '#' + encodeURIComponent(underscoredAnchor);
|
||||
};
|
||||
|
||||
wiki.entityIDs = (val) => {
|
||||
if (!arguments.length) return _entityIDs;
|
||||
|
||||
@@ -113,6 +113,48 @@ describe('iD.uiFieldWikipedia', function() {
|
||||
}, 20);
|
||||
});
|
||||
|
||||
describe('encodePath', function() {
|
||||
it('returns an encoded URI component that contains the title with spaces replaced by underscores', function(done) {
|
||||
var wikipedia = iD.uiFieldWikipedia(field, context).entityIDs([entity.id]);
|
||||
expect(wikipedia.encodePath('? (film)', undefined)).to.equal('%3F_(film)');
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns an encoded URI component that includes an anchor fragment', function(done) {
|
||||
var wikipedia = iD.uiFieldWikipedia(field, context).entityIDs([entity.id]);
|
||||
// this can be tested manually by entering '? (film)#Themes and style in the search box before focusing out'
|
||||
expect(wikipedia.encodePath('? (film)', 'Themes and style')).to.equal('%3F_(film)#Themes_and_style');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('encodeURIAnchorFragment', function() {
|
||||
it('returns an encoded URI anchor fragment', function(done) {
|
||||
var wikipedia = iD.uiFieldWikipedia(field, context).entityIDs([entity.id]);
|
||||
// this can be similarily tested by entering 'Section#Arts, entertainment and media' in the search box before focusing out'
|
||||
expect(wikipedia.encodeURIAnchorFragment('Theme?')).to.equal('#Theme%3F');
|
||||
done();
|
||||
});
|
||||
|
||||
it('replaces all whitespace characters with underscore', function(done) {
|
||||
var wikipedia = iD.uiFieldWikipedia(field, context).entityIDs([entity.id]);
|
||||
expect(wikipedia.encodeURIAnchorFragment('Themes And Styles')).to.equal('#Themes_And_Styles');
|
||||
done();
|
||||
});
|
||||
|
||||
it('encodes % characters, does not replace them with a dot', function(done) {
|
||||
var wikipedia = iD.uiFieldWikipedia(field, context).entityIDs([entity.id]);
|
||||
expect(wikipedia.encodeURIAnchorFragment('Is%this_100% correct')).to.equal('#Is%25this_100%25_correct');
|
||||
done();
|
||||
});
|
||||
|
||||
it('encodes characters that are URI encoded characters', function (done) {
|
||||
var wikipedia = iD.uiFieldWikipedia(field, context).entityIDs([entity.id]);
|
||||
expect(wikipedia.encodeURIAnchorFragment('Section %20%25')).to.equal('#Section_%2520%2525');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
// note - currently skipping the tests that use `options` to delay responses
|
||||
it('preserves existing language', function(done) {
|
||||
var wikipedia1 = iD.uiFieldWikipedia(field, context);
|
||||
|
||||
Reference in New Issue
Block a user