";
+IriSP.annotation_template = "{{! template for an annotation displayed in a segmentWidget }}
";
+IriSP.annotationWidget_template = "{{! template for the annotation widget }}
";
+IriSP.annotation_loading_template = "{{! template shown while the annotation widget is loading }}
";
+IriSP.annotationsListWidget_template = "{{! template for the annotation list widget }}
";
+IriSP.createAnnotationWidget_template = "{{! template for the annotation creation widget }}
";
+IriSP.overlay_marker_template = "{{! the template for the small bars which is z-indexed over our segment widget }}
";
+IriSP.sliderWidget_template = "{{! template for the slider widget - it's composed of two divs we one overlayed on top of the other }}
";
IriSP.tweetWidget_template = "{{! template for the tweet widget }}";/* utils.js - various utils that don't belong anywhere else */
/* trace function, for debugging */
@@ -1626,9 +1625,9 @@
IriSP.paths = {};
-IriSP.libdir = "";
-IriSP.jwplayer_swf_path = "";
-IriSP.platform_url = "";
+IriSP.libdir = "/mdp/src/js/libs/";
+IriSP.jwplayer_swf_path = "/mdp/test/libs/player.swf";
+IriSP.platform_url = "http://localhost/pf";
IriSP.default_templates_vars = { };
/** ugly ugly ugly ugly - returns an object defining
@@ -1697,7 +1696,11 @@
Ldt-createAnnotation-polemic-equalequal for equalequal, etc.
*/
polemics: {"++" : "positive", "--" : "negative", "==" : "reference", "??" : "question"},
- cinecast_version: true /* put to false to enable the platform version, true for the festival cinecast one. */
+ cinecast_version: true, /* put to false to enable the platform version, true for the festival cinecast one. */
+ /* where does the widget PUT the annotations - this is a mustache template. id refers to the id of the media ans is filled
+ by the widget.
+ */
+ api_endpoint_template: platform_url + "/ldtplatform/api/ldt/annotations/{{id}}.json"
},
"SparklineWidget" : {
column_width: 10 // the width of a column in pixels.
@@ -1709,13 +1712,13 @@
ajax_mode: true, /* use ajax to get information about the annotations.
if set to false, only search in the annotations for the
current project. */
+
/* the platform generates some funky urls. We replace them afterwards to point to the
correct place - this setting will probably be overwritten by the platform
implementers.
Note that the player has to replace the variables between {{ and }} by its own values.
*/
ajax_url: platform_url + "/ldtplatform/api/ldt/segments/{media}/{begin}/{end}",
-
ajax_granularity: 10000, /* how much ms should we look before and after the
current timecode */
@@ -1726,28 +1729,27 @@
};
};
+IriSP.defaults.paths = {
+// "imgs": "/tweetlive/res/metadataplayer/src/css/imgs"
+ "imgs": "/mdp/src/css/imgs"
+};
+
+IriSP.defaults.default_templates_vars = function() {
+ return {
+ //"img_dir" : IriSP.paths.imgs
+ };
+}
+
/*
Override this if you want to change the info the player receives about the user.
It's typically overrided in server-side templates with user-specific data.
*/
-IriSP.defaults.user = function() { return {
+IriSP.defaults.user = function() {
+ return {
"name" : "Anonymous user",
"avatar" : IriSP.paths.imgs + "/user_default_icon.png"
- }
-};
-
-
-IriSP.defaults.paths = {
-// "imgs": "/tweetlive/res/metadataplayer/src/css/imgs"
- "imgs": ""
-};
-
-IriSP.defaults.default_templates_vars = function() {
- return {
- "img_dir" : IriSP.paths.imgs
- };
-}
-
+ }
+};
/* the widget classes and definitions */
/**
@@ -1982,6 +1984,16 @@
opts.file = "";
opts.streamer = "";
var fullPath = IriSP.__jsonMetadata["medias"][0]["href"];
+
+ /* files can either use href or url to refer to the stream */
+ if (IriSP.null_or_undefined(fullPath)) {
+ fullPath = IriSP.__jsonMetadata["medias"][0]["url"];
+ }
+
+ if (IriSP.null_or_undefined(fullPath)) {
+ console.log("no url or href field defined in the metadata.");
+ }
+
var pathSplit = fullPath.split('/');
for (var i = 0; i < pathSplit.length; i++) {
@@ -2047,13 +2059,16 @@
var serialFactory = new IriSP.SerializerFactory(IriSP.__dataloader);
var params = {width: guiOptions.width, height: guiOptions.height};
+ var default_options = guiOptions.default_options;
+ if (IriSP.null_or_undefined(default_options))
+ default_options = {};
+
var ret_widgets = [];
var index;
for (index = 0; index < guiOptions.widgets.length; index++) {
- var widgetConfig = guiOptions.widgets[index];
- var widget = IriSP.instantiateWidget(popcornInstance, serialFactory, layoutManager, widgetConfig);
-
+ var widget = IriSP.instantiateWidget(popcornInstance, serialFactory, layoutManager, guiOptions.widgets[index], default_options);
+
ret_widgets.push(widget);
};
@@ -2086,8 +2101,14 @@
@param serialFactory serializer factory to instantiate the widget with
@param layoutManager layout manager
@param widgetConfig configuration options for the widget
+ @param defaultOptions a dictionnary with some options defined for every widget.
*/
-IriSP.instantiateWidget = function(popcornInstance, serialFactory, layoutManager, widgetConfig) {
+IriSP.instantiateWidget = function(popcornInstance, serialFactory, layoutManager, widgetConfig, defaultOptions) {
+
+ if (IriSP.null_or_undefined(defaultOptions))
+ defaultOptions = {};
+
+ widgetConfig = IriSP.underscore.defaults(widgetConfig, defaultOptions);
var arr = IriSP.jQuery.extend({}, widgetConfig);
@@ -2117,7 +2138,7 @@
var i = 0;
for(i = 0; i < widgetConfig.requires.length; i++) {
var widgetName = widgetConfig.requires[i]["type"];
- widget[widgetName] = IriSP.instantiateWidget(popcornInstance, serialFactory, layoutManager, widgetConfig.requires[i]);
+ widget[widgetName] = IriSP.instantiateWidget(popcornInstance, serialFactory, layoutManager, widgetConfig.requires[i], defaultOptions);
}
}
@@ -2317,7 +2338,27 @@
};
IriSP.PopcornReplacement.jwplayer.prototype = new IriSP.PopcornReplacement.player("", {});
-/* mediafragment module */
+/* embed module - listens and relay hash changes to a parent window. */
+
+IriSP.EmbedModule = function(Popcorn, config, Serializer) {
+ IriSP.Module.call(this, Popcorn, config, Serializer);
+
+ window.addEventListener('message', IriSP.wrap(this, this.handleMessages), false);
+ this._Popcorn.listen("IriSP.Mediafragment.hashchange", IriSP.wrap(this, this.relayChanges));
+};
+
+IriSP.EmbedModule.prototype = new IriSP.Module();
+
+IriSP.EmbedModule.prototype.handleMessages = function(e) {
+ if (e.data.type === "hashchange") {
+ window.location.hash = e.data.value;
+ }
+};
+
+IriSP.EmbedModule.prototype.relayChanges = function(newHash) {
+ window.parent.postMessage({type: "hashchange", value: newHash}, "*");
+ return;
+};/* mediafragment module */
IriSP.MediaFragment = function(Popcorn, config, Serializer) {
IriSP.Module.call(this, Popcorn, config, Serializer);
@@ -2359,7 +2400,7 @@
this._serializer.sync(IriSP.wrap(this, function() {
this.lookupAnnotation.call(this, annotationId);
}));
- }
+ }
}
};
@@ -2381,6 +2422,9 @@
} else {
var ntime = time.toFixed(2);
}
+
+ // used to relay the new hash to the embedder
+ this._Popcorn.trigger("IriSP.Mediafragment.hashchange", "#t=" + ntime);
splitArr = window.location.href.split( "#" )
history.replaceState( {}, "", splitArr[0] + "#t=" + ntime );
@@ -2395,10 +2439,15 @@
if ( !history.pushState ) {
return false;
}
+
+
+ // used to relay the new hash to the embedder
+ this._Popcorn.trigger("IriSP.Mediafragment.hashchange", "#id=" + annotationId);
splitArr = window.location.href.split( "#" )
history.replaceState( {}, "", splitArr[0] + "#id=" + annotationId);
-
+
+
// reset the mutex afterwards to prevent the module from reacting to his own changes.
window.setTimeout(function() { _this.mutex = false }, 50);
};
@@ -2660,7 +2709,7 @@
IriSP.AnnotationsWidget.prototype.displayAnnotation = function(annotation) {
var title = annotation.content.title;
var description = annotation.content.description;
- var keywords = "" // FIXME;
+ var keywords = "";
var begin = +annotation.begin / 1000;
var end = +annotation.end / 1000;
var duration = +this._serializer.currentMedia().meta["dc:duration"];
@@ -2838,15 +2887,15 @@
if (corrected_pixels <= 0)
corrected_pixels = 0;
- if (corrected_pixels <= 15) {
- var left_edge_img_templ = IriSP.templToHTML("url('{{img_dir}}/left_edge_arrow.png')");
- this.selector.children(".Ldt-arrowWidget").css("background-image", left_edge_img_templ);
+ if (corrected_pixels <= 15) {
+ this.selector.children(".Ldt-arrowWidget").removeClass("Ldt-arrowLeftEdge Ldt-arrowCenter Ldt-arrowRightEdge")
+ .addClass("Ldt-arrowLeftEdge");
} else if (corrected_pixels >= totalWidth - 25) {
- var right_edge_img_templ = IriSP.templToHTML("url('{{img_dir}}/right_edge_arrow.png')");
- this.selector.children(".Ldt-arrowWidget").css("background-image", right_edge_img_templ);
+ this.selector.children(".Ldt-arrowWidget").removeClass("Ldt-arrowLeftEdge Ldt-arrowCenter Ldt-arrowRightEdge")
+ .addClass("Ldt-arrowRightEdge");
} else {
- var img_templ = IriSP.templToHTML("url('{{img_dir}}/arrow.png')");
- this.selector.children(".Ldt-arrowWidget").css("background-image", img_templ);
+ this.selector.children(".Ldt-arrowWidget").removeClass("Ldt-arrowLeftEdge Ldt-arrowCenter Ldt-arrowRightEdge")
+ .addClass("Ldt-arrowCenter");
}
this.selector.children(".Ldt-arrowWidget").animate({"left" : corrected_pixels + "px"});
@@ -2872,6 +2921,8 @@
this.polemics = IriSP.widgetsDefaults["createAnnotationWidget"].polemics;
this.cinecast_version = IriSP.widgetsDefaults["createAnnotationWidget"].cinecast_version;
+ this.api_endpoint_template = IriSP.widgetsDefaults["createAnnotationWidget"].api_endpoint_template;
+
this.ids = {}; /* a dictionnary linking buttons ids to keywords */
/* variables to save the current position of the slicer */
@@ -2905,6 +2956,9 @@
if (!this.cinecast_version)
this.selector.hide();
+ else {
+ this.showStartScreen();
+ }
// add the keywords.
for (var i = 0; i < this.keywords.length; i++) {
@@ -2963,17 +3017,17 @@
}
_this.selector.find(".Ldt-createAnnotation-Description").val(newVal);
- // we use a custom event because there's no simple way to test for a js
- // change in a textfield.
- _this.selector.find(".Ldt-createAnnotation-Description").trigger("js_mod");
+
// also call our update function.
_this.handleTextChanges();
}
}(polemic));
}
+ // js_mod is a custom event because there's no simple way to test for a js
+ // change in a textfield.
this.selector.find(".Ldt-createAnnotation-Description")
- .bind("propertychange keyup input paste", IriSP.wrap(this, this.handleTextChanges));
+ .bind("propertychange keyup input paste js_mod", IriSP.wrap(this, this.handleTextChanges));
/* the cinecast version of the player is supposed to pause when the user clicks on the button */
if (this.cinecast_version) {
@@ -3052,7 +3106,7 @@
} else {
this._Popcorn.trigger("IriSP.AnnotationsWidget.hide");
- this.showStartScreen();
+ this.showStartScreen();
this.selector.show();
this._hidden = false;
var currentTime = this._Popcorn.currentTime();
@@ -3133,8 +3187,19 @@
IriSP.createAnnotationWidget.prototype.showStartScreen = function() {
this.selector.find(".Ldt-createAnnotation-DoubleBorder").children().hide();
this.selector.find(".Ldt-createAnnotation-startScreen").show();
- this.selector.find(".Ldt-createAnnotation-Description").val("Type your annotation here.");
-
+
+ var jqTextfield = this.selector.find(".Ldt-createAnnotation-Description"); // handle on the textfield. used for the closure
+
+ /* test if the browser supports the placeholder attribute */
+ if (!IriSP.null_or_undefined(jqTextfield.get(0).placeholder)) {
+ jqTextfield.attr("placeholder", "Type your annotation here.");
+ } else {
+ jqTextfield.val("Type your annotation here.");
+ jqTextfield.one("click", IriSP.wrap(this, function() { jqTextfield.val(""); }));
+ }
+
+
+
this._state = "startScreen";
};
@@ -3275,8 +3340,8 @@
var project_id = this._serializer._data.meta.id;
//TODO: extract magic url
- var url = Mustache.to_html("{{platf_url}}/ldtplatform/api/ldt/annotations/{{id}}.json",
- {platf_url: IriSP.platform_url, id: project_id});
+ var url = Mustache.to_html(this.api_endpoint_template,
+ {id: project_id});
IriSP.jQuery.ajax({
url: url,
@@ -3420,21 +3485,13 @@
IriSP.PlayerWidget.prototype.playButtonUpdater = function() {
var status = this._Popcorn.media.paused;
- if ( status == true ){
+ if ( status == true ){
+ /* the background sprite is changed by adding/removing the correct classes */
this.selector.find(".Ldt-CtrlPlay").attr("title", "Play");
-
- // we use templToHTML because it has some predefined
- // vars like where to get the images
- var templ = IriSP.templToHTML("url({{img_dir}}/play_sprite.png)");
- this.selector.find(".Ldt-CtrlPlay").css("background-image", templ);
-
+ this.selector.find(".Ldt-CtrlPlay").removeClass("Ldt-CtrlPlay-PauseState").addClass("Ldt-CtrlPlay-PlayState");
} else {
this.selector.find(".Ldt-CtrlPlay").attr("title", "Pause");
-
- // we use templToHTML because it has some predefined
- // vars like where to get the images
- var templ = IriSP.templToHTML("url({{img_dir}}/pause_sprite.png)");
- this.selector.find(".Ldt-CtrlPlay").css("background-image", templ);
+ this.selector.find(".Ldt-CtrlPlay").removeClass("Ldt-CtrlPlay-PlayState").addClass("Ldt-CtrlPlay-PauseState");
}
return;
@@ -3464,19 +3521,10 @@
if ( status == true ){
this.selector.find(".Ldt-CtrlSound").attr("title", "Unmute");
-
- // we use templToHTML because it has some predefined
- // vars like where to get the images
- var templ = IriSP.templToHTML("url({{img_dir}}/sound_sprite.png)");
- this.selector.find(".Ldt-CtrlSound").css("background-image", templ);
-
+ this.selector.find(".Ldt-CtrlSound").removeClass("Ldt-CtrlSound-MuteState").addClass("Ldt-CtrlSound-SoundState");
} else {
this.selector.find(".Ldt-CtrlSound").attr("title", "Mute");
-
- // we use templToHTML because it has some predefined
- // vars like where to get the images
- var templ = IriSP.templToHTML("url({{img_dir}}/mute_sprite.png)");
- this.selector.find(".Ldt-CtrlSound").css("background-image", templ);
+ this.selector.find(".Ldt-CtrlSound").removeClass("Ldt-CtrlSound-SoundState").addClass("Ldt-CtrlSound-MuteState");
}
return;