1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
/* Copyright 2011 Canonical Ltd. This software is licensed under the
* GNU Affero General Public License version 3 (see the file LICENSE).
*
* Utility functions for converting valid Launchpad names for use in
* CSS classes and back.
*
* Launchpad account names match the pattern [a-z0-9][a-z0-9+.-]*.
* CSS class names roughly match the pattern -?[_a-z][_a-z0-9-]*.
*
* These method uses the fact that CSS allows '_' anywhere whereas LP
* does not use it to escape starting digits and '+' or '.'.
*
* When no exceptions are thrown,
* css_to_launchpad(launchpad_to_css(string))
* is idempotent.
*
* See `lp.app.validators.name.valid_name_pattern` and
* http://www.w3.org/TR/CSS21/grammar.html#scanner
*
* @module lp
* @submodule names
*/
YUI.add('lp.names', function(Y) {
var namespace = Y.namespace('lp.names');
/**
* Gets a name suitable to be used as a CSS class for the "valid"
* Launchpad name.
*
* Throws an exception if the `name` is not a valid Launchpad name.
*
* This is a bijective function with the inverse provided by
* css_to_launchpad().
*
* @method launchpad_to_css
* @param name {String} A valid Launchpad name (eg. a person or project name).
* @return {String} A converted `name` usable in a CSS class directly.
*/
function launchpad_to_css(name) {
// Ensure we're being asked to convert the valid LP name.
if (!name.match(/^[a-z0-9][a-z0-9\+\.\-]*$/)) {
Y.error(
'Passed value "' + name + '" is not a valid Launchpad name.');
return;
}
if (name.match(/^[a-z][a-z0-9\-]*$/)) {
// This is an intersection between valid LP and CSS names.
return name;
} else {
// Do the conversion.
var first_char = name.charAt(0);
if (first_char >= '0' && first_char <= '9') {
name = '_' + name;
}
// In the rest of the string, we convert all "+"s with "_y" and all
// "."s with "_z".
name = name.replace(/\+/g, '_y');
name = name.replace(/\./g, '_z');
}
return name;
}
namespace.launchpad_to_css = launchpad_to_css;
/**
* Convert the CSS name as gotten by launchpad_to_css to
* it's originating Launchpad name.
*
* Throws an exception if the `name` is not a valid CSS class name
* and in the format as produced by launchpad_to_css.
* WARNING: this won't produce a valid Launchpad name for arbitrary
* CSS class names.
*
* This is an inverse function of the function
* launchpad_to_css().
*
* @method css_to_launchpad
* @param name {String} A valid CSS class name, but usually the result of
* launchpad_to_css() call.
* @return {String} A converted `name` that is identical to the originating
* Launchpad name passed into launchpad_to_css().
* In practice, starting '_a', '_b', ..., '_j' are replaced with
* '0', '1', ..., '9' and '_y' and '_z' are replaced with '+' and '.'
* throughout the string.
*/
function css_to_launchpad(name) {
if (!name.match(/^-?[_a-z][_a-z0-9\-]*$/)) {
Y.error(
'Passed value "' + name + '" is not a valid CSS class name.');
}
if (!name.match(/^((_[0-9yz])|[a-z])([a-z0-9\-]|(_[yz]))*$/)) {
Y.error(
'Passed value "' + name +
'" is not produced by launchpad_to_css.');
}
if (name.match(/^[a-z][a-z0-9\-]*$/)) {
// This is an intersection between valid LP and CSS names.
return name;
}
if (name.charAt(0) === '_') {
// It may start with a digit (iow, '_0' to '_9' for digits,
// or '_y', '_z' for '+', '.' but we don't care about these [yet]).
var second_char = name.charAt(1);
if (second_char >= '0' && second_char <= '9') {
name = name.substr(1);
}
}
// Replace escaped variants of '+' and '.' back.
name = name.replace(/_y/g, '+');
name = name.replace(/_z/g, '.');
return name;
}
namespace.css_to_launchpad = css_to_launchpad;
}, "0.1", {});
|