merb-admin 0.8.1 → 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. data/.gitignore +29 -27
  2. data/Gemfile +24 -22
  3. data/Gemfile.lock +86 -0
  4. data/LICENSE +20 -20
  5. data/README.rdoc +54 -58
  6. data/Rakefile +11 -44
  7. data/app/controllers/application.rb +6 -6
  8. data/app/controllers/main.rb +191 -191
  9. data/app/helpers/application_helper.rb +64 -64
  10. data/app/helpers/main_helper.rb +167 -167
  11. data/app/models/.gitkeep +0 -0
  12. data/app/views/layout/_message.html.erb +10 -10
  13. data/app/views/layout/dashboard.html.erb +34 -34
  14. data/app/views/layout/form.html.erb +48 -48
  15. data/app/views/layout/list.html.erb +42 -42
  16. data/app/views/main/_belongs_to.html.erb +29 -29
  17. data/app/views/main/_big_decimal.html.erb +12 -12
  18. data/app/views/main/_boolean.html.erb +7 -7
  19. data/app/views/main/_date.html.erb +12 -12
  20. data/app/views/main/_datetime.html.erb +12 -12
  21. data/app/views/main/_float.html.erb +12 -12
  22. data/app/views/main/_has_many.html.erb +16 -16
  23. data/app/views/main/_has_one.html.erb +30 -30
  24. data/app/views/main/_integer.html.erb +12 -12
  25. data/app/views/main/_properties.html.erb +18 -18
  26. data/app/views/main/_string.html.erb +15 -15
  27. data/app/views/main/_text.html.erb +11 -11
  28. data/app/views/main/_time.html.erb +12 -12
  29. data/app/views/main/_timestamp.html.erb +12 -12
  30. data/app/views/main/delete.html.erb +28 -28
  31. data/app/views/main/edit.html.erb +19 -19
  32. data/app/views/main/index.html.erb +22 -22
  33. data/app/views/main/list.html.erb +93 -93
  34. data/app/views/main/new.html.erb +16 -16
  35. data/config/init.rb +30 -0
  36. data/config/router.rb +4 -0
  37. data/lib/abstract_model.rb +84 -86
  38. data/lib/active_record_support.rb +147 -147
  39. data/lib/datamapper_support.rb +139 -140
  40. data/lib/generic_support.rb +13 -13
  41. data/lib/merb-admin.rb +99 -99
  42. data/lib/merb-admin/merbtasks.rb +103 -103
  43. data/lib/merb-admin/slicetasks.rb +174 -174
  44. data/lib/merb-admin/spectasks.rb +55 -55
  45. data/lib/merb-admin/version.rb +3 -0
  46. data/lib/sequel_support.rb +275 -275
  47. data/merb-admin.gemspec +42 -232
  48. data/public/javascripts/CollapsedFieldsets.js +85 -85
  49. data/public/javascripts/DateTimeShortcuts.js +255 -255
  50. data/public/javascripts/RelatedObjectLookups.js +96 -96
  51. data/public/javascripts/SelectBox.js +111 -111
  52. data/public/javascripts/SelectFilter2.js +113 -113
  53. data/public/javascripts/actions.js +39 -39
  54. data/public/javascripts/calendar.js +143 -143
  55. data/public/javascripts/core.js +176 -176
  56. data/public/javascripts/dateparse.js +233 -233
  57. data/public/javascripts/getElementsBySelector.js +167 -167
  58. data/public/javascripts/i18n.js +33 -33
  59. data/public/javascripts/ordering.js +137 -137
  60. data/public/javascripts/timeparse.js +94 -94
  61. data/public/javascripts/urlify.js +140 -140
  62. data/public/stylesheets/base.css +746 -746
  63. data/public/stylesheets/changelists.css +269 -269
  64. data/public/stylesheets/dashboard.css +24 -24
  65. data/public/stylesheets/forms.css +327 -327
  66. data/public/stylesheets/global.css +142 -142
  67. data/public/stylesheets/ie.css +50 -50
  68. data/public/stylesheets/layout.css +29 -29
  69. data/public/stylesheets/login.css +54 -54
  70. data/public/stylesheets/master.css +1 -1
  71. data/public/stylesheets/patch-iewin.css +7 -7
  72. data/public/stylesheets/rtl.css +206 -206
  73. data/public/stylesheets/widgets.css +506 -506
  74. data/screenshots/create.png +0 -0
  75. data/screenshots/delete.png +0 -0
  76. data/screenshots/edit.png +0 -0
  77. data/screenshots/index.png +0 -0
  78. data/screenshots/list.png +0 -0
  79. data/screenshots/new.png +0 -0
  80. data/spec/controllers/main_spec.rb +25 -25
  81. data/spec/migrations/activerecord/001_create_divisions_migration.rb +13 -13
  82. data/spec/migrations/activerecord/002_create_drafts_migration.rb +19 -19
  83. data/spec/migrations/activerecord/003_create_leagues_migration.rb +12 -12
  84. data/spec/migrations/activerecord/004_create_players_migration.rb +19 -20
  85. data/spec/migrations/activerecord/005_create_teams_migration.rb +22 -22
  86. data/spec/migrations/sequel/001_create_divisions_migration.rb +15 -15
  87. data/spec/migrations/sequel/002_create_drafts_migration.rb +21 -21
  88. data/spec/migrations/sequel/003_create_leagues_migration.rb +14 -14
  89. data/spec/migrations/sequel/004_create_players_migration.rb +21 -22
  90. data/spec/migrations/sequel/005_create_teams_migration.rb +24 -24
  91. data/spec/models/activerecord/division.rb +7 -7
  92. data/spec/models/activerecord/draft.rb +11 -11
  93. data/spec/models/activerecord/league.rb +6 -6
  94. data/spec/models/activerecord/player.rb +8 -8
  95. data/spec/models/activerecord/team.rb +13 -13
  96. data/spec/models/datamapper/division.rb +12 -12
  97. data/spec/models/datamapper/draft.rb +18 -18
  98. data/spec/models/datamapper/league.rb +11 -11
  99. data/spec/models/datamapper/player.rb +20 -21
  100. data/spec/models/datamapper/team.rb +22 -22
  101. data/spec/models/sequel/division.rb +15 -15
  102. data/spec/models/sequel/draft.rb +19 -19
  103. data/spec/models/sequel/league.rb +14 -14
  104. data/spec/models/sequel/player.rb +18 -18
  105. data/spec/models/sequel/team.rb +21 -21
  106. data/spec/requests/main_spec.rb +763 -763
  107. data/spec/spec_helper.rb +113 -112
  108. metadata +247 -41
  109. data/VERSION +0 -1
@@ -1,94 +1,94 @@
1
- var timeParsePatterns = [
2
- // 9
3
- { re: /^\d{1,2}$/i,
4
- handler: function(bits) {
5
- if (bits[0].length == 1) {
6
- return '0' + bits[0] + ':00';
7
- } else {
8
- return bits[0] + ':00';
9
- }
10
- }
11
- },
12
- // 13:00
13
- { re: /^\d{2}[:.]\d{2}$/i,
14
- handler: function(bits) {
15
- return bits[0].replace('.', ':');
16
- }
17
- },
18
- // 9:00
19
- { re: /^\d[:.]\d{2}$/i,
20
- handler: function(bits) {
21
- return '0' + bits[0].replace('.', ':');
22
- }
23
- },
24
- // 3 am / 3 a.m. / 3am
25
- { re: /^(\d+)\s*([ap])(?:.?m.?)?$/i,
26
- handler: function(bits) {
27
- var hour = parseInt(bits[1]);
28
- if (hour == 12) {
29
- hour = 0;
30
- }
31
- if (bits[2].toLowerCase() == 'p') {
32
- if (hour == 12) {
33
- hour = 0;
34
- }
35
- return (hour + 12) + ':00';
36
- } else {
37
- if (hour < 10) {
38
- return '0' + hour + ':00';
39
- } else {
40
- return hour + ':00';
41
- }
42
- }
43
- }
44
- },
45
- // 3.30 am / 3:15 a.m. / 3.00am
46
- { re: /^(\d+)[.:](\d{2})\s*([ap]).?m.?$/i,
47
- handler: function(bits) {
48
- var hour = parseInt(bits[1]);
49
- var mins = parseInt(bits[2]);
50
- if (mins < 10) {
51
- mins = '0' + mins;
52
- }
53
- if (hour == 12) {
54
- hour = 0;
55
- }
56
- if (bits[3].toLowerCase() == 'p') {
57
- if (hour == 12) {
58
- hour = 0;
59
- }
60
- return (hour + 12) + ':' + mins;
61
- } else {
62
- if (hour < 10) {
63
- return '0' + hour + ':' + mins;
64
- } else {
65
- return hour + ':' + mins;
66
- }
67
- }
68
- }
69
- },
70
- // noon
71
- { re: /^no/i,
72
- handler: function(bits) {
73
- return '12:00';
74
- }
75
- },
76
- // midnight
77
- { re: /^mid/i,
78
- handler: function(bits) {
79
- return '00:00';
80
- }
81
- }
82
- ];
83
-
84
- function parseTimeString(s) {
85
- for (var i = 0; i < timeParsePatterns.length; i++) {
86
- var re = timeParsePatterns[i].re;
87
- var handler = timeParsePatterns[i].handler;
88
- var bits = re.exec(s);
89
- if (bits) {
90
- return handler(bits);
91
- }
92
- }
93
- return s;
94
- }
1
+ var timeParsePatterns = [
2
+ // 9
3
+ { re: /^\d{1,2}$/i,
4
+ handler: function(bits) {
5
+ if (bits[0].length == 1) {
6
+ return '0' + bits[0] + ':00';
7
+ } else {
8
+ return bits[0] + ':00';
9
+ }
10
+ }
11
+ },
12
+ // 13:00
13
+ { re: /^\d{2}[:.]\d{2}$/i,
14
+ handler: function(bits) {
15
+ return bits[0].replace('.', ':');
16
+ }
17
+ },
18
+ // 9:00
19
+ { re: /^\d[:.]\d{2}$/i,
20
+ handler: function(bits) {
21
+ return '0' + bits[0].replace('.', ':');
22
+ }
23
+ },
24
+ // 3 am / 3 a.m. / 3am
25
+ { re: /^(\d+)\s*([ap])(?:.?m.?)?$/i,
26
+ handler: function(bits) {
27
+ var hour = parseInt(bits[1]);
28
+ if (hour == 12) {
29
+ hour = 0;
30
+ }
31
+ if (bits[2].toLowerCase() == 'p') {
32
+ if (hour == 12) {
33
+ hour = 0;
34
+ }
35
+ return (hour + 12) + ':00';
36
+ } else {
37
+ if (hour < 10) {
38
+ return '0' + hour + ':00';
39
+ } else {
40
+ return hour + ':00';
41
+ }
42
+ }
43
+ }
44
+ },
45
+ // 3.30 am / 3:15 a.m. / 3.00am
46
+ { re: /^(\d+)[.:](\d{2})\s*([ap]).?m.?$/i,
47
+ handler: function(bits) {
48
+ var hour = parseInt(bits[1]);
49
+ var mins = parseInt(bits[2]);
50
+ if (mins < 10) {
51
+ mins = '0' + mins;
52
+ }
53
+ if (hour == 12) {
54
+ hour = 0;
55
+ }
56
+ if (bits[3].toLowerCase() == 'p') {
57
+ if (hour == 12) {
58
+ hour = 0;
59
+ }
60
+ return (hour + 12) + ':' + mins;
61
+ } else {
62
+ if (hour < 10) {
63
+ return '0' + hour + ':' + mins;
64
+ } else {
65
+ return hour + ':' + mins;
66
+ }
67
+ }
68
+ }
69
+ },
70
+ // noon
71
+ { re: /^no/i,
72
+ handler: function(bits) {
73
+ return '12:00';
74
+ }
75
+ },
76
+ // midnight
77
+ { re: /^mid/i,
78
+ handler: function(bits) {
79
+ return '00:00';
80
+ }
81
+ }
82
+ ];
83
+
84
+ function parseTimeString(s) {
85
+ for (var i = 0; i < timeParsePatterns.length; i++) {
86
+ var re = timeParsePatterns[i].re;
87
+ var handler = timeParsePatterns[i].handler;
88
+ var bits = re.exec(s);
89
+ if (bits) {
90
+ return handler(bits);
91
+ }
92
+ }
93
+ return s;
94
+ }
@@ -1,140 +1,140 @@
1
- var LATIN_MAP = {
2
- 'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', 'Ç':
3
- 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', 'Î': 'I',
4
- 'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', 'Õ': 'O', 'Ö':
5
- 'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', 'Ü': 'U', 'Ű': 'U',
6
- 'Ý': 'Y', 'Þ': 'TH', 'ß': 'ss', 'à':'a', 'á':'a', 'â': 'a', 'ã': 'a', 'ä':
7
- 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', 'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e',
8
- 'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò': 'o', 'ó':
9
- 'o', 'ô': 'o', 'õ': 'o', 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 'ú': 'u',
10
- 'û': 'u', 'ü': 'u', 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y'
11
- }
12
- var LATIN_SYMBOLS_MAP = {
13
- '©':'(c)'
14
- }
15
- var GREEK_MAP = {
16
- 'α':'a', 'β':'b', 'γ':'g', 'δ':'d', 'ε':'e', 'ζ':'z', 'η':'h', 'θ':'8',
17
- 'ι':'i', 'κ':'k', 'λ':'l', 'μ':'m', 'ν':'n', 'ξ':'3', 'ο':'o', 'π':'p',
18
- 'ρ':'r', 'σ':'s', 'τ':'t', 'υ':'y', 'φ':'f', 'χ':'x', 'ψ':'ps', 'ω':'w',
19
- 'ά':'a', 'έ':'e', 'ί':'i', 'ό':'o', 'ύ':'y', 'ή':'h', 'ώ':'w', 'ς':'s',
20
- 'ϊ':'i', 'ΰ':'y', 'ϋ':'y', 'ΐ':'i',
21
- 'Α':'A', 'Β':'B', 'Γ':'G', 'Δ':'D', 'Ε':'E', 'Ζ':'Z', 'Η':'H', 'Θ':'8',
22
- 'Ι':'I', 'Κ':'K', 'Λ':'L', 'Μ':'M', 'Ν':'N', 'Ξ':'3', 'Ο':'O', 'Π':'P',
23
- 'Ρ':'R', 'Σ':'S', 'Τ':'T', 'Υ':'Y', 'Φ':'F', 'Χ':'X', 'Ψ':'PS', 'Ω':'W',
24
- 'Ά':'A', 'Έ':'E', 'Ί':'I', 'Ό':'O', 'Ύ':'Y', 'Ή':'H', 'Ώ':'W', 'Ϊ':'I',
25
- 'Ϋ':'Y'
26
- }
27
- var TURKISH_MAP = {
28
- 'ş':'s', 'Ş':'S', 'ı':'i', 'İ':'I', 'ç':'c', 'Ç':'C', 'ü':'u', 'Ü':'U',
29
- 'ö':'o', 'Ö':'O', 'ğ':'g', 'Ğ':'G'
30
- }
31
- var RUSSIAN_MAP = {
32
- 'а':'a', 'б':'b', 'в':'v', 'г':'g', 'д':'d', 'е':'e', 'ё':'yo', 'ж':'zh',
33
- 'з':'z', 'и':'i', 'й':'j', 'к':'k', 'л':'l', 'м':'m', 'н':'n', 'о':'o',
34
- 'п':'p', 'р':'r', 'с':'s', 'т':'t', 'у':'u', 'ф':'f', 'х':'h', 'ц':'c',
35
- 'ч':'ch', 'ш':'sh', 'щ':'sh', 'ъ':'', 'ы':'y', 'ь':'', 'э':'e', 'ю':'yu',
36
- 'я':'ya',
37
- 'А':'A', 'Б':'B', 'В':'V', 'Г':'G', 'Д':'D', 'Е':'E', 'Ё':'Yo', 'Ж':'Zh',
38
- 'З':'Z', 'И':'I', 'Й':'J', 'К':'K', 'Л':'L', 'М':'M', 'Н':'N', 'О':'O',
39
- 'П':'P', 'Р':'R', 'С':'S', 'Т':'T', 'У':'U', 'Ф':'F', 'Х':'H', 'Ц':'C',
40
- 'Ч':'Ch', 'Ш':'Sh', 'Щ':'Sh', 'Ъ':'', 'Ы':'Y', 'Ь':'', 'Э':'E', 'Ю':'Yu',
41
- 'Я':'Ya'
42
- }
43
- var UKRAINIAN_MAP = {
44
- 'Є':'Ye', 'І':'I', 'Ї':'Yi', 'Ґ':'G', 'є':'ye', 'і':'i', 'ї':'yi', 'ґ':'g'
45
- }
46
- var CZECH_MAP = {
47
- 'č':'c', 'ď':'d', 'ě':'e', 'ň': 'n', 'ř':'r', 'š':'s', 'ť':'t', 'ů':'u',
48
- 'ž':'z', 'Č':'C', 'Ď':'D', 'Ě':'E', 'Ň': 'N', 'Ř':'R', 'Š':'S', 'Ť':'T',
49
- 'Ů':'U', 'Ž':'Z'
50
- }
51
-
52
- var POLISH_MAP = {
53
- 'ą':'a', 'ć':'c', 'ę':'e', 'ł':'l', 'ń':'n', 'ó':'o', 'ś':'s', 'ź':'z',
54
- 'ż':'z', 'Ą':'A', 'Ć':'C', 'Ę':'e', 'Ł':'L', 'Ń':'N', 'Ó':'o', 'Ś':'S',
55
- 'Ź':'Z', 'Ż':'Z'
56
- }
57
-
58
- var LATVIAN_MAP = {
59
- 'ā':'a', 'č':'c', 'ē':'e', 'ģ':'g', 'ī':'i', 'ķ':'k', 'ļ':'l', 'ņ':'n',
60
- 'š':'s', 'ū':'u', 'ž':'z', 'Ā':'A', 'Č':'C', 'Ē':'E', 'Ģ':'G', 'Ī':'i',
61
- 'Ķ':'k', 'Ļ':'L', 'Ņ':'N', 'Š':'S', 'Ū':'u', 'Ž':'Z'
62
- }
63
-
64
- var ALL_DOWNCODE_MAPS=new Array()
65
- ALL_DOWNCODE_MAPS[0]=LATIN_MAP
66
- ALL_DOWNCODE_MAPS[1]=LATIN_SYMBOLS_MAP
67
- ALL_DOWNCODE_MAPS[2]=GREEK_MAP
68
- ALL_DOWNCODE_MAPS[3]=TURKISH_MAP
69
- ALL_DOWNCODE_MAPS[4]=RUSSIAN_MAP
70
- ALL_DOWNCODE_MAPS[5]=UKRAINIAN_MAP
71
- ALL_DOWNCODE_MAPS[6]=CZECH_MAP
72
- ALL_DOWNCODE_MAPS[7]=POLISH_MAP
73
- ALL_DOWNCODE_MAPS[8]=LATVIAN_MAP
74
-
75
- var Downcoder = new Object();
76
- Downcoder.Initialize = function()
77
- {
78
- if (Downcoder.map) // already made
79
- return ;
80
- Downcoder.map ={}
81
- Downcoder.chars = '' ;
82
- for(var i in ALL_DOWNCODE_MAPS)
83
- {
84
- var lookup = ALL_DOWNCODE_MAPS[i]
85
- for (var c in lookup)
86
- {
87
- Downcoder.map[c] = lookup[c] ;
88
- Downcoder.chars += c ;
89
- }
90
- }
91
- Downcoder.regex = new RegExp('[' + Downcoder.chars + ']|[^' + Downcoder.chars + ']+','g') ;
92
- }
93
-
94
- downcode= function( slug )
95
- {
96
- Downcoder.Initialize() ;
97
- var downcoded =""
98
- var pieces = slug.match(Downcoder.regex);
99
- if(pieces)
100
- {
101
- for (var i = 0 ; i < pieces.length ; i++)
102
- {
103
- if (pieces[i].length == 1)
104
- {
105
- var mapped = Downcoder.map[pieces[i]] ;
106
- if (mapped != null)
107
- {
108
- downcoded+=mapped;
109
- continue ;
110
- }
111
- }
112
- downcoded+=pieces[i];
113
- }
114
- }
115
- else
116
- {
117
- downcoded = slug;
118
- }
119
- return downcoded;
120
- }
121
-
122
-
123
- function URLify(s, num_chars) {
124
- // changes, e.g., "Petty theft" to "petty_theft"
125
- // remove all these words from the string before urlifying
126
- s = downcode(s);
127
- removelist = ["a", "an", "as", "at", "before", "but", "by", "for", "from",
128
- "is", "in", "into", "like", "of", "off", "on", "onto", "per",
129
- "since", "than", "the", "this", "that", "to", "up", "via",
130
- "with"];
131
- r = new RegExp('\\b(' + removelist.join('|') + ')\\b', 'gi');
132
- s = s.replace(r, '');
133
- // if downcode doesn't hit, the char will be stripped here
134
- s = s.replace(/[^-\w\s]/g, ''); // remove unneeded chars
135
- s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces
136
- s = s.replace(/[-\s]+/g, '-'); // convert spaces to hyphens
137
- s = s.toLowerCase(); // convert to lowercase
138
- return s.substring(0, num_chars);// trim to first num_chars chars
139
- }
140
-
1
+ var LATIN_MAP = {
2
+ 'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', 'Ç':
3
+ 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', 'Î': 'I',
4
+ 'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', 'Õ': 'O', 'Ö':
5
+ 'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', 'Ü': 'U', 'Ű': 'U',
6
+ 'Ý': 'Y', 'Þ': 'TH', 'ß': 'ss', 'à':'a', 'á':'a', 'â': 'a', 'ã': 'a', 'ä':
7
+ 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', 'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e',
8
+ 'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò': 'o', 'ó':
9
+ 'o', 'ô': 'o', 'õ': 'o', 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 'ú': 'u',
10
+ 'û': 'u', 'ü': 'u', 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y'
11
+ }
12
+ var LATIN_SYMBOLS_MAP = {
13
+ '©':'(c)'
14
+ }
15
+ var GREEK_MAP = {
16
+ 'α':'a', 'β':'b', 'γ':'g', 'δ':'d', 'ε':'e', 'ζ':'z', 'η':'h', 'θ':'8',
17
+ 'ι':'i', 'κ':'k', 'λ':'l', 'μ':'m', 'ν':'n', 'ξ':'3', 'ο':'o', 'π':'p',
18
+ 'ρ':'r', 'σ':'s', 'τ':'t', 'υ':'y', 'φ':'f', 'χ':'x', 'ψ':'ps', 'ω':'w',
19
+ 'ά':'a', 'έ':'e', 'ί':'i', 'ό':'o', 'ύ':'y', 'ή':'h', 'ώ':'w', 'ς':'s',
20
+ 'ϊ':'i', 'ΰ':'y', 'ϋ':'y', 'ΐ':'i',
21
+ 'Α':'A', 'Β':'B', 'Γ':'G', 'Δ':'D', 'Ε':'E', 'Ζ':'Z', 'Η':'H', 'Θ':'8',
22
+ 'Ι':'I', 'Κ':'K', 'Λ':'L', 'Μ':'M', 'Ν':'N', 'Ξ':'3', 'Ο':'O', 'Π':'P',
23
+ 'Ρ':'R', 'Σ':'S', 'Τ':'T', 'Υ':'Y', 'Φ':'F', 'Χ':'X', 'Ψ':'PS', 'Ω':'W',
24
+ 'Ά':'A', 'Έ':'E', 'Ί':'I', 'Ό':'O', 'Ύ':'Y', 'Ή':'H', 'Ώ':'W', 'Ϊ':'I',
25
+ 'Ϋ':'Y'
26
+ }
27
+ var TURKISH_MAP = {
28
+ 'ş':'s', 'Ş':'S', 'ı':'i', 'İ':'I', 'ç':'c', 'Ç':'C', 'ü':'u', 'Ü':'U',
29
+ 'ö':'o', 'Ö':'O', 'ğ':'g', 'Ğ':'G'
30
+ }
31
+ var RUSSIAN_MAP = {
32
+ 'а':'a', 'б':'b', 'в':'v', 'г':'g', 'д':'d', 'е':'e', 'ё':'yo', 'ж':'zh',
33
+ 'з':'z', 'и':'i', 'й':'j', 'к':'k', 'л':'l', 'м':'m', 'н':'n', 'о':'o',
34
+ 'п':'p', 'р':'r', 'с':'s', 'т':'t', 'у':'u', 'ф':'f', 'х':'h', 'ц':'c',
35
+ 'ч':'ch', 'ш':'sh', 'щ':'sh', 'ъ':'', 'ы':'y', 'ь':'', 'э':'e', 'ю':'yu',
36
+ 'я':'ya',
37
+ 'А':'A', 'Б':'B', 'В':'V', 'Г':'G', 'Д':'D', 'Е':'E', 'Ё':'Yo', 'Ж':'Zh',
38
+ 'З':'Z', 'И':'I', 'Й':'J', 'К':'K', 'Л':'L', 'М':'M', 'Н':'N', 'О':'O',
39
+ 'П':'P', 'Р':'R', 'С':'S', 'Т':'T', 'У':'U', 'Ф':'F', 'Х':'H', 'Ц':'C',
40
+ 'Ч':'Ch', 'Ш':'Sh', 'Щ':'Sh', 'Ъ':'', 'Ы':'Y', 'Ь':'', 'Э':'E', 'Ю':'Yu',
41
+ 'Я':'Ya'
42
+ }
43
+ var UKRAINIAN_MAP = {
44
+ 'Є':'Ye', 'І':'I', 'Ї':'Yi', 'Ґ':'G', 'є':'ye', 'і':'i', 'ї':'yi', 'ґ':'g'
45
+ }
46
+ var CZECH_MAP = {
47
+ 'č':'c', 'ď':'d', 'ě':'e', 'ň': 'n', 'ř':'r', 'š':'s', 'ť':'t', 'ů':'u',
48
+ 'ž':'z', 'Č':'C', 'Ď':'D', 'Ě':'E', 'Ň': 'N', 'Ř':'R', 'Š':'S', 'Ť':'T',
49
+ 'Ů':'U', 'Ž':'Z'
50
+ }
51
+
52
+ var POLISH_MAP = {
53
+ 'ą':'a', 'ć':'c', 'ę':'e', 'ł':'l', 'ń':'n', 'ó':'o', 'ś':'s', 'ź':'z',
54
+ 'ż':'z', 'Ą':'A', 'Ć':'C', 'Ę':'e', 'Ł':'L', 'Ń':'N', 'Ó':'o', 'Ś':'S',
55
+ 'Ź':'Z', 'Ż':'Z'
56
+ }
57
+
58
+ var LATVIAN_MAP = {
59
+ 'ā':'a', 'č':'c', 'ē':'e', 'ģ':'g', 'ī':'i', 'ķ':'k', 'ļ':'l', 'ņ':'n',
60
+ 'š':'s', 'ū':'u', 'ž':'z', 'Ā':'A', 'Č':'C', 'Ē':'E', 'Ģ':'G', 'Ī':'i',
61
+ 'Ķ':'k', 'Ļ':'L', 'Ņ':'N', 'Š':'S', 'Ū':'u', 'Ž':'Z'
62
+ }
63
+
64
+ var ALL_DOWNCODE_MAPS=new Array()
65
+ ALL_DOWNCODE_MAPS[0]=LATIN_MAP
66
+ ALL_DOWNCODE_MAPS[1]=LATIN_SYMBOLS_MAP
67
+ ALL_DOWNCODE_MAPS[2]=GREEK_MAP
68
+ ALL_DOWNCODE_MAPS[3]=TURKISH_MAP
69
+ ALL_DOWNCODE_MAPS[4]=RUSSIAN_MAP
70
+ ALL_DOWNCODE_MAPS[5]=UKRAINIAN_MAP
71
+ ALL_DOWNCODE_MAPS[6]=CZECH_MAP
72
+ ALL_DOWNCODE_MAPS[7]=POLISH_MAP
73
+ ALL_DOWNCODE_MAPS[8]=LATVIAN_MAP
74
+
75
+ var Downcoder = new Object();
76
+ Downcoder.Initialize = function()
77
+ {
78
+ if (Downcoder.map) // already made
79
+ return ;
80
+ Downcoder.map ={}
81
+ Downcoder.chars = '' ;
82
+ for(var i in ALL_DOWNCODE_MAPS)
83
+ {
84
+ var lookup = ALL_DOWNCODE_MAPS[i]
85
+ for (var c in lookup)
86
+ {
87
+ Downcoder.map[c] = lookup[c] ;
88
+ Downcoder.chars += c ;
89
+ }
90
+ }
91
+ Downcoder.regex = new RegExp('[' + Downcoder.chars + ']|[^' + Downcoder.chars + ']+','g') ;
92
+ }
93
+
94
+ downcode= function( slug )
95
+ {
96
+ Downcoder.Initialize() ;
97
+ var downcoded =""
98
+ var pieces = slug.match(Downcoder.regex);
99
+ if(pieces)
100
+ {
101
+ for (var i = 0 ; i < pieces.length ; i++)
102
+ {
103
+ if (pieces[i].length == 1)
104
+ {
105
+ var mapped = Downcoder.map[pieces[i]] ;
106
+ if (mapped != null)
107
+ {
108
+ downcoded+=mapped;
109
+ continue ;
110
+ }
111
+ }
112
+ downcoded+=pieces[i];
113
+ }
114
+ }
115
+ else
116
+ {
117
+ downcoded = slug;
118
+ }
119
+ return downcoded;
120
+ }
121
+
122
+
123
+ function URLify(s, num_chars) {
124
+ // changes, e.g., "Petty theft" to "petty_theft"
125
+ // remove all these words from the string before urlifying
126
+ s = downcode(s);
127
+ removelist = ["a", "an", "as", "at", "before", "but", "by", "for", "from",
128
+ "is", "in", "into", "like", "of", "off", "on", "onto", "per",
129
+ "since", "than", "the", "this", "that", "to", "up", "via",
130
+ "with"];
131
+ r = new RegExp('\\b(' + removelist.join('|') + ')\\b', 'gi');
132
+ s = s.replace(r, '');
133
+ // if downcode doesn't hit, the char will be stripped here
134
+ s = s.replace(/[^-\w\s]/g, ''); // remove unneeded chars
135
+ s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces
136
+ s = s.replace(/[-\s]+/g, '-'); // convert spaces to hyphens
137
+ s = s.toLowerCase(); // convert to lowercase
138
+ return s.substring(0, num_chars);// trim to first num_chars chars
139
+ }
140
+