mediaelement_rails 0.4.0 → 0.5.0

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.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # MediaelementRails #
2
2
 
3
- This neat project brings the cool [MediaElement.js](http://mediaelementjs.com/) (HTML5/Flash/Silverlight video player) to the Rails asset pipeline.
3
+ This neat project brings the cool [MediaElement.js](http://mediaelementjs.com/) (HTML5/Flash/Silverlight video player) to the Rails asset pipeline. __*NOTE:*__ This gem requires jquery, which shouldn't be an issue.
4
4
 
5
5
  ## All you have to do is: ##
6
6
 
@@ -0,0 +1 @@
1
+ <?xml version="1.0" standalone="no"?>
@@ -0,0 +1 @@
1
+ <?xml version="1.0" standalone="no"?>
@@ -1,3 +1,2 @@
1
- //= require jquery
2
1
  //= require ./rails
3
2
  //= require ./mediaelementplayer
@@ -8,150 +8,173 @@
8
8
  * Can play MP4 (H.264), Ogg, WebM, FLV, WMV, WMA, ACC, and MP3
9
9
  *
10
10
  * Copyright 2010-2012, John Dyer (http://j.hn)
11
- * Dual licensed under the MIT or GPL Version 2 licenses.
11
+ * License: MIT
12
12
  *
13
13
  */
14
- // Namespace
15
- var mejs = mejs || {};
16
-
17
- // version number
18
- mejs.version = '2.9.1';
19
-
20
- // player number (for missing, same id attr)
21
- mejs.meIndex = 0;
22
-
23
- // media types accepted by plugins
24
- mejs.plugins = {
25
- silverlight: [
26
- {version: [3,0], types: ['video/mp4','video/m4v','video/mov','video/wmv','audio/wma','audio/m4a','audio/mp3','audio/wav','audio/mpeg']}
27
- ],
28
- flash: [
29
- {version: [9,0,124], types: ['video/mp4','video/m4v','video/mov','video/flv','video/x-flv','audio/flv','audio/x-flv','audio/mp3','audio/m4a','audio/mpeg', 'video/youtube', 'video/x-youtube']}
30
- //,{version: [12,0], types: ['video/webm']} // for future reference (hopefully!)
31
- ],
32
- youtube: [
33
- {version: null, types: ['video/youtube', 'video/x-youtube']}
34
- ],
35
- vimeo: [
36
- {version: null, types: ['video/vimeo']}
37
- ]
14
+ // Namespace
15
+ var mejs = mejs || {};
16
+
17
+ // version number
18
+ mejs.version = '2.10.3';
19
+
20
+ // player number (for missing, same id attr)
21
+ mejs.meIndex = 0;
22
+
23
+ // media types accepted by plugins
24
+ mejs.plugins = {
25
+ silverlight: [
26
+ {version: [3,0], types: ['video/mp4','video/m4v','video/mov','video/wmv','audio/wma','audio/m4a','audio/mp3','audio/wav','audio/mpeg']}
27
+ ],
28
+ flash: [
29
+ {version: [9,0,124], types: ['video/mp4','video/m4v','video/mov','video/flv','video/rtmp','video/x-flv','audio/flv','audio/x-flv','audio/mp3','audio/m4a','audio/mpeg', 'video/youtube', 'video/x-youtube']}
30
+ //,{version: [12,0], types: ['video/webm']} // for future reference (hopefully!)
31
+ ],
32
+ youtube: [
33
+ {version: null, types: ['video/youtube', 'video/x-youtube']}
34
+ ],
35
+ vimeo: [
36
+ {version: null, types: ['video/vimeo', 'video/x-vimeo']}
37
+ ]
38
+ };
39
+
40
+ /*
41
+ Utility methods
42
+ */
43
+ mejs.Utility = {
44
+ encodeUrl: function(url) {
45
+ return encodeURIComponent(url); //.replace(/\?/gi,'%3F').replace(/=/gi,'%3D').replace(/&/gi,'%26');
46
+ },
47
+ escapeHTML: function(s) {
48
+ return s.toString().split('&').join('&amp;').split('<').join('&lt;').split('"').join('&quot;');
49
+ },
50
+ absolutizeUrl: function(url) {
51
+ var el = document.createElement('div');
52
+ el.innerHTML = '<a href="' + this.escapeHTML(url) + '">x</a>';
53
+ return el.firstChild.href;
54
+ },
55
+ getScriptPath: function(scriptNames) {
56
+ var
57
+ i = 0,
58
+ j,
59
+ path = '',
60
+ name = '',
61
+ script,
62
+ scripts = document.getElementsByTagName('script'),
63
+ il = scripts.length,
64
+ jl = scriptNames.length;
65
+
66
+ for (; i < il; i++) {
67
+ script = scripts[i].src;
68
+ for (j = 0; j < jl; j++) {
69
+ name = scriptNames[j];
70
+ if (script.indexOf(name) > -1) {
71
+ path = script.substring(0, script.indexOf(name));
72
+ break;
73
+ }
74
+ }
75
+ if (path !== '') {
76
+ break;
77
+ }
78
+ }
79
+ return path;
80
+ },
81
+ secondsToTimeCode: function(time, forceHours, showFrameCount, fps) {
82
+ //add framecount
83
+ if (typeof showFrameCount == 'undefined') {
84
+ showFrameCount=false;
85
+ } else if(typeof fps == 'undefined') {
86
+ fps = 25;
87
+ }
88
+
89
+ var hours = Math.floor(time / 3600) % 24,
90
+ minutes = Math.floor(time / 60) % 60,
91
+ seconds = Math.floor(time % 60),
92
+ frames = Math.floor(((time % 1)*fps).toFixed(3)),
93
+ result =
94
+ ( (forceHours || hours > 0) ? (hours < 10 ? '0' + hours : hours) + ':' : '')
95
+ + (minutes < 10 ? '0' + minutes : minutes) + ':'
96
+ + (seconds < 10 ? '0' + seconds : seconds)
97
+ + ((showFrameCount) ? ':' + (frames < 10 ? '0' + frames : frames) : '');
98
+
99
+ return result;
100
+ },
101
+
102
+ timeCodeToSeconds: function(hh_mm_ss_ff, forceHours, showFrameCount, fps){
103
+ if (typeof showFrameCount == 'undefined') {
104
+ showFrameCount=false;
105
+ } else if(typeof fps == 'undefined') {
106
+ fps = 25;
107
+ }
108
+
109
+ var tc_array = hh_mm_ss_ff.split(":"),
110
+ tc_hh = parseInt(tc_array[0], 10),
111
+ tc_mm = parseInt(tc_array[1], 10),
112
+ tc_ss = parseInt(tc_array[2], 10),
113
+ tc_ff = 0,
114
+ tc_in_seconds = 0;
115
+
116
+ if (showFrameCount) {
117
+ tc_ff = parseInt(tc_array[3])/fps;
118
+ }
119
+
120
+ tc_in_seconds = ( tc_hh * 3600 ) + ( tc_mm * 60 ) + tc_ss + tc_ff;
121
+
122
+ return tc_in_seconds;
123
+ },
124
+
125
+
126
+ convertSMPTEtoSeconds: function (SMPTE) {
127
+ if (typeof SMPTE != 'string')
128
+ return false;
129
+
130
+ SMPTE = SMPTE.replace(',', '.');
131
+
132
+ var secs = 0,
133
+ decimalLen = (SMPTE.indexOf('.') != -1) ? SMPTE.split('.')[1].length : 0,
134
+ multiplier = 1;
135
+
136
+ SMPTE = SMPTE.split(':').reverse();
137
+
138
+ for (var i = 0; i < SMPTE.length; i++) {
139
+ multiplier = 1;
140
+ if (i > 0) {
141
+ multiplier = Math.pow(60, i);
142
+ }
143
+ secs += Number(SMPTE[i]) * multiplier;
144
+ }
145
+ return Number(secs.toFixed(decimalLen));
146
+ },
147
+
148
+ /* borrowed from SWFObject: http://code.google.com/p/swfobject/source/browse/trunk/swfobject/src/swfobject.js#474 */
149
+ removeSwf: function(id) {
150
+ var obj = document.getElementById(id);
151
+ if (obj && obj.nodeName == "OBJECT") {
152
+ if (mejs.MediaFeatures.isIE) {
153
+ obj.style.display = "none";
154
+ (function(){
155
+ if (obj.readyState == 4) {
156
+ mejs.Utility.removeObjectInIE(id);
157
+ } else {
158
+ setTimeout(arguments.callee, 10);
159
+ }
160
+ })();
161
+ } else {
162
+ obj.parentNode.removeChild(obj);
163
+ }
164
+ }
165
+ },
166
+ removeObjectInIE: function(id) {
167
+ var obj = document.getElementById(id);
168
+ if (obj) {
169
+ for (var i in obj) {
170
+ if (typeof obj[i] == "function") {
171
+ obj[i] = null;
172
+ }
173
+ }
174
+ obj.parentNode.removeChild(obj);
175
+ }
176
+ }
38
177
  };
39
-
40
- /*
41
- Utility methods
42
- */
43
- mejs.Utility = {
44
- encodeUrl: function(url) {
45
- return encodeURIComponent(url); //.replace(/\?/gi,'%3F').replace(/=/gi,'%3D').replace(/&/gi,'%26');
46
- },
47
- escapeHTML: function(s) {
48
- return s.toString().split('&').join('&amp;').split('<').join('&lt;').split('"').join('&quot;');
49
- },
50
- absolutizeUrl: function(url) {
51
- var el = document.createElement('div');
52
- el.innerHTML = '<a href="' + this.escapeHTML(url) + '">x</a>';
53
- return el.firstChild.href;
54
- },
55
- getScriptPath: function(scriptNames) {
56
- var
57
- i = 0,
58
- j,
59
- path = '',
60
- name = '',
61
- script,
62
- scripts = document.getElementsByTagName('script'),
63
- il = scripts.length,
64
- jl = scriptNames.length;
65
-
66
- for (; i < il; i++) {
67
- script = scripts[i].src;
68
- for (j = 0; j < jl; j++) {
69
- name = scriptNames[j];
70
- if (script.indexOf(name) > -1) {
71
- path = script.substring(0, script.indexOf(name));
72
- break;
73
- }
74
- }
75
- if (path !== '') {
76
- break;
77
- }
78
- }
79
- return path;
80
- },
81
- secondsToTimeCode: function(time, forceHours, showFrameCount, fps) {
82
- //add framecount
83
- if (typeof showFrameCount == 'undefined') {
84
- showFrameCount=false;
85
- } else if(typeof fps == 'undefined') {
86
- fps = 25;
87
- }
88
-
89
- var hours = Math.floor(time / 3600) % 24,
90
- minutes = Math.floor(time / 60) % 60,
91
- seconds = Math.floor(time % 60),
92
- frames = Math.floor(((time % 1)*fps).toFixed(3)),
93
- result =
94
- ( (forceHours || hours > 0) ? (hours < 10 ? '0' + hours : hours) + ':' : '')
95
- + (minutes < 10 ? '0' + minutes : minutes) + ':'
96
- + (seconds < 10 ? '0' + seconds : seconds)
97
- + ((showFrameCount) ? ':' + (frames < 10 ? '0' + frames : frames) : '');
98
-
99
- return result;
100
- },
101
-
102
- timeCodeToSeconds: function(hh_mm_ss_ff, forceHours, showFrameCount, fps){
103
- if (typeof showFrameCount == 'undefined') {
104
- showFrameCount=false;
105
- } else if(typeof fps == 'undefined') {
106
- fps = 25;
107
- }
108
-
109
- var tc_array = hh_mm_ss_ff.split(":"),
110
- tc_hh = parseInt(tc_array[0], 10),
111
- tc_mm = parseInt(tc_array[1], 10),
112
- tc_ss = parseInt(tc_array[2], 10),
113
- tc_ff = 0,
114
- tc_in_seconds = 0;
115
-
116
- if (showFrameCount) {
117
- tc_ff = parseInt(tc_array[3])/fps;
118
- }
119
-
120
- tc_in_seconds = ( tc_hh * 3600 ) + ( tc_mm * 60 ) + tc_ss + tc_ff;
121
-
122
- return tc_in_seconds;
123
- },
124
-
125
- /* borrowed from SWFObject: http://code.google.com/p/swfobject/source/browse/trunk/swfobject/src/swfobject.js#474 */
126
- removeSwf: function(id) {
127
- var obj = document.getElementById(id);
128
- if (obj && obj.nodeName == "OBJECT") {
129
- if (mejs.MediaFeatures.isIE) {
130
- obj.style.display = "none";
131
- (function(){
132
- if (obj.readyState == 4) {
133
- mejs.Utility.removeObjectInIE(id);
134
- } else {
135
- setTimeout(arguments.callee, 10);
136
- }
137
- })();
138
- } else {
139
- obj.parentNode.removeChild(obj);
140
- }
141
- }
142
- },
143
- removeObjectInIE: function(id) {
144
- var obj = document.getElementById(id);
145
- if (obj) {
146
- for (var i in obj) {
147
- if (typeof obj[i] == "function") {
148
- obj[i] = null;
149
- }
150
- }
151
- obj.parentNode.removeChild(obj);
152
- }
153
- }
154
- };
155
178
 
156
179
 
157
180
  // Core detector, plugins are added below
@@ -280,6 +303,10 @@ mejs.MediaFeatures = {
280
303
  t.isGecko = (ua.match(/gecko/gi) !== null) && !t.isWebkit;
281
304
  t.isOpera = (ua.match(/opera/gi) !== null);
282
305
  t.hasTouch = ('ontouchstart' in window);
306
+
307
+ // borrowed from Modernizr
308
+ t.svg = !! document.createElementNS &&
309
+ !! document.createElementNS('http://www.w3.org/2000/svg','svg').createSVGRect;
283
310
 
284
311
  // create HTML5 media elements for IE before 9, get a <video> element for fullscreen detection
285
312
  for (i=0; i<html5Elements.length; i++) {
@@ -350,7 +377,6 @@ mejs.MediaFeatures = {
350
377
  };
351
378
  mejs.MediaFeatures.init();
352
379
 
353
-
354
380
  /*
355
381
  extension methods to <video> or <audio> object to bring it into parity with PluginMediaElement (see below)
356
382
  */
@@ -395,6 +421,7 @@ mejs.HtmlMediaElement = {
395
421
  media = url[i];
396
422
  if (this.canPlayType(media.type)) {
397
423
  this.src = media.src;
424
+ break;
398
425
  }
399
426
  }
400
427
  }
@@ -414,6 +441,7 @@ mejs.PluginMediaElement = function (pluginid, pluginType, mediaUrl) {
414
441
  this.pluginType = pluginType;
415
442
  this.src = mediaUrl;
416
443
  this.events = {};
444
+ this.attributes = {};
417
445
  };
418
446
 
419
447
  // JavaScript values and ExternalInterface methods that match HTML5 video properties methods
@@ -542,6 +570,7 @@ mejs.PluginMediaElement.prototype = {
542
570
  if (this.canPlayType(media.type)) {
543
571
  this.pluginApi.setSrc(mejs.Utility.absolutizeUrl(media.src));
544
572
  this.src = mejs.Utility.absolutizeUrl(url);
573
+ break;
545
574
  }
546
575
  }
547
576
  }
@@ -654,7 +683,6 @@ mejs.PluginMediaElement.prototype = {
654
683
  // end: fake events
655
684
 
656
685
  // fake DOM attribute methods
657
- attributes: {},
658
686
  hasAttribute: function(name){
659
687
  return (name in this.attributes);
660
688
  },
@@ -721,9 +749,6 @@ mejs.MediaPluginBridge = {
721
749
  bufferedTime,
722
750
  pluginMediaElement = this.pluginMediaElements[id];
723
751
 
724
- pluginMediaElement.ended = false;
725
- pluginMediaElement.paused = true;
726
-
727
752
  // fake event object to mimic real HTML media event.
728
753
  e = {
729
754
  type: eventName,
@@ -774,6 +799,8 @@ mejs.MediaElementDefaults = {
774
799
  pluginPath: mejs.Utility.getScriptPath(['mediaelement.js','mediaelement.min.js','mediaelement-and-player.js','mediaelement-and-player.min.js']),
775
800
  // name of flash file
776
801
  flashName: 'flashmediaelement.swf',
802
+ // streamer for RTMP streaming
803
+ flashStreamer: '',
777
804
  // turns on the smoothing filter in Flash
778
805
  enablePluginSmoothing: false,
779
806
  // name of silverlight file
@@ -874,7 +901,8 @@ mejs.HtmlMediaElementShim = {
874
901
  pluginName,
875
902
  pluginVersions,
876
903
  pluginInfo,
877
- dummy;
904
+ dummy,
905
+ media;
878
906
 
879
907
  // STEP 1: Get URL and type from <video src> or <source src>
880
908
 
@@ -904,7 +932,11 @@ mejs.HtmlMediaElementShim = {
904
932
  if (n.nodeType == 1 && n.tagName.toLowerCase() == 'source') {
905
933
  src = n.getAttribute('src');
906
934
  type = this.formatType(src, n.getAttribute('type'));
907
- mediaFiles.push({type:type, url:src});
935
+ media = n.getAttribute('media');
936
+
937
+ if (!media || !window.matchMedia || (window.matchMedia && window.matchMedia(media).matches)) {
938
+ mediaFiles.push({type:type, url:src});
939
+ }
908
940
  }
909
941
  }
910
942
  }
@@ -1035,24 +1067,28 @@ mejs.HtmlMediaElementShim = {
1035
1067
  },
1036
1068
 
1037
1069
  getTypeFromFile: function(url) {
1070
+ url = url.split('?')[0];
1038
1071
  var ext = url.substring(url.lastIndexOf('.') + 1);
1039
1072
  return (/(mp4|m4v|ogg|ogv|webm|webmv|flv|wmv|mpeg|mov)/gi.test(ext) ? 'video' : 'audio') + '/' + this.getTypeFromExtension(ext);
1040
1073
  },
1041
1074
 
1042
1075
  getTypeFromExtension: function(ext) {
1043
- var ext_types = {
1044
- 'mp4': ['mp4','m4v'],
1045
- 'ogg': ['ogg','ogv','oga'],
1046
- 'webm': ['webm','webmv','webma']
1047
- };
1048
- var r = ext;
1049
- $.each(ext_types, function(key, value) {
1050
- if (value.indexOf(ext) > -1) {
1051
- r = key;
1052
- return;
1053
- }
1054
- });
1055
- return r;
1076
+
1077
+ switch (ext) {
1078
+ case 'mp4':
1079
+ case 'm4v':
1080
+ return 'mp4';
1081
+ case 'webm':
1082
+ case 'webma':
1083
+ case 'webmv':
1084
+ return 'webm';
1085
+ case 'ogg':
1086
+ case 'oga':
1087
+ case 'ogv':
1088
+ return 'ogg';
1089
+ default:
1090
+ return ext;
1091
+ }
1056
1092
  },
1057
1093
 
1058
1094
  createErrorMessage: function(playback, options, poster) {
@@ -1069,7 +1105,7 @@ mejs.HtmlMediaElementShim = {
1069
1105
 
1070
1106
  errorContainer.innerHTML = (poster !== '') ?
1071
1107
  '<a href="' + playback.url + '"><img src="' + poster + '" width="100%" height="100%" /></a>' :
1072
- '<a href="' + playback.url + '"><span>Download File</span></a>';
1108
+ '<a href="' + playback.url + '"><span>' + mejs.i18n.t('Download File') + '</span></a>';
1073
1109
 
1074
1110
  htmlMediaElement.parentNode.insertBefore(errorContainer, htmlMediaElement);
1075
1111
  htmlMediaElement.style.display = 'none';
@@ -1148,6 +1184,7 @@ mejs.HtmlMediaElementShim = {
1148
1184
  'width=' + width,
1149
1185
  'startvolume=' + options.startVolume,
1150
1186
  'timerrate=' + options.timerRate,
1187
+ 'flashstreamer=' + options.flashStreamer,
1151
1188
  'height=' + height];
1152
1189
 
1153
1190
  if (playback.url !== null) {
@@ -1248,6 +1285,9 @@ mejs.HtmlMediaElementShim = {
1248
1285
 
1249
1286
  pluginMediaElement.vimeoid = playback.url.substr(playback.url.lastIndexOf('/')+1);
1250
1287
 
1288
+ container.innerHTML ='<iframe src="http://player.vimeo.com/video/' + pluginMediaElement.vimeoid + '?portrait=0&byline=0&title=0" width="' + width +'" height="' + height +'" frameborder="0"></iframe>';
1289
+
1290
+ /*
1251
1291
  container.innerHTML =
1252
1292
  '<object width="' + width + '" height="' + height + '">' +
1253
1293
  '<param name="allowfullscreen" value="true" />' +
@@ -1256,7 +1296,8 @@ mejs.HtmlMediaElementShim = {
1256
1296
  '<param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=' + pluginMediaElement.vimeoid + '&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=00adef&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" />' +
1257
1297
  '<embed src="//vimeo.com/moogaloop.swf?api=1&amp;clip_id=' + pluginMediaElement.vimeoid + '&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=00adef&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="' + width + '" height="' + height + '"></embed>' +
1258
1298
  '</object>';
1259
-
1299
+ */
1300
+
1260
1301
  break;
1261
1302
  }
1262
1303
  // hide original element
@@ -1482,7 +1523,7 @@ mejs.YouTubeApi = {
1482
1523
  // load the youtube video
1483
1524
  player.cueVideoById(settings.videoId);
1484
1525
 
1485
- var callbackName = settings.containerId + '_callback'
1526
+ var callbackName = settings.containerId + '_callback';
1486
1527
 
1487
1528
  window[callbackName] = function(e) {
1488
1529
  mejs.YouTubeApi.handleStateChange(e, player, pluginMediaElement);
@@ -1542,3 +1583,224 @@ function onYouTubePlayerReady(id) {
1542
1583
  window.mejs = mejs;
1543
1584
  window.MediaElement = mejs.MediaElement;
1544
1585
 
1586
+ /*!
1587
+ * Adds Internationalization and localization to objects.
1588
+ *
1589
+ * What is the concept beyond i18n?
1590
+ * http://en.wikipedia.org/wiki/Internationalization_and_localization
1591
+ *
1592
+ *
1593
+ * This file both i18n methods and locale which is used to translate
1594
+ * strings into other languages.
1595
+ *
1596
+ * Default translations are not available, you have to add them
1597
+ * through locale objects which are named exactly as the langcode
1598
+ * they stand for. The default language is always english (en).
1599
+ *
1600
+ *
1601
+ * Wrapper built to be able to attach the i18n object to
1602
+ * other objects without changing more than one line.
1603
+ *
1604
+ *
1605
+ * LICENSE:
1606
+ *
1607
+ * The i18n file uses methods from the Drupal project (drupal.js):
1608
+ * - i18n.methods.t() (modified)
1609
+ * - i18n.methods.checkPlain() (full copy)
1610
+ * - i18n.methods.formatString() (full copy)
1611
+ *
1612
+ * The Drupal project is (like mediaelementjs) licensed under GPLv2.
1613
+ * - http://drupal.org/licensing/faq/#q1
1614
+ * - https://github.com/johndyer/mediaelement
1615
+ * - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
1616
+ *
1617
+ *
1618
+ * @author
1619
+ * Tim Latz (latz.tim@gmail.com)
1620
+ *
1621
+ * @see
1622
+ * me-i18n-locale.js
1623
+ *
1624
+ * @params
1625
+ * - $ - zepto || jQuery ..
1626
+ * - context - document, iframe ..
1627
+ * - exports - CommonJS, window ..
1628
+ *
1629
+ */
1630
+ ;(function($, context, exports, undefined) {
1631
+ "use strict";
1632
+ var i18n = {
1633
+ "locale": {
1634
+ "strings" : {}
1635
+ },
1636
+ "methods" : {}
1637
+ };
1638
+ // start i18n
1639
+
1640
+
1641
+ /**
1642
+ * Get the current browser's language
1643
+ *
1644
+ * @see: i18n.methods.t()
1645
+ */
1646
+ i18n.locale.getLanguage = function () {
1647
+ return {
1648
+ "language" : navigator.language
1649
+ };
1650
+ };
1651
+
1652
+ /**
1653
+ * Store the language the locale object was initialized with
1654
+ */
1655
+ i18n.locale.INIT_LANGUAGE = i18n.locale.getLanguage();
1656
+
1657
+
1658
+ /**
1659
+ * Encode special characters in a plain-text string for display as HTML.
1660
+ */
1661
+ i18n.methods.checkPlain = function (str) {
1662
+ var character, regex,
1663
+ replace = {
1664
+ '&': '&amp;',
1665
+ '"': '&quot;',
1666
+ '<': '&lt;',
1667
+ '>': '&gt;'
1668
+ };
1669
+ str = String(str);
1670
+ for (character in replace) {
1671
+ if (replace.hasOwnProperty(character)) {
1672
+ regex = new RegExp(character, 'g');
1673
+ str = str.replace(regex, replace[character]);
1674
+ }
1675
+ }
1676
+ return str;
1677
+ };
1678
+
1679
+ /**
1680
+ * Replace placeholders with sanitized values in a string.
1681
+ *
1682
+ * @param str
1683
+ * A string with placeholders.
1684
+ * @param args
1685
+ * An object of replacements pairs to make. Incidences of any key in this
1686
+ * array are replaced with the corresponding value. Based on the first
1687
+ * character of the key, the value is escaped and/or themed:
1688
+ * - !variable: inserted as is
1689
+ * - @variable: escape plain text to HTML (i18n.methods.checkPlain)
1690
+ * - %variable: escape text and theme as a placeholder for user-submitted
1691
+ * content (checkPlain + <em class="placeholder" > )
1692
+ *
1693
+ * @see i18n.methods.t()
1694
+ */
1695
+ i18n.methods.formatString = function(str, args) {
1696
+ // Transform arguments before inserting them.
1697
+ for (var key in args) {
1698
+ switch (key.charAt(0)) {
1699
+ // Escaped only.
1700
+ case '@':
1701
+ args[key] = i18n.methods.checkPlain(args[key]);
1702
+ break;
1703
+ // Pass-through.
1704
+ case '!':
1705
+ break;
1706
+ // Escaped and placeholder.
1707
+ case '%':
1708
+ default:
1709
+ args[key] = '<em class="placeholder">' + i18n.methods.checkPlain(args[key]) + '</em>';
1710
+ break;
1711
+ }
1712
+ str = str.replace(key, args[key]);
1713
+ }
1714
+ return str;
1715
+ };
1716
+
1717
+ /**
1718
+ * Translate strings to the page language or a given language.
1719
+ *
1720
+ * See the documentation of the server-side t() function for further details.
1721
+ *
1722
+ * @param str
1723
+ * A string containing the English string to translate.
1724
+ * @param args
1725
+ * An object of replacements pairs to make after translation. Incidences
1726
+ * of any key in this array are replaced with the corresponding value.
1727
+ * See i18n.methods.formatString().
1728
+ *
1729
+ * @param options
1730
+ * - 'context' (defaults to the default context): The context the source string
1731
+ * belongs to.
1732
+ *
1733
+ * @return
1734
+ * The translated string.
1735
+ */
1736
+ i18n.methods.t = function (str, args, options) {
1737
+
1738
+ // Fetch the localized version of the string.
1739
+ if (i18n.locale.strings && i18n.locale.strings[options.context] && i18n.locale.strings[options.context][str]) {
1740
+ str = i18n.locale.strings[options.context][str];
1741
+ }
1742
+
1743
+ if (args) {
1744
+ str = i18n.methods.formatString(str, args);
1745
+ }
1746
+ return str;
1747
+ };
1748
+
1749
+
1750
+ /**
1751
+ * Wrapper for i18n.methods.t()
1752
+ *
1753
+ * @see i18n.methods.t()
1754
+ * @throws InvalidArgumentException
1755
+ */
1756
+ i18n.t = function(str, args, options) {
1757
+
1758
+ if (typeof str === 'string' && str.length > 0) {
1759
+
1760
+ // check every time due languge can change for
1761
+ // different reasons (translation, lang switcher ..)
1762
+ var lang = i18n.locale.getLanguage();
1763
+
1764
+ options = options || {
1765
+ "context" : lang.language
1766
+ };
1767
+
1768
+ return i18n.methods.t(str, args, options);
1769
+ }
1770
+ else {
1771
+ throw {
1772
+ "name" : 'InvalidArgumentException',
1773
+ "message" : 'First argument is either not a string or empty.'
1774
+ }
1775
+ }
1776
+ };
1777
+
1778
+ // end i18n
1779
+ exports.i18n = i18n;
1780
+ }(jQuery, document, mejs));
1781
+ /*!
1782
+ * This is a i18n.locale language object.
1783
+ *
1784
+ *<de> German translation by Tim Latz, latz.tim@gmail.com
1785
+ *
1786
+ * @author
1787
+ * Tim Latz (latz.tim@gmail.com)
1788
+ *
1789
+ * @see
1790
+ * me-i18n.js
1791
+ *
1792
+ * @params
1793
+ * - exports - CommonJS, window ..
1794
+ */
1795
+ ;(function(exports, undefined) {
1796
+
1797
+ "use strict";
1798
+
1799
+ exports.de = {
1800
+ "Fullscreen" : "Vollbild",
1801
+ "Go Fullscreen" : "Vollbild an",
1802
+ "Turn off Fullscreen" : "Vollbild aus",
1803
+ "Close" : "Schließen"
1804
+ };
1805
+
1806
+ }(mejs.i18n.locale.strings));