transit 0.0.1 → 0.0.2
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/Gemfile +19 -11
- data/app/assets/images/transit/icon24x24.png +0 -0
- data/app/assets/images/transit/icon24x24_files.png +0 -0
- data/app/assets/images/transit/jplayer.swf +0 -0
- data/app/assets/images/transit/uploadify.swf +0 -0
- data/app/assets/images/transit/video_player.swf +0 -0
- data/app/assets/javascripts/jqtools/expose.js +224 -0
- data/app/assets/javascripts/jqtools/flashembed.js +300 -0
- data/app/assets/javascripts/jqtools/overlay.js +294 -0
- data/app/assets/javascripts/jqtools/scrollable.js +3 -0
- data/app/assets/javascripts/jqtools/scrollable/autoscroll.js +81 -0
- data/app/assets/javascripts/jqtools/scrollable/base.js +335 -0
- data/app/assets/javascripts/jqtools/scrollable/navigator.js +139 -0
- data/app/assets/javascripts/jqtools/validator.js +590 -0
- data/app/assets/javascripts/jqueryui/accordion.js +611 -0
- data/app/assets/javascripts/jqueryui/autocomplete.js +612 -0
- data/app/assets/javascripts/jqueryui/button.js +388 -0
- data/app/assets/javascripts/jqueryui/core.js +312 -0
- data/app/assets/javascripts/jqueryui/datepicker.js +1791 -0
- data/app/assets/javascripts/jqueryui/dialog.js +878 -0
- data/app/assets/javascripts/jqueryui/draggable.js +815 -0
- data/app/assets/javascripts/jqueryui/droppable.js +285 -0
- data/app/assets/javascripts/jqueryui/effects/blind.js +49 -0
- data/app/assets/javascripts/jqueryui/effects/bounce.js +78 -0
- data/app/assets/javascripts/jqueryui/effects/clip.js +54 -0
- data/app/assets/javascripts/jqueryui/effects/core.js +746 -0
- data/app/assets/javascripts/jqueryui/effects/drop.js +50 -0
- data/app/assets/javascripts/jqueryui/effects/explode.js +79 -0
- data/app/assets/javascripts/jqueryui/effects/fade.js +32 -0
- data/app/assets/javascripts/jqueryui/effects/fold.js +56 -0
- data/app/assets/javascripts/jqueryui/effects/highlight.js +50 -0
- data/app/assets/javascripts/jqueryui/effects/pulsate.js +51 -0
- data/app/assets/javascripts/jqueryui/effects/scale.js +178 -0
- data/app/assets/javascripts/jqueryui/effects/shake.js +57 -0
- data/app/assets/javascripts/jqueryui/effects/slide.js +50 -0
- data/app/assets/javascripts/jqueryui/effects/transfer.js +45 -0
- data/app/assets/javascripts/jqueryui/mouse.js +160 -0
- data/app/assets/javascripts/jqueryui/position.js +252 -0
- data/app/assets/javascripts/jqueryui/progressbar.js +109 -0
- data/app/assets/javascripts/jqueryui/resizable.js +814 -0
- data/app/assets/javascripts/jqueryui/selectable.js +266 -0
- data/app/assets/javascripts/jqueryui/slider.js +666 -0
- data/app/assets/javascripts/jqueryui/sortable.js +1077 -0
- data/app/assets/javascripts/jqueryui/tabs.js +758 -0
- data/app/assets/javascripts/jqueryui/widget.js +262 -0
- data/app/assets/javascripts/libs/backbone.js +1152 -0
- data/app/assets/javascripts/libs/cookie.js +89 -0
- data/app/assets/javascripts/libs/fileinput.js +130 -0
- data/app/assets/javascripts/libs/jplayer.js +1768 -0
- data/app/assets/javascripts/libs/proper.js +541 -0
- data/app/assets/javascripts/libs/sanitize.js +282 -0
- data/app/assets/javascripts/libs/selecttolist.js +75 -0
- data/app/assets/javascripts/libs/underscore.js +807 -0
- data/app/assets/javascripts/libs/uploadify.js +677 -0
- data/app/assets/javascripts/libs/wymeditor.js +9538 -0
- data/app/assets/javascripts/transit.js +4 -0
- data/app/assets/javascripts/transit/admin.js +22 -0
- data/app/assets/javascripts/transit/admin/contexts.js +52 -0
- data/app/assets/javascripts/transit/admin/fields.js +36 -0
- data/app/assets/javascripts/transit/admin/upload.js +109 -0
- data/app/assets/javascripts/transit/config.js.erb +101 -0
- data/app/assets/javascripts/transit/contexts/audio.js +39 -0
- data/app/assets/javascripts/transit/contexts/video.js +79 -0
- data/app/assets/javascripts/transit/core.js +171 -0
- data/app/assets/javascripts/transit/frontend.js +3 -0
- data/app/assets/javascripts/transit/lib/base64.js +120 -0
- data/app/assets/javascripts/transit/lib/editor.js +177 -0
- data/app/assets/javascripts/transit/views/audio_player.jst +22 -0
- data/app/assets/javascripts/transit/views/editor_toolbar.jst +12 -0
- data/app/assets/javascripts/transit/views/file_upload.jst +5 -0
- data/app/assets/javascripts/transit/views/video_player.jst +20 -0
- data/app/assets/javascripts/transit/views/wym_box.jst +4 -0
- data/app/assets/javascripts/transit/views/wym_iframe.jst +3 -0
- data/app/assets/stylesheets/transit.css.scss.erb +42 -0
- data/app/assets/stylesheets/transit/forms.css.scss +66 -0
- data/app/assets/stylesheets/transit/media/audio.css.scss +65 -0
- data/app/assets/stylesheets/transit/media/video.css.scss +30 -0
- data/app/assets/stylesheets/transit/panel.css.scss +100 -0
- data/app/assets/stylesheets/transit/ui.css.scss +507 -0
- data/app/controllers/pages_controller.rb +3 -0
- data/app/controllers/posts_controller.rb +3 -0
- data/app/controllers/transit/assets_controller.rb +38 -0
- data/app/controllers/transit/contexts_controller.rb +12 -9
- data/app/controllers/transit/pages_controller.rb +26 -0
- data/app/controllers/transit/posts_controller.rb +31 -0
- data/app/controllers/transit/topics_controller.rb +5 -0
- data/app/controllers/transit_controller.rb +16 -0
- data/app/helpers/transit/admin_helper.rb +43 -0
- data/app/helpers/transit/form_helper.rb +17 -0
- data/app/helpers/transit/package_helper.rb +41 -0
- data/app/helpers/transit/pagination_helper.rb +58 -0
- data/app/helpers/transit_helper.rb +42 -0
- data/app/models/comment.rb +37 -0
- data/app/models/contexts/audio.rb +12 -0
- data/app/models/{text.rb → contexts/text.rb} +0 -0
- data/app/models/contexts/video.rb +24 -0
- data/app/models/topic.rb +19 -0
- data/app/models/transit/asset.rb +68 -0
- data/{lib → app/models}/transit/context.rb +29 -0
- data/app/views/contexts/_text.html.erb +1 -1
- data/app/views/posts/index.rss.builder +18 -0
- data/app/views/transit/assets/_file.html.erb +4 -0
- data/app/views/transit/assets/_image.html.erb +13 -0
- data/app/views/transit/assets/create.js.erb +8 -0
- data/app/views/transit/assets/destroy.js.erb +3 -0
- data/app/views/transit/assets/manage.html.erb +20 -0
- data/app/views/transit/contexts/_audio.html.erb +18 -0
- data/app/views/transit/contexts/_text.html.erb +6 -0
- data/app/views/transit/contexts/_video.html.erb +13 -0
- data/app/views/transit/contexts/destroy.js.erb +1 -0
- data/app/views/transit/contexts/index.html.erb +5 -0
- data/app/views/transit/contexts/new.js.erb +7 -0
- data/app/views/transit/contexts/show.html.erb +8 -0
- data/app/views/transit/index.html.erb +26 -0
- data/app/views/transit/index.js.erb +1 -0
- data/app/views/transit/interface/post_panel.html.erb +96 -0
- data/app/views/transit/pages/_table.html.erb +7 -0
- data/app/views/transit/pages/edit.html.erb +17 -0
- data/app/views/transit/pages/index.html.erb +17 -0
- data/app/views/transit/pages/update.js.erb +1 -0
- data/app/views/transit/posts/_form.html.erb +49 -0
- data/app/views/transit/posts/edit.html.erb +14 -0
- data/app/views/transit/posts/new.html.erb +21 -0
- data/app/views/transit/table.html.erb +13 -0
- data/app/views/transit/table.js.erb +8 -0
- data/app/views/transit/topics/manage.html.erb +28 -0
- data/config/locales/en.yml +22 -0
- data/config/routes.rb +3 -3
- data/lib/transit.rb +51 -17
- data/lib/transit/admin.rb +85 -0
- data/lib/transit/builders/form_builder.rb +319 -0
- data/lib/transit/builders/jst_builder.rb +38 -0
- data/lib/transit/builders/package_builder.rb +45 -0
- data/lib/transit/config.rb +20 -0
- data/lib/transit/controller/generator.rb +42 -0
- data/lib/transit/controller/responder.rb +34 -0
- data/lib/transit/core_ext.rb +18 -0
- data/lib/transit/errors/resource_not_found.rb +6 -0
- data/lib/transit/model/assets.rb +14 -0
- data/lib/transit/model/attachments.rb +55 -0
- data/lib/transit/model/auto_increment.rb +22 -0
- data/lib/transit/model/base.rb +56 -0
- data/lib/transit/model/comments.rb +19 -0
- data/lib/transit/model/hooks.rb +38 -0
- data/lib/transit/model/owners.rb +14 -0
- data/lib/transit/model/paginator.rb +92 -0
- data/lib/transit/model/topics.rb +14 -0
- data/lib/transit/package/page.rb +20 -12
- data/lib/transit/package/post.rb +87 -33
- data/lib/transit/package/post/validations.rb +14 -0
- data/lib/transit/rails/engine.rb +29 -13
- data/lib/transit/rails/railtie.rb +31 -0
- data/lib/transit/rails/routing.rb +11 -6
- data/lib/transit/services.rb +13 -0
- data/lib/transit/services/base.rb +14 -0
- data/lib/transit/services/facebook.rb +13 -0
- data/lib/transit/services/ted.rb +10 -0
- data/lib/transit/services/twitter.rb +13 -0
- data/lib/transit/services/vimeo.rb +10 -0
- data/lib/transit/services/you_tube.rb +12 -0
- data/lib/transit/version.rb +1 -1
- metadata +178 -31
- data/app/assets/stylesheets/includes/_compat.scss +0 -24
- data/app/assets/stylesheets/includes/_defaults.scss +0 -99
- data/app/assets/stylesheets/includes/_global.scss +0 -16
- data/app/assets/stylesheets/includes/_imports.scss +0 -27
- data/app/assets/stylesheets/includes/_mixins.scss +0 -38
- data/app/assets/stylesheets/includes/_setup.scss +0 -85
- data/app/assets/stylesheets/layout.css.scss +0 -29
- data/app/assets/stylesheets/transit.css +0 -3
- data/app/controllers/application_controller.rb +0 -5
- data/app/controllers/transit/index_controller.rb +0 -7
- data/app/controllers/transit/packages_controller.rb +0 -64
- data/app/controllers/transit/transit_controller.rb +0 -4
- data/app/helpers/routing_helpers.rb +0 -7
- data/app/models/audio.rb +0 -4
- data/app/models/package_asset.rb +0 -11
- data/app/models/video.rb +0 -8
- data/app/views/contexts/_audio.html.erb +0 -1
- data/app/views/contexts/_video.html.erb +0 -1
- data/app/views/layouts/transit.html.erb +0 -31
- data/app/views/transit/index/index.html.erb +0 -0
- data/lib/transit/helpers/controller_helpers.rb +0 -40
- data/lib/transit/helpers/model_helpers.rb +0 -26
- data/lib/transit/package.rb +0 -25
- data/lib/transit/package/base.rb +0 -49
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/*jslint browser: true */ /*global jQuery: true */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* jQuery Cookie plugin
|
|
5
|
+
*
|
|
6
|
+
* Copyright (c) 2010 Klaus Hartl (stilbuero.de)
|
|
7
|
+
* Dual licensed under the MIT and GPL licenses:
|
|
8
|
+
* http://www.opensource.org/licenses/mit-license.php
|
|
9
|
+
* http://www.gnu.org/licenses/gpl.html
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
// TODO JsDoc
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Create a cookie with the given key and value and other optional parameters.
|
|
17
|
+
*
|
|
18
|
+
* @example $.cookie('the_cookie', 'the_value');
|
|
19
|
+
* @desc Set the value of a cookie.
|
|
20
|
+
* @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
|
|
21
|
+
* @desc Create a cookie with all available options.
|
|
22
|
+
* @example $.cookie('the_cookie', 'the_value');
|
|
23
|
+
* @desc Create a session cookie.
|
|
24
|
+
* @example $.cookie('the_cookie', null);
|
|
25
|
+
* @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
|
|
26
|
+
* used when the cookie was set.
|
|
27
|
+
*
|
|
28
|
+
* @param String key The key of the cookie.
|
|
29
|
+
* @param String value The value of the cookie.
|
|
30
|
+
* @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
|
|
31
|
+
* @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
|
|
32
|
+
* If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
|
|
33
|
+
* If set to null or omitted, the cookie will be a session cookie and will not be retained
|
|
34
|
+
* when the the browser exits.
|
|
35
|
+
* @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
|
|
36
|
+
* @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
|
|
37
|
+
* @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
|
|
38
|
+
* require a secure protocol (like HTTPS).
|
|
39
|
+
* @type undefined
|
|
40
|
+
*
|
|
41
|
+
* @name $.cookie
|
|
42
|
+
* @cat Plugins/Cookie
|
|
43
|
+
* @author Klaus Hartl/klaus.hartl@stilbuero.de
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Get the value of a cookie with the given key.
|
|
48
|
+
*
|
|
49
|
+
* @example $.cookie('the_cookie');
|
|
50
|
+
* @desc Get the value of a cookie.
|
|
51
|
+
*
|
|
52
|
+
* @param String key The key of the cookie.
|
|
53
|
+
* @return The value of the cookie.
|
|
54
|
+
* @type String
|
|
55
|
+
*
|
|
56
|
+
* @name $.cookie
|
|
57
|
+
* @cat Plugins/Cookie
|
|
58
|
+
* @author Klaus Hartl/klaus.hartl@stilbuero.de
|
|
59
|
+
*/
|
|
60
|
+
jQuery.cookie = function (key, value, options) {
|
|
61
|
+
|
|
62
|
+
// key and value given, set cookie...
|
|
63
|
+
if (arguments.length > 1 && (value === null || typeof value !== "object")) {
|
|
64
|
+
options = jQuery.extend({}, options);
|
|
65
|
+
|
|
66
|
+
if (value === null) {
|
|
67
|
+
options.expires = -1;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (typeof options.expires === 'number') {
|
|
71
|
+
var days = options.expires, t = options.expires = new Date();
|
|
72
|
+
t.setDate(t.getDate() + days);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return (document.cookie = [
|
|
76
|
+
encodeURIComponent(key), '=',
|
|
77
|
+
options.raw ? String(value) : encodeURIComponent(String(value)),
|
|
78
|
+
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
|
|
79
|
+
options.path ? '; path=' + options.path : '',
|
|
80
|
+
options.domain ? '; domain=' + options.domain : '',
|
|
81
|
+
options.secure ? '; secure' : ''
|
|
82
|
+
].join(''));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// key and possibly options given, get cookie...
|
|
86
|
+
options = value || {};
|
|
87
|
+
var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent;
|
|
88
|
+
return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null;
|
|
89
|
+
};
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of fileinput.
|
|
3
|
+
*
|
|
4
|
+
* fileinput is free software: you can redistribute it and/or modify
|
|
5
|
+
* it under the terms of the GNU General Public License as published by
|
|
6
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
* (at your option) any later version.
|
|
8
|
+
*
|
|
9
|
+
* fileinput is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
* GNU General Public License for more details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU General Public License
|
|
15
|
+
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
(function($){
|
|
19
|
+
|
|
20
|
+
var wrapperClasses = 'fileinput-wrapper ui-widget',
|
|
21
|
+
inputClasses = 'fileinput-input ui-state-default ui-widget-content ui-corner-left',
|
|
22
|
+
buttonClasses = 'fileinput-button ui-state-default ui-widget-header ui-corner-right',
|
|
23
|
+
buttonTextClasses = 'fileinput-button-text',
|
|
24
|
+
fileClasses = 'fileinput-file',
|
|
25
|
+
hoverClasses = 'ui-state-hover',
|
|
26
|
+
activeClasses = 'ui-state-active',
|
|
27
|
+
stateClasses = hoverClasses + ' ' + activeClasses,
|
|
28
|
+
fakePath = 'C:\\fakepath\\';
|
|
29
|
+
|
|
30
|
+
$.widget("shimmy.fileinput", {
|
|
31
|
+
options: {
|
|
32
|
+
buttonText: "Browse",
|
|
33
|
+
inputText: ""
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
_create: function(){
|
|
37
|
+
var self = this,
|
|
38
|
+
options = self.options;
|
|
39
|
+
|
|
40
|
+
self.fileFile = self.element,
|
|
41
|
+
self.fileWrapper = $('<div></div>')
|
|
42
|
+
.addClass(wrapperClasses)
|
|
43
|
+
.hover(function(){
|
|
44
|
+
self.fileButton.addClass(hoverClasses);
|
|
45
|
+
},function(){
|
|
46
|
+
self.fileButton.removeClass(stateClasses);
|
|
47
|
+
}).bind('mousemove.fileinput',function(e){
|
|
48
|
+
var x = (e.pageX - $(this).offset().left) - (self.fileFile.width() / 1.2);
|
|
49
|
+
var y = (e.pageY - $(this).offset().top) - (self.fileFile.height() / 2);
|
|
50
|
+
self.fileFile.css('top', y).css('left', x);
|
|
51
|
+
}).bind('mousedown.fileinput',function(e){
|
|
52
|
+
self.fileButton.addClass(activeClasses);
|
|
53
|
+
}).bind('mouseup.fileinput',function(e){
|
|
54
|
+
self.fileButton.removeClass(activeClasses);
|
|
55
|
+
}),
|
|
56
|
+
self.fileFile
|
|
57
|
+
.addClass(fileClasses)
|
|
58
|
+
.wrap(self.fileWrapper),
|
|
59
|
+
self.fileInput = $('<span></span>')
|
|
60
|
+
.addClass(inputClasses)
|
|
61
|
+
.text(self._getText())
|
|
62
|
+
.insertBefore(self.fileFile),
|
|
63
|
+
self.fileButtonText = $('<span></span>')
|
|
64
|
+
.addClass(buttonTextClasses)
|
|
65
|
+
.text(options.buttonText)
|
|
66
|
+
self.fileButton = $('<span></span>')
|
|
67
|
+
.addClass(buttonClasses)
|
|
68
|
+
.insertAfter(self.fileInput)
|
|
69
|
+
.html(self.fileButtonText);
|
|
70
|
+
|
|
71
|
+
self.fileFile.bind('change.fileinput mouseout.fileinput',function(){
|
|
72
|
+
self.fileInput.text(self._getText());
|
|
73
|
+
}).bind('focusin.fileinput',function(){
|
|
74
|
+
self.fileButton.addClass(hoverClasses);
|
|
75
|
+
}).bind('focusout.fileinput',function(){
|
|
76
|
+
self.fileButton.removeClass(hoverClasses);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
_getText: function(){
|
|
82
|
+
var self = this;
|
|
83
|
+
fileValue = self.getValue();
|
|
84
|
+
inputTextValue = self.options.inputText;
|
|
85
|
+
|
|
86
|
+
if(fileValue == ''){
|
|
87
|
+
return inputTextValue;
|
|
88
|
+
}else{
|
|
89
|
+
return fileValue;
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
getValue: function(){
|
|
94
|
+
var self = this;
|
|
95
|
+
return fileValue = self.fileFile.val().replace(fakePath,'');
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
reset: function() {
|
|
99
|
+
var self = this;
|
|
100
|
+
self.fileInput.text(self.options.inputText);
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
destroy: function(){
|
|
104
|
+
var self = this;
|
|
105
|
+
|
|
106
|
+
self.fileInput.remove();
|
|
107
|
+
self.fileButton.remove();
|
|
108
|
+
self.fileButtonText.remove();
|
|
109
|
+
self.fileFile.removeClass(fileClasses).unwrap(self.fileWrapper);
|
|
110
|
+
self.fileWrapper.remove();
|
|
111
|
+
|
|
112
|
+
$.Widget.prototype.destroy.call( self );
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
_setOption: function(option, value){
|
|
116
|
+
var self = this;
|
|
117
|
+
$.Widget.prototype._setOption.apply( self, arguments );
|
|
118
|
+
switch(option){
|
|
119
|
+
case "buttonText":
|
|
120
|
+
self.fileButtonText.text(value);
|
|
121
|
+
break;
|
|
122
|
+
case "inputText":
|
|
123
|
+
self.fileInput.text(self._getText());
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
})(jQuery);
|
|
@@ -0,0 +1,1768 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* jPlayer Plugin for jQuery JavaScript Library
|
|
3
|
+
* http://www.happyworm.com/jquery/jplayer
|
|
4
|
+
*
|
|
5
|
+
* Copyright (c) 2009 - 2010 Happyworm Ltd
|
|
6
|
+
* Dual licensed under the MIT and GPL licenses.
|
|
7
|
+
* - http://www.opensource.org/licenses/mit-license.php
|
|
8
|
+
* - http://www.gnu.org/copyleft/gpl.html
|
|
9
|
+
*
|
|
10
|
+
* Author: Mark J Panaghiston
|
|
11
|
+
* Version: 2.0.0
|
|
12
|
+
* Date: 20th December 2010
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
(function($, undefined) {
|
|
16
|
+
|
|
17
|
+
// Adapted from jquery.ui.widget.js (1.8.7): $.widget.bridge
|
|
18
|
+
$.fn.jPlayer = function( options ) {
|
|
19
|
+
var name = "jPlayer";
|
|
20
|
+
var isMethodCall = typeof options === "string",
|
|
21
|
+
args = Array.prototype.slice.call( arguments, 1 ),
|
|
22
|
+
returnValue = this;
|
|
23
|
+
|
|
24
|
+
// allow multiple hashes to be passed on init
|
|
25
|
+
options = !isMethodCall && args.length ?
|
|
26
|
+
$.extend.apply( null, [ true, options ].concat(args) ) :
|
|
27
|
+
options;
|
|
28
|
+
|
|
29
|
+
// prevent calls to internal methods
|
|
30
|
+
if ( isMethodCall && options.charAt( 0 ) === "_" ) {
|
|
31
|
+
return returnValue;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if ( isMethodCall ) {
|
|
35
|
+
this.each(function() {
|
|
36
|
+
var instance = $.data( this, name ),
|
|
37
|
+
methodValue = instance && $.isFunction( instance[options] ) ?
|
|
38
|
+
instance[ options ].apply( instance, args ) :
|
|
39
|
+
instance;
|
|
40
|
+
if ( methodValue !== instance && methodValue !== undefined ) {
|
|
41
|
+
returnValue = methodValue;
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
} else {
|
|
46
|
+
this.each(function() {
|
|
47
|
+
var instance = $.data( this, name );
|
|
48
|
+
if ( instance ) {
|
|
49
|
+
instance.option( options || {} )._init(); // Orig jquery.ui.widget.js code: Not recommend for jPlayer. ie., Applying new options to an existing instance (via the jPlayer constructor) and performing the _init(). The _init() is what concerns me. It would leave a lot of event handlers acting on jPlayer instance and the interface.
|
|
50
|
+
instance.option( options || {} ); // The new constructor only changes the options. Changing options only has basic support atm.
|
|
51
|
+
} else {
|
|
52
|
+
$.data( this, name, new $.jPlayer( options, this ) );
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return returnValue;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
$.jPlayer = function( options, element ) {
|
|
61
|
+
// allow instantiation without initializing for simple inheritance
|
|
62
|
+
if ( arguments.length ) {
|
|
63
|
+
this.element = $(element);
|
|
64
|
+
this.options = $.extend(true, {},
|
|
65
|
+
this.options,
|
|
66
|
+
options
|
|
67
|
+
);
|
|
68
|
+
var self = this;
|
|
69
|
+
this.element.bind( "remove.jPlayer", function() {
|
|
70
|
+
self.destroy();
|
|
71
|
+
});
|
|
72
|
+
this._init();
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
// End of: (Adapted from jquery.ui.widget.js (1.8.7))
|
|
76
|
+
|
|
77
|
+
$.jPlayer.event = {
|
|
78
|
+
ready: "jPlayer_ready",
|
|
79
|
+
resize: "jPlayer_resize", // Not implemented.
|
|
80
|
+
error: "jPlayer_error", // Event error code in event.jPlayer.error.type. See $.jPlayer.error
|
|
81
|
+
warning: "jPlayer_warning", // Event warning code in event.jPlayer.warning.type. See $.jPlayer.warning
|
|
82
|
+
|
|
83
|
+
// Other events match HTML5 spec.
|
|
84
|
+
loadstart: "jPlayer_loadstart",
|
|
85
|
+
progress: "jPlayer_progress",
|
|
86
|
+
suspend: "jPlayer_suspend",
|
|
87
|
+
abort: "jPlayer_abort",
|
|
88
|
+
emptied: "jPlayer_emptied",
|
|
89
|
+
stalled: "jPlayer_stalled",
|
|
90
|
+
play: "jPlayer_play",
|
|
91
|
+
pause: "jPlayer_pause",
|
|
92
|
+
loadedmetadata: "jPlayer_loadedmetadata",
|
|
93
|
+
loadeddata: "jPlayer_loadeddata",
|
|
94
|
+
waiting: "jPlayer_waiting",
|
|
95
|
+
playing: "jPlayer_playing",
|
|
96
|
+
canplay: "jPlayer_canplay",
|
|
97
|
+
canplaythrough: "jPlayer_canplaythrough",
|
|
98
|
+
seeking: "jPlayer_seeking",
|
|
99
|
+
seeked: "jPlayer_seeked",
|
|
100
|
+
timeupdate: "jPlayer_timeupdate",
|
|
101
|
+
ended: "jPlayer_ended",
|
|
102
|
+
ratechange: "jPlayer_ratechange",
|
|
103
|
+
durationchange: "jPlayer_durationchange",
|
|
104
|
+
volumechange: "jPlayer_volumechange"
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
$.jPlayer.htmlEvent = [ // These HTML events are bubbled through to the jPlayer event, without any internal action.
|
|
108
|
+
"loadstart",
|
|
109
|
+
// "progress", // jPlayer uses internally before bubbling.
|
|
110
|
+
// "suspend", // jPlayer uses internally before bubbling.
|
|
111
|
+
"abort",
|
|
112
|
+
// "error", // jPlayer uses internally before bubbling.
|
|
113
|
+
"emptied",
|
|
114
|
+
"stalled",
|
|
115
|
+
// "play", // jPlayer uses internally before bubbling.
|
|
116
|
+
// "pause", // jPlayer uses internally before bubbling.
|
|
117
|
+
"loadedmetadata",
|
|
118
|
+
"loadeddata",
|
|
119
|
+
// "waiting", // jPlayer uses internally before bubbling.
|
|
120
|
+
// "playing", // jPlayer uses internally before bubbling.
|
|
121
|
+
// "canplay", // jPlayer fixes the volume (for Chrome) before bubbling.
|
|
122
|
+
"canplaythrough",
|
|
123
|
+
// "seeking", // jPlayer uses internally before bubbling.
|
|
124
|
+
// "seeked", // jPlayer uses internally before bubbling.
|
|
125
|
+
// "timeupdate", // jPlayer uses internally before bubbling.
|
|
126
|
+
// "ended", // jPlayer uses internally before bubbling.
|
|
127
|
+
"ratechange"
|
|
128
|
+
// "durationchange" // jPlayer uses internally before bubbling.
|
|
129
|
+
// "volumechange" // Handled by jPlayer in volume() method, primarily due to the volume fix (for Chrome) in the canplay event. [*] Need to review whether the latest Chrome still needs the fix sometime.
|
|
130
|
+
];
|
|
131
|
+
|
|
132
|
+
$.jPlayer.pause = function() {
|
|
133
|
+
// $.each($.jPlayer.instances, function(i, element) {
|
|
134
|
+
$.each($.jPlayer.prototype.instances, function(i, element) {
|
|
135
|
+
if(element.data("jPlayer").status.srcSet) { // Check that media is set otherwise would cause error event.
|
|
136
|
+
element.jPlayer("pause");
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
$.jPlayer.timeFormat = {
|
|
142
|
+
showHour: false,
|
|
143
|
+
showMin: true,
|
|
144
|
+
showSec: true,
|
|
145
|
+
padHour: false,
|
|
146
|
+
padMin: true,
|
|
147
|
+
padSec: true,
|
|
148
|
+
sepHour: ":",
|
|
149
|
+
sepMin: ":",
|
|
150
|
+
sepSec: ""
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
$.jPlayer.convertTime = function(sec) {
|
|
154
|
+
var myTime = new Date(sec * 1000);
|
|
155
|
+
var hour = myTime.getUTCHours();
|
|
156
|
+
var min = myTime.getUTCMinutes();
|
|
157
|
+
var sec = myTime.getUTCSeconds();
|
|
158
|
+
var strHour = ($.jPlayer.timeFormat.padHour && hour < 10) ? "0" + hour : hour;
|
|
159
|
+
var strMin = ($.jPlayer.timeFormat.padMin && min < 10) ? "0" + min : min;
|
|
160
|
+
var strSec = ($.jPlayer.timeFormat.padSec && sec < 10) ? "0" + sec : sec;
|
|
161
|
+
return (($.jPlayer.timeFormat.showHour) ? strHour + $.jPlayer.timeFormat.sepHour : "") + (($.jPlayer.timeFormat.showMin) ? strMin + $.jPlayer.timeFormat.sepMin : "") + (($.jPlayer.timeFormat.showSec) ? strSec + $.jPlayer.timeFormat.sepSec : "");
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// Adapting jQuery 1.4.4 code for jQuery.browser. Required since jQuery 1.3.2 does not detect Chrome as webkit.
|
|
165
|
+
$.jPlayer.uaMatch = function( ua ) {
|
|
166
|
+
var ua = ua.toLowerCase();
|
|
167
|
+
|
|
168
|
+
// Useragent RegExp
|
|
169
|
+
var rwebkit = /(webkit)[ \/]([\w.]+)/;
|
|
170
|
+
var ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/;
|
|
171
|
+
var rmsie = /(msie) ([\w.]+)/;
|
|
172
|
+
var rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/;
|
|
173
|
+
|
|
174
|
+
var match = rwebkit.exec( ua ) ||
|
|
175
|
+
ropera.exec( ua ) ||
|
|
176
|
+
rmsie.exec( ua ) ||
|
|
177
|
+
ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
|
|
178
|
+
[];
|
|
179
|
+
|
|
180
|
+
return { browser: match[1] || "", version: match[2] || "0" };
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
$.jPlayer.browser = {
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
var browserMatch = $.jPlayer.uaMatch(navigator.userAgent);
|
|
187
|
+
if ( browserMatch.browser ) {
|
|
188
|
+
$.jPlayer.browser[ browserMatch.browser ] = true;
|
|
189
|
+
$.jPlayer.browser.version = browserMatch.version;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
$.jPlayer.prototype = {
|
|
193
|
+
count: 0, // Static Variable: Change it via prototype.
|
|
194
|
+
version: { // Static Object
|
|
195
|
+
script: "2.0.0",
|
|
196
|
+
needFlash: "2.0.0",
|
|
197
|
+
flash: "unknown"
|
|
198
|
+
},
|
|
199
|
+
options: { // Instanced in $.jPlayer() constructor
|
|
200
|
+
swfPath: "js", // Path to Jplayer.swf. Can be relative, absolute or server root relative.
|
|
201
|
+
solution: "html, flash", // Valid solutions: html, flash. Order defines priority. 1st is highest,
|
|
202
|
+
supplied: "mp3", // Defines which formats jPlayer will try and support and the priority by the order. 1st is highest,
|
|
203
|
+
preload: 'metadata', // HTML5 Spec values: none, metadata, auto.
|
|
204
|
+
volume: 0.8, // The volume. Number 0 to 1.
|
|
205
|
+
muted: false,
|
|
206
|
+
backgroundColor: "#000000", // To define the jPlayer div and Flash background color.
|
|
207
|
+
cssSelectorAncestor: "#jp_interface_1",
|
|
208
|
+
cssSelector: {
|
|
209
|
+
videoPlay: ".jp-video-play",
|
|
210
|
+
play: ".jp-play",
|
|
211
|
+
pause: ".jp-pause",
|
|
212
|
+
stop: ".jp-stop",
|
|
213
|
+
seekBar: ".jp-seek-bar",
|
|
214
|
+
playBar: ".jp-play-bar",
|
|
215
|
+
mute: ".jp-mute",
|
|
216
|
+
unmute: ".jp-unmute",
|
|
217
|
+
volumeBar: ".jp-volume-bar",
|
|
218
|
+
volumeBarValue: ".jp-volume-bar-value",
|
|
219
|
+
currentTime: ".jp-current-time",
|
|
220
|
+
duration: ".jp-duration"
|
|
221
|
+
},
|
|
222
|
+
// globalVolume: false, // Not implemented: Set to make volume changes affect all jPlayer instances
|
|
223
|
+
// globalMute: false, // Not implemented: Set to make mute changes affect all jPlayer instances
|
|
224
|
+
idPrefix: "jp", // Prefix for the ids of html elements created by jPlayer. For flash, this must not include characters: . - + * / \
|
|
225
|
+
errorAlerts: false,
|
|
226
|
+
warningAlerts: false
|
|
227
|
+
},
|
|
228
|
+
instances: {}, // Static Object
|
|
229
|
+
status: { // Instanced in _init()
|
|
230
|
+
src: "",
|
|
231
|
+
media: {},
|
|
232
|
+
paused: true,
|
|
233
|
+
format: {},
|
|
234
|
+
formatType: "",
|
|
235
|
+
waitForPlay: true, // Same as waitForLoad except in case where preloading.
|
|
236
|
+
waitForLoad: true,
|
|
237
|
+
srcSet: false,
|
|
238
|
+
video: false, // True if playing a video
|
|
239
|
+
seekPercent: 0,
|
|
240
|
+
currentPercentRelative: 0,
|
|
241
|
+
currentPercentAbsolute: 0,
|
|
242
|
+
currentTime: 0,
|
|
243
|
+
duration: 0
|
|
244
|
+
},
|
|
245
|
+
_status: { // Instanced in _init(): These status values are persistent. ie., Are not affected by a status reset.
|
|
246
|
+
volume: undefined, // Set by constructor option/default.
|
|
247
|
+
muted: false, // Set by constructor option/default.
|
|
248
|
+
width: 0, // Read from CSS
|
|
249
|
+
height: 0 // Read from CSS
|
|
250
|
+
},
|
|
251
|
+
internal: { // Instanced in _init()
|
|
252
|
+
ready: false,
|
|
253
|
+
instance: undefined,
|
|
254
|
+
htmlDlyCmdId: undefined
|
|
255
|
+
},
|
|
256
|
+
solution: { // Static Object: Defines the solutions built in jPlayer.
|
|
257
|
+
html: true,
|
|
258
|
+
flash: true
|
|
259
|
+
},
|
|
260
|
+
// 'MPEG-4 support' : canPlayType('video/mp4; codecs="mp4v.20.8"')
|
|
261
|
+
format: { // Static Object
|
|
262
|
+
mp3: {
|
|
263
|
+
codec: 'audio/mpeg; codecs="mp3"',
|
|
264
|
+
flashCanPlay: true,
|
|
265
|
+
media: 'audio'
|
|
266
|
+
},
|
|
267
|
+
m4a: { // AAC / MP4
|
|
268
|
+
codec: 'audio/mp4; codecs="mp4a.40.2"',
|
|
269
|
+
flashCanPlay: true,
|
|
270
|
+
media: 'audio'
|
|
271
|
+
},
|
|
272
|
+
oga: { // OGG
|
|
273
|
+
codec: 'audio/ogg; codecs="vorbis"',
|
|
274
|
+
flashCanPlay: false,
|
|
275
|
+
media: 'audio'
|
|
276
|
+
},
|
|
277
|
+
wav: { // PCM
|
|
278
|
+
codec: 'audio/wav; codecs="1"',
|
|
279
|
+
flashCanPlay: false,
|
|
280
|
+
media: 'audio'
|
|
281
|
+
},
|
|
282
|
+
webma: { // WEBM
|
|
283
|
+
codec: 'audio/webm; codecs="vorbis"',
|
|
284
|
+
flashCanPlay: false,
|
|
285
|
+
media: 'audio'
|
|
286
|
+
},
|
|
287
|
+
m4v: { // H.264 / MP4
|
|
288
|
+
codec: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"',
|
|
289
|
+
flashCanPlay: true,
|
|
290
|
+
media: 'video'
|
|
291
|
+
},
|
|
292
|
+
ogv: { // OGG
|
|
293
|
+
codec: 'video/ogg; codecs="theora, vorbis"',
|
|
294
|
+
flashCanPlay: false,
|
|
295
|
+
media: 'video'
|
|
296
|
+
},
|
|
297
|
+
webmv: { // WEBM
|
|
298
|
+
codec: 'video/webm; codecs="vorbis, vp8"',
|
|
299
|
+
flashCanPlay: false,
|
|
300
|
+
media: 'video'
|
|
301
|
+
}
|
|
302
|
+
},
|
|
303
|
+
_init: function() {
|
|
304
|
+
var self = this;
|
|
305
|
+
|
|
306
|
+
this.element.empty();
|
|
307
|
+
|
|
308
|
+
this.status = $.extend({}, this.status, this._status); // Copy static to unique instance. Adds the status propeties that persist through a reset. NB: Might want to use $.jPlayer.prototype.status instead once options completely implmented and _init() returned to $.fn.jPlayer plugin.
|
|
309
|
+
this.internal = $.extend({}, this.internal); // Copy static to unique instance.
|
|
310
|
+
|
|
311
|
+
this.formats = []; // Array based on supplied string option. Order defines priority.
|
|
312
|
+
this.solutions = []; // Array based on solution string option. Order defines priority.
|
|
313
|
+
this.require = {}; // Which media types are required: video, audio.
|
|
314
|
+
|
|
315
|
+
this.htmlElement = {}; // DOM elements created by jPlayer
|
|
316
|
+
this.html = {}; // In _init()'s this.desired code and setmedia(): Accessed via this[solution], where solution from this.solutions array.
|
|
317
|
+
this.html.audio = {};
|
|
318
|
+
this.html.video = {};
|
|
319
|
+
this.flash = {}; // In _init()'s this.desired code and setmedia(): Accessed via this[solution], where solution from this.solutions array.
|
|
320
|
+
|
|
321
|
+
this.css = {};
|
|
322
|
+
this.css.cs = {}; // Holds the css selector strings
|
|
323
|
+
this.css.jq = {}; // Holds jQuery selectors. ie., $(css.cs.method)
|
|
324
|
+
|
|
325
|
+
this.status.volume = this._limitValue(this.options.volume, 0, 1); // Set volume status from constructor option.
|
|
326
|
+
this.status.muted = this.options.muted; // Set muted status from constructor option.
|
|
327
|
+
this.status.width = this.element.css('width'); // Sets from CSS.
|
|
328
|
+
this.status.height = this.element.css('height'); // Sets from CSS.
|
|
329
|
+
|
|
330
|
+
this.element.css({'background-color': this.options.backgroundColor});
|
|
331
|
+
|
|
332
|
+
// Create the formats array, with prority based on the order of the supplied formats string
|
|
333
|
+
$.each(this.options.supplied.toLowerCase().split(","), function(index1, value1) {
|
|
334
|
+
var format = value1.replace(/^\s+|\s+$/g, ""); //trim
|
|
335
|
+
if(self.format[format]) { // Check format is valid.
|
|
336
|
+
var dupFound = false;
|
|
337
|
+
$.each(self.formats, function(index2, value2) { // Check for duplicates
|
|
338
|
+
if(format === value2) {
|
|
339
|
+
dupFound = true;
|
|
340
|
+
return false;
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
if(!dupFound) {
|
|
344
|
+
self.formats.push(format);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
// Create the solutions array, with prority based on the order of the solution string
|
|
350
|
+
$.each(this.options.solution.toLowerCase().split(","), function(index1, value1) {
|
|
351
|
+
var solution = value1.replace(/^\s+|\s+$/g, ""); //trim
|
|
352
|
+
if(self.solution[solution]) { // Check solution is valid.
|
|
353
|
+
var dupFound = false;
|
|
354
|
+
$.each(self.solutions, function(index2, value2) { // Check for duplicates
|
|
355
|
+
if(solution === value2) {
|
|
356
|
+
dupFound = true;
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
if(!dupFound) {
|
|
361
|
+
self.solutions.push(solution);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
this.internal.instance = "jp_" + this.count;
|
|
367
|
+
this.instances[this.internal.instance] = this.element;
|
|
368
|
+
|
|
369
|
+
// Check the jPlayer div has an id and create one if required. Important for Flash to know the unique id for comms.
|
|
370
|
+
if(this.element.attr("id") === "") {
|
|
371
|
+
this.element.attr("id", this.options.idPrefix + "_jplayer_" + this.count);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
this.internal.self = $.extend({}, {
|
|
375
|
+
id: this.element.attr("id"),
|
|
376
|
+
jq: this.element
|
|
377
|
+
});
|
|
378
|
+
this.internal.audio = $.extend({}, {
|
|
379
|
+
id: this.options.idPrefix + "_audio_" + this.count,
|
|
380
|
+
jq: undefined
|
|
381
|
+
});
|
|
382
|
+
this.internal.video = $.extend({}, {
|
|
383
|
+
id: this.options.idPrefix + "_video_" + this.count,
|
|
384
|
+
jq: undefined
|
|
385
|
+
});
|
|
386
|
+
this.internal.flash = $.extend({}, {
|
|
387
|
+
id: this.options.idPrefix + "_flash_" + this.count,
|
|
388
|
+
jq: undefined,
|
|
389
|
+
swf: this.options.swfPath// + ((this.options.swfPath !== "" && this.options.swfPath.slice(-1) !== "/") ? "/" : "")
|
|
390
|
+
});
|
|
391
|
+
this.internal.poster = $.extend({}, {
|
|
392
|
+
id: this.options.idPrefix + "_poster_" + this.count,
|
|
393
|
+
jq: undefined
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
// Register listeners defined in the constructor
|
|
397
|
+
$.each($.jPlayer.event, function(eventName,eventType) {
|
|
398
|
+
if(self.options[eventName] !== undefined) {
|
|
399
|
+
self.element.bind(eventType + ".jPlayer", self.options[eventName]); // With .jPlayer namespace.
|
|
400
|
+
self.options[eventName] = undefined; // Destroy the handler pointer copy on the options. Reason, events can be added/removed in other ways so this could be obsolete and misleading.
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
// Create the poster image.
|
|
405
|
+
this.htmlElement.poster = document.createElement('img');
|
|
406
|
+
this.htmlElement.poster.id = this.internal.poster.id;
|
|
407
|
+
this.htmlElement.poster.onload = function() { // Note that this did not work on Firefox 3.6: poster.addEventListener("onload", function() {}, false); Did not investigate x-browser.
|
|
408
|
+
if(!self.status.video || self.status.waitForPlay) {
|
|
409
|
+
self.internal.poster.jq.show();
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
this.element.append(this.htmlElement.poster);
|
|
413
|
+
this.internal.poster.jq = $("#" + this.internal.poster.id);
|
|
414
|
+
this.internal.poster.jq.css({'width': this.status.width, 'height': this.status.height});
|
|
415
|
+
this.internal.poster.jq.hide();
|
|
416
|
+
|
|
417
|
+
// Determine if we require solutions for audio, video or both media types.
|
|
418
|
+
this.require.audio = false;
|
|
419
|
+
this.require.video = false;
|
|
420
|
+
$.each(this.formats, function(priority, format) {
|
|
421
|
+
self.require[self.format[format].media] = true;
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
this.html.audio.available = false;
|
|
425
|
+
if(this.require.audio) { // If a supplied format is audio
|
|
426
|
+
this.htmlElement.audio = document.createElement('audio');
|
|
427
|
+
this.htmlElement.audio.id = this.internal.audio.id;
|
|
428
|
+
this.html.audio.available = !!this.htmlElement.audio.canPlayType;
|
|
429
|
+
}
|
|
430
|
+
this.html.video.available = false;
|
|
431
|
+
if(this.require.video) { // If a supplied format is video
|
|
432
|
+
this.htmlElement.video = document.createElement('video');
|
|
433
|
+
this.htmlElement.video.id = this.internal.video.id;
|
|
434
|
+
this.html.video.available = !!this.htmlElement.video.canPlayType;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
this.flash.available = this._checkForFlash(10); // IE9 forced to false due to ExternalInterface problem.
|
|
438
|
+
|
|
439
|
+
this.html.canPlay = {};
|
|
440
|
+
this.flash.canPlay = {};
|
|
441
|
+
$.each(this.formats, function(priority, format) {
|
|
442
|
+
self.html.canPlay[format] = self.html[self.format[format].media].available && "" !== self.htmlElement[self.format[format].media].canPlayType(self.format[format].codec);
|
|
443
|
+
self.flash.canPlay[format] = self.format[format].flashCanPlay && self.flash.available;
|
|
444
|
+
});
|
|
445
|
+
this.html.desired = false;
|
|
446
|
+
this.flash.desired = false;
|
|
447
|
+
$.each(this.solutions, function(solutionPriority, solution) {
|
|
448
|
+
if(solutionPriority === 0) {
|
|
449
|
+
self[solution].desired = true;
|
|
450
|
+
} else {
|
|
451
|
+
var audioCanPlay = false;
|
|
452
|
+
var videoCanPlay = false;
|
|
453
|
+
$.each(self.formats, function(formatPriority, format) {
|
|
454
|
+
if(self[self.solutions[0]].canPlay[format]) { // The other solution can play
|
|
455
|
+
if(self.format[format].media === 'video') {
|
|
456
|
+
videoCanPlay = true;
|
|
457
|
+
} else {
|
|
458
|
+
audioCanPlay = true;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
self[solution].desired = (self.require.audio && !audioCanPlay) || (self.require.video && !videoCanPlay);
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
// This is what jPlayer will support, based on solution and supplied.
|
|
466
|
+
this.html.support = {};
|
|
467
|
+
this.flash.support = {};
|
|
468
|
+
$.each(this.formats, function(priority, format) {
|
|
469
|
+
self.html.support[format] = self.html.canPlay[format] && self.html.desired;
|
|
470
|
+
self.flash.support[format] = self.flash.canPlay[format] && self.flash.desired;
|
|
471
|
+
});
|
|
472
|
+
// If jPlayer is supporting any format in a solution, then the solution is used.
|
|
473
|
+
this.html.used = false;
|
|
474
|
+
this.flash.used = false;
|
|
475
|
+
$.each(this.solutions, function(solutionPriority, solution) {
|
|
476
|
+
$.each(self.formats, function(formatPriority, format) {
|
|
477
|
+
if(self[solution].support[format]) {
|
|
478
|
+
self[solution].used = true;
|
|
479
|
+
return false;
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
// If neither html nor flash are being used by this browser, then media playback is not possible. Trigger an error event.
|
|
485
|
+
if(!(this.html.used || this.flash.used)) {
|
|
486
|
+
this._error( {
|
|
487
|
+
type: $.jPlayer.error.NO_SOLUTION,
|
|
488
|
+
context: "{solution:'" + this.options.solution + "', supplied:'" + this.options.supplied + "'}",
|
|
489
|
+
message: $.jPlayer.errorMsg.NO_SOLUTION,
|
|
490
|
+
hint: $.jPlayer.errorHint.NO_SOLUTION
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// Init solution active state and the event gates to false.
|
|
495
|
+
this.html.active = false;
|
|
496
|
+
this.html.audio.gate = false;
|
|
497
|
+
this.html.video.gate = false;
|
|
498
|
+
this.flash.active = false;
|
|
499
|
+
this.flash.gate = false;
|
|
500
|
+
|
|
501
|
+
// Add the flash solution if it is being used.
|
|
502
|
+
if(this.flash.used) {
|
|
503
|
+
var flashVars = 'id=' + escape(this.internal.self.id) + '&vol=' + this.status.volume + '&muted=' + this.status.muted;
|
|
504
|
+
|
|
505
|
+
if($.browser.msie && Number($.browser.version) <= 8) {
|
|
506
|
+
var html_obj = '<object id="' + this.internal.flash.id + '"';
|
|
507
|
+
html_obj += ' classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"';
|
|
508
|
+
html_obj += ' codebase="' + document.URL.substring(0,document.URL.indexOf(':')) + '://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab"'; // Fixed IE non secured element warning.
|
|
509
|
+
html_obj += ' type="application/x-shockwave-flash"';
|
|
510
|
+
html_obj += ' width="0" height="0">';
|
|
511
|
+
html_obj += '</object>';
|
|
512
|
+
|
|
513
|
+
var obj_param = [];
|
|
514
|
+
obj_param[0] = '<param name="movie" value="' + this.internal.flash.swf + '" />';
|
|
515
|
+
obj_param[1] = '<param name="quality" value="high" />';
|
|
516
|
+
obj_param[2] = '<param name="FlashVars" value="' + flashVars + '" />';
|
|
517
|
+
obj_param[3] = '<param name="allowScriptAccess" value="always" />';
|
|
518
|
+
obj_param[4] = '<param name="bgcolor" value="' + this.options.backgroundColor + '" />';
|
|
519
|
+
|
|
520
|
+
var ie_dom = document.createElement(html_obj);
|
|
521
|
+
for(var i=0; i < obj_param.length; i++) {
|
|
522
|
+
ie_dom.appendChild(document.createElement(obj_param[i]));
|
|
523
|
+
}
|
|
524
|
+
this.element.append(ie_dom);
|
|
525
|
+
} else {
|
|
526
|
+
var html_embed = '<embed name="' + this.internal.flash.id + '" id="' + this.internal.flash.id + '" src="' + this.internal.flash.swf + '"';
|
|
527
|
+
html_embed += ' width="0" height="0" bgcolor="' + this.options.backgroundColor + '"';
|
|
528
|
+
html_embed += ' quality="high" FlashVars="' + flashVars + '"';
|
|
529
|
+
html_embed += ' allowScriptAccess="always"';
|
|
530
|
+
html_embed += ' type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />';
|
|
531
|
+
this.element.append(html_embed);
|
|
532
|
+
}
|
|
533
|
+
this.internal.flash.jq = $("#" + this.internal.flash.id);
|
|
534
|
+
this.internal.flash.jq.css({'width':'0px', 'height':'0px'}); // Must do via CSS as setting attr() to zero causes a jQuery error in IE.
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// Add the HTML solution if being used.
|
|
538
|
+
if(this.html.used) {
|
|
539
|
+
|
|
540
|
+
// The HTML Audio handlers
|
|
541
|
+
if(this.html.audio.available) {
|
|
542
|
+
this._addHtmlEventListeners(this.htmlElement.audio, this.html.audio);
|
|
543
|
+
this.element.append(this.htmlElement.audio);
|
|
544
|
+
this.internal.audio.jq = $("#" + this.internal.audio.id);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// The HTML Video handlers
|
|
548
|
+
if(this.html.video.available) {
|
|
549
|
+
this._addHtmlEventListeners(this.htmlElement.video, this.html.video);
|
|
550
|
+
this.element.append(this.htmlElement.video);
|
|
551
|
+
this.internal.video.jq = $("#" + this.internal.video.id);
|
|
552
|
+
this.internal.video.jq.css({'width':'0px', 'height':'0px'}); // Using size 0x0 since a .hide() causes issues in iOS
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
if(this.html.used && !this.flash.used) { // If only HTML, then emulate flash ready() call after 100ms.
|
|
557
|
+
window.setTimeout( function() {
|
|
558
|
+
self.internal.ready = true;
|
|
559
|
+
self.version.flash = "n/a";
|
|
560
|
+
self._trigger($.jPlayer.event.ready);
|
|
561
|
+
}, 100);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// Set up the css selectors for the control and feedback entities.
|
|
565
|
+
$.each(this.options.cssSelector, function(fn, cssSel) {
|
|
566
|
+
self._cssSelector(fn, cssSel);
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
this._updateInterface();
|
|
570
|
+
this._updateButtons(false);
|
|
571
|
+
this._updateVolume(this.status.volume);
|
|
572
|
+
this._updateMute(this.status.muted);
|
|
573
|
+
if(this.css.jq.videoPlay.length) {
|
|
574
|
+
this.css.jq.videoPlay.hide();
|
|
575
|
+
}
|
|
576
|
+
$.jPlayer.prototype.count++; // Change static variable via prototype.
|
|
577
|
+
},
|
|
578
|
+
destroy: function() {
|
|
579
|
+
// MJP: The background change remains. Review later.
|
|
580
|
+
|
|
581
|
+
// Reset the interface, remove seeking effect and times.
|
|
582
|
+
this._resetStatus();
|
|
583
|
+
this._updateInterface();
|
|
584
|
+
this._seeked();
|
|
585
|
+
if(this.css.jq.currentTime.length) {
|
|
586
|
+
this.css.jq.currentTime.text("");
|
|
587
|
+
}
|
|
588
|
+
if(this.css.jq.duration.length) {
|
|
589
|
+
this.css.jq.duration.text("");
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
if(this.status.srcSet) { // Or you get a bogus error event
|
|
593
|
+
this.pause(); // Pauses the media and clears any delayed commands used in the HTML solution.
|
|
594
|
+
}
|
|
595
|
+
$.each(this.css.jq, function(fn, jq) { // Remove any bindings from the interface controls.
|
|
596
|
+
jq.unbind(".jPlayer");
|
|
597
|
+
});
|
|
598
|
+
this.element.removeData("jPlayer"); // Remove jPlayer data
|
|
599
|
+
this.element.unbind(".jPlayer"); // Remove all event handlers created by the jPlayer constructor
|
|
600
|
+
this.element.empty(); // Remove the inserted child elements
|
|
601
|
+
|
|
602
|
+
this.instances[this.internal.instance] = undefined; // Clear the instance on the static instance object
|
|
603
|
+
},
|
|
604
|
+
enable: function() { // Plan to implement
|
|
605
|
+
// options.disabled = false
|
|
606
|
+
},
|
|
607
|
+
disable: function () { // Plan to implement
|
|
608
|
+
// options.disabled = true
|
|
609
|
+
},
|
|
610
|
+
_addHtmlEventListeners: function(mediaElement, entity) {
|
|
611
|
+
var self = this;
|
|
612
|
+
mediaElement.preload = this.options.preload;
|
|
613
|
+
mediaElement.muted = this.options.muted;
|
|
614
|
+
|
|
615
|
+
// Create the event listeners
|
|
616
|
+
// Only want the active entity to affect jPlayer and bubble events.
|
|
617
|
+
// Using entity.gate so that object is referenced and gate property always current
|
|
618
|
+
|
|
619
|
+
mediaElement.addEventListener("progress", function() {
|
|
620
|
+
if(entity.gate && !self.status.waitForLoad) {
|
|
621
|
+
self._getHtmlStatus(mediaElement);
|
|
622
|
+
self._updateInterface();
|
|
623
|
+
self._trigger($.jPlayer.event.progress);
|
|
624
|
+
}
|
|
625
|
+
}, false);
|
|
626
|
+
mediaElement.addEventListener("timeupdate", function() {
|
|
627
|
+
if(entity.gate && !self.status.waitForLoad) {
|
|
628
|
+
self._getHtmlStatus(mediaElement);
|
|
629
|
+
self._updateInterface();
|
|
630
|
+
self._trigger($.jPlayer.event.timeupdate);
|
|
631
|
+
}
|
|
632
|
+
}, false);
|
|
633
|
+
mediaElement.addEventListener("durationchange", function() {
|
|
634
|
+
if(entity.gate && !self.status.waitForLoad) {
|
|
635
|
+
self.status.duration = this.duration;
|
|
636
|
+
self._getHtmlStatus(mediaElement);
|
|
637
|
+
self._updateInterface();
|
|
638
|
+
self._trigger($.jPlayer.event.durationchange);
|
|
639
|
+
}
|
|
640
|
+
}, false);
|
|
641
|
+
mediaElement.addEventListener("play", function() {
|
|
642
|
+
if(entity.gate && !self.status.waitForLoad) {
|
|
643
|
+
self._updateButtons(true);
|
|
644
|
+
self._trigger($.jPlayer.event.play);
|
|
645
|
+
}
|
|
646
|
+
}, false);
|
|
647
|
+
mediaElement.addEventListener("playing", function() {
|
|
648
|
+
if(entity.gate && !self.status.waitForLoad) {
|
|
649
|
+
self._updateButtons(true);
|
|
650
|
+
self._seeked();
|
|
651
|
+
self._trigger($.jPlayer.event.playing);
|
|
652
|
+
}
|
|
653
|
+
}, false);
|
|
654
|
+
mediaElement.addEventListener("pause", function() {
|
|
655
|
+
if(entity.gate && !self.status.waitForLoad) {
|
|
656
|
+
self._updateButtons(false);
|
|
657
|
+
self._trigger($.jPlayer.event.pause);
|
|
658
|
+
}
|
|
659
|
+
}, false);
|
|
660
|
+
mediaElement.addEventListener("waiting", function() {
|
|
661
|
+
if(entity.gate && !self.status.waitForLoad) {
|
|
662
|
+
self._seeking();
|
|
663
|
+
self._trigger($.jPlayer.event.waiting);
|
|
664
|
+
}
|
|
665
|
+
}, false);
|
|
666
|
+
mediaElement.addEventListener("canplay", function() {
|
|
667
|
+
if(entity.gate && !self.status.waitForLoad) {
|
|
668
|
+
mediaElement.volume = self._volumeFix(self.status.volume);
|
|
669
|
+
self._trigger($.jPlayer.event.canplay);
|
|
670
|
+
}
|
|
671
|
+
}, false);
|
|
672
|
+
mediaElement.addEventListener("seeking", function() {
|
|
673
|
+
if(entity.gate && !self.status.waitForLoad) {
|
|
674
|
+
self._seeking();
|
|
675
|
+
self._trigger($.jPlayer.event.seeking);
|
|
676
|
+
}
|
|
677
|
+
}, false);
|
|
678
|
+
mediaElement.addEventListener("seeked", function() {
|
|
679
|
+
if(entity.gate && !self.status.waitForLoad) {
|
|
680
|
+
self._seeked();
|
|
681
|
+
self._trigger($.jPlayer.event.seeked);
|
|
682
|
+
}
|
|
683
|
+
}, false);
|
|
684
|
+
mediaElement.addEventListener("suspend", function() { // Seems to be the only way of capturing that the iOS4 browser did not actually play the media from the page code. ie., It needs a user gesture.
|
|
685
|
+
if(entity.gate && !self.status.waitForLoad) {
|
|
686
|
+
self._seeked();
|
|
687
|
+
self._trigger($.jPlayer.event.suspend);
|
|
688
|
+
}
|
|
689
|
+
}, false);
|
|
690
|
+
mediaElement.addEventListener("ended", function() {
|
|
691
|
+
if(entity.gate && !self.status.waitForLoad) {
|
|
692
|
+
// Order of the next few commands are important. Change the time and then pause.
|
|
693
|
+
// Solves a bug in Firefox, where issuing pause 1st causes the media to play from the start. ie., The pause is ignored.
|
|
694
|
+
if(!$.jPlayer.browser.webkit) { // Chrome crashes if you do this in conjunction with a setMedia command in an ended event handler. ie., The playlist demo.
|
|
695
|
+
self.htmlElement.media.currentTime = 0; // Safari does not care about this command. ie., It works with or without this line. (Both Safari and Chrome are Webkit.)
|
|
696
|
+
}
|
|
697
|
+
self.htmlElement.media.pause(); // Pause otherwise a click on the progress bar will play from that point, when it shouldn't, since it stopped playback.
|
|
698
|
+
self._updateButtons(false);
|
|
699
|
+
self._getHtmlStatus(mediaElement, true); // With override true. Otherwise Chrome leaves progress at full.
|
|
700
|
+
self._updateInterface();
|
|
701
|
+
self._trigger($.jPlayer.event.ended);
|
|
702
|
+
}
|
|
703
|
+
}, false);
|
|
704
|
+
mediaElement.addEventListener("error", function() {
|
|
705
|
+
if(entity.gate && !self.status.waitForLoad) {
|
|
706
|
+
self._updateButtons(false);
|
|
707
|
+
self._seeked();
|
|
708
|
+
if(self.status.srcSet) { // Deals with case of clearMedia() causing an error event.
|
|
709
|
+
self.status.waitForLoad = true; // Allows the load operation to try again.
|
|
710
|
+
self.status.waitForPlay = true; // Reset since a play was captured.
|
|
711
|
+
if(self.status.video) {
|
|
712
|
+
self.internal.video.jq.css({'width':'0px', 'height':'0px'});
|
|
713
|
+
}
|
|
714
|
+
if(self._validString(self.status.media.poster)) {
|
|
715
|
+
self.internal.poster.jq.show();
|
|
716
|
+
}
|
|
717
|
+
if(self.css.jq.videoPlay.length) {
|
|
718
|
+
self.css.jq.videoPlay.show();
|
|
719
|
+
}
|
|
720
|
+
self._error( {
|
|
721
|
+
type: $.jPlayer.error.URL,
|
|
722
|
+
context: self.status.src, // this.src shows absolute urls. Want context to show the url given.
|
|
723
|
+
message: $.jPlayer.errorMsg.URL,
|
|
724
|
+
hint: $.jPlayer.errorHint.URL
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
}, false);
|
|
729
|
+
// Create all the other event listeners that bubble up to a jPlayer event from html, without being used by jPlayer.
|
|
730
|
+
$.each($.jPlayer.htmlEvent, function(i, eventType) {
|
|
731
|
+
mediaElement.addEventListener(this, function() {
|
|
732
|
+
if(entity.gate && !self.status.waitForLoad) {
|
|
733
|
+
self._trigger($.jPlayer.event[eventType]);
|
|
734
|
+
}
|
|
735
|
+
}, false);
|
|
736
|
+
});
|
|
737
|
+
},
|
|
738
|
+
_getHtmlStatus: function(media, override) {
|
|
739
|
+
var ct = 0, d = 0, cpa = 0, sp = 0, cpr = 0;
|
|
740
|
+
|
|
741
|
+
ct = media.currentTime;
|
|
742
|
+
cpa = (this.status.duration > 0) ? 100 * ct / this.status.duration : 0;
|
|
743
|
+
if((typeof media.seekable === "object") && (media.seekable.length > 0)) {
|
|
744
|
+
sp = (this.status.duration > 0) ? 100 * media.seekable.end(media.seekable.length-1) / this.status.duration : 100;
|
|
745
|
+
cpr = 100 * media.currentTime / media.seekable.end(media.seekable.length-1);
|
|
746
|
+
} else {
|
|
747
|
+
sp = 100;
|
|
748
|
+
cpr = cpa;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
if(override) {
|
|
752
|
+
ct = 0;
|
|
753
|
+
cpr = 0;
|
|
754
|
+
cpa = 0;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
this.status.seekPercent = sp;
|
|
758
|
+
this.status.currentPercentRelative = cpr;
|
|
759
|
+
this.status.currentPercentAbsolute = cpa;
|
|
760
|
+
this.status.currentTime = ct;
|
|
761
|
+
},
|
|
762
|
+
_resetStatus: function() {
|
|
763
|
+
var self = this;
|
|
764
|
+
this.status = $.extend({}, this.status, $.jPlayer.prototype.status); // Maintains the status properties that persist through a reset. ie., The properties of this._status, contained in the current this.status.
|
|
765
|
+
|
|
766
|
+
},
|
|
767
|
+
_trigger: function(eventType, error, warning) { // eventType always valid as called using $.jPlayer.event.eventType
|
|
768
|
+
var event = $.Event(eventType);
|
|
769
|
+
event.jPlayer = {};
|
|
770
|
+
event.jPlayer.version = $.extend({}, this.version);
|
|
771
|
+
event.jPlayer.status = $.extend(true, {}, this.status); // Deep copy
|
|
772
|
+
event.jPlayer.html = $.extend(true, {}, this.html); // Deep copy
|
|
773
|
+
event.jPlayer.flash = $.extend(true, {}, this.flash); // Deep copy
|
|
774
|
+
if(error) event.jPlayer.error = $.extend({}, error);
|
|
775
|
+
if(warning) event.jPlayer.warning = $.extend({}, warning);
|
|
776
|
+
this.element.trigger(event);
|
|
777
|
+
},
|
|
778
|
+
jPlayerFlashEvent: function(eventType, status) { // Called from Flash
|
|
779
|
+
if(eventType === $.jPlayer.event.ready && !this.internal.ready) {
|
|
780
|
+
this.internal.ready = true;
|
|
781
|
+
this.version.flash = status.version;
|
|
782
|
+
if(this.version.needFlash !== this.version.flash) {
|
|
783
|
+
this._error( {
|
|
784
|
+
type: $.jPlayer.error.VERSION,
|
|
785
|
+
context: this.version.flash,
|
|
786
|
+
message: $.jPlayer.errorMsg.VERSION + this.version.flash,
|
|
787
|
+
hint: $.jPlayer.errorHint.VERSION
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
this._trigger(eventType);
|
|
791
|
+
}
|
|
792
|
+
if(this.flash.gate) {
|
|
793
|
+
switch(eventType) {
|
|
794
|
+
case $.jPlayer.event.progress:
|
|
795
|
+
this._getFlashStatus(status);
|
|
796
|
+
this._updateInterface();
|
|
797
|
+
this._trigger(eventType);
|
|
798
|
+
break;
|
|
799
|
+
case $.jPlayer.event.timeupdate:
|
|
800
|
+
this._getFlashStatus(status);
|
|
801
|
+
this._updateInterface();
|
|
802
|
+
this._trigger(eventType);
|
|
803
|
+
break;
|
|
804
|
+
case $.jPlayer.event.play:
|
|
805
|
+
this._seeked();
|
|
806
|
+
this._updateButtons(true);
|
|
807
|
+
this._trigger(eventType);
|
|
808
|
+
break;
|
|
809
|
+
case $.jPlayer.event.pause:
|
|
810
|
+
this._updateButtons(false);
|
|
811
|
+
this._trigger(eventType);
|
|
812
|
+
break;
|
|
813
|
+
case $.jPlayer.event.ended:
|
|
814
|
+
this._updateButtons(false);
|
|
815
|
+
this._trigger(eventType);
|
|
816
|
+
break;
|
|
817
|
+
case $.jPlayer.event.error:
|
|
818
|
+
this.status.waitForLoad = true; // Allows the load operation to try again.
|
|
819
|
+
this.status.waitForPlay = true; // Reset since a play was captured.
|
|
820
|
+
if(this.status.video) {
|
|
821
|
+
this.internal.flash.jq.css({'width':'0px', 'height':'0px'});
|
|
822
|
+
}
|
|
823
|
+
if(this._validString(this.status.media.poster)) {
|
|
824
|
+
this.internal.poster.jq.show();
|
|
825
|
+
}
|
|
826
|
+
if(this.css.jq.videoPlay.length) {
|
|
827
|
+
this.css.jq.videoPlay.show();
|
|
828
|
+
}
|
|
829
|
+
if(this.status.video) { // Set up for another try. Execute before error event.
|
|
830
|
+
this._flash_setVideo(this.status.media);
|
|
831
|
+
} else {
|
|
832
|
+
this._flash_setAudio(this.status.media);
|
|
833
|
+
}
|
|
834
|
+
this._error( {
|
|
835
|
+
type: $.jPlayer.error.URL,
|
|
836
|
+
context:status.src,
|
|
837
|
+
message: $.jPlayer.errorMsg.URL,
|
|
838
|
+
hint: $.jPlayer.errorHint.URL
|
|
839
|
+
});
|
|
840
|
+
break;
|
|
841
|
+
case $.jPlayer.event.seeking:
|
|
842
|
+
this._seeking();
|
|
843
|
+
this._trigger(eventType);
|
|
844
|
+
break;
|
|
845
|
+
case $.jPlayer.event.seeked:
|
|
846
|
+
this._seeked();
|
|
847
|
+
this._trigger(eventType);
|
|
848
|
+
break;
|
|
849
|
+
default:
|
|
850
|
+
this._trigger(eventType);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
return false;
|
|
854
|
+
},
|
|
855
|
+
_getFlashStatus: function(status) {
|
|
856
|
+
this.status.seekPercent = status.seekPercent;
|
|
857
|
+
this.status.currentPercentRelative = status.currentPercentRelative;
|
|
858
|
+
this.status.currentPercentAbsolute = status.currentPercentAbsolute;
|
|
859
|
+
this.status.currentTime = status.currentTime;
|
|
860
|
+
this.status.duration = status.duration;
|
|
861
|
+
},
|
|
862
|
+
_updateButtons: function(playing) {
|
|
863
|
+
this.status.paused = !playing;
|
|
864
|
+
if(this.css.jq.play.length && this.css.jq.pause.length) {
|
|
865
|
+
if(playing) {
|
|
866
|
+
this.css.jq.play.hide();
|
|
867
|
+
this.css.jq.pause.show();
|
|
868
|
+
} else {
|
|
869
|
+
this.css.jq.play.show();
|
|
870
|
+
this.css.jq.pause.hide();
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
},
|
|
874
|
+
_updateInterface: function() {
|
|
875
|
+
if(this.css.jq.seekBar.length) {
|
|
876
|
+
this.css.jq.seekBar.width(this.status.seekPercent+"%");
|
|
877
|
+
}
|
|
878
|
+
if(this.css.jq.playBar.length) {
|
|
879
|
+
this.css.jq.playBar.width(this.status.currentPercentRelative+"%");
|
|
880
|
+
}
|
|
881
|
+
if(this.css.jq.currentTime.length) {
|
|
882
|
+
this.css.jq.currentTime.text($.jPlayer.convertTime(this.status.currentTime));
|
|
883
|
+
}
|
|
884
|
+
if(this.css.jq.duration.length) {
|
|
885
|
+
this.css.jq.duration.text($.jPlayer.convertTime(this.status.duration));
|
|
886
|
+
}
|
|
887
|
+
},
|
|
888
|
+
_seeking: function() {
|
|
889
|
+
if(this.css.jq.seekBar.length) {
|
|
890
|
+
this.css.jq.seekBar.addClass("jp-seeking-bg");
|
|
891
|
+
}
|
|
892
|
+
},
|
|
893
|
+
_seeked: function() {
|
|
894
|
+
if(this.css.jq.seekBar.length) {
|
|
895
|
+
this.css.jq.seekBar.removeClass("jp-seeking-bg");
|
|
896
|
+
}
|
|
897
|
+
},
|
|
898
|
+
setMedia: function(media) {
|
|
899
|
+
|
|
900
|
+
/* media[format] = String: URL of format. Must contain all of the supplied option's video or audio formats.
|
|
901
|
+
* media.poster = String: Video poster URL.
|
|
902
|
+
* media.subtitles = String: * NOT IMPLEMENTED * URL of subtitles SRT file
|
|
903
|
+
* media.chapters = String: * NOT IMPLEMENTED * URL of chapters SRT file
|
|
904
|
+
* media.stream = Boolean: * NOT IMPLEMENTED * Designating actual media streams. ie., "false/undefined" for files. Plan to refresh the flash every so often.
|
|
905
|
+
*/
|
|
906
|
+
|
|
907
|
+
var self = this;
|
|
908
|
+
|
|
909
|
+
this._seeked();
|
|
910
|
+
clearTimeout(this.internal.htmlDlyCmdId); // Clears any delayed commands used in the HTML solution.
|
|
911
|
+
|
|
912
|
+
// Store the current html gates, since we need for clearMedia() conditions.
|
|
913
|
+
var audioGate = this.html.audio.gate;
|
|
914
|
+
var videoGate = this.html.video.gate;
|
|
915
|
+
|
|
916
|
+
var supported = false;
|
|
917
|
+
$.each(this.formats, function(formatPriority, format) {
|
|
918
|
+
var isVideo = self.format[format].media === 'video';
|
|
919
|
+
$.each(self.solutions, function(solutionPriority, solution) {
|
|
920
|
+
if(self[solution].support[format] && self._validString(media[format])) { // Format supported in solution and url given for format.
|
|
921
|
+
var isHtml = solution === 'html';
|
|
922
|
+
|
|
923
|
+
if(isVideo) {
|
|
924
|
+
if(isHtml) {
|
|
925
|
+
self.html.audio.gate = false;
|
|
926
|
+
self.html.video.gate = true;
|
|
927
|
+
self.flash.gate = false;
|
|
928
|
+
} else {
|
|
929
|
+
self.html.audio.gate = false;
|
|
930
|
+
self.html.video.gate = false;
|
|
931
|
+
self.flash.gate = true;
|
|
932
|
+
}
|
|
933
|
+
} else {
|
|
934
|
+
if(isHtml) {
|
|
935
|
+
self.html.audio.gate = true;
|
|
936
|
+
self.html.video.gate = false;
|
|
937
|
+
self.flash.gate = false;
|
|
938
|
+
} else {
|
|
939
|
+
self.html.audio.gate = false;
|
|
940
|
+
self.html.video.gate = false;
|
|
941
|
+
self.flash.gate = true;
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
// Clear media of the previous solution if:
|
|
946
|
+
// - it was Flash
|
|
947
|
+
// - changing from HTML to Flash
|
|
948
|
+
// - the HTML solution media type (audio or video) remained the same.
|
|
949
|
+
// Note that, we must be careful with clearMedia() on iPhone, otherwise clearing the video when changing to audio corrupts the built in video player.
|
|
950
|
+
if(self.flash.active || (self.html.active && self.flash.gate) || (audioGate === self.html.audio.gate && videoGate === self.html.video.gate)) {
|
|
951
|
+
self.clearMedia();
|
|
952
|
+
} else if(audioGate !== self.html.audio.gate && videoGate !== self.html.video.gate) { // If switching between html elements
|
|
953
|
+
self._html_pause();
|
|
954
|
+
// Hide the video if it was being used.
|
|
955
|
+
if(self.status.video) {
|
|
956
|
+
self.internal.video.jq.css({'width':'0px', 'height':'0px'});
|
|
957
|
+
}
|
|
958
|
+
self._resetStatus(); // Since clearMedia usually does this. Execute after status.video useage.
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
if(isVideo) {
|
|
962
|
+
if(isHtml) {
|
|
963
|
+
self._html_setVideo(media);
|
|
964
|
+
self.html.active = true;
|
|
965
|
+
self.flash.active = false;
|
|
966
|
+
} else {
|
|
967
|
+
self._flash_setVideo(media);
|
|
968
|
+
self.html.active = false;
|
|
969
|
+
self.flash.active = true;
|
|
970
|
+
}
|
|
971
|
+
if(self.css.jq.videoPlay.length) {
|
|
972
|
+
self.css.jq.videoPlay.show();
|
|
973
|
+
}
|
|
974
|
+
self.status.video = true;
|
|
975
|
+
} else {
|
|
976
|
+
if(isHtml) {
|
|
977
|
+
self._html_setAudio(media);
|
|
978
|
+
self.html.active = true;
|
|
979
|
+
self.flash.active = false;
|
|
980
|
+
} else {
|
|
981
|
+
self._flash_setAudio(media);
|
|
982
|
+
self.html.active = false;
|
|
983
|
+
self.flash.active = true;
|
|
984
|
+
}
|
|
985
|
+
if(self.css.jq.videoPlay.length) {
|
|
986
|
+
self.css.jq.videoPlay.hide();
|
|
987
|
+
}
|
|
988
|
+
self.status.video = false;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
supported = true;
|
|
992
|
+
return false; // Exit $.each
|
|
993
|
+
}
|
|
994
|
+
});
|
|
995
|
+
if(supported) {
|
|
996
|
+
return false; // Exit $.each
|
|
997
|
+
}
|
|
998
|
+
});
|
|
999
|
+
|
|
1000
|
+
if(supported) {
|
|
1001
|
+
// Set poster after the possible clearMedia() command above. IE had issues since the IMG onload event occurred immediately when cached. ie., The clearMedia() hide the poster.
|
|
1002
|
+
if(this._validString(media.poster)) {
|
|
1003
|
+
if(this.htmlElement.poster.src !== media.poster) { // Since some browsers do not generate img onload event.
|
|
1004
|
+
this.htmlElement.poster.src = media.poster;
|
|
1005
|
+
} else {
|
|
1006
|
+
this.internal.poster.jq.show();
|
|
1007
|
+
}
|
|
1008
|
+
} else {
|
|
1009
|
+
this.internal.poster.jq.hide(); // Hide if not used, since clearMedia() does not always occur above. ie., HTML audio <-> video switching.
|
|
1010
|
+
}
|
|
1011
|
+
this.status.srcSet = true;
|
|
1012
|
+
this.status.media = $.extend({}, media);
|
|
1013
|
+
this._updateButtons(false);
|
|
1014
|
+
this._updateInterface();
|
|
1015
|
+
} else { // jPlayer cannot support any formats provided in this browser
|
|
1016
|
+
// Pause here if old media could be playing. Otherwise, playing media being changed to bad media would leave the old media playing.
|
|
1017
|
+
if(this.status.srcSet && !this.status.waitForPlay) {
|
|
1018
|
+
this.pause();
|
|
1019
|
+
}
|
|
1020
|
+
// Reset all the control flags
|
|
1021
|
+
this.html.audio.gate = false;
|
|
1022
|
+
this.html.video.gate = false;
|
|
1023
|
+
this.flash.gate = false;
|
|
1024
|
+
this.html.active = false;
|
|
1025
|
+
this.flash.active = false;
|
|
1026
|
+
// Reset status and interface.
|
|
1027
|
+
this._resetStatus();
|
|
1028
|
+
this._updateInterface();
|
|
1029
|
+
this._updateButtons(false);
|
|
1030
|
+
// Hide the any old media
|
|
1031
|
+
this.internal.poster.jq.hide();
|
|
1032
|
+
if(this.html.used && this.require.video) {
|
|
1033
|
+
this.internal.video.jq.css({'width':'0px', 'height':'0px'});
|
|
1034
|
+
}
|
|
1035
|
+
if(this.flash.used) {
|
|
1036
|
+
this.internal.flash.jq.css({'width':'0px', 'height':'0px'});
|
|
1037
|
+
}
|
|
1038
|
+
// Send an error event
|
|
1039
|
+
this._error( {
|
|
1040
|
+
type: $.jPlayer.error.NO_SUPPORT,
|
|
1041
|
+
context: "{supplied:'" + this.options.supplied + "'}",
|
|
1042
|
+
message: $.jPlayer.errorMsg.NO_SUPPORT,
|
|
1043
|
+
hint: $.jPlayer.errorHint.NO_SUPPORT
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
},
|
|
1047
|
+
clearMedia: function() {
|
|
1048
|
+
this._resetStatus();
|
|
1049
|
+
this._updateButtons(false);
|
|
1050
|
+
|
|
1051
|
+
this.internal.poster.jq.hide();
|
|
1052
|
+
|
|
1053
|
+
clearTimeout(this.internal.htmlDlyCmdId);
|
|
1054
|
+
|
|
1055
|
+
if(this.html.active) {
|
|
1056
|
+
this._html_clearMedia();
|
|
1057
|
+
} else if(this.flash.active) {
|
|
1058
|
+
this._flash_clearMedia();
|
|
1059
|
+
}
|
|
1060
|
+
},
|
|
1061
|
+
load: function() {
|
|
1062
|
+
if(this.status.srcSet) {
|
|
1063
|
+
if(this.html.active) {
|
|
1064
|
+
this._html_load();
|
|
1065
|
+
} else if(this.flash.active) {
|
|
1066
|
+
this._flash_load();
|
|
1067
|
+
}
|
|
1068
|
+
} else {
|
|
1069
|
+
this._urlNotSetError("load");
|
|
1070
|
+
}
|
|
1071
|
+
},
|
|
1072
|
+
play: function(time) {
|
|
1073
|
+
time = (typeof time === "number") ? time : NaN; // Remove jQuery event from click handler
|
|
1074
|
+
if(this.status.srcSet) {
|
|
1075
|
+
if(this.html.active) {
|
|
1076
|
+
this._html_play(time);
|
|
1077
|
+
} else if(this.flash.active) {
|
|
1078
|
+
this._flash_play(time);
|
|
1079
|
+
}
|
|
1080
|
+
} else {
|
|
1081
|
+
this._urlNotSetError("play");
|
|
1082
|
+
}
|
|
1083
|
+
},
|
|
1084
|
+
videoPlay: function(e) { // Handles clicks on the play button over the video poster
|
|
1085
|
+
this.play();
|
|
1086
|
+
},
|
|
1087
|
+
pause: function(time) {
|
|
1088
|
+
time = (typeof time === "number") ? time : NaN; // Remove jQuery event from click handler
|
|
1089
|
+
if(this.status.srcSet) {
|
|
1090
|
+
if(this.html.active) {
|
|
1091
|
+
this._html_pause(time);
|
|
1092
|
+
} else if(this.flash.active) {
|
|
1093
|
+
this._flash_pause(time);
|
|
1094
|
+
}
|
|
1095
|
+
} else {
|
|
1096
|
+
this._urlNotSetError("pause");
|
|
1097
|
+
}
|
|
1098
|
+
},
|
|
1099
|
+
pauseOthers: function() {
|
|
1100
|
+
var self = this;
|
|
1101
|
+
$.each(this.instances, function(i, element) {
|
|
1102
|
+
if(self.element !== element) { // Do not this instance.
|
|
1103
|
+
if(element.data("jPlayer").status.srcSet) { // Check that media is set otherwise would cause error event.
|
|
1104
|
+
element.jPlayer("pause");
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
});
|
|
1108
|
+
},
|
|
1109
|
+
stop: function() {
|
|
1110
|
+
if(this.status.srcSet) {
|
|
1111
|
+
if(this.html.active) {
|
|
1112
|
+
this._html_pause(0);
|
|
1113
|
+
} else if(this.flash.active) {
|
|
1114
|
+
this._flash_pause(0);
|
|
1115
|
+
}
|
|
1116
|
+
} else {
|
|
1117
|
+
this._urlNotSetError("stop");
|
|
1118
|
+
}
|
|
1119
|
+
},
|
|
1120
|
+
playHead: function(p) {
|
|
1121
|
+
p = this._limitValue(p, 0, 100);
|
|
1122
|
+
if(this.status.srcSet) {
|
|
1123
|
+
if(this.html.active) {
|
|
1124
|
+
this._html_playHead(p);
|
|
1125
|
+
} else if(this.flash.active) {
|
|
1126
|
+
this._flash_playHead(p);
|
|
1127
|
+
}
|
|
1128
|
+
} else {
|
|
1129
|
+
this._urlNotSetError("playHead");
|
|
1130
|
+
}
|
|
1131
|
+
},
|
|
1132
|
+
mute: function() {
|
|
1133
|
+
this.status.muted = true;
|
|
1134
|
+
if(this.html.used) {
|
|
1135
|
+
this._html_mute(true);
|
|
1136
|
+
}
|
|
1137
|
+
if(this.flash.used) {
|
|
1138
|
+
this._flash_mute(true);
|
|
1139
|
+
}
|
|
1140
|
+
this._updateMute(true);
|
|
1141
|
+
this._updateVolume(0);
|
|
1142
|
+
this._trigger($.jPlayer.event.volumechange);
|
|
1143
|
+
},
|
|
1144
|
+
unmute: function() {
|
|
1145
|
+
this.status.muted = false;
|
|
1146
|
+
if(this.html.used) {
|
|
1147
|
+
this._html_mute(false);
|
|
1148
|
+
}
|
|
1149
|
+
if(this.flash.used) {
|
|
1150
|
+
this._flash_mute(false);
|
|
1151
|
+
}
|
|
1152
|
+
this._updateMute(false);
|
|
1153
|
+
this._updateVolume(this.status.volume);
|
|
1154
|
+
this._trigger($.jPlayer.event.volumechange);
|
|
1155
|
+
},
|
|
1156
|
+
_updateMute: function(mute) {
|
|
1157
|
+
if(this.css.jq.mute.length && this.css.jq.unmute.length) {
|
|
1158
|
+
if(mute) {
|
|
1159
|
+
this.css.jq.mute.hide();
|
|
1160
|
+
this.css.jq.unmute.show();
|
|
1161
|
+
} else {
|
|
1162
|
+
this.css.jq.mute.show();
|
|
1163
|
+
this.css.jq.unmute.hide();
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
},
|
|
1167
|
+
volume: function(v) {
|
|
1168
|
+
v = this._limitValue(v, 0, 1);
|
|
1169
|
+
this.status.volume = v;
|
|
1170
|
+
|
|
1171
|
+
if(this.html.used) {
|
|
1172
|
+
this._html_volume(v);
|
|
1173
|
+
}
|
|
1174
|
+
if(this.flash.used) {
|
|
1175
|
+
this._flash_volume(v);
|
|
1176
|
+
}
|
|
1177
|
+
if(!this.status.muted) {
|
|
1178
|
+
this._updateVolume(v);
|
|
1179
|
+
}
|
|
1180
|
+
this._trigger($.jPlayer.event.volumechange);
|
|
1181
|
+
},
|
|
1182
|
+
volumeBar: function(e) { // Handles clicks on the volumeBar
|
|
1183
|
+
if(!this.status.muted && this.css.jq.volumeBar) { // Ignore clicks when muted
|
|
1184
|
+
var offset = this.css.jq.volumeBar.offset();
|
|
1185
|
+
var x = e.pageX - offset.left;
|
|
1186
|
+
var w = this.css.jq.volumeBar.width();
|
|
1187
|
+
var v = x/w;
|
|
1188
|
+
this.volume(v);
|
|
1189
|
+
}
|
|
1190
|
+
},
|
|
1191
|
+
volumeBarValue: function(e) { // Handles clicks on the volumeBarValue
|
|
1192
|
+
this.volumeBar(e);
|
|
1193
|
+
},
|
|
1194
|
+
_updateVolume: function(v) {
|
|
1195
|
+
if(this.css.jq.volumeBarValue.length) {
|
|
1196
|
+
this.css.jq.volumeBarValue.width((v*100)+"%");
|
|
1197
|
+
}
|
|
1198
|
+
},
|
|
1199
|
+
_volumeFix: function(v) { // Need to review if this is still necessary on latest Chrome
|
|
1200
|
+
var rnd = 0.001 * Math.random(); // Fix for Chrome 4: Fix volume being set multiple times before playing bug.
|
|
1201
|
+
var fix = (v < 0.5) ? rnd : -rnd; // Fix for Chrome 4: Solves volume change before play bug. (When new vol == old vol Chrome 4 does nothing!)
|
|
1202
|
+
return (v + fix); // Fix for Chrome 4: Event solves initial volume not being set correctly.
|
|
1203
|
+
},
|
|
1204
|
+
_cssSelectorAncestor: function(ancestor, refresh) {
|
|
1205
|
+
this.options.cssSelectorAncestor = ancestor;
|
|
1206
|
+
if(refresh) {
|
|
1207
|
+
$.each(this.options.cssSelector, function(fn, cssSel) {
|
|
1208
|
+
self._cssSelector(fn, cssSel);
|
|
1209
|
+
});
|
|
1210
|
+
}
|
|
1211
|
+
},
|
|
1212
|
+
_cssSelector: function(fn, cssSel) {
|
|
1213
|
+
var self = this;
|
|
1214
|
+
if(typeof cssSel === 'string') {
|
|
1215
|
+
if($.jPlayer.prototype.options.cssSelector[fn]) {
|
|
1216
|
+
if(this.css.jq[fn] && this.css.jq[fn].length) {
|
|
1217
|
+
this.css.jq[fn].unbind(".jPlayer");
|
|
1218
|
+
}
|
|
1219
|
+
this.options.cssSelector[fn] = cssSel;
|
|
1220
|
+
this.css.cs[fn] = this.options.cssSelectorAncestor + " " + cssSel;
|
|
1221
|
+
|
|
1222
|
+
if(cssSel) { // Checks for empty string
|
|
1223
|
+
this.css.jq[fn] = $(this.css.cs[fn]);
|
|
1224
|
+
} else {
|
|
1225
|
+
this.css.jq[fn] = []; // To comply with the css.jq[fn].length check before its use. As of jQuery 1.4 could have used $() for an empty set.
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
if(this.css.jq[fn].length) {
|
|
1229
|
+
var handler = function(e) {
|
|
1230
|
+
self[fn](e);
|
|
1231
|
+
$(this).blur();
|
|
1232
|
+
return false;
|
|
1233
|
+
}
|
|
1234
|
+
this.css.jq[fn].bind("click.jPlayer", handler); // Using jPlayer namespace
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
if(cssSel && this.css.jq[fn].length !== 1) { // So empty strings do not generate the warning. ie., they just remove the old one.
|
|
1238
|
+
this._warning( {
|
|
1239
|
+
type: $.jPlayer.warning.CSS_SELECTOR_COUNT,
|
|
1240
|
+
context: this.css.cs[fn],
|
|
1241
|
+
message: $.jPlayer.warningMsg.CSS_SELECTOR_COUNT + this.css.jq[fn].length + " found for " + fn + " method.",
|
|
1242
|
+
hint: $.jPlayer.warningHint.CSS_SELECTOR_COUNT
|
|
1243
|
+
});
|
|
1244
|
+
}
|
|
1245
|
+
} else {
|
|
1246
|
+
this._warning( {
|
|
1247
|
+
type: $.jPlayer.warning.CSS_SELECTOR_METHOD,
|
|
1248
|
+
context: fn,
|
|
1249
|
+
message: $.jPlayer.warningMsg.CSS_SELECTOR_METHOD,
|
|
1250
|
+
hint: $.jPlayer.warningHint.CSS_SELECTOR_METHOD
|
|
1251
|
+
});
|
|
1252
|
+
}
|
|
1253
|
+
} else {
|
|
1254
|
+
this._warning( {
|
|
1255
|
+
type: $.jPlayer.warning.CSS_SELECTOR_STRING,
|
|
1256
|
+
context: cssSel,
|
|
1257
|
+
message: $.jPlayer.warningMsg.CSS_SELECTOR_STRING,
|
|
1258
|
+
hint: $.jPlayer.warningHint.CSS_SELECTOR_STRING
|
|
1259
|
+
});
|
|
1260
|
+
}
|
|
1261
|
+
},
|
|
1262
|
+
seekBar: function(e) { // Handles clicks on the seekBar
|
|
1263
|
+
if(this.css.jq.seekBar) {
|
|
1264
|
+
var offset = this.css.jq.seekBar.offset();
|
|
1265
|
+
var x = e.pageX - offset.left;
|
|
1266
|
+
var w = this.css.jq.seekBar.width();
|
|
1267
|
+
var p = 100*x/w;
|
|
1268
|
+
this.playHead(p);
|
|
1269
|
+
}
|
|
1270
|
+
},
|
|
1271
|
+
playBar: function(e) { // Handles clicks on the playBar
|
|
1272
|
+
this.seekBar(e);
|
|
1273
|
+
},
|
|
1274
|
+
currentTime: function(e) { // Handles clicks on the text
|
|
1275
|
+
// Added to avoid errors using cssSelector system for the text
|
|
1276
|
+
},
|
|
1277
|
+
duration: function(e) { // Handles clicks on the text
|
|
1278
|
+
// Added to avoid errors using cssSelector system for the text
|
|
1279
|
+
},
|
|
1280
|
+
// Options code adapted from ui.widget.js (1.8.7). Made changes so the key can use dot notation. To match previous getData solution in jPlayer 1.
|
|
1281
|
+
option: function(key, value) {
|
|
1282
|
+
var options = key;
|
|
1283
|
+
|
|
1284
|
+
// Enables use: options(). Returns a copy of options object
|
|
1285
|
+
if ( arguments.length === 0 ) {
|
|
1286
|
+
return $.extend( true, {}, this.options );
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
if(typeof key === "string") {
|
|
1290
|
+
var keys = key.split(".");
|
|
1291
|
+
|
|
1292
|
+
// Enables use: options("someOption") Returns a copy of the option. Supports dot notation.
|
|
1293
|
+
if(value === undefined) {
|
|
1294
|
+
|
|
1295
|
+
var opt = $.extend(true, {}, this.options);
|
|
1296
|
+
for(var i = 0; i < keys.length; i++) {
|
|
1297
|
+
if(opt[keys[i]] !== undefined) {
|
|
1298
|
+
opt = opt[keys[i]];
|
|
1299
|
+
} else {
|
|
1300
|
+
this._warning( {
|
|
1301
|
+
type: $.jPlayer.warning.OPTION_KEY,
|
|
1302
|
+
context: key,
|
|
1303
|
+
message: $.jPlayer.warningMsg.OPTION_KEY,
|
|
1304
|
+
hint: $.jPlayer.warningHint.OPTION_KEY
|
|
1305
|
+
});
|
|
1306
|
+
return undefined;
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
return opt;
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
// Enables use: options("someOptionObject", someObject}). Creates: {someOptionObject:someObject}
|
|
1313
|
+
// Enables use: options("someOption", someValue). Creates: {someOption:someValue}
|
|
1314
|
+
// Enables use: options("someOptionObject.someOption", someValue). Creates: {someOptionObject:{someOption:someValue}}
|
|
1315
|
+
|
|
1316
|
+
options = {};
|
|
1317
|
+
var opt = options;
|
|
1318
|
+
|
|
1319
|
+
for(var i = 0; i < keys.length; i++) {
|
|
1320
|
+
if(i < keys.length - 1) {
|
|
1321
|
+
opt[keys[i]] = {};
|
|
1322
|
+
opt = opt[keys[i]];
|
|
1323
|
+
} else {
|
|
1324
|
+
opt[keys[i]] = value;
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
// Otherwise enables use: options(optionObject). Uses original object (the key)
|
|
1330
|
+
|
|
1331
|
+
this._setOptions(options);
|
|
1332
|
+
|
|
1333
|
+
return this;
|
|
1334
|
+
},
|
|
1335
|
+
_setOptions: function(options) {
|
|
1336
|
+
var self = this;
|
|
1337
|
+
$.each(options, function(key, value) { // This supports the 2 level depth that the options of jPlayer has. Would review if we ever need more depth.
|
|
1338
|
+
self._setOption(key, value);
|
|
1339
|
+
});
|
|
1340
|
+
|
|
1341
|
+
return this;
|
|
1342
|
+
},
|
|
1343
|
+
_setOption: function(key, value) {
|
|
1344
|
+
var self = this;
|
|
1345
|
+
|
|
1346
|
+
// The ability to set options is limited at this time.
|
|
1347
|
+
|
|
1348
|
+
switch(key) {
|
|
1349
|
+
case "cssSelectorAncestor" :
|
|
1350
|
+
this.options[key] = value;
|
|
1351
|
+
$.each(self.options.cssSelector, function(fn, cssSel) { // Refresh all associations for new ancestor.
|
|
1352
|
+
self._cssSelector(fn, cssSel);
|
|
1353
|
+
});
|
|
1354
|
+
break;
|
|
1355
|
+
case "cssSelector" :
|
|
1356
|
+
$.each(value, function(fn, cssSel) {
|
|
1357
|
+
self._cssSelector(fn, cssSel);
|
|
1358
|
+
});
|
|
1359
|
+
break;
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
return this;
|
|
1363
|
+
},
|
|
1364
|
+
// End of: (Options code adapted from ui.widget.js)
|
|
1365
|
+
|
|
1366
|
+
// The resize() set of functions are not implemented yet.
|
|
1367
|
+
// Basically are currently used to allow Flash debugging without too much hassle.
|
|
1368
|
+
resize: function(css) {
|
|
1369
|
+
// MJP: Want to run some checks on dim {} first.
|
|
1370
|
+
if(this.html.active) {
|
|
1371
|
+
this._resizeHtml(css);
|
|
1372
|
+
}
|
|
1373
|
+
if(this.flash.active) {
|
|
1374
|
+
this._resizeFlash(css);
|
|
1375
|
+
}
|
|
1376
|
+
this._trigger($.jPlayer.event.resize);
|
|
1377
|
+
},
|
|
1378
|
+
_resizePoster: function(css) {
|
|
1379
|
+
// Not implemented yet
|
|
1380
|
+
},
|
|
1381
|
+
_resizeHtml: function(css) {
|
|
1382
|
+
// Not implemented yet
|
|
1383
|
+
},
|
|
1384
|
+
_resizeFlash: function(css) {
|
|
1385
|
+
this.internal.flash.jq.css({'width':css.width, 'height':css.height});
|
|
1386
|
+
},
|
|
1387
|
+
|
|
1388
|
+
_html_initMedia: function() {
|
|
1389
|
+
if(this.status.srcSet && !this.status.waitForPlay) {
|
|
1390
|
+
this.htmlElement.media.pause();
|
|
1391
|
+
}
|
|
1392
|
+
if(this.options.preload !== 'none') {
|
|
1393
|
+
this._html_load();
|
|
1394
|
+
}
|
|
1395
|
+
this._trigger($.jPlayer.event.timeupdate); // The flash generates this event for its solution.
|
|
1396
|
+
},
|
|
1397
|
+
_html_setAudio: function(media) {
|
|
1398
|
+
var self = this;
|
|
1399
|
+
// Always finds a format due to checks in setMedia()
|
|
1400
|
+
$.each(this.formats, function(priority, format) {
|
|
1401
|
+
if(self.html.support[format] && media[format]) {
|
|
1402
|
+
self.status.src = media[format];
|
|
1403
|
+
self.status.format[format] = true;
|
|
1404
|
+
self.status.formatType = format;
|
|
1405
|
+
return false;
|
|
1406
|
+
}
|
|
1407
|
+
});
|
|
1408
|
+
this.htmlElement.media = this.htmlElement.audio;
|
|
1409
|
+
this._html_initMedia();
|
|
1410
|
+
},
|
|
1411
|
+
_html_setVideo: function(media) {
|
|
1412
|
+
var self = this;
|
|
1413
|
+
// Always finds a format due to checks in setMedia()
|
|
1414
|
+
$.each(this.formats, function(priority, format) {
|
|
1415
|
+
if(self.html.support[format] && media[format]) {
|
|
1416
|
+
self.status.src = media[format];
|
|
1417
|
+
self.status.format[format] = true;
|
|
1418
|
+
self.status.formatType = format;
|
|
1419
|
+
return false;
|
|
1420
|
+
}
|
|
1421
|
+
});
|
|
1422
|
+
this.htmlElement.media = this.htmlElement.video;
|
|
1423
|
+
this._html_initMedia();
|
|
1424
|
+
},
|
|
1425
|
+
_html_clearMedia: function() {
|
|
1426
|
+
if(this.htmlElement.media) {
|
|
1427
|
+
if(this.htmlElement.media.id === this.internal.video.id) {
|
|
1428
|
+
this.internal.video.jq.css({'width':'0px', 'height':'0px'});
|
|
1429
|
+
}
|
|
1430
|
+
this.htmlElement.media.pause();
|
|
1431
|
+
this.htmlElement.media.src = "";
|
|
1432
|
+
|
|
1433
|
+
if(!($.browser.msie && Number($.browser.version) >= 9)) { // IE9 Bug: media.load() on broken src causes an exception. In try/catch IE9 generates the error event too, but it is delayed and corrupts jPlayer's event masking.
|
|
1434
|
+
this.htmlElement.media.load(); // Stops an old, "in progress" download from continuing the download. Triggers the loadstart, error and emptied events, due to the empty src. Also an abort event if a download was in progress.
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
},
|
|
1438
|
+
_html_load: function() {
|
|
1439
|
+
if(this.status.waitForLoad) {
|
|
1440
|
+
this.status.waitForLoad = false;
|
|
1441
|
+
this.htmlElement.media.src = this.status.src;
|
|
1442
|
+
try {
|
|
1443
|
+
this.htmlElement.media.load(); // IE9 Beta throws an exception here on broken links. Review again later as IE9 Beta matures
|
|
1444
|
+
} catch(err) {}
|
|
1445
|
+
}
|
|
1446
|
+
clearTimeout(this.internal.htmlDlyCmdId);
|
|
1447
|
+
},
|
|
1448
|
+
_html_play: function(time) {
|
|
1449
|
+
var self = this;
|
|
1450
|
+
this._html_load(); // Loads if required and clears any delayed commands.
|
|
1451
|
+
|
|
1452
|
+
this.htmlElement.media.play(); // Before currentTime attempt otherwise Firefox 4 Beta never loads.
|
|
1453
|
+
|
|
1454
|
+
if(!isNaN(time)) {
|
|
1455
|
+
try {
|
|
1456
|
+
this.htmlElement.media.currentTime = time;
|
|
1457
|
+
} catch(err) {
|
|
1458
|
+
this.internal.htmlDlyCmdId = setTimeout(function() {
|
|
1459
|
+
self.play(time);
|
|
1460
|
+
}, 100);
|
|
1461
|
+
return; // Cancel execution and wait for the delayed command.
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
this._html_checkWaitForPlay();
|
|
1465
|
+
},
|
|
1466
|
+
_html_pause: function(time) {
|
|
1467
|
+
var self = this;
|
|
1468
|
+
|
|
1469
|
+
if(time > 0) { // We do not want the stop() command, which does pause(0), causing a load operation.
|
|
1470
|
+
this._html_load(); // Loads if required and clears any delayed commands.
|
|
1471
|
+
} else {
|
|
1472
|
+
clearTimeout(this.internal.htmlDlyCmdId);
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
// Order of these commands is important for Safari (Win) and IE9. Pause then change currentTime.
|
|
1476
|
+
this.htmlElement.media.pause();
|
|
1477
|
+
|
|
1478
|
+
if(!isNaN(time)) {
|
|
1479
|
+
try {
|
|
1480
|
+
this.htmlElement.media.currentTime = time;
|
|
1481
|
+
} catch(err) {
|
|
1482
|
+
this.internal.htmlDlyCmdId = setTimeout(function() {
|
|
1483
|
+
self.pause(time);
|
|
1484
|
+
}, 100);
|
|
1485
|
+
return; // Cancel execution and wait for the delayed command.
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
if(time > 0) { // Avoids a setMedia() followed by stop() or pause(0) hiding the video play button.
|
|
1489
|
+
this._html_checkWaitForPlay();
|
|
1490
|
+
}
|
|
1491
|
+
},
|
|
1492
|
+
_html_playHead: function(percent) {
|
|
1493
|
+
var self = this;
|
|
1494
|
+
this._html_load(); // Loads if required and clears any delayed commands.
|
|
1495
|
+
try {
|
|
1496
|
+
if((typeof this.htmlElement.media.seekable === "object") && (this.htmlElement.media.seekable.length > 0)) {
|
|
1497
|
+
this.htmlElement.media.currentTime = percent * this.htmlElement.media.seekable.end(this.htmlElement.media.seekable.length-1) / 100;
|
|
1498
|
+
} else if(this.htmlElement.media.duration > 0 && !isNaN(this.htmlElement.media.duration)) {
|
|
1499
|
+
this.htmlElement.media.currentTime = percent * this.htmlElement.media.duration / 100;
|
|
1500
|
+
} else {
|
|
1501
|
+
throw "e";
|
|
1502
|
+
}
|
|
1503
|
+
} catch(err) {
|
|
1504
|
+
this.internal.htmlDlyCmdId = setTimeout(function() {
|
|
1505
|
+
self.playHead(percent);
|
|
1506
|
+
}, 100);
|
|
1507
|
+
return; // Cancel execution and wait for the delayed command.
|
|
1508
|
+
}
|
|
1509
|
+
if(!this.status.waitForLoad) {
|
|
1510
|
+
this._html_checkWaitForPlay();
|
|
1511
|
+
}
|
|
1512
|
+
},
|
|
1513
|
+
_html_checkWaitForPlay: function() {
|
|
1514
|
+
if(this.status.waitForPlay) {
|
|
1515
|
+
this.status.waitForPlay = false;
|
|
1516
|
+
if(this.css.jq.videoPlay.length) {
|
|
1517
|
+
this.css.jq.videoPlay.hide();
|
|
1518
|
+
}
|
|
1519
|
+
if(this.status.video) {
|
|
1520
|
+
this.internal.poster.jq.hide();
|
|
1521
|
+
this.internal.video.jq.css({'width': this.status.width, 'height': this.status.height});
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
},
|
|
1525
|
+
_html_volume: function(v) {
|
|
1526
|
+
if(this.html.audio.available) {
|
|
1527
|
+
this.htmlElement.audio.volume = v;
|
|
1528
|
+
}
|
|
1529
|
+
if(this.html.video.available) {
|
|
1530
|
+
this.htmlElement.video.volume = v;
|
|
1531
|
+
}
|
|
1532
|
+
},
|
|
1533
|
+
_html_mute: function(m) {
|
|
1534
|
+
if(this.html.audio.available) {
|
|
1535
|
+
this.htmlElement.audio.muted = m;
|
|
1536
|
+
}
|
|
1537
|
+
if(this.html.video.available) {
|
|
1538
|
+
this.htmlElement.video.muted = m;
|
|
1539
|
+
}
|
|
1540
|
+
},
|
|
1541
|
+
_flash_setAudio: function(media) {
|
|
1542
|
+
var self = this;
|
|
1543
|
+
try {
|
|
1544
|
+
// Always finds a format due to checks in setMedia()
|
|
1545
|
+
$.each(this.formats, function(priority, format) {
|
|
1546
|
+
if(self.flash.support[format] && media[format]) {
|
|
1547
|
+
switch (format) {
|
|
1548
|
+
case "m4a" :
|
|
1549
|
+
self._getMovie().fl_setAudio_m4a(media[format]);
|
|
1550
|
+
break;
|
|
1551
|
+
case "mp3" :
|
|
1552
|
+
self._getMovie().fl_setAudio_mp3(media[format]);
|
|
1553
|
+
break;
|
|
1554
|
+
}
|
|
1555
|
+
self.status.src = media[format];
|
|
1556
|
+
self.status.format[format] = true;
|
|
1557
|
+
self.status.formatType = format;
|
|
1558
|
+
return false;
|
|
1559
|
+
}
|
|
1560
|
+
});
|
|
1561
|
+
|
|
1562
|
+
if(this.options.preload === 'auto') {
|
|
1563
|
+
this._flash_load();
|
|
1564
|
+
this.status.waitForLoad = false;
|
|
1565
|
+
}
|
|
1566
|
+
} catch(err) { this._flashError(err); }
|
|
1567
|
+
},
|
|
1568
|
+
_flash_setVideo: function(media) {
|
|
1569
|
+
var self = this;
|
|
1570
|
+
try {
|
|
1571
|
+
// Always finds a format due to checks in setMedia()
|
|
1572
|
+
$.each(this.formats, function(priority, format) {
|
|
1573
|
+
if(self.flash.support[format] && media[format]) {
|
|
1574
|
+
switch (format) {
|
|
1575
|
+
case "m4v" :
|
|
1576
|
+
self._getMovie().fl_setVideo_m4v(media[format]);
|
|
1577
|
+
break;
|
|
1578
|
+
}
|
|
1579
|
+
self.status.src = media[format];
|
|
1580
|
+
self.status.format[format] = true;
|
|
1581
|
+
self.status.formatType = format;
|
|
1582
|
+
return false;
|
|
1583
|
+
}
|
|
1584
|
+
});
|
|
1585
|
+
|
|
1586
|
+
if(this.options.preload === 'auto') {
|
|
1587
|
+
this._flash_load();
|
|
1588
|
+
this.status.waitForLoad = false;
|
|
1589
|
+
}
|
|
1590
|
+
} catch(err) { this._flashError(err); }
|
|
1591
|
+
},
|
|
1592
|
+
_flash_clearMedia: function() {
|
|
1593
|
+
this.internal.flash.jq.css({'width':'0px', 'height':'0px'}); // Must do via CSS as setting attr() to zero causes a jQuery error in IE.
|
|
1594
|
+
try {
|
|
1595
|
+
this._getMovie().fl_clearMedia();
|
|
1596
|
+
} catch(err) { this._flashError(err); }
|
|
1597
|
+
},
|
|
1598
|
+
_flash_load: function() {
|
|
1599
|
+
try {
|
|
1600
|
+
this._getMovie().fl_load();
|
|
1601
|
+
} catch(err) { this._flashError(err); }
|
|
1602
|
+
this.status.waitForLoad = false;
|
|
1603
|
+
},
|
|
1604
|
+
_flash_play: function(time) {
|
|
1605
|
+
try {
|
|
1606
|
+
this._getMovie().fl_play(time);
|
|
1607
|
+
} catch(err) { this._flashError(err); }
|
|
1608
|
+
this.status.waitForLoad = false;
|
|
1609
|
+
this._flash_checkWaitForPlay();
|
|
1610
|
+
},
|
|
1611
|
+
_flash_pause: function(time) {
|
|
1612
|
+
try {
|
|
1613
|
+
this._getMovie().fl_pause(time);
|
|
1614
|
+
} catch(err) { this._flashError(err); }
|
|
1615
|
+
if(time > 0) { // Avoids a setMedia() followed by stop() or pause(0) hiding the video play button.
|
|
1616
|
+
this.status.waitForLoad = false;
|
|
1617
|
+
this._flash_checkWaitForPlay();
|
|
1618
|
+
}
|
|
1619
|
+
},
|
|
1620
|
+
_flash_playHead: function(p) {
|
|
1621
|
+
try {
|
|
1622
|
+
this._getMovie().fl_play_head(p)
|
|
1623
|
+
} catch(err) { this._flashError(err); }
|
|
1624
|
+
if(!this.status.waitForLoad) {
|
|
1625
|
+
this._flash_checkWaitForPlay();
|
|
1626
|
+
}
|
|
1627
|
+
},
|
|
1628
|
+
_flash_checkWaitForPlay: function() {
|
|
1629
|
+
if(this.status.waitForPlay) {
|
|
1630
|
+
this.status.waitForPlay = false;
|
|
1631
|
+
if(this.css.jq.videoPlay.length) {
|
|
1632
|
+
this.css.jq.videoPlay.hide();
|
|
1633
|
+
}
|
|
1634
|
+
if(this.status.video) {
|
|
1635
|
+
this.internal.poster.jq.hide();
|
|
1636
|
+
this.internal.flash.jq.css({'width': this.status.width, 'height': this.status.height});
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
},
|
|
1640
|
+
_flash_volume: function(v) {
|
|
1641
|
+
try {
|
|
1642
|
+
this._getMovie().fl_volume(v);
|
|
1643
|
+
} catch(err) { this._flashError(err); }
|
|
1644
|
+
},
|
|
1645
|
+
_flash_mute: function(m) {
|
|
1646
|
+
try {
|
|
1647
|
+
this._getMovie().fl_mute(m);
|
|
1648
|
+
} catch(err) { this._flashError(err); }
|
|
1649
|
+
},
|
|
1650
|
+
_getMovie: function() {
|
|
1651
|
+
return document[this.internal.flash.id];
|
|
1652
|
+
},
|
|
1653
|
+
_checkForFlash: function (version) {
|
|
1654
|
+
// Function checkForFlash adapted from FlashReplace by Robert Nyman
|
|
1655
|
+
// http://code.google.com/p/flashreplace/
|
|
1656
|
+
var flashIsInstalled = false;
|
|
1657
|
+
var flash;
|
|
1658
|
+
if(window.ActiveXObject){
|
|
1659
|
+
try{
|
|
1660
|
+
flash = new ActiveXObject(("ShockwaveFlash.ShockwaveFlash." + version));
|
|
1661
|
+
flashIsInstalled = true;
|
|
1662
|
+
}
|
|
1663
|
+
catch(e){
|
|
1664
|
+
// Throws an error if the version isn't available
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
else if(navigator.plugins && navigator.mimeTypes.length > 0){
|
|
1668
|
+
flash = navigator.plugins["Shockwave Flash"];
|
|
1669
|
+
if(flash){
|
|
1670
|
+
var flashVersion = navigator.plugins["Shockwave Flash"].description.replace(/.*\s(\d+\.\d+).*/, "$1");
|
|
1671
|
+
if(flashVersion >= version){
|
|
1672
|
+
flashIsInstalled = true;
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
if($.browser.msie && Number($.browser.version) >= 9) { // IE9 does not work with external interface. With dynamic Flash insertion like jPlayer uses.
|
|
1677
|
+
return false;
|
|
1678
|
+
} else {
|
|
1679
|
+
return flashIsInstalled;
|
|
1680
|
+
}
|
|
1681
|
+
},
|
|
1682
|
+
_validString: function(url) {
|
|
1683
|
+
return (url && typeof url === "string"); // Empty strings return false
|
|
1684
|
+
},
|
|
1685
|
+
_limitValue: function(value, min, max) {
|
|
1686
|
+
return (value < min) ? min : ((value > max) ? max : value);
|
|
1687
|
+
},
|
|
1688
|
+
_urlNotSetError: function(context) {
|
|
1689
|
+
this._error( {
|
|
1690
|
+
type: $.jPlayer.error.URL_NOT_SET,
|
|
1691
|
+
context: context,
|
|
1692
|
+
message: $.jPlayer.errorMsg.URL_NOT_SET,
|
|
1693
|
+
hint: $.jPlayer.errorHint.URL_NOT_SET
|
|
1694
|
+
});
|
|
1695
|
+
},
|
|
1696
|
+
_flashError: function(error) {
|
|
1697
|
+
this._error( {
|
|
1698
|
+
type: $.jPlayer.error.FLASH,
|
|
1699
|
+
context: this.internal.flash.swf,
|
|
1700
|
+
message: $.jPlayer.errorMsg.FLASH + error.message,
|
|
1701
|
+
hint: $.jPlayer.errorHint.FLASH
|
|
1702
|
+
});
|
|
1703
|
+
},
|
|
1704
|
+
_error: function(error) {
|
|
1705
|
+
this._trigger($.jPlayer.event.error, error);
|
|
1706
|
+
if(this.options.errorAlerts) {
|
|
1707
|
+
this._alert("Error!" + (error.message ? "\n\n" + error.message : "") + (error.hint ? "\n\n" + error.hint : "") + "\n\nContext: " + error.context);
|
|
1708
|
+
}
|
|
1709
|
+
},
|
|
1710
|
+
_warning: function(warning) {
|
|
1711
|
+
this._trigger($.jPlayer.event.warning, undefined, warning);
|
|
1712
|
+
if(this.options.errorAlerts) {
|
|
1713
|
+
this._alert("Warning!" + (warning.message ? "\n\n" + warning.message : "") + (warning.hint ? "\n\n" + warning.hint : "") + "\n\nContext: " + warning.context);
|
|
1714
|
+
}
|
|
1715
|
+
},
|
|
1716
|
+
_alert: function(message) {
|
|
1717
|
+
alert("jPlayer " + this.version.script + " : id='" + this.internal.self.id +"' : " + message);
|
|
1718
|
+
}
|
|
1719
|
+
};
|
|
1720
|
+
|
|
1721
|
+
$.jPlayer.error = {
|
|
1722
|
+
FLASH: "e_flash",
|
|
1723
|
+
NO_SOLUTION: "e_no_solution",
|
|
1724
|
+
NO_SUPPORT: "e_no_support",
|
|
1725
|
+
URL: "e_url",
|
|
1726
|
+
URL_NOT_SET: "e_url_not_set",
|
|
1727
|
+
VERSION: "e_version"
|
|
1728
|
+
};
|
|
1729
|
+
|
|
1730
|
+
$.jPlayer.errorMsg = {
|
|
1731
|
+
FLASH: "jPlayer's Flash fallback is not configured correctly, or a command was issued before the jPlayer Ready event. Details: ", // Used in: _flashError()
|
|
1732
|
+
NO_SOLUTION: "No solution can be found by jPlayer in this browser. Neither HTML nor Flash can be used.", // Used in: _init()
|
|
1733
|
+
NO_SUPPORT: "It is not possible to play any media format provided in setMedia() on this browser using your current options.", // Used in: setMedia()
|
|
1734
|
+
URL: "Media URL could not be loaded.", // Used in: jPlayerFlashEvent() and _addHtmlEventListeners()
|
|
1735
|
+
URL_NOT_SET: "Attempt to issue media playback commands, while no media url is set.", // Used in: load(), play(), pause(), stop() and playHead()
|
|
1736
|
+
VERSION: "jPlayer " + $.jPlayer.prototype.version.script + " needs Jplayer.swf version " + $.jPlayer.prototype.version.needFlash + " but found " // Used in: jPlayerReady()
|
|
1737
|
+
};
|
|
1738
|
+
|
|
1739
|
+
$.jPlayer.errorHint = {
|
|
1740
|
+
FLASH: "Check your swfPath option and that Jplayer.swf is there.",
|
|
1741
|
+
NO_SOLUTION: "Review the jPlayer options: support and supplied.",
|
|
1742
|
+
NO_SUPPORT: "Video or audio formats defined in the supplied option are missing.",
|
|
1743
|
+
URL: "Check media URL is valid.",
|
|
1744
|
+
URL_NOT_SET: "Use setMedia() to set the media URL.",
|
|
1745
|
+
VERSION: "Update jPlayer files."
|
|
1746
|
+
};
|
|
1747
|
+
|
|
1748
|
+
$.jPlayer.warning = {
|
|
1749
|
+
CSS_SELECTOR_COUNT: "e_css_selector_count",
|
|
1750
|
+
CSS_SELECTOR_METHOD: "e_css_selector_method",
|
|
1751
|
+
CSS_SELECTOR_STRING: "e_css_selector_string",
|
|
1752
|
+
OPTION_KEY: "e_option_key"
|
|
1753
|
+
};
|
|
1754
|
+
|
|
1755
|
+
$.jPlayer.warningMsg = {
|
|
1756
|
+
CSS_SELECTOR_COUNT: "The number of methodCssSelectors found did not equal one: ",
|
|
1757
|
+
CSS_SELECTOR_METHOD: "The methodName given in jPlayer('cssSelector') is not a valid jPlayer method.",
|
|
1758
|
+
CSS_SELECTOR_STRING: "The methodCssSelector given in jPlayer('cssSelector') is not a String or is empty.",
|
|
1759
|
+
OPTION_KEY: "The option requested in jPlayer('option') is undefined."
|
|
1760
|
+
};
|
|
1761
|
+
|
|
1762
|
+
$.jPlayer.warningHint = {
|
|
1763
|
+
CSS_SELECTOR_COUNT: "Check your css selector and the ancestor.",
|
|
1764
|
+
CSS_SELECTOR_METHOD: "Check your method name.",
|
|
1765
|
+
CSS_SELECTOR_STRING: "Check your css selector is a string.",
|
|
1766
|
+
OPTION_KEY: "Check your option name."
|
|
1767
|
+
};
|
|
1768
|
+
})(jQuery);
|