kopia lustrzana https://github.com/wagtail/wagtail
Move urlify (Django port) & remove xregexp vendor library
- Move vendor/urlify.js into our own codebase as a port of the Djago util - Remove the need for xregexp polyfill librarypull/11854/head
rodzic
f0cf73f0d3
commit
be5b69078a
|
@ -229,8 +229,6 @@ describe('compare behaviour', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('urlify behaviour', () => {
|
describe('urlify behaviour', () => {
|
||||||
require('../../../wagtail/admin/static_src/wagtailadmin/js/vendor/urlify')
|
|
||||||
.default;
|
|
||||||
let application;
|
let application;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
@ -77,6 +77,11 @@ export class SlugController extends Controller<HTMLInputElement> {
|
||||||
/**
|
/**
|
||||||
* Advanced slugify of a string, updates the controlled element's value
|
* Advanced slugify of a string, updates the controlled element's value
|
||||||
* or can be used to simply return the transformed value.
|
* or can be used to simply return the transformed value.
|
||||||
|
*
|
||||||
|
* The urlify (Django port) function performs extra processing on the string &
|
||||||
|
* is more suitable for creating a slug from the title, rather than sanitising manually.
|
||||||
|
* If the urlify util returns an empty string it will fall back to the slugify method.
|
||||||
|
*
|
||||||
* If a custom event with detail.value is provided, that value will be used
|
* If a custom event with detail.value is provided, that value will be used
|
||||||
* instead of the field's value.
|
* instead of the field's value.
|
||||||
*/
|
*/
|
||||||
|
@ -84,9 +89,13 @@ export class SlugController extends Controller<HTMLInputElement> {
|
||||||
event: CustomEvent<{ value: string }> | { detail: { value: string } },
|
event: CustomEvent<{ value: string }> | { detail: { value: string } },
|
||||||
ignoreUpdate = false,
|
ignoreUpdate = false,
|
||||||
) {
|
) {
|
||||||
const unicodeSlugsEnabled = this.allowUnicodeValue;
|
|
||||||
const { value = this.element.value } = event?.detail || {};
|
const { value = this.element.value } = event?.detail || {};
|
||||||
const newValue = urlify(value.trim(), { unicodeSlugsEnabled });
|
|
||||||
|
const trimmedValue = value.trim();
|
||||||
|
|
||||||
|
const newValue =
|
||||||
|
urlify(trimmedValue) ||
|
||||||
|
this.slugify({ detail: { value: trimmedValue } }, true);
|
||||||
|
|
||||||
if (!ignoreUpdate) {
|
if (!ignoreUpdate) {
|
||||||
this.element.value = newValue;
|
this.element.value = newValue;
|
||||||
|
|
|
@ -0,0 +1,494 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"LATIN_MAP": [
|
||||||
|
["À", "A"],
|
||||||
|
["Á", "A"],
|
||||||
|
["Â", "A"],
|
||||||
|
["Ã", "A"],
|
||||||
|
["Ä", "A"],
|
||||||
|
["Å", "A"],
|
||||||
|
["Æ", "AE"],
|
||||||
|
["Ç", "C"],
|
||||||
|
["È", "E"],
|
||||||
|
["É", "E"],
|
||||||
|
["Ê", "E"],
|
||||||
|
["Ë", "E"],
|
||||||
|
["Ì", "I"],
|
||||||
|
["Í", "I"],
|
||||||
|
["Î", "I"],
|
||||||
|
["Ï", "I"],
|
||||||
|
["Ð", "D"],
|
||||||
|
["Ñ", "N"],
|
||||||
|
["Ò", "O"],
|
||||||
|
["Ó", "O"],
|
||||||
|
["Ô", "O"],
|
||||||
|
["Õ", "O"],
|
||||||
|
["Ö", "O"],
|
||||||
|
["Ő", "O"],
|
||||||
|
["Ø", "O"],
|
||||||
|
["Ù", "U"],
|
||||||
|
["Ú", "U"],
|
||||||
|
["Û", "U"],
|
||||||
|
["Ü", "U"],
|
||||||
|
["Ű", "U"],
|
||||||
|
["Ý", "Y"],
|
||||||
|
["Þ", "TH"],
|
||||||
|
["Ÿ", "Y"],
|
||||||
|
["ß", "ss"],
|
||||||
|
["à", "a"],
|
||||||
|
["á", "a"],
|
||||||
|
["â", "a"],
|
||||||
|
["ã", "a"],
|
||||||
|
["ä", "a"],
|
||||||
|
["å", "a"],
|
||||||
|
["æ", "ae"],
|
||||||
|
["ç", "c"],
|
||||||
|
["è", "e"],
|
||||||
|
["é", "e"],
|
||||||
|
["ê", "e"],
|
||||||
|
["ë", "e"],
|
||||||
|
["ì", "i"],
|
||||||
|
["í", "i"],
|
||||||
|
["î", "i"],
|
||||||
|
["ï", "i"],
|
||||||
|
["ð", "d"],
|
||||||
|
["ñ", "n"],
|
||||||
|
["ò", "o"],
|
||||||
|
["ó", "o"],
|
||||||
|
["ô", "o"],
|
||||||
|
["õ", "o"],
|
||||||
|
["ö", "o"],
|
||||||
|
["ő", "o"],
|
||||||
|
["ø", "o"],
|
||||||
|
["ù", "u"],
|
||||||
|
["ú", "u"],
|
||||||
|
["û", "u"],
|
||||||
|
["ü", "u"],
|
||||||
|
["ű", "u"],
|
||||||
|
["ý", "y"],
|
||||||
|
["þ", "th"],
|
||||||
|
["ÿ", "y"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ "LATIN_SYMBOLS_MAP": [["©", "(c)"]] },
|
||||||
|
{
|
||||||
|
"GREEK_MAP": [
|
||||||
|
["α", "a"],
|
||||||
|
["β", "b"],
|
||||||
|
["γ", "g"],
|
||||||
|
["δ", "d"],
|
||||||
|
["ε", "e"],
|
||||||
|
["ζ", "z"],
|
||||||
|
["η", "h"],
|
||||||
|
["θ", "8"],
|
||||||
|
["ι", "i"],
|
||||||
|
["κ", "k"],
|
||||||
|
["λ", "l"],
|
||||||
|
["μ", "m"],
|
||||||
|
["ν", "n"],
|
||||||
|
["ξ", "3"],
|
||||||
|
["ο", "o"],
|
||||||
|
["π", "p"],
|
||||||
|
["ρ", "r"],
|
||||||
|
["σ", "s"],
|
||||||
|
["τ", "t"],
|
||||||
|
["υ", "y"],
|
||||||
|
["φ", "f"],
|
||||||
|
["χ", "x"],
|
||||||
|
["ψ", "ps"],
|
||||||
|
["ω", "w"],
|
||||||
|
["ά", "a"],
|
||||||
|
["έ", "e"],
|
||||||
|
["ί", "i"],
|
||||||
|
["ό", "o"],
|
||||||
|
["ύ", "y"],
|
||||||
|
["ή", "h"],
|
||||||
|
["ώ", "w"],
|
||||||
|
["ς", "s"],
|
||||||
|
["ϊ", "i"],
|
||||||
|
["ΰ", "y"],
|
||||||
|
["ϋ", "y"],
|
||||||
|
["ΐ", "i"],
|
||||||
|
["Α", "A"],
|
||||||
|
["Β", "B"],
|
||||||
|
["Γ", "G"],
|
||||||
|
["Δ", "D"],
|
||||||
|
["Ε", "E"],
|
||||||
|
["Ζ", "Z"],
|
||||||
|
["Η", "H"],
|
||||||
|
["Θ", "8"],
|
||||||
|
["Ι", "I"],
|
||||||
|
["Κ", "K"],
|
||||||
|
["Λ", "L"],
|
||||||
|
["Μ", "M"],
|
||||||
|
["Ν", "N"],
|
||||||
|
["Ξ", "3"],
|
||||||
|
["Ο", "O"],
|
||||||
|
["Π", "P"],
|
||||||
|
["Ρ", "R"],
|
||||||
|
["Σ", "S"],
|
||||||
|
["Τ", "T"],
|
||||||
|
["Υ", "Y"],
|
||||||
|
["Φ", "F"],
|
||||||
|
["Χ", "X"],
|
||||||
|
["Ψ", "PS"],
|
||||||
|
["Ω", "W"],
|
||||||
|
["Ά", "A"],
|
||||||
|
["Έ", "E"],
|
||||||
|
["Ί", "I"],
|
||||||
|
["Ό", "O"],
|
||||||
|
["Ύ", "Y"],
|
||||||
|
["Ή", "H"],
|
||||||
|
["Ώ", "W"],
|
||||||
|
["Ϊ", "I"],
|
||||||
|
["Ϋ", "Y"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"TURKISH_MAP": [
|
||||||
|
["ş", "s"],
|
||||||
|
["Ş", "S"],
|
||||||
|
["ı", "i"],
|
||||||
|
["İ", "I"],
|
||||||
|
["ç", "c"],
|
||||||
|
["Ç", "C"],
|
||||||
|
["ü", "u"],
|
||||||
|
["Ü", "U"],
|
||||||
|
["ö", "o"],
|
||||||
|
["Ö", "O"],
|
||||||
|
["ğ", "g"],
|
||||||
|
["Ğ", "G"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ROMANIAN_MAP": [
|
||||||
|
["ă", "a"],
|
||||||
|
["î", "i"],
|
||||||
|
["ș", "s"],
|
||||||
|
["ț", "t"],
|
||||||
|
["â", "a"],
|
||||||
|
["Ă", "A"],
|
||||||
|
["Î", "I"],
|
||||||
|
["Ș", "S"],
|
||||||
|
["Ț", "T"],
|
||||||
|
["Â", "A"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"RUSSIAN_MAP": [
|
||||||
|
["а", "a"],
|
||||||
|
["б", "b"],
|
||||||
|
["в", "v"],
|
||||||
|
["г", "g"],
|
||||||
|
["д", "d"],
|
||||||
|
["е", "e"],
|
||||||
|
["ё", "yo"],
|
||||||
|
["ж", "zh"],
|
||||||
|
["з", "z"],
|
||||||
|
["и", "i"],
|
||||||
|
["й", "j"],
|
||||||
|
["к", "k"],
|
||||||
|
["л", "l"],
|
||||||
|
["м", "m"],
|
||||||
|
["н", "n"],
|
||||||
|
["о", "o"],
|
||||||
|
["п", "p"],
|
||||||
|
["р", "r"],
|
||||||
|
["с", "s"],
|
||||||
|
["т", "t"],
|
||||||
|
["у", "u"],
|
||||||
|
["ф", "f"],
|
||||||
|
["х", "h"],
|
||||||
|
["ц", "c"],
|
||||||
|
["ч", "ch"],
|
||||||
|
["ш", "sh"],
|
||||||
|
["щ", "sh"],
|
||||||
|
["ъ", ""],
|
||||||
|
["ы", "y"],
|
||||||
|
["ь", ""],
|
||||||
|
["э", "e"],
|
||||||
|
["ю", "yu"],
|
||||||
|
["я", "ya"],
|
||||||
|
["А", "A"],
|
||||||
|
["Б", "B"],
|
||||||
|
["В", "V"],
|
||||||
|
["Г", "G"],
|
||||||
|
["Д", "D"],
|
||||||
|
["Е", "E"],
|
||||||
|
["Ё", "Yo"],
|
||||||
|
["Ж", "Zh"],
|
||||||
|
["З", "Z"],
|
||||||
|
["И", "I"],
|
||||||
|
["Й", "J"],
|
||||||
|
["К", "K"],
|
||||||
|
["Л", "L"],
|
||||||
|
["М", "M"],
|
||||||
|
["Н", "N"],
|
||||||
|
["О", "O"],
|
||||||
|
["П", "P"],
|
||||||
|
["Р", "R"],
|
||||||
|
["С", "S"],
|
||||||
|
["Т", "T"],
|
||||||
|
["У", "U"],
|
||||||
|
["Ф", "F"],
|
||||||
|
["Х", "H"],
|
||||||
|
["Ц", "C"],
|
||||||
|
["Ч", "Ch"],
|
||||||
|
["Ш", "Sh"],
|
||||||
|
["Щ", "Sh"],
|
||||||
|
["Ъ", ""],
|
||||||
|
["Ы", "Y"],
|
||||||
|
["Ь", ""],
|
||||||
|
["Э", "E"],
|
||||||
|
["Ю", "Yu"],
|
||||||
|
["Я", "Ya"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"UKRAINIAN_MAP": [
|
||||||
|
["Є", "Ye"],
|
||||||
|
["І", "I"],
|
||||||
|
["Ї", "Yi"],
|
||||||
|
["Ґ", "G"],
|
||||||
|
["є", "ye"],
|
||||||
|
["і", "i"],
|
||||||
|
["ї", "yi"],
|
||||||
|
["ґ", "g"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"CZECH_MAP": [
|
||||||
|
["č", "c"],
|
||||||
|
["ď", "d"],
|
||||||
|
["ě", "e"],
|
||||||
|
["ň", "n"],
|
||||||
|
["ř", "r"],
|
||||||
|
["š", "s"],
|
||||||
|
["ť", "t"],
|
||||||
|
["ů", "u"],
|
||||||
|
["ž", "z"],
|
||||||
|
["Č", "C"],
|
||||||
|
["Ď", "D"],
|
||||||
|
["Ě", "E"],
|
||||||
|
["Ň", "N"],
|
||||||
|
["Ř", "R"],
|
||||||
|
["Š", "S"],
|
||||||
|
["Ť", "T"],
|
||||||
|
["Ů", "U"],
|
||||||
|
["Ž", "Z"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"SLOVAK_MAP": [
|
||||||
|
["á", "a"],
|
||||||
|
["ä", "a"],
|
||||||
|
["č", "c"],
|
||||||
|
["ď", "d"],
|
||||||
|
["é", "e"],
|
||||||
|
["í", "i"],
|
||||||
|
["ľ", "l"],
|
||||||
|
["ĺ", "l"],
|
||||||
|
["ň", "n"],
|
||||||
|
["ó", "o"],
|
||||||
|
["ô", "o"],
|
||||||
|
["ŕ", "r"],
|
||||||
|
["š", "s"],
|
||||||
|
["ť", "t"],
|
||||||
|
["ú", "u"],
|
||||||
|
["ý", "y"],
|
||||||
|
["ž", "z"],
|
||||||
|
["Á", "a"],
|
||||||
|
["Ä", "A"],
|
||||||
|
["Č", "C"],
|
||||||
|
["Ď", "D"],
|
||||||
|
["É", "E"],
|
||||||
|
["Í", "I"],
|
||||||
|
["Ľ", "L"],
|
||||||
|
["Ĺ", "L"],
|
||||||
|
["Ň", "N"],
|
||||||
|
["Ó", "O"],
|
||||||
|
["Ô", "O"],
|
||||||
|
["Ŕ", "R"],
|
||||||
|
["Š", "S"],
|
||||||
|
["Ť", "T"],
|
||||||
|
["Ú", "U"],
|
||||||
|
["Ý", "Y"],
|
||||||
|
["Ž", "Z"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"POLISH_MAP": [
|
||||||
|
["ą", "a"],
|
||||||
|
["ć", "c"],
|
||||||
|
["ę", "e"],
|
||||||
|
["ł", "l"],
|
||||||
|
["ń", "n"],
|
||||||
|
["ó", "o"],
|
||||||
|
["ś", "s"],
|
||||||
|
["ź", "z"],
|
||||||
|
["ż", "z"],
|
||||||
|
["Ą", "A"],
|
||||||
|
["Ć", "C"],
|
||||||
|
["Ę", "E"],
|
||||||
|
["Ł", "L"],
|
||||||
|
["Ń", "N"],
|
||||||
|
["Ó", "O"],
|
||||||
|
["Ś", "S"],
|
||||||
|
["Ź", "Z"],
|
||||||
|
["Ż", "Z"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"LATVIAN_MAP": [
|
||||||
|
["ā", "a"],
|
||||||
|
["č", "c"],
|
||||||
|
["ē", "e"],
|
||||||
|
["ģ", "g"],
|
||||||
|
["ī", "i"],
|
||||||
|
["ķ", "k"],
|
||||||
|
["ļ", "l"],
|
||||||
|
["ņ", "n"],
|
||||||
|
["š", "s"],
|
||||||
|
["ū", "u"],
|
||||||
|
["ž", "z"],
|
||||||
|
["Ā", "A"],
|
||||||
|
["Č", "C"],
|
||||||
|
["Ē", "E"],
|
||||||
|
["Ģ", "G"],
|
||||||
|
["Ī", "I"],
|
||||||
|
["Ķ", "K"],
|
||||||
|
["Ļ", "L"],
|
||||||
|
["Ņ", "N"],
|
||||||
|
["Š", "S"],
|
||||||
|
["Ū", "U"],
|
||||||
|
["Ž", "Z"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ARABIC_MAP": [
|
||||||
|
["أ", "a"],
|
||||||
|
["ب", "b"],
|
||||||
|
["ت", "t"],
|
||||||
|
["ث", "th"],
|
||||||
|
["ج", "g"],
|
||||||
|
["ح", "h"],
|
||||||
|
["خ", "kh"],
|
||||||
|
["د", "d"],
|
||||||
|
["ذ", "th"],
|
||||||
|
["ر", "r"],
|
||||||
|
["ز", "z"],
|
||||||
|
["س", "s"],
|
||||||
|
["ش", "sh"],
|
||||||
|
["ص", "s"],
|
||||||
|
["ض", "d"],
|
||||||
|
["ط", "t"],
|
||||||
|
["ظ", "th"],
|
||||||
|
["ع", "aa"],
|
||||||
|
["غ", "gh"],
|
||||||
|
["ف", "f"],
|
||||||
|
["ق", "k"],
|
||||||
|
["ك", "k"],
|
||||||
|
["ل", "l"],
|
||||||
|
["م", "m"],
|
||||||
|
["ن", "n"],
|
||||||
|
["ه", "h"],
|
||||||
|
["و", "o"],
|
||||||
|
["ي", "y"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"LITHUANIAN_MAP": [
|
||||||
|
["ą", "a"],
|
||||||
|
["č", "c"],
|
||||||
|
["ę", "e"],
|
||||||
|
["ė", "e"],
|
||||||
|
["į", "i"],
|
||||||
|
["š", "s"],
|
||||||
|
["ų", "u"],
|
||||||
|
["ū", "u"],
|
||||||
|
["ž", "z"],
|
||||||
|
["Ą", "A"],
|
||||||
|
["Č", "C"],
|
||||||
|
["Ę", "E"],
|
||||||
|
["Ė", "E"],
|
||||||
|
["Į", "I"],
|
||||||
|
["Š", "S"],
|
||||||
|
["Ų", "U"],
|
||||||
|
["Ū", "U"],
|
||||||
|
["Ž", "Z"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"SERBIAN_MAP": [
|
||||||
|
["ђ", "dj"],
|
||||||
|
["ј", "j"],
|
||||||
|
["љ", "lj"],
|
||||||
|
["њ", "nj"],
|
||||||
|
["ћ", "c"],
|
||||||
|
["џ", "dz"],
|
||||||
|
["đ", "dj"],
|
||||||
|
["Ђ", "Dj"],
|
||||||
|
["Ј", "j"],
|
||||||
|
["Љ", "Lj"],
|
||||||
|
["Њ", "Nj"],
|
||||||
|
["Ћ", "C"],
|
||||||
|
["Џ", "Dz"],
|
||||||
|
["Đ", "Dj"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"AZERBAIJANI_MAP": [
|
||||||
|
["ç", "c"],
|
||||||
|
["ə", "e"],
|
||||||
|
["ğ", "g"],
|
||||||
|
["ı", "i"],
|
||||||
|
["ö", "o"],
|
||||||
|
["ş", "s"],
|
||||||
|
["ü", "u"],
|
||||||
|
["Ç", "C"],
|
||||||
|
["Ə", "E"],
|
||||||
|
["Ğ", "G"],
|
||||||
|
["İ", "I"],
|
||||||
|
["Ö", "O"],
|
||||||
|
["Ş", "S"],
|
||||||
|
["Ü", "U"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GEORGIAN_MAP": [
|
||||||
|
["ა", "a"],
|
||||||
|
["ბ", "b"],
|
||||||
|
["გ", "g"],
|
||||||
|
["დ", "d"],
|
||||||
|
["ე", "e"],
|
||||||
|
["ვ", "v"],
|
||||||
|
["ზ", "z"],
|
||||||
|
["თ", "t"],
|
||||||
|
["ი", "i"],
|
||||||
|
["კ", "k"],
|
||||||
|
["ლ", "l"],
|
||||||
|
["მ", "m"],
|
||||||
|
["ნ", "n"],
|
||||||
|
["ო", "o"],
|
||||||
|
["პ", "p"],
|
||||||
|
["ჟ", "j"],
|
||||||
|
["რ", "r"],
|
||||||
|
["ს", "s"],
|
||||||
|
["ტ", "t"],
|
||||||
|
["უ", "u"],
|
||||||
|
["ფ", "f"],
|
||||||
|
["ქ", "q"],
|
||||||
|
["ღ", "g"],
|
||||||
|
["ყ", "y"],
|
||||||
|
["შ", "sh"],
|
||||||
|
["ჩ", "ch"],
|
||||||
|
["ც", "c"],
|
||||||
|
["ძ", "dz"],
|
||||||
|
["წ", "w"],
|
||||||
|
["ჭ", "ch"],
|
||||||
|
["ხ", "x"],
|
||||||
|
["ჯ", "j"],
|
||||||
|
["ჰ", "h"]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
|
@ -1,16 +1,10 @@
|
||||||
import { urlify } from './urlify';
|
import { urlify } from './urlify';
|
||||||
|
|
||||||
describe('urlify', () => {
|
describe('urlify', () => {
|
||||||
beforeAll(() => {
|
|
||||||
// load window.URLify
|
|
||||||
require('../../../wagtail/admin/static_src/wagtailadmin/js/vendor/urlify')
|
|
||||||
.default;
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('urlify with unicode slugs disabled (default)', () => {
|
describe('urlify with unicode slugs disabled (default)', () => {
|
||||||
it('should return a correct slug which is escaped by urlify', () => {
|
it('should return a correct slug which is escaped by urlify', () => {
|
||||||
expect(urlify('This & That')).toBe('this-that');
|
expect(urlify('This & That')).toBe('this-that');
|
||||||
|
expect(urlify('The Price is $72.00!')).toBe('the-price-is-7200');
|
||||||
expect(urlify('Lisboa é ótima à beira-mar')).toBe(
|
expect(urlify('Lisboa é ótima à beira-mar')).toBe(
|
||||||
'lisboa-e-otima-a-beira-mar',
|
'lisboa-e-otima-a-beira-mar',
|
||||||
);
|
);
|
||||||
|
@ -18,7 +12,7 @@ describe('urlify', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('urlify with unicode slugs enabled', () => {
|
describe('urlify with unicode slugs enabled', () => {
|
||||||
const options = { unicodeSlugsEnabled: true };
|
const options = { allowUnicode: true };
|
||||||
|
|
||||||
it('should return a correct slug which is escaped by urlify', () => {
|
it('should return a correct slug which is escaped by urlify', () => {
|
||||||
expect(urlify('Before', options)).toBe('before');
|
expect(urlify('Before', options)).toBe('before');
|
||||||
|
@ -31,9 +25,9 @@ describe('urlify', () => {
|
||||||
'on-this-day-in-november',
|
'on-this-day-in-november',
|
||||||
);
|
);
|
||||||
expect(urlify('This & That', options)).toBe('this-that');
|
expect(urlify('This & That', options)).toBe('this-that');
|
||||||
|
expect(urlify('The Price is $72.00!', options)).toBe('the-price-is-7200');
|
||||||
expect(urlify('Lisboa é ótima à beira-mar', options)).toBe(
|
expect(urlify('Lisboa é ótima à beira-mar', options)).toBe(
|
||||||
'lisboa-e-otima-a-beira-mar',
|
'lisboa-é-ótima-à-beira-mar',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,21 +1,45 @@
|
||||||
import { slugify } from './slugify';
|
import config from './urlify.config.json';
|
||||||
|
|
||||||
declare global {
|
const downcodeMapping = config.reduce((acc, downcodeMap) => {
|
||||||
interface Window {
|
Object.values(downcodeMap)
|
||||||
URLify: any;
|
.flat()
|
||||||
}
|
.forEach(([char, replacedChar]) => {
|
||||||
}
|
acc[char] = replacedChar;
|
||||||
|
});
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
const regex = new RegExp(Object.keys(downcodeMapping).join('|'), 'g');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the supplied string as a slug suitable for a URL using the vendor URLify util.
|
* IMPORTANT This util and the mapping is a direct port of Django's urlify.js util,
|
||||||
* If the vendor util returns an empty string it will fall back to the slugify method.
|
* without the need for a full Regex polyfill implementation.
|
||||||
|
* @see https://github.com/django/django/blob/main/django/contrib/admin/static/admin/js/urlify.js
|
||||||
*/
|
*/
|
||||||
export const urlify = (value: string, options = {}) => {
|
export const urlify = (
|
||||||
// URLify performs extra processing on the string (e.g. removing stopwords) and is more suitable
|
originalStr: string,
|
||||||
// for creating a slug from the title, rather than sanitising a slug entered manually
|
{
|
||||||
const cleaned = window.URLify(value, 255);
|
numChars = 255,
|
||||||
|
allowUnicode = false,
|
||||||
// if the result is blank (e.g. because the title consisted entirely of stopwords),
|
}: { numChars?: number; allowUnicode?: boolean } = {},
|
||||||
// fall through to the non-URLify method
|
) => {
|
||||||
return cleaned || slugify(value, options);
|
let str = originalStr;
|
||||||
|
// changes, e.g., "Petty theft" to "petty-theft"
|
||||||
|
if (!allowUnicode) {
|
||||||
|
str = str.replace(regex, (item) => downcodeMapping[item]);
|
||||||
|
}
|
||||||
|
str = str.toLowerCase(); // convert to lowercase
|
||||||
|
// if downcode doesn't hit, the char will be stripped here
|
||||||
|
if (allowUnicode) {
|
||||||
|
// Keep Unicode letters including both lowercase and uppercase
|
||||||
|
// characters, whitespace, and dash; remove other characters.
|
||||||
|
str = str.replace(/[^-_\p{L}\p{N}\s]/gu, '');
|
||||||
|
} else {
|
||||||
|
str = str.replace(/[^-\w\s]/g, ''); // remove unneeded chars
|
||||||
|
}
|
||||||
|
str = str.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces
|
||||||
|
str = str.replace(/[-\s]+/g, '-'); // convert spaces to hyphens
|
||||||
|
str = str.substring(0, numChars); // trim to first num_chars chars
|
||||||
|
str = str.replace(/-+$/g, ''); // trim any trailing hyphens
|
||||||
|
return str;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,182 +0,0 @@
|
||||||
/*global XRegExp*/
|
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var LATIN_MAP = {
|
|
||||||
'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE',
|
|
||||||
'Ç': 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I',
|
|
||||||
'Î': 'I', 'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O',
|
|
||||||
'Õ': 'O', 'Ö': 'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U',
|
|
||||||
'Ü': 'U', 'Ű': 'U', 'Ý': 'Y', 'Þ': 'TH', 'Ÿ': 'Y', 'ß': 'ss', 'à': 'a',
|
|
||||||
'á': 'a', 'â': 'a', 'ã': 'a', 'ä': 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c',
|
|
||||||
'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e', 'ì': 'i', 'í': 'i', 'î': 'i',
|
|
||||||
'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò': 'o', 'ó': 'o', 'ô': 'o', 'õ': 'o',
|
|
||||||
'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 'ú': 'u', 'û': 'u', 'ü': 'u',
|
|
||||||
'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y'
|
|
||||||
};
|
|
||||||
var LATIN_SYMBOLS_MAP = {
|
|
||||||
'©': '(c)'
|
|
||||||
};
|
|
||||||
var GREEK_MAP = {
|
|
||||||
'α': 'a', 'β': 'b', 'γ': 'g', 'δ': 'd', 'ε': 'e', 'ζ': 'z', 'η': 'h',
|
|
||||||
'θ': '8', 'ι': 'i', 'κ': 'k', 'λ': 'l', 'μ': 'm', 'ν': 'n', 'ξ': '3',
|
|
||||||
'ο': 'o', 'π': 'p', 'ρ': 'r', 'σ': 's', 'τ': 't', 'υ': 'y', 'φ': 'f',
|
|
||||||
'χ': 'x', 'ψ': 'ps', 'ω': 'w', 'ά': 'a', 'έ': 'e', 'ί': 'i', 'ό': 'o',
|
|
||||||
'ύ': 'y', 'ή': 'h', 'ώ': 'w', 'ς': 's', 'ϊ': 'i', 'ΰ': 'y', 'ϋ': 'y',
|
|
||||||
'ΐ': 'i', 'Α': 'A', 'Β': 'B', 'Γ': 'G', 'Δ': 'D', 'Ε': 'E', 'Ζ': 'Z',
|
|
||||||
'Η': 'H', 'Θ': '8', 'Ι': 'I', 'Κ': 'K', 'Λ': 'L', 'Μ': 'M', 'Ν': 'N',
|
|
||||||
'Ξ': '3', 'Ο': 'O', 'Π': 'P', 'Ρ': 'R', 'Σ': 'S', 'Τ': 'T', 'Υ': 'Y',
|
|
||||||
'Φ': 'F', 'Χ': 'X', 'Ψ': 'PS', 'Ω': 'W', 'Ά': 'A', 'Έ': 'E', 'Ί': 'I',
|
|
||||||
'Ό': 'O', 'Ύ': 'Y', 'Ή': 'H', 'Ώ': 'W', 'Ϊ': 'I', 'Ϋ': 'Y'
|
|
||||||
};
|
|
||||||
var TURKISH_MAP = {
|
|
||||||
'ş': 's', 'Ş': 'S', 'ı': 'i', 'İ': 'I', 'ç': 'c', 'Ç': 'C', 'ü': 'u',
|
|
||||||
'Ü': 'U', 'ö': 'o', 'Ö': 'O', 'ğ': 'g', 'Ğ': 'G'
|
|
||||||
};
|
|
||||||
var ROMANIAN_MAP = {
|
|
||||||
'ă': 'a', 'î': 'i', 'ș': 's', 'ț': 't', 'â': 'a',
|
|
||||||
'Ă': 'A', 'Î': 'I', 'Ș': 'S', 'Ț': 'T', 'Â': 'A'
|
|
||||||
};
|
|
||||||
var RUSSIAN_MAP = {
|
|
||||||
'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', 'е': 'e', 'ё': 'yo',
|
|
||||||
'ж': 'zh', 'з': 'z', 'и': 'i', 'й': 'j', 'к': 'k', 'л': 'l', 'м': 'm',
|
|
||||||
'н': 'n', 'о': 'o', 'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u',
|
|
||||||
'ф': 'f', 'х': 'h', 'ц': 'c', 'ч': 'ch', 'ш': 'sh', 'щ': 'sh', 'ъ': '',
|
|
||||||
'ы': 'y', 'ь': '', 'э': 'e', 'ю': 'yu', 'я': 'ya',
|
|
||||||
'А': 'A', 'Б': 'B', 'В': 'V', 'Г': 'G', 'Д': 'D', 'Е': 'E', 'Ё': 'Yo',
|
|
||||||
'Ж': 'Zh', 'З': 'Z', 'И': 'I', 'Й': 'J', 'К': 'K', 'Л': 'L', 'М': 'M',
|
|
||||||
'Н': 'N', 'О': 'O', 'П': 'P', 'Р': 'R', 'С': 'S', 'Т': 'T', 'У': 'U',
|
|
||||||
'Ф': 'F', 'Х': 'H', 'Ц': 'C', 'Ч': 'Ch', 'Ш': 'Sh', 'Щ': 'Sh', 'Ъ': '',
|
|
||||||
'Ы': 'Y', 'Ь': '', 'Э': 'E', 'Ю': 'Yu', 'Я': 'Ya'
|
|
||||||
};
|
|
||||||
var UKRAINIAN_MAP = {
|
|
||||||
'Є': 'Ye', 'І': 'I', 'Ї': 'Yi', 'Ґ': 'G', 'є': 'ye', 'і': 'i',
|
|
||||||
'ї': 'yi', 'ґ': 'g'
|
|
||||||
};
|
|
||||||
var CZECH_MAP = {
|
|
||||||
'č': 'c', 'ď': 'd', 'ě': 'e', 'ň': 'n', 'ř': 'r', 'š': 's', 'ť': 't',
|
|
||||||
'ů': 'u', 'ž': 'z', 'Č': 'C', 'Ď': 'D', 'Ě': 'E', 'Ň': 'N', 'Ř': 'R',
|
|
||||||
'Š': 'S', 'Ť': 'T', 'Ů': 'U', 'Ž': 'Z'
|
|
||||||
};
|
|
||||||
var SLOVAK_MAP = {
|
|
||||||
'á': 'a', 'ä': 'a', 'č': 'c', 'ď': 'd', 'é': 'e', 'í': 'i', 'ľ': 'l',
|
|
||||||
'ĺ': 'l', 'ň': 'n', 'ó': 'o', 'ô': 'o', 'ŕ': 'r', 'š': 's', 'ť': 't',
|
|
||||||
'ú': 'u', 'ý': 'y', 'ž': 'z',
|
|
||||||
'Á': 'a', 'Ä': 'A', 'Č': 'C', 'Ď': 'D', 'É': 'E', 'Í': 'I', 'Ľ': 'L',
|
|
||||||
'Ĺ': 'L', 'Ň': 'N', 'Ó': 'O', 'Ô': 'O', 'Ŕ': 'R', 'Š': 'S', 'Ť': 'T',
|
|
||||||
'Ú': 'U', 'Ý': 'Y', 'Ž': 'Z'
|
|
||||||
};
|
|
||||||
var POLISH_MAP = {
|
|
||||||
'ą': 'a', 'ć': 'c', 'ę': 'e', 'ł': 'l', 'ń': 'n', 'ó': 'o', 'ś': 's',
|
|
||||||
'ź': 'z', 'ż': 'z',
|
|
||||||
'Ą': 'A', 'Ć': 'C', 'Ę': 'E', 'Ł': 'L', 'Ń': 'N', 'Ó': 'O', 'Ś': 'S',
|
|
||||||
'Ź': 'Z', 'Ż': 'Z'
|
|
||||||
};
|
|
||||||
var LATVIAN_MAP = {
|
|
||||||
'ā': 'a', 'č': 'c', 'ē': 'e', 'ģ': 'g', 'ī': 'i', 'ķ': 'k', 'ļ': 'l',
|
|
||||||
'ņ': 'n', 'š': 's', 'ū': 'u', 'ž': 'z',
|
|
||||||
'Ā': 'A', 'Č': 'C', 'Ē': 'E', 'Ģ': 'G', 'Ī': 'I', 'Ķ': 'K', 'Ļ': 'L',
|
|
||||||
'Ņ': 'N', 'Š': 'S', 'Ū': 'U', 'Ž': 'Z'
|
|
||||||
};
|
|
||||||
var ARABIC_MAP = {
|
|
||||||
'أ': 'a', 'ب': 'b', 'ت': 't', 'ث': 'th', 'ج': 'g', 'ح': 'h', 'خ': 'kh', 'د': 'd',
|
|
||||||
'ذ': 'th', 'ر': 'r', 'ز': 'z', 'س': 's', 'ش': 'sh', 'ص': 's', 'ض': 'd', 'ط': 't',
|
|
||||||
'ظ': 'th', 'ع': 'aa', 'غ': 'gh', 'ف': 'f', 'ق': 'k', 'ك': 'k', 'ل': 'l', 'م': 'm',
|
|
||||||
'ن': 'n', 'ه': 'h', 'و': 'o', 'ي': 'y'
|
|
||||||
};
|
|
||||||
var LITHUANIAN_MAP = {
|
|
||||||
'ą': 'a', 'č': 'c', 'ę': 'e', 'ė': 'e', 'į': 'i', 'š': 's', 'ų': 'u',
|
|
||||||
'ū': 'u', 'ž': 'z',
|
|
||||||
'Ą': 'A', 'Č': 'C', 'Ę': 'E', 'Ė': 'E', 'Į': 'I', 'Š': 'S', 'Ų': 'U',
|
|
||||||
'Ū': 'U', 'Ž': 'Z'
|
|
||||||
};
|
|
||||||
var SERBIAN_MAP = {
|
|
||||||
'ђ': 'dj', 'ј': 'j', 'љ': 'lj', 'њ': 'nj', 'ћ': 'c', 'џ': 'dz',
|
|
||||||
'đ': 'dj', 'Ђ': 'Dj', 'Ј': 'j', 'Љ': 'Lj', 'Њ': 'Nj', 'Ћ': 'C',
|
|
||||||
'Џ': 'Dz', 'Đ': 'Dj'
|
|
||||||
};
|
|
||||||
var AZERBAIJANI_MAP = {
|
|
||||||
'ç': 'c', 'ə': 'e', 'ğ': 'g', 'ı': 'i', 'ö': 'o', 'ş': 's', 'ü': 'u',
|
|
||||||
'Ç': 'C', 'Ə': 'E', 'Ğ': 'G', 'İ': 'I', 'Ö': 'O', 'Ş': 'S', 'Ü': 'U'
|
|
||||||
};
|
|
||||||
var GEORGIAN_MAP = {
|
|
||||||
'ა': 'a', 'ბ': 'b', 'გ': 'g', 'დ': 'd', 'ე': 'e', 'ვ': 'v', 'ზ': 'z',
|
|
||||||
'თ': 't', 'ი': 'i', 'კ': 'k', 'ლ': 'l', 'მ': 'm', 'ნ': 'n', 'ო': 'o',
|
|
||||||
'პ': 'p', 'ჟ': 'j', 'რ': 'r', 'ს': 's', 'ტ': 't', 'უ': 'u', 'ფ': 'f',
|
|
||||||
'ქ': 'q', 'ღ': 'g', 'ყ': 'y', 'შ': 'sh', 'ჩ': 'ch', 'ც': 'c', 'ძ': 'dz',
|
|
||||||
'წ': 'w', 'ჭ': 'ch', 'ხ': 'x', 'ჯ': 'j', 'ჰ': 'h'
|
|
||||||
};
|
|
||||||
|
|
||||||
var ALL_DOWNCODE_MAPS = [
|
|
||||||
LATIN_MAP,
|
|
||||||
LATIN_SYMBOLS_MAP,
|
|
||||||
GREEK_MAP,
|
|
||||||
TURKISH_MAP,
|
|
||||||
ROMANIAN_MAP,
|
|
||||||
RUSSIAN_MAP,
|
|
||||||
UKRAINIAN_MAP,
|
|
||||||
CZECH_MAP,
|
|
||||||
SLOVAK_MAP,
|
|
||||||
POLISH_MAP,
|
|
||||||
LATVIAN_MAP,
|
|
||||||
ARABIC_MAP,
|
|
||||||
LITHUANIAN_MAP,
|
|
||||||
SERBIAN_MAP,
|
|
||||||
AZERBAIJANI_MAP,
|
|
||||||
GEORGIAN_MAP
|
|
||||||
];
|
|
||||||
|
|
||||||
var Downcoder = {
|
|
||||||
'Initialize': function() {
|
|
||||||
if (Downcoder.map) { // already made
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Downcoder.map = {};
|
|
||||||
Downcoder.chars = [];
|
|
||||||
for (var i = 0; i < ALL_DOWNCODE_MAPS.length; i++) {
|
|
||||||
var lookup = ALL_DOWNCODE_MAPS[i];
|
|
||||||
for (var c in lookup) {
|
|
||||||
if (lookup.hasOwnProperty(c)) {
|
|
||||||
Downcoder.map[c] = lookup[c];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (var k in Downcoder.map) {
|
|
||||||
if (Downcoder.map.hasOwnProperty(k)) {
|
|
||||||
Downcoder.chars.push(k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Downcoder.regex = new RegExp(Downcoder.chars.join('|'), 'g');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function downcode(slug) {
|
|
||||||
Downcoder.Initialize();
|
|
||||||
return slug.replace(Downcoder.regex, function(m) {
|
|
||||||
return Downcoder.map[m];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function URLify(s, num_chars, allowUnicode) {
|
|
||||||
// changes, e.g., "Petty theft" to "petty-theft"
|
|
||||||
if (!allowUnicode) {
|
|
||||||
s = downcode(s);
|
|
||||||
}
|
|
||||||
s = s.toLowerCase(); // convert to lowercase
|
|
||||||
// if downcode doesn't hit, the char will be stripped here
|
|
||||||
if (allowUnicode) {
|
|
||||||
// Keep Unicode letters including both lowercase and uppercase
|
|
||||||
// characters, whitespace, and dash; remove other characters.
|
|
||||||
s = XRegExp.replace(s, XRegExp('[^-_\\p{L}\\p{N}\\s]', 'g'), '');
|
|
||||||
} else {
|
|
||||||
s = s.replace(/[^-\w\s]/g, ''); // remove unneeded chars
|
|
||||||
}
|
|
||||||
s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces
|
|
||||||
s = s.replace(/[-\s]+/g, '-'); // convert spaces to hyphens
|
|
||||||
s = s.substring(0, num_chars); // trim to first num_chars chars
|
|
||||||
s = s.replace(/-+$/g, ''); // trim any trailing hyphens
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
window.URLify = URLify;
|
|
||||||
})();
|
|
File diff suppressed because one or more lines are too long
|
@ -9,7 +9,5 @@
|
||||||
<script src="{% versioned_static 'wagtailadmin/js/expanding-formset.js' %}"></script>
|
<script src="{% versioned_static 'wagtailadmin/js/expanding-formset.js' %}"></script>
|
||||||
<script src="{% versioned_static 'wagtailadmin/js/preview-panel.js' %}"></script>
|
<script src="{% versioned_static 'wagtailadmin/js/preview-panel.js' %}"></script>
|
||||||
<script src="{% versioned_static 'wagtailadmin/js/privacy-switch.js' %}"></script>
|
<script src="{% versioned_static 'wagtailadmin/js/privacy-switch.js' %}"></script>
|
||||||
<script src="{% versioned_static 'wagtailadmin/js/vendor/xregexp.min.js' %}"></script>
|
|
||||||
<script src="{% versioned_static 'wagtailadmin/js/vendor/urlify.js' %}"></script>
|
|
||||||
<script src="{% versioned_static 'wagtailadmin/js/workflow-action.js' %}"></script>
|
<script src="{% versioned_static 'wagtailadmin/js/workflow-action.js' %}"></script>
|
||||||
{% hook_output 'insert_editor_js' %}
|
{% hook_output 'insert_editor_js' %}
|
||||||
|
|
Ładowanie…
Reference in New Issue