# HG changeset patch # User veltr # Date 1335201068 -7200 # Node ID 43629caa77bc2bb8bba8e502dc88bb703d25bfe8 # Parent 38b65761a7d56923d5be47d1abe5f0932e87e4a9 Big refactoring of widget files + started migration of segmentwidget diff -r 38b65761a7d5 -r 43629caa77bc .hgignore --- a/.hgignore Fri Apr 20 19:13:11 2012 +0200 +++ b/.hgignore Mon Apr 23 19:11:08 2012 +0200 @@ -10,4 +10,6 @@ doc/jsdoc/* syntax: regexp -^src/css/LdtPlayer-release\.css$ \ No newline at end of file +^src/css/LdtPlayer-release\.css$ +syntax: regexp +^build$ \ No newline at end of file diff -r 38b65761a7d5 -r 43629caa77bc sbin/build/client.xml --- a/sbin/build/client.xml Fri Apr 20 19:13:11 2012 +0200 +++ b/sbin/build/client.xml Mon Apr 23 19:11:08 2012 +0200 @@ -37,21 +37,11 @@ - - - - - - - - - - - - + + + files="lab.js"/> @@ -62,14 +52,6 @@ - - - - - - - - diff -r 38b65761a7d5 -r 43629caa77bc src/css/LdtPlayer-base.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/css/LdtPlayer-base.css Mon Apr 23 19:11:08 2012 +0200 @@ -0,0 +1,2 @@ +/* Base classes */ + diff -r 38b65761a7d5 -r 43629caa77bc src/css/base.css --- a/src/css/base.css Fri Apr 20 19:13:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -/* Base classes */ - diff -r 38b65761a7d5 -r 43629caa77bc src/css/imgs/player-sprites.png Binary file src/css/imgs/player-sprites.png has changed diff -r 38b65761a7d5 -r 43629caa77bc src/css/imgs/player_gradient.png Binary file src/css/imgs/player_gradient.png has changed diff -r 38b65761a7d5 -r 43629caa77bc src/css/imgs/white_arrow_long.png Binary file src/css/imgs/white_arrow_long.png has changed diff -r 38b65761a7d5 -r 43629caa77bc src/css/widgets/annotationsListWidget.css --- a/src/css/widgets/annotationsListWidget.css Fri Apr 20 19:13:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* AnnotationsListWidget */ - -.Ldt-AnnotationsListWidget { - font-family: "Open Sans", Helvetica, Arial, sans-serif; - border: 1px solid #b6b8b8; - overflow: auto; - max-height: 480px; -} -.Ldt-AnnotationsListWidget a { - text-decoration: none; -} -ul.Ldt-AnnotationsList-ul { - list-style: none; - padding: 2px; - margin: 0; -} -li.Ldt-AnnotationsList-li { - width: 100%; - clear: both; - margin: 2px 0; - padding: 2px 0; - min-height: 60px; -} -.Ldt-AnnotationsList-li:hover { - background-color: #e9e9e9; -} -.Ldt-AnnotationsList-highlight { - background: #F7268E; - color: #ffffff; -} -.Ldt-AnnotationsList-ThumbContainer { - float: left; - width: 80px; - height: 50px; - text-align: center; - margin: 2px 0; -} -.Ldt-AnnotationsList-Thumbnail { - border: none; - max-width: 100%; - max-height: 100%; - margin: 0 auto; -} -.Ldt-AnnotationsList-Duration { - color: #f7268e; - float: right; - text-align: right; - font-size: 12px; - margin: 2px; -} -h3.Ldt-AnnotationsList-Title { - color: #0068c4; - font-size: 13px; - margin: 2px 2px 0 82px; - font-weight: bold; -} -.Ldt-AnnotationsList-Title a { - color: #0068c4; -} -p.Ldt-AnnotationsList-Description { - margin: 2px 0 2px 82px; - font-size: 12px; - color: #666666; -} -ul.Ldt-AnnotationsList-Tags { - list-style: none; - padding: 0; - margin: 2px 0 0 82px; -} -li.Ldt-AnnotationsList-Tag-Li { - display: inline-block; - margin: 2px; - background: #0068c4; - color: #fff; - padding: 2px; - font-size: 12px; -} -li.Ldt-AnnotationsList-Tag-Li:hover { - background: #F7268E; -} diff -r 38b65761a7d5 -r 43629caa77bc src/css/widgets/playerWidget.css --- a/src/css/widgets/playerWidget.css Fri Apr 20 19:13:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,178 +0,0 @@ -/* Player Widget */ - -.Ldt-Ctrl { - font-size: 10px; - font-family: "Trebuchet MS", "Helvetica", "Arial", "Verdana", "sans-serif"; - background:url('imgs/player_gradient.png') repeat-x transparent ; - height: 25px; - border: 1px solid #b6b8b8; - position: relative; -} - -.Ldt-Ctrl-Left { - float:left; -} - -.Ldt-Ctrl-Right { - float: right; -} - -.Ldt-Ctrl-button { - float: left; - width: 30px; height: 25px; - background: url('imgs/player-sprites.png'); - cursor: pointer; -} - -.Ldt-Ctrl-spacer { - float: left; width: 1px; height: 25px; background: #b6b8b8; -} - -.Ldt-Ctrl-Play { - margin: 0 15px; -} - -.Ldt-Ctrl-Play-PlayState { - background-position: 0 0; -} - -.Ldt-Ctrl-Play-PlayState:hover { - background-position: 0 -25px; -} - -.Ldt-Ctrl-Play-PlayState:active { - background-position: 0 -50px; -} - -.Ldt-Ctrl-Play-PauseState { - background-position: -30px 0; -} - -.Ldt-Ctrl-Play-PauseState:hover { - background-position: -30px -25px; -} - -.Ldt-Ctrl-Play-PauseState:active { - background-position: -30px -50px; -} - -.Ldt-Ctrl-Annotate { - margin: 0 2px; - background-position: -60px 0; -} - -.Ldt-Ctrl-Annotate:hover { - background-position: -60px -25px; -} - -.Ldt-Ctrl-Annotate:active { - background-position: -60px -50px; -} - -.Ldt-Ctrl-SearchBtn { - margin: 0 2px; - background-position: -90px 0; -} - -.Ldt-Ctrl-SearchBtn:hover { - background-position: -90px -25px; -} - -.Ldt-Ctrl-SearchBtn:active { - background-position: -90px -50px; -} - -.Ldt-Ctrl-Search { - display: none; - width: 165px; - height: 25px; - border: 1px; - border-color: #CFCFCF; - float: left; - text-align: center; -} - -.Ldt-Ctrl-Time { - float: left; - margin: 5px; - font-size: 12px; - font-family: Arial, Verdana, sans-serif; -} - -.Ldt-Ctrl-Time-Elapsed { - float: left; - color: #4a4a4a; -} - -.Ldt-Ctrl-Time-Separator { - margin: 0 4px; - float: left; -} - -.Ldt-Ctrl-Time-Total { - float: left; - color: #b2b2b2; -} - -.Ldt-Ctrl-Sound { - margin: 0 2px; -} - -.Ldt-Ctrl-Sound-Full { - background-position: -120px 0; -} - -.Ldt-Ctrl-Sound-Full:hover { - background-position: -120px -25px; -} - -.Ldt-Ctrl-Sound-Full:active { - background-position: -120px -50px; -} - -.Ldt-Ctrl-Sound-Mute { - background-position: -150px 0; -} - -.Ldt-Ctrl-Sound-Mute:hover { - background-position: -150px -25px; -} - -.Ldt-Ctrl-Sound-Mute:active { - background-position: -150px -50px; -} - -.Ldt-Ctrl-Sound-Half { - background-position: -180px 0; -} - -.Ldt-Ctrl-Sound-Half:hover { - background-position: -180px -25px; -} - -.Ldt-Ctrl-Sound-Half:active { - background-position: -180px -50px; -} - -.Ldt-Ctrl-Volume-Control { - display: none; - position: absolute; - background:url('imgs/player_gradient.png') repeat-x transparent ; - height: 25px; - width: 100px; top: 25px; right: -1px; z-index: 100; - padding: 0 2px; - border: 1px solid #b6b8b8; -} - -.Ldt-Ctrl-Volume-Bar { - height: 5px; margin: 9px 3px 0; background: #cccccc; border: 1px solid #999999; border-radius: 2px; -} - -.Ldt-Ctrl-Volume-Control .ui-slider-handle { - width: 6px; height: 19px; background: #a8a8a8; border: 1px solid #999999; border-radius: 2px; top: -8px; margin-left: -4px; - cursor: pointer; -} - -.Ldt-Ctrl-Volume-Control:hover .ui-slider-handle { - background: #F7268E; -} \ No newline at end of file diff -r 38b65761a7d5 -r 43629caa77bc src/css/widgets/sliderWidget.css --- a/src/css/widgets/sliderWidget.css Fri Apr 20 19:13:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -/* Slider Widget */ - -.Ldt-Slider { - border: none; border-radius: 0; padding: 0; margin: 0; background: #B6B8B8; -} - -.Ldt-Slider .ui-slider-handle { - border-radius: 8px; top: -2px; background: #fc00ff; border: 1px solid #ffffff; -} - -.Ldt-Slider .ui-slider-range { - background: #747474; -} - diff -r 38b65761a7d5 -r 43629caa77bc src/css/widgets/tooltipWidget.css --- a/src/css/widgets/tooltipWidget.css Fri Apr 20 19:13:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -/* ToolTip Widget */ - -.Ldt-Tooltip { - position: absolute; - padding : 3px; - z-index: 10000000000; - max-width: 200px; - background: transparent url("imgs/white_arrow_long.png"); - font-size: 12px; - height: 115px; - width: 180px; - padding: 15px 15px 20px; - color: black; - font-family: "Trebuchet MS", "Helvetica", "Arial", "Verdana", "sans-serif"; - overflow:hidden; -} - -.Ldt-Tooltip-Color { - float: left; margin: 2px 4px 2px 0; width: 10px; height: 10px; -} - -.Ldt-Tooltip img { - max-width: 140px; max-height: 70px; margin: 0 20px; -} - diff -r 38b65761a7d5 -r 43629caa77bc src/js/defaults.js --- a/src/js/defaults.js Fri Apr 20 19:13:11 2012 +0200 +++ b/src/js/defaults.js Mon Apr 23 19:11:08 2012 +0200 @@ -3,6 +3,8 @@ IriSP.libFiles = { defaultDir : "js/libs/", inDefaultDir : { + underscore : "underscore.js", + Mustache : "mustache.js", jQuery : "jquery.min.js", jQueryUI : "jquery-ui.min.js", swfObject : "swfobject.js", @@ -27,6 +29,8 @@ useCdn : false } +IriSP.widgetsDir = 'widgets'; + IriSP.guiDefaults = { width : 640, container : 'LdtPlayer', @@ -34,9 +38,6 @@ } IriSP.widgetsDefaults = { - "PlayerWidget" : { - - }, "AnnotationsWidget" : { "share_text" : "I'm watching " }, @@ -44,11 +45,6 @@ default_profile_picture : "https://si0.twimg.com/sticky/default_profile_images/default_profile_1_normal.png", tweet_display_period : 10000 // how long do we show a tweet ? }, - "SliderWidget" : { - minimized_height : 4, - maximized_height : 10, - minimize_timeout : 1500 // time before minimizing slider after mouseout - }, "SegmentsWidget" : { cinecast_version : false }, @@ -93,33 +89,6 @@ api_endpoint_template : "", // platform_url + "/ldtplatform/api/ldt/annotations/{{id}}.json", api_method : "PUT" }, - "SparklineWidget" : { - lineColor : "#7492b4", - fillColor : "#aeaeb8", - lineWidth : 2 - }, - "AnnotationsListWidget" : { - /* 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 : false, - /* URL when the annotations are to be reloaded from an LDT-like segment API - * e.g. http://ldt.iri.centrepompidou.fr/ldtplatform/api/ldt/segments/{{media}}/{{begin}}/{{end}}?callback=? - */ - ajax_granularity : 300000, /* how much ms should we look before and after the current timecode */ - default_thumbnail : "http://ldt.iri.centrepompidou.fr/static/site/ldt/css/imgs/video_sequence.png", - foreign_url : "", - /* URL when the annotation is not in the current project, - * e.g. http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/{{media}}/{{project}}/{{annotationType}}#id={{annotation}} - */ - cinecast_version : false, - annotation_type : false, - refresh_interval : 0, - limit_count : 10, - newest_first : false - }, "StackGraphWidget" : { defaultcolor : "#585858", tags : [ @@ -145,39 +114,5 @@ } ], streamgraph : false - }, - "PolemicWidget" : { - element_width : 5, - element_height : 5, - annotation_type : "tweet", - defaultcolor : "#585858", - foundcolor : "#fc00ff", - tags : [ - { - "keywords" : [ "++" ], - "description" : "positif", - "color" : "#1D973D" - }, - { - "keywords" : [ "--" ], - "description" : "negatif", - "color" : "#CE0A15" - }, - { - "keywords" : [ "==" ], - "description" : "reference", - "color" : "#C5A62D" - }, - { - "keywords" : [ "??" ], - "description" : "question", - "color" : "#036AAE" - } - ], - requires : [ - { - type: "TooltipWidget" - } - ] } } \ No newline at end of file diff -r 38b65761a7d5 -r 43629caa77bc src/js/i18n.js --- a/src/js/i18n.js Fri Apr 20 19:13:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -IriSP.I18n = function() { - this.messages = {}; - this.base_lang = 'en'; -} - -IriSP.I18n.prototype.getLanguage = function(lang) { - var _lang = ( - typeof lang != "undefined" - ? lang - : ( - typeof IriSP.language != "undefined" - ? IriSP.language - : this.base_lang - ) - ); - return ( - typeof this.messages[_lang] == "object" - ? _lang - : ( - typeof this.messages[this.base_lang] == "object" - ? this.base_lang - : null - ) - ) -} - -IriSP.I18n.prototype.getMessages = function(lang) { - var _lang = this.getLanguage(lang); - return ( - _lang != null - ? this.messages[_lang] - : {} - ); -} - -IriSP.I18n.prototype.getMessage = function(message, lang) { - var _msgs = this.getMessages(lang); - return ( - typeof _msgs[message] != "undefined" - ? _msgs[message] - : message - ) -} - -IriSP.I18n.prototype.addMessage = function(lang, messagekey, messagevalue) { - if (typeof this.messages[lang] == "undefined") { - this.messages[lang] = {}; - } - this.messages[lang][messagekey] = messagevalue; -} - -IriSP.I18n.prototype.addMessages = function(messagesObj) { - var _this = this; - IriSP.underscore(messagesObj).each(function(_messages, _lang) { - IriSP.underscore(_messages).each(function(_value, _key) { - _this.addMessage(_lang, _key, _value); - }) - }); -} - -IriSP.i18n = new IriSP.I18n(); - -IriSP.i18n.addMessages({ - "fr": { - "loading_wait": "Chargement en cours, veuillez patienter…" - }, - "en": { - "loading_wait": "Loading, please wait…" - } -}) diff -r 38b65761a7d5 -r 43629caa77bc src/js/init.js --- a/src/js/init.js Fri Apr 20 19:13:11 2012 +0200 +++ b/src/js/init.js Mon Apr 23 19:11:08 2012 +0200 @@ -5,9 +5,13 @@ /* The Metadataplayer Object, single point of entry, replaces IriSP.init_player */ IriSP.Metadataplayer = function(config, video_metadata) { - IriSP._.defaults(config.gui, IriSP.guiDefaults); + for (var key in IriSP.guiDefaults) { + if (IriSP.guiDefaults.hasOwnProperty(key) && !config.gui.hasOwnProperty('key')) { + config.gui[key] = IriSP.guiDefaults[key] + } + } var _container = document.getElementById(config.gui.container); - _container.innerHTML = IriSP.templToHTML(IriSP.loading_template, config.gui); + _container.innerHTML = '
Loading... Chargement...
'; this.video_metadata = video_metadata; this.sourceManager = new IriSP.Model.Directory(); this.config = config; @@ -21,7 +25,7 @@ IriSP.Metadataplayer.prototype.loadLibs = function() { // Localize jQuery variable IriSP.jQuery = null; - var $L = $LAB.script(IriSP.getLib("jQuery")).script(IriSP.getLib("swfObject")).wait().script(IriSP.getLib("jQueryUI")); + var $L = $LAB.script(IriSP.getLib("underscore")).script(IriSP.getLib("Mustache")).script(IriSP.getLib("jQuery")).script(IriSP.getLib("swfObject")).wait().script(IriSP.getLib("jQueryUI")); if(this.config.player.type === "jwplayer" || this.config.player.type === "allocine" || this.config.player.type === "dailymotion") { // load our popcorn.js lookalike @@ -40,7 +44,7 @@ /* widget specific requirements */ for(var _i = 0; _i < this.config.gui.widgets.length; _i++) { - if(this.config.gui.widgets[_i].type === "StackGraphWidget" || this.config.gui.widgets[_i].type === "SparklineWidget") { + if(this.config.gui.widgets[_i].type === "Sparkline") { $L.script(IriSP.getLib("raphael")); } if(this.config.gui.widgets[_i].type === "TraceWidget") { @@ -52,26 +56,34 @@ $L.wait(function() { IriSP.jQuery = window.jQuery.noConflict(true); - - var css_link_jquery = IriSP.jQuery("", { - rel : "stylesheet", - type : "text/css", - href : IriSP.getLib("cssjQueryUI") - }); - var css_link_custom = IriSP.jQuery("", { - rel : "stylesheet", - type : "text/css", - href : _this.config.gui.css - }); - - css_link_jquery.appendTo('head'); - css_link_custom.appendTo('head'); + IriSP._ = window._.noConflict(); + + IriSP.loadCss(IriSP.getLib("cssjQueryUI")) + IriSP.loadCss(_this.config.gui.css); _this.onLibsLoaded(); }); } +IriSP.Metadataplayer.prototype.onLibsLoaded = function() { + console.log('OnLibsLoaded'); + this.videoData = this.loadMetadata(this.video_metadata); + this.$ = IriSP.jQuery('#' + this.config.gui.container); + this.$.css({ + "width": this.config.gui.width, + "clear": "both" + }); + if (typeof this.config.gui.height !== "undefined") { + this.$.css("height", this.config.gui.height); + } + + var _this = this; + this.videoData.onLoad(function() { + _this.onVideoDataLoaded(); + }); +} + IriSP.Metadataplayer.prototype.loadMetadata = function(_metadataInfo) { if (typeof _metadataInfo.serializer === "undefined" && typeof _metadataInfo.format !== "undefined") { _metadataInfo.serializer = IriSP.serializers[_metadataInfo.format]; @@ -86,23 +98,6 @@ } } -IriSP.Metadataplayer.prototype.onLibsLoaded = function() { - this.videoData = this.loadMetadata(this.video_metadata); - this.$ = IriSP.jQuery('#' + this.config.gui.container); - this.$.css({ - "width": this.config.gui.width, - "clear": "both" - }); - if (typeof this.config.gui.height !== "undefined") { - this.$.css("height", this.config.gui.height); - } - - var _this = this; - this.videoData.onLoad(function() { - _this.onVideoDataLoaded(); - }); -} - IriSP.Metadataplayer.prototype.onVideoDataLoaded = function() { if (typeof this.videoData !== "undefined" && typeof this.config.player.video === "undefined") { var _media = this.videoData.currentMedia; @@ -117,15 +112,36 @@ } this.configurePopcorn(); this.widgets = []; + var _this = this; for(var i = 0; i < this.config.gui.widgets.length; i++) { - var _widget = this.config.gui.widgets[i]; - if (typeof IriSP[_widget.type] !== "undefined") { - this.widgets.push(new IriSP[_widget.type](this, _widget)); - } else { - console.log("Error, Call to Undefined Widget Type : "+_widget.type); - } + this.loadWidget(this.config.gui.widgets[i], function(_widget) { + _this.widgets.push(_widget) + }); }; - this.$.find('.Ldt-loader').detach(); + this.$.find('.Ldt-Loader').detach(); +} + +IriSP.Metadataplayer.prototype.loadWidget = function(_widgetConfig, _callback) { + /* Creating containers if needed */ + if (typeof _widgetConfig.container === "undefined") { + var _divs = this.layoutDivs(_widgetConfig.type); + _widgetConfig.container = _divs[0]; + } + + var _this = this; + + if (typeof IriSP.Widgets[_widgetConfig.type] !== "undefined") { + IriSP._.defer(function() { + _callback(new IriSP.Widgets[_widgetConfig.type](_this, _widgetConfig)); + }); + } else { + /* Loading Widget CSS */ + IriSP.loadCss(IriSP.widgetsDir + '/' + _widgetConfig.type + '.css'); + /* Loading Widget JS */ + $LAB.script(IriSP.widgetsDir + '/' + _widgetConfig.type + '.js').wait(function() { + _callback(new IriSP.Widgets[_widgetConfig.type](_this, _widgetConfig)); + }); + } } IriSP.Metadataplayer.prototype.configurePopcorn = function() { diff -r 38b65761a7d5 -r 43629caa77bc src/js/main.js --- a/src/js/main.js Fri Apr 20 19:13:11 2012 +0200 +++ b/src/js/main.js Mon Apr 23 19:11:08 2012 +0200 @@ -12,25 +12,3 @@ __IriSP = IriSP; } -/* underscore comes bundled with the player and we need - it ASAP, so load it that way - */ - -IriSP._ = window._.noConflict(); -IriSP.underscore = IriSP._; - -IriSP.getLib = function(lib) { - return ( - IriSP.libFiles.useCdn && typeof IriSP.libFiles.cdn[lib] == "string" - ? IriSP.libFiles.cdn[lib] - : ( - typeof IriSP.libFiles.locations[lib] == "string" - ? IriSP.libFiles.locations[lib] - : ( - typeof IriSP.libFiles.inDefaultDir[lib] == "string" - ? IriSP.libFiles.defaultDir + IriSP.libFiles.inDefaultDir[lib] - : null - ) - ) - ) -} diff -r 38b65761a7d5 -r 43629caa77bc src/js/pop.js --- a/src/js/pop.js Fri Apr 20 19:13:11 2012 +0200 +++ b/src/js/pop.js Mon Apr 23 19:11:08 2012 +0200 @@ -9,7 +9,9 @@ IriSP.PopcornReplacement.player = function(container, options) { /* the jwplayer calls the callbacks in the global space so we need to preserve them this way */ - var _this = this; + if (typeof IriSP._ === "undefined") { + return; + } this.callbacks = { onReady: IriSP._.bind(this.__initApi, this), diff -r 38b65761a7d5 -r 43629caa77bc src/js/serializers/CinecastSerializer.js --- a/src/js/serializers/CinecastSerializer.js Fri Apr 20 19:13:11 2012 +0200 +++ b/src/js/serializers/CinecastSerializer.js Mon Apr 23 19:11:08 2012 +0200 @@ -70,11 +70,6 @@ _res.title = _data.meta.creator_name; _res.description = _data.content.data; _res.created = IriSP.Model.isoToDate(_data.meta.created); - var _c = parseInt(_data.color).toString(16); - while (_c.length < 6) { - _c = '0' + _c; - } - _res.color = '#' + _c; _res.setMedia(_data.media, _source); _res.setAnnotationType(_data.type); _res.setTags(IriSP._(_data.tags).map(function(_t) { diff -r 38b65761a7d5 -r 43629caa77bc src/js/serializers/PlatformSerializer.js --- a/src/js/serializers/PlatformSerializer.js Fri Apr 20 19:13:11 2012 +0200 +++ b/src/js/serializers/PlatformSerializer.js Mon Apr 23 19:11:08 2012 +0200 @@ -80,11 +80,13 @@ _res.title = _data.content.title || ""; _res.description = _data.content.description || ""; _res.created = IriSP.Model.isoToDate(_data.meta["dc:created"]); - var _c = parseInt(_data.color).toString(16); - while (_c.length < 6) { - _c = '0' + _c; + if (typeof _data.color !== "undefined") { + var _c = parseInt(_data.color).toString(16); + while (_c.length < 6) { + _c = '0' + _c; + } + _res.color = '#' + _c; } - _res.color = '#' + _c; _res.setMedia(_data.media, _source); _res.setAnnotationType(_data.meta["id-ref"]); _res.setTags(IriSP._(_data.tags).pluck("id-ref")); diff -r 38b65761a7d5 -r 43629caa77bc src/js/utils.js --- a/src/js/utils.js Fri Apr 20 19:13:11 2012 +0200 +++ b/src/js/utils.js Mon Apr 23 19:11:08 2012 +0200 @@ -1,5 +1,26 @@ /* utils.js - various utils that don't belong anywhere else */ +IriSP.getLib = function(lib) { + if (IriSP.libFiles.useCdn && typeof IriSP.libFiles.cdn[lib] == "string") { + return IriSP.libFiles.cdn[lib]; + } + if (typeof IriSP.libFiles.locations[lib] == "string") { + return IriSP.libFiles.locations[lib]; + } + if (typeof IriSP.libFiles.inDefaultDir[lib] == "string") { + return IriSP.libFiles.defaultDir + IriSP.libFiles.inDefaultDir[lib]; + } +} + +IriSP.loadCss = function(_cssFile) { + IriSP.jQuery("", { + rel : "stylesheet", + type : "text/css", + href : _cssFile + }).appendTo('head'); +} + +/* IriSP.padWithZeros = function(num) { if (Math.abs(num) < 10) { return "0" + num.toString(); @@ -10,7 +31,7 @@ /* convert a number of milliseconds to a tuple of the form [hours, minutes, seconds] -*/ + IriSP.msToTime = function(ms) { return IriSP.secondsToTime(ms / 1000); } @@ -38,7 +59,7 @@ return tweet; }; - +/* IriSP.countProperties = function(obj) { var count = 0; @@ -62,9 +83,9 @@ return zeroes + str; }; -/* shortcut to have global variables in templates */ +/* shortcut to have global variables in templates IriSP.templToHTML = function(template, values) { - var params = IriSP.underscore.extend( + var params = IriSP._.extend( { "l10n" : IriSP.i18n.getMessages() }, diff -r 38b65761a7d5 -r 43629caa77bc src/js/widgets.js --- a/src/js/widgets.js Fri Apr 20 19:13:11 2012 +0200 +++ b/src/js/widgets.js Mon Apr 23 19:11:08 2012 +0200 @@ -1,4 +1,8 @@ -/* the widget classes and definitions */ +/* Definition of an ancestor for the Widget classes */ + +if (typeof IriSP.Widgets === "undefined") { + IriSP.Widgets = {} +} /** * @class IriSP.Widget is an "abstract" class. It's mostly used to define some properties common to every widget. @@ -10,7 +14,9 @@ * @param player - a reference to the player widget * @param config - configuration options for the widget */ -IriSP.Widget = function(player, config) { + + +IriSP.Widgets.Widget = function(player, config) { if( typeof player === "undefined") { /* Probably an abstract call of the class when @@ -20,16 +26,9 @@ /* Setting all the configuration options */ var _type = config.type, - _config = IriSP._.defaults({}, config, player.config.gui.default_options, IriSP.widgetsDefaults[_type]), + _config = IriSP._.defaults({}, config, player.config.gui.default_options, this.defaults), _this = this; - /* Creating containers if needed */ - if (typeof _config.container === "undefined") { - var _divs = player.layoutDivs(_type); - _config.container = _divs[0]; - _config.spacer = _divs[1]; - } - IriSP._(_config).forEach(function(_value, _key) { _this[_key] = _value; }); @@ -52,28 +51,40 @@ }); /* Adding classes and html attributes */ - console.log(this.container); this.$ = IriSP.jQuery('#' + this.container); - this.$.addClass("Ldt-TraceMe").addClass("Ldt-Widget").attr("widget-type", _type); + this.$.addClass("Ldt-TraceMe Ldt-Widget").attr("widget-type", _type); /* Does the widget require other widgets ? */ if (typeof this.requires !== "undefined") { for (var _i = 0; _i < this.requires.length; _i++) { var _subconfig = this.requires[_i]; - if (typeof IriSP[_subconfig.type] !== "undefined") { - _subconfig.container = IriSP._.uniqueId(this.container + '_' + _subconfig.type + '_'); - this.$.append(IriSP.jQuery('
').attr("id",_subconfig.container)); - console.log(this.$.html()); - this[_subconfig.type] = new IriSP[_subconfig.type](player, _subconfig); - } else { - console.log("Error, Call to Undefined Widget Type : "+_subconfig.type); - } + _subconfig.container = IriSP._.uniqueId(this.container + '_' + _subconfig.type + '_'); + this.$.append(IriSP.jQuery('
').attr("id",_subconfig.container)); + this.player.loadWidget(_subconfig, function(_widget) { + _this[_subconfig.type.replace(/^./,function(_s){return _s.toLowerCase();})] = _widget + }); } } + this.l10n = (typeof this.messages[IriSP.language] !== "undefined" ? this.messages[IriSP.language] : this.messages["en"]); + }; -IriSP.Widget.prototype.functionWrapper = function(_name) { +IriSP.Widgets.Widget.prototype.defaults = {} + +IriSP.Widgets.Widget.prototype.template = ''; + +IriSP.Widgets.Widget.prototype.messages = {"en":{}}; + +IriSP.Widgets.Widget.prototype.templateToHtml = function(_template) { + return Mustache.to_html(_template, this); +} + +IriSP.Widgets.Widget.prototype.renderTemplate = function() { + this.$.append(this.templateToHtml(this.template)); +} + +IriSP.Widgets.Widget.prototype.functionWrapper = function(_name) { var _this = this, _function = this[_name]; if (typeof _function !== "undefined") { @@ -85,19 +96,19 @@ } } -IriSP.Widget.prototype.bindPopcorn = function(_popcornEvent, _functionName) { +IriSP.Widgets.Widget.prototype.bindPopcorn = function(_popcornEvent, _functionName) { this.player.popcorn.listen(_popcornEvent, this.functionWrapper(_functionName)) } /** * This method responsible of drawing a widget on screen. */ -IriSP.Widget.prototype.draw = function() { +IriSP.Widgets.Widget.prototype.draw = function() { /* implemented by "sub-classes" */ }; /** * Optional method if you want your widget to support redraws. */ -IriSP.Widget.prototype.redraw = function() { +IriSP.Widgets.Widget.prototype.redraw = function() { /* implemented by "sub-classes" */ }; diff -r 38b65761a7d5 -r 43629caa77bc src/js/widgets/annotationsListWidget.js --- a/src/js/widgets/annotationsListWidget.js Fri Apr 20 19:13:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,174 +0,0 @@ -IriSP.AnnotationsListWidget = function(player, config) { - IriSP.Widget.call(this, player, config); - this.bindPopcorn("IriSP.search", "searchHandler"); - this.bindPopcorn("IriSP.search.closed", "searchHandler"); - this.bindPopcorn("IriSP.search.cleared", "searchHandler"); - this.searchString = false; - this.lastIds = []; - var _this = this; - this.throttledRefresh = IriSP._.throttle(function() { - _this.refresh(false); - }, 1500); -}; - -IriSP.AnnotationsListWidget.prototype = new IriSP.Widget(); - -IriSP.AnnotationsListWidget.prototype.clear = function() { -}; - -IriSP.AnnotationsListWidget.prototype.clearWidget = function() { -}; - -IriSP.AnnotationsListWidget.prototype.searchHandler = function(searchString) { - this.searchString = typeof searchString !== "undefined" ? searchString : ''; - var _n = this.refresh(true); - if (this.searchString) { - if (_n) { - this.player.popcorn.trigger("IriSP.search.matchFound"); - } else { - this.player.popcorn.trigger("IriSP.search.noMatchFound"); - } - } -} - -//obj.url = this.project_url + "/" + media + "/" + annotations[i].meta.project + "/" + annotations[i].meta["id-ref"] + '#id=' + annotations[i].id; - -IriSP.AnnotationsListWidget.prototype.ajaxSource = function() { - var _currentTime = this.player.popcorn.currentTime(), - _duration = this.source.getDuration(); - if (typeof _currentTime == "undefined") { - _currentTime = 0; - } - this.lastAjaxQuery = _currentTime; - _currentTime = Math.floor(1000 * _currentTime); - var _url = Mustache.to_html(this.ajax_url, { - media : this.source.currentMedia.namespacedId.name, - begin : Math.max(0, _currentTime - this.ajax_granularity), - end : Math.min(_duration.milliseconds, _currentTime + this.ajax_granularity) - }); - this.currentSource = this.player.loadMetadata(IriSP._.defaults({ - "url" : _url - }, this.metadata)); -} - -IriSP.AnnotationsListWidget.prototype.refresh = function(_forceRedraw) { - _forceRedraw = (typeof _forceRedraw !== "undefined" && _forceRedraw); - if (this.currentSource.status !== IriSP.Model._SOURCE_STATUS_READY) { - return 0; - } - var _this = this, - _currentTime = this.player.popcorn.currentTime(); - if (typeof _currentTime == "undefined") { - _currentTime = 0; - } - var _list = this.annotation_type ? this.currentSource.getAnnotationsByTypeTitle(this.annotation_type, true) : this.currentSource.getAnnotations(); - if (this.searchString) { - _list = _list.searchByTextFields(this.searchString); - } - if (this.limit_count) { - _list = _list.sortBy(function(_annotation) { - return Math.abs(_annotation.begin.getSeconds() - _currentTime); - }).slice(0, this.limit_count) - } - if (this.newest_first) { - _list = _list.sortBy(function(_annotation) { - return -_annotation.created.valueOf(); - }); - } else { - _list = _list.sortBy(function(_annotation) { - return _annotation.begin; - }); - } - - var _ids = _list.idIndex; - - if (_forceRedraw || !IriSP._.isEqual(_ids, this.lastIds)) { - /* This part only gets executed if the list needs updating */ - this.lastIds = _ids; - - var _html = IriSP.templToHTML( - IriSP.annotationsListWidget_template, - { - annotations : _list.map(function(_annotation) { - var _url = ( - ( typeof _annotation.url !== "undefined" ) - ? _annotation.url - : ( - ( typeof _this.source.projectId !== "undefined" && typeof _annotation.project !== "undefined" && _this.source.projectId !== _annotation.project ) - ? Mustache.to_html( - this.foreign_url, - { - project : _annotation.project, - media : _annotation.media.id.replace(/^.*:/,''), - annotation : _annotation.namespacedId.name, - annotationType : _annotation.annotationType.id.replace(/^.*:/,'') - } - ) - : '#id=' + _annotation.namespacedId.name - ) - ); - var _res = { - id : _annotation.id, - title : _annotation.title.replace(_annotation.description,''), - description : _annotation.description, - begin : _annotation.begin.toString(), - end : _annotation.end.toString(), - thumbnail : typeof _annotation.thumbnail !== "undefined" ? _annotation.thumbnail : _this.default_thumbnail, - url : _url, - tags : _annotation.getTagTexts() - } - return _res; - }) - }); - - this.$.html(_html); - - this.$.find('.Ldt-AnnotationsList-Tag-Li').click(function() { - _this.player.popcorn.trigger("IriSP.search.triggeredSearch", IriSP.jQuery(this).text().replace(/(^\s+|\s+$)/g,'')); - }) - - if(this.searchString) { - var _searchRe = new RegExp('(' + this.searchString.replace(/(\W)/gm,'\\$1') + ')','gim'); - this.$.find(".Ldt-AnnotationsList-Title a, .Ldt-AnnotationsList-Description").each(function() { - var _$ = IriSP.jQuery(this); - _$.html(_$.text().replace(/(^\s+|\s+$)/g,'').replace(_searchRe, '$1')) - }) - } - } - - if (this.ajax_url && this.ajax_granularity) { - if (Math.abs(_currentTime - this.lastAjaxQuery) > (this.ajax_granularity / 2000)) { - this.ajaxSource(); - } - } - return _list.length; -} - -IriSP.AnnotationsListWidget.prototype.draw = function() { - var _this = this; - - if (this.ajax_url && this.ajax_granularity) { - this.ajaxSource(); - } else { - this.currentSource = this.source; - } - - if (this.refresh_interval) { - window.setInterval(function() { - _this.currentSource.get() - }, this.refresh_interval); - } - - var _events = [ - "IriSP.createAnnotationWidget.addedAnnotation", - "timeupdate", - "seeked", - "loadedmetadata" - ]; - for (var _i = 0; _i < _events.length; _i++) { - this.player.popcorn.listen(_events[_i], this.throttledRefresh); - } - - this.throttledRefresh(); - -}; diff -r 38b65761a7d5 -r 43629caa77bc src/js/widgets/helloWorldWidget.js --- a/src/js/widgets/helloWorldWidget.js Fri Apr 20 19:13:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -IriSP.i18n.addMessages({ - "fr": { - "Hello" : "Bonjour," - }, - "en" : { - "Hello" : "Hello," - } -}) - -IriSP.HelloWorldWidget = function(player, config) { - console.log("Calling IriSP.Widget's constructor from IriSP.HelloWorldWidget"); - IriSP.Widget.call(this, player, config); - if (typeof this.text == "undefined") { - this.text = 'world' - } -} - -IriSP.HelloWorldWidget.prototype = new IriSP.Widget(); - -IriSP.HelloWorldWidget.prototype.draw = function() { - var _tmpl = '

{{l10n.Hello}} {{text}}

Looks like we have {{source.contents.annotation.length}} annotations in this feed

' - _html = IriSP.templToHTML(_tmpl, this); - this.$.append(_html); - this.$.find('p').css({ - "text-align" : "center", - "margin": "10px 0", - "font-size" : "14px" - }); - console.log("HelloWorldWidget was drawn"); -} diff -r 38b65761a7d5 -r 43629caa77bc src/js/widgets/playerWidget.js --- a/src/js/widgets/playerWidget.js Fri Apr 20 19:13:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,264 +0,0 @@ -/* Internationalization for this widget */ - -IriSP.i18n.addMessages( - { - "en": { - "play_pause": "Play/Pause", - "mute_unmute": "Mute/Unmute", - "play": "Play", - "pause": "Pause", - "mute": "Mute", - "unmute": "Unmute", - "annotate": "Annotate", - "search": "Search", - "elapsed_time": "Elapsed time", - "total_time": "Total time", - "volume": "Volume", - "volume_control": "Volume control" - }, - "fr": { - "play_pause": "Lecture/Pause", - "mute_unmute": "Couper/Activer le son", - "play": "Lecture", - "pause": "Pause", - "mute": "Couper le son", - "unmute": "Activer le son", - "annotate": "Annoter", - "search": "Rechercher", - "elapsed_time": "Durée écoulée", - "total_time": "Durée totale", - "volume": "Niveau sonore", - "volume_control": "Réglage du niveau sonore" - } - } -); - - -IriSP.PlayerWidget = function(player, config) { - IriSP.Widget.call(this, player, config); - - this._searchLastValue = ""; -}; - -IriSP.PlayerWidget.prototype = new IriSP.Widget(); - -IriSP.PlayerWidget.prototype.draw = function() { - var _this = this, - _html = IriSP.templToHTML(IriSP.player_template, this); - - this.$.append(_html); - - // Define blocks - this.$playButton = this.$.find(".Ldt-Ctrl-Play"); - this.$searchBlock = this.$.find(".Ldt-Ctrl-Search"); - this.$searchInput = this.$.find(".Ldt-Ctrl-SearchInput"); - this.$volumeBar = this.$.find(".Ldt-Ctrl-Volume-Bar"); - - // handle events - this.bindPopcorn("play","playButtonUpdater"); - this.bindPopcorn("pause","playButtonUpdater"); - this.bindPopcorn("volumechange","volumeUpdater"); - this.bindPopcorn("timeupdate","timeDisplayUpdater"); - this.bindPopcorn("loadedmetadata","timeDisplayUpdater"); - this.bindPopcorn("IriSP.search.matchFound","searchMatch"); - this.bindPopcorn("IriSP.search.noMatchFound","searchNoMatch"); - this.bindPopcorn("IriSP.search.triggeredSearch","triggeredSearch"); - - // handle clicks - this.$playButton.click(this.functionWrapper("playHandler")); - - this.$.find(".Ldt-Ctrl-Annotate").click(function() { - _this.player.popcorn.trigger("IriSP.PlayerWidget.AnnotateButton.clicked"); - }); - this.$.find(".Ldt-Ctrl-SearchBtn").click(this.functionWrapper("searchButtonHandler")); - - this.$searchInput.keyup(this.functionWrapper("searchHandler") ); - - var _volctrl = this.$.find(".Ldt-Ctrl-Volume-Control"); - this.$.find('.Ldt-Ctrl-Sound') - .click(this.functionWrapper("muteHandler")) - .mouseover(function() { - _volctrl.show(); - }) - .mouseout(function() { - _volctrl.hide(); - }); - _volctrl.mouseover(function() { - _volctrl.show(); - }).mouseout(function() { - _volctrl.hide(); - }); - - - // Allow Volume Cursor Dragging - this.$volumeBar.slider({ - slide: function(event, ui) { - _this.$volumeBar.attr("title",IriSP.i18n.getMessage('volume')+': ' + ui.value + '%'); - _this.player.popcorn.volume(ui.value / 100); - }, - stop: this.functionWrapper("volumeUpdater") - }); - - // trigger an IriSP.PlayerWidget.MouseOver to the widgets that are interested (i.e : sliderWidget) - this.$.hover( - function() { - _this.player.popcorn.trigger("IriSP.PlayerWidget.MouseOver"); - }, - function() { - _this.player.popcorn.trigger("IriSP.PlayerWidget.MouseOut"); - }); - setTimeout(this.functionWrapper("volumeUpdater"), 1000); - /* some players - including jwplayer - save the state of the mute button between sessions */ -}; - -/* Update the elasped time div */ -IriSP.PlayerWidget.prototype.timeDisplayUpdater = function() { - var _curTime = this.player.popcorn.roundTime(); - if (typeof this._previousSecond !== "undefined" && _curTime === this._previousSecond) { - return; - } - - // we get it at each call because it may change. - var _totalTime = this.source.getDuration(), - _elapsedTime = new IriSP.Model.Time(); - - _elapsedTime.setSeconds(_curTime); - - this.$.find(".Ldt-Ctrl-Time-Elapsed").html(_elapsedTime.toString()); - this.$.find(".Ldt-Ctrl-Time-Total").html(_totalTime.toString()); - this._previousSecond = _curTime; -}; - -/* update the icon of the button - separate function from playHandler - because in some cases (for instance, when the user directly clicks on - the jwplayer window) we have to change the icon without playing/pausing -*/ -IriSP.PlayerWidget.prototype.playButtonUpdater = function() { - - var status = this.player.popcorn.media.paused; - - if (status) { - /* the background sprite is changed by adding/removing the correct classes */ - this.$playButton - .attr("title", IriSP.i18n.getMessage('play')) - .removeClass("Ldt-Ctrl-Play-PauseState") - .addClass("Ldt-Ctrl-Play-PlayState"); - } else { - this.$playButton - .attr("title", IriSP.i18n.getMessage('pause')) - .removeClass("Ldt-Ctrl-Play-PlayState") - .addClass("Ldt-Ctrl-Play-PauseState"); - } -}; - - -IriSP.PlayerWidget.prototype.playHandler = function() { - - var status = this.player.popcorn.media.paused; - - if (status) { - this.player.popcorn.play(); - } else { - this.player.popcorn.pause(); - } -}; - -IriSP.PlayerWidget.prototype.muteHandler = function() { - this.player.popcorn.mute(!this.player.popcorn.muted()); -}; - -IriSP.PlayerWidget.prototype.volumeUpdater = function() { - var _muted = this.player.popcorn.muted(), - _vol = this.player.popcorn.volume(); - if (_vol === false) { - _vol = .5; - } - var _soundCtl = this.$.find(".Ldt-Ctrl-Sound"); - _soundCtl.removeClass("Ldt-Ctrl-Sound-Mute Ldt-Ctrl-Sound-Half Ldt-Ctrl-Sound-Full"); - if (_muted) { - _soundCtl.attr("title", IriSP.i18n.getMessage('unmute')) - .addClass("Ldt-Ctrl-Sound-Mute"); - } else { - _soundCtl.attr("title", IriSP.i18n.getMessage('mute')) - .addClass(_vol < .5 ? "Ldt-Ctrl-Sound-Half" : "Ldt-Ctrl-Sound-Full" ) - } - this.$volumeBar.slider("value", _muted ? 0 : 100 * _vol); -}; - -IriSP.PlayerWidget.prototype.showSearchBlock = function() { - this.$searchBlock.show("blind", { direction: "horizontal"}, 100); - this.$searchInput.css('background-color','#fff'); - - this.$searchInput.focus(); - - // we need this variable because some widgets can find a match in - // their data while at the same time others don't. As we want the - // search field to become green when there's a match, we need a - // variable to remember that we had one. - this._positiveMatch = false; - - // tell the world the field is open - this.player.popcorn.trigger("IriSP.search.open"); -}; - -IriSP.PlayerWidget.prototype.hideSearchBlock = function() { - this._searchLastValue = this.$searchInput.val(); - this.$searchInput.val(''); - this.$searchBlock.hide("blind", { direction: "horizontal"}, 75); - - this._positiveMatch = false; - - this.player.popcorn.trigger("IriSP.search.closed"); -}; - -/** react to clicks on the search button */ -IriSP.PlayerWidget.prototype.searchButtonHandler = function() { - if ( this.$searchBlock.is(":hidden") ) { - this.showSearchBlock(); - this.$searchInput.val(this._searchLastValue); - this.player.popcorn.trigger("IriSP.search", this._searchLastValue); // trigger the search to make it more natural. - } else { - this.hideSearchBlock(); - } -}; - -/** this handler is called whenever the content of the search - field changes */ -IriSP.PlayerWidget.prototype.searchHandler = function() { - this._searchLastValue = this.$searchInput.val(); - this._positiveMatch = false; - - // do nothing if the search field is empty, instead of highlighting everything. - if (this._searchLastValue == "") { - this.player.popcorn.trigger("IriSP.search.cleared"); - this.$searchInput.css('background-color',''); - } else { - this.player.popcorn.trigger("IriSP.search", this._searchLastValue); - } -}; - -/** - handler for the IriSP.search.found message, which is sent by some views when they - highlight a match. -*/ -IriSP.PlayerWidget.prototype.searchMatch = function() { - this._positiveMatch = true; - this.$searchInput.css('background-color','#e1ffe1'); -}; - -/** the same, except that no value could be found */ -IriSP.PlayerWidget.prototype.searchNoMatch = function() { - if (this._positiveMatch !== true) { - this.$searchInput.css('background-color', "#d62e3a"); - } -}; - -/** react to an IriSP.Player.triggeredSearch - that is, when - a widget ask the PlayerWidget to do a search on his behalf */ -IriSP.PlayerWidget.prototype.triggeredSearch = function(searchString) { - this.showSearchBlock(); - this.$searchInput.attr('value', searchString); - this.player.popcorn.trigger("IriSP.search", searchString); // trigger the search to make it more natural. -}; - - diff -r 38b65761a7d5 -r 43629caa77bc src/js/widgets/polemicWidget.js --- a/src/js/widgets/polemicWidget.js Fri Apr 20 19:13:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,178 +0,0 @@ -IriSP.PolemicWidget = function(player, config) { - IriSP.Widget.call(this, player, config); - this.bindPopcorn("IriSP.search", "searchHandler"); - this.bindPopcorn("IriSP.search.closed", "searchHandler"); - this.bindPopcorn("IriSP.search.cleared", "searchHandler"); - this.bindPopcorn("timeupdate", "onTimeupdate"); - this.sliceCount = Math.floor( this.width / this.element_width ); - this.$zone = IriSP.jQuery('
'); - this.$.append(this.$zone); -}; - -IriSP.PolemicWidget.prototype = new IriSP.Widget(); - -IriSP.PolemicWidget.prototype.searchHandler = function(searchString) { - this.searchString = typeof searchString !== "undefined" ? searchString : ''; - var _found = 0, - _re = IriSP.Model.regexpFromTextOrArray(searchString) - _this = this; - this.$tweets.each(function() { - var _el = IriSP.jQuery(this); - if (_this.searchString) { - if (_re.test(_el.attr("tweet-title"))) { - _el.css({ - "background" : _this.foundcolor, - "opacity" : 1 - }); - _found++; - } else { - _el.css({ - "background" : _el.attr("polemic-color"), - "opacity" : .5 - }); - } - } else { - _el.css({ - "background" : _el.attr("polemic-color"), - "opacity" : 1 - }); - } - }); - if (this.searchString) { - if (_found) { - this.player.popcorn.trigger("IriSP.search.matchFound"); - } else { - this.player.popcorn.trigger("IriSP.search.noMatchFound"); - } - } -} - -IriSP.PolemicWidget.prototype.draw = function() { - var _slices = [], - _duration = this.source.getDuration(), - _max = 0, - _list = this.annotation_type ? this.source.getAnnotationsByTypeTitle(this.annotation_type) : this.source.getAnnotations(); - - for (var _i = 0; _i < this.sliceCount; _i++) { - var _begin = new IriSP.Model.Time(_i*_duration/this.sliceCount), - _end = new IriSP.Model.Time((_i+1)*_duration/this.sliceCount), - _count = 0, - _res = { - annotations : _list.filter(function(_annotation) { - return _annotation.begin >= _begin && _annotation.end < _end; - }), - polemicStacks : [] - } - - for (var _j = 0; _j < this.tags.length; _j++) { - var _polemic = _res.annotations.searchByDescription(this.tags[_j].keywords); - _count += _polemic.length; - _res.polemicStacks.push(_polemic); - } - for (var _j = 0; _j < this.tags.length; _j++) { - _res.annotations.removeElements(_res.polemicStacks[_j]); - } - _count += _res.annotations.length; - _max = Math.max(_max, _count); - _slices.push(_res); - } - this.height = (_max ? (_max + 2) * this.element_height : 0); - this.$zone.css({ - width: this.width + "px", - height: this.height + "px", - position: "relative" - }); - - this.$elapsed = IriSP.jQuery('
') - .css({ - background: '#cccccc', - position: "absolute", - top: 0, - left: 0, - width: 0, - height: "100%" - }); - - this.$zone.append(this.$elapsed); - - var _x = 0, - _this = this; - - function displayElement(_x, _y, _color, _id, _title) { - var _el = IriSP.jQuery('
') - .attr({ - "tweet-title" : _title, - "pos-x" : Math.floor(_x + (_this.element_width - 1) / 2), - "pos-y" : _y, - "polemic-color" : _color, - "annotation-id" : _id - }) - .css({ - position: "absolute", - width: (_this.element_width-1) + "px", - height: _this.element_height + "px", - left: _x + "px", - top: _y + "px", - background: _color - }) - .addClass("Ldt-Polemic-TweetDiv"); - _this.$zone.append(_el); - return _el; - } - - IriSP._(_slices).forEach(function(_slice) { - var _y = _this.height; - _slice.annotations.forEach(function(_annotation) { - _y -= _this.element_height; - displayElement(_x, _y, _this.defaultcolor, _annotation.namespacedId.name, _annotation.title); - }); - IriSP._(_slice.polemicStacks).forEach(function(_annotations, _j) { - var _color = _this.tags[_j].color; - _annotations.forEach(function(_annotation) { - _y -= _this.element_height; - displayElement(_x, _y, _color, _annotation.namespacedId.name, _annotation.title); - }); - }); - _x += _this.element_width; - }); - - this.$tweets = this.$.find(".Ldt-Polemic-TweetDiv"); - - this.$position = IriSP.jQuery('
') - .css({ - background: '#fc00ff', - position: "absolute", - top: 0, - left: "-1px", - width: "2px", - height: "100%" - }); - - this.$zone.append(this.$position); - - this.$tweets - .mouseover(function() { - var _el = IriSP.jQuery(this); - _this.TooltipWidget.show(_el.attr("pos-x"), _el.attr("pos-y"), _el.attr("tweet-title"), _el.attr("polemic-color")); - }) - .mouseout(function() { - _this.TooltipWidget.hide(); - }); - - //TODO: Display Tweet in Tweet Widget on click - - this.$zone.click(function(_e) { - var _x = _e.pageX - _this.$zone.offset().left; - _this.player.popcorn.currentTime(_this.source.getDuration().getSeconds() * _x / _this.width); - }); -} - -IriSP.PolemicWidget.prototype.onTimeupdate = function() { - var _x = Math.floor( this.width * this.player.popcorn.currentTime() / this.source.getDuration().getSeconds()); - this.$elapsed.css({ - width: _x + "px" - }); - this.$position.css({ - left: (_x - 1) + "px" - }) -} diff -r 38b65761a7d5 -r 43629caa77bc src/js/widgets/sliderWidget.js --- a/src/js/widgets/sliderWidget.js Fri Apr 20 19:13:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,105 +0,0 @@ -/* - The Slider Widget fits right under the video - */ - -IriSP.SliderWidget = function(player, config) { - IriSP.Widget.call(this, player, config); - this.bindPopcorn("timeupdate","onTimeupdate"); - this.bindPopcorn("IriSP.PlayerWidget.MouseOver","onMouseover"); - this.bindPopcorn("IriSP.PlayerWidget.MouseOut","onMouseout"); -}; - -IriSP.SliderWidget.prototype = new IriSP.Widget(); - -IriSP.SliderWidget.prototype.draw = function() { - - this.$slider = IriSP.jQuery('
') - .addClass("Ldt-Slider") - .css(this.calculateSliderCss(this.minimized_height)); - - this.$.append(this.$slider); - - var _this = this; - - this.$slider.slider({ - range: "min", - value: 0, - min: 0, - max: this.source.getDuration().getSeconds(), - slide: function(event, ui) { - _this.player.popcorn.currentTime(ui.value); - } - }); - - this.$handle = this.$slider.find('.ui-slider-handle'); - - this.$handle.css(this.calculateHandleCss(this.minimized_height)); - - this.$ - .mouseover(this.functionWrapper("onMouseover")) - .mouseout(this.functionWrapper("onMouseout")); - - this.maximized = false; - this.timeoutId = false; -}; - -IriSP.SliderWidget.prototype.onTimeupdate = function() { - this.$slider.slider("value",this.player.popcorn.currentTime()); -} - -IriSP.SliderWidget.prototype.onMouseover = function() { - if (this.timeoutId) { - window.clearTimeout(this.timeoutId); - this.timeoutId = false; - } - if (!this.maximized) { - this.animateToHeight(this.maximized_height); - this.maximized = true; - } -} - -IriSP.SliderWidget.prototype.onMouseout = function() { - if (this.timeoutId) { - window.clearTimeout(this.timeoutId); - this.timeoutId = false; - } - var _this = this; - this.timeoutId = window.setTimeout(function() { - if (_this.maximized) { - _this.animateToHeight(_this.minimized_height); - _this.maximized = false; - } - _this.timeoutId = false; - }, this.minimize_timeout); - -} - -IriSP.SliderWidget.prototype.animateToHeight = function(_height) { - this.$slider.stop().animate( - this.calculateSliderCss(_height), - 500, - function() { - IriSP.jQuery(this).css("overflow","visible"); - }); - this.$handle.stop().animate( - this.calculateHandleCss(_height), - 500, - function() { - IriSP.jQuery(this).css("overflow","visible"); - }); -} - -IriSP.SliderWidget.prototype.calculateSliderCss = function(_size) { - return { - height: _size + "px", - "margin-top": (this.minimized_height - _size) + "px" - }; -} - -IriSP.SliderWidget.prototype.calculateHandleCss = function(_size) { - return { - height: (2 + _size) + "px", - width: (2 + _size) + "px", - "margin-left": -Math.ceil(2 + _size / 2) + "px" - } -} \ No newline at end of file diff -r 38b65761a7d5 -r 43629caa77bc src/js/widgets/sparklineWidget.js --- a/src/js/widgets/sparklineWidget.js Fri Apr 20 19:13:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,143 +0,0 @@ -/** @class The constructor for the sparkline widget */ -IriSP.SparklineWidget = function(Popcorn, config, Serializer) { - IriSP.Widget.call(this, Popcorn, config, Serializer); - - this._oldAnnotation = null; - this._results = []; - - this.slices = this._config.slices || Math.floor(this.width/20); - if (!this.width) { - this.width = this.selector.width(); - } - if (!this.height) { - this.height = 40; - } - this.selector.css("height", this.height + "px"); - if (this._config.background) { - this.selector.css("background", this._config.background); - } -}; - - -IriSP.SparklineWidget.prototype = new IriSP.Widget(); - -IriSP.SparklineWidget.prototype.clear = function() { - -}; - -/** draw the sparkline using jquery sparkline */ -IriSP.SparklineWidget.prototype.draw = function() { - this.duration = this.getDuration(); - this.paper = new Raphael(this.selector[0], this.width, this.height); - var _this = this; - - var views = this._serializer._data.views; - var stat_view; - if (!IriSP.null_or_undefined(views)) { - for (var i = 0; i < views.length; i++) { - var view = views[i]; - if (view.id === "stat") { - stat_view = view; - break; - } - } - } - - var _ = IriSP.underscore; - // If we've found the correct view, feed the directly the data from the view - // to jquery sparkline. Otherwise, compute it ourselves. - if (!IriSP.null_or_undefined(stat_view)) { - //console.log("sparklinewidget : using stats embedded in the json"); - var _results = stat_view.meta.stat.split(","); - } else { - var _annotations = this._serializer._data.annotations, - _sliceDuration = Math.floor( this.duration / this.slices), - _results = _(_.range(this.slices)).map(function(_i) { - return _(_annotations).filter(function(_a){ - return (_a.begin <= (1 + _i) * _sliceDuration) && (_a.end >= _i * _sliceDuration) - }).length; - }); - } - var _max = Math.max(1, _(_results).max()), - _h = this.height, - _scale = (_h - this.lineWidth) / _max, - _width = this.width / this.slices, - _y = _(_results).map(function(_v) { - return _h - (_scale * _v); - }), - _d = _(_y).reduce(function(_memo, _v, _k) { - return _memo + ( _k - ? 'C' + (_k * _width) + ' ' + _y[_k - 1] + ' ' + (_k * _width) + ' ' + _v + ' ' + ((_k + .5) * _width) + ' ' + _v - : 'M0 ' + _v + 'L' + (.5*_width) + ' ' + _v ) - },'') + 'L' + this.width + ' ' + _y[_y.length - 1], - _d2 = _d + 'L' + this.width + ' ' + this.height + 'L0 ' + this.height; - this.paper.path(_d2).attr({ - "stroke" : "none", - "fill" : this.fillColor - }); - - this.paper.path(_d).attr({ - "fill" : "none", - "stroke" : this.lineColor, - "stroke-width" : this.lineWidth - }); - - this.rectangleProgress = this.paper.rect(0,0,0,this.height) - .attr({ - "stroke" : "none", - "fill" : "#808080", - "opacity" : .3 - }); - this.ligneProgress = this.paper.path("M0 0L0 "+this.height).attr({"stroke":"#ff00ff", "line-width" : 2}); - // save the results in an array so that we can re-use them when a new annotation - // is added. - this._results = _results; - - this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.timeUpdateHandler)); -// this._Popcorn.listen("IriSP.createAnnotationWidget.addedAnnotation", IriSP.wrap(this, this.handleNewAnnotation)); - - this.selector.click(IriSP.wrap(this, this.clickHandler)); -}; - -/** react to a timeupdate event */ -IriSP.SparklineWidget.prototype.timeUpdateHandler = function() { - var _currentTime = this._Popcorn.currentTime(), - _x = (1000 * _currentTime / this.duration) * this.width; - this.rectangleProgress.attr({ - "width" : _x - }); - this.ligneProgress.attr({ - "path" : "M" + _x + " 0L" + _x + " " + this.height - }); - -} - -/** handle clicks on the widget */ -IriSP.SparklineWidget.prototype.clickHandler = function(event) { - var relX = event.pageX - this.selector.offset().left; - var newTime = ((relX / this.width) * this.duration/1000).toFixed(2); - - this._Popcorn.trigger("IriSP.SparklineWidget.clicked", newTime); - this._Popcorn.currentTime(newTime); -}; - -/** react when a new annotation is added */ -IriSP.SparklineWidget.prototype.handleNewAnnotation = function(annotation) { -// var num_columns = this._results.length; -// var duration = this._serializer.getDuration(); -// var time_step = Math.round(duration / num_columns); /* the time interval between two columns */ -// var begin = +annotation.begin; -// var end = +annotation.end; -// -// /* increment all the values between the beginning and the end of the annotation */ -// var index_begin = Math.floor(begin / time_step); -// var index_end = Math.floor(end / time_step); -// -// for (var i = index_begin; i < Math.min(index_end, this._results.length); i++) { -// this._results[i]++; -// } -// -// this.selector.find(".Ldt-sparkLine").sparkline(this._results, {lineColor: "#7492b4", fillColor: "#aeaeb8", -// spotColor: "#b70056", -// width: this.width, height: this.height}); -}; \ No newline at end of file diff -r 38b65761a7d5 -r 43629caa77bc src/js/widgets/tooltipWidget.js --- a/src/js/widgets/tooltipWidget.js Fri Apr 20 19:13:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* this widget displays a small tooltip */ -IriSP.TooltipWidget = function(Popcorn, config, Serializer) { - IriSP.Widget.call(this, Popcorn, config, Serializer); -}; - -IriSP.TooltipWidget.prototype = new IriSP.Widget(); - -IriSP.TooltipWidget.prototype.draw = function() { - var _html = Mustache.to_html(IriSP.tooltipWidget_template), - _this = this; - this.$.parent().css({ - "position" : "relative" - }); - this.$.append(_html); - this.$tip = this.$.find(".Ldt-Tooltip"); - this.$.mouseover(function() { - _this.$tip.hide(); - }); - this.hide(); -}; - -IriSP.TooltipWidget.prototype.show = function(x, y, text, color) { - - if (typeof color !== "undefined") { - this.$.find(".Ldt-Tooltip-Color").show().css("background-color", color); - } else { - this.$.find(".Ldt-Tooltip-Color").hide(); - } - - this.$.find(".Ldt-Tooltip-Text").html(text); - - this.$tip.show(); - this.$tip.css({ - "left" : Math.floor(x - this.$tip.outerWidth() / 2) + "px", - "top" : Math.floor(y - this.$tip.outerHeight() - 5) + "px" - }); -}; - -IriSP.TooltipWidget.prototype.hide = function() { - this.$tip.hide(); -}; diff -r 38b65761a7d5 -r 43629caa77bc src/templates/annotationsListWidget.html --- a/src/templates/annotationsListWidget.html Fri Apr 20 19:13:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -{{! template for the annotation list widget }} -
-
    - {{#annotations}} -
  • -
    - - - -
    -
    {{begin}} - {{end}}
    -

    - {{title}} -

    -

    {{description}}

    - {{#tags.length}} -
      - {{#tags}} - {{#.}} -
    • -
      {{.}}
      -
    • - {{/.}} - {{/tags}} -
    - {{/tags.length}} -
  • - {{/annotations}} -
-
diff -r 38b65761a7d5 -r 43629caa77bc src/templates/player.html --- a/src/templates/player.html Fri Apr 20 19:13:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -{{! template for the radio player }} -
-
-
-
- {{^disable_annotate_btn}} -
-
- {{/disable_annotate_btn}} - {{^disable_search_btn}} -
-
- {{/disable_search_btn}} - -
-
-
-
-
00:00
-
/
-
00:00
-
-
-
-
-
-
-
-
diff -r 38b65761a7d5 -r 43629caa77bc src/templates/tooltipWidget.html --- a/src/templates/tooltipWidget.html Fri Apr 20 19:13:11 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -{{! template for the tooltip widget }} - -
-
-
-
\ No newline at end of file diff -r 38b65761a7d5 -r 43629caa77bc src/widgets/AnnotationsList.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/AnnotationsList.css Mon Apr 23 19:11:08 2012 +0200 @@ -0,0 +1,80 @@ +/* AnnotationsListWidget */ + +.Ldt-AnnotationsListWidget { + font-family: "Open Sans", Helvetica, Arial, sans-serif; + border: 1px solid #b6b8b8; + overflow: auto; + max-height: 480px; +} +.Ldt-AnnotationsListWidget a { + text-decoration: none; +} +ul.Ldt-AnnotationsList-ul { + list-style: none; + padding: 2px; + margin: 0; +} +li.Ldt-AnnotationsList-li { + width: 100%; + clear: both; + margin: 2px 0; + padding: 2px 0; + min-height: 60px; +} +.Ldt-AnnotationsList-li:hover { + background-color: #e9e9e9; +} +.Ldt-AnnotationsList-highlight { + background: #F7268E; + color: #ffffff; +} +.Ldt-AnnotationsList-ThumbContainer { + float: left; + width: 80px; + height: 50px; + text-align: center; + margin: 2px 0; +} +.Ldt-AnnotationsList-Thumbnail { + border: none; + max-width: 100%; + max-height: 100%; + margin: 0 auto; +} +.Ldt-AnnotationsList-Duration { + color: #f7268e; + float: right; + text-align: right; + font-size: 12px; + margin: 2px; +} +h3.Ldt-AnnotationsList-Title { + color: #0068c4; + font-size: 13px; + margin: 2px 2px 0 82px; + font-weight: bold; +} +.Ldt-AnnotationsList-Title a { + color: #0068c4; +} +p.Ldt-AnnotationsList-Description { + margin: 2px 0 2px 82px; + font-size: 12px; + color: #666666; +} +ul.Ldt-AnnotationsList-Tags { + list-style: none; + padding: 0; + margin: 2px 0 0 82px; +} +li.Ldt-AnnotationsList-Tag-Li { + display: inline-block; + margin: 2px; + background: #0068c4; + color: #fff; + padding: 2px; + font-size: 12px; +} +li.Ldt-AnnotationsList-Tag-Li:hover { + background: #F7268E; +} diff -r 38b65761a7d5 -r 43629caa77bc src/widgets/AnnotationsList.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/AnnotationsList.js Mon Apr 23 19:11:08 2012 +0200 @@ -0,0 +1,225 @@ +IriSP.Widgets.AnnotationsList = function(player, config) { + IriSP.Widgets.Widget.call(this, player, config); + this.bindPopcorn("IriSP.search", "searchHandler"); + this.bindPopcorn("IriSP.search.closed", "searchHandler"); + this.bindPopcorn("IriSP.search.cleared", "searchHandler"); + this.searchString = false; + this.lastIds = []; + var _this = this; + this.throttledRefresh = IriSP._.throttle(function() { + _this.refresh(false); + }, 1500); +}; + +IriSP.Widgets.AnnotationsList.prototype = new IriSP.Widgets.Widget(); + +IriSP.Widgets.AnnotationsList.prototype.defaults = { + /* URL when the annotations are to be reloaded from an LDT-like segment API + * e.g. http://ldt.iri.centrepompidou.fr/ldtplatform/api/ldt/segments/{{media}}/{{begin}}/{{end}}?callback=? + */ + ajax_url : false, + /* how much ms should we look before and after the current timecode in the segment API + */ + ajax_granularity : 300000, + default_thumbnail : "http://ldt.iri.centrepompidou.fr/static/site/ldt/css/imgs/video_sequence.png", + /* URL when the annotation is not in the current project, + * e.g. http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/{{media}}/{{project}}/{{annotationType}}#id={{annotation}} + */ + foreign_url : "", + cinecast_version : false, + annotation_type : false, + refresh_interval : 0, + limit_count : 10, + newest_first : false +}; + +IriSP.Widgets.AnnotationsList.prototype.template = + '
' + + '
    ' + + '{{#annotations}}' + + '
  • ' + + '
    ' + + '' + + '' + + '' + + '
    ' + + '
    {{begin}} - {{end}}
    ' + + '

    ' + + '{{title}}' + + '

    ' + + '

    {{description}}

    ' + + '{{#tags.length}}' + + '
      ' + + '{{#tags}}' + + '{{#.}}' + + '
    • ' + + '
      {{.}}
      ' + + '
    • ' + + '{{/.}}' + + '{{/tags}}' + + '
    ' + + '{{/tags.length}}' + + '
  • ' + + '{{/annotations}}' + + '
' + + '
'; + +IriSP.Widgets.AnnotationsList.prototype.clear = function() { +}; + +IriSP.Widgets.AnnotationsList.prototype.clearWidget = function() { +}; + +IriSP.Widgets.AnnotationsList.prototype.searchHandler = function(searchString) { + this.searchString = typeof searchString !== "undefined" ? searchString : ''; + var _n = this.refresh(true); + if (this.searchString) { + if (_n) { + this.player.popcorn.trigger("IriSP.search.matchFound"); + } else { + this.player.popcorn.trigger("IriSP.search.noMatchFound"); + } + } +} + +//obj.url = this.project_url + "/" + media + "/" + annotations[i].meta.project + "/" + annotations[i].meta["id-ref"] + '#id=' + annotations[i].id; + +IriSP.Widgets.AnnotationsList.prototype.ajaxSource = function() { + var _currentTime = this.player.popcorn.currentTime(), + _duration = this.source.getDuration(); + if (typeof _currentTime == "undefined") { + _currentTime = 0; + } + this.lastAjaxQuery = _currentTime; + _currentTime = Math.floor(1000 * _currentTime); + var _url = Mustache.to_html(this.ajax_url, { + media : this.source.currentMedia.namespacedId.name, + begin : Math.max(0, _currentTime - this.ajax_granularity), + end : Math.min(_duration.milliseconds, _currentTime + this.ajax_granularity) + }); + this.currentSource = this.player.loadMetadata(IriSP._.defaults({ + "url" : _url + }, this.metadata)); +} + +IriSP.Widgets.AnnotationsList.prototype.refresh = function(_forceRedraw) { + _forceRedraw = (typeof _forceRedraw !== "undefined" && _forceRedraw); + if (this.currentSource.status !== IriSP.Model._SOURCE_STATUS_READY) { + return 0; + } + var _this = this, + _currentTime = this.player.popcorn.currentTime(); + if (typeof _currentTime == "undefined") { + _currentTime = 0; + } + var _list = this.annotation_type ? this.currentSource.getAnnotationsByTypeTitle(this.annotation_type, true) : this.currentSource.getAnnotations(); + if (this.searchString) { + _list = _list.searchByTextFields(this.searchString); + } + if (this.limit_count) { + _list = _list.sortBy(function(_annotation) { + return Math.abs(_annotation.begin.getSeconds() - _currentTime); + }).slice(0, this.limit_count) + } + if (this.newest_first) { + _list = _list.sortBy(function(_annotation) { + return -_annotation.created.valueOf(); + }); + } else { + _list = _list.sortBy(function(_annotation) { + return _annotation.begin; + }); + } + + var _ids = _list.idIndex; + + if (_forceRedraw || !IriSP._.isEqual(_ids, this.lastIds)) { + /* This part only gets executed if the list needs updating */ + this.lastIds = _ids; + + var _html = Mustache.to_html( + this.template, + { + annotations : _list.map(function(_annotation) { + var _url = ( + ( typeof _annotation.url !== "undefined" ) + ? _annotation.url + : ( + ( typeof _this.source.projectId !== "undefined" && typeof _annotation.project !== "undefined" && _this.source.projectId !== _annotation.project ) + ? Mustache.to_html( + this.foreign_url, + { + project : _annotation.project, + media : _annotation.media.id.replace(/^.*:/,''), + annotation : _annotation.namespacedId.name, + annotationType : _annotation.annotationType.id.replace(/^.*:/,'') + } + ) + : '#id=' + _annotation.namespacedId.name + ) + ); + var _res = { + id : _annotation.id, + title : _annotation.title.replace(_annotation.description,''), + description : _annotation.description, + begin : _annotation.begin.toString(), + end : _annotation.end.toString(), + thumbnail : typeof _annotation.thumbnail !== "undefined" ? _annotation.thumbnail : _this.default_thumbnail, + url : _url, + tags : _annotation.getTagTexts() + } + return _res; + }) + }); + + this.$.html(_html); + + this.$.find('.Ldt-AnnotationsList-Tag-Li').click(function() { + _this.player.popcorn.trigger("IriSP.search.triggeredSearch", IriSP.jQuery(this).text().replace(/(^\s+|\s+$)/g,'')); + }) + + if(this.searchString) { + var _searchRe = new RegExp('(' + this.searchString.replace(/(\W)/gm,'\\$1') + ')','gim'); + this.$.find(".Ldt-AnnotationsList-Title a, .Ldt-AnnotationsList-Description").each(function() { + var _$ = IriSP.jQuery(this); + _$.html(_$.text().replace(/(^\s+|\s+$)/g,'').replace(_searchRe, '$1')) + }) + } + } + + if (this.ajax_url && this.ajax_granularity) { + if (Math.abs(_currentTime - this.lastAjaxQuery) > (this.ajax_granularity / 2000)) { + this.ajaxSource(); + } + } + return _list.length; +} + +IriSP.Widgets.AnnotationsList.prototype.draw = function() { + var _this = this; + + if (this.ajax_url && this.ajax_granularity) { + this.ajaxSource(); + } else { + this.currentSource = this.source; + } + + if (this.refresh_interval) { + window.setInterval(function() { + _this.currentSource.get() + }, this.refresh_interval); + } + + var _events = [ + "IriSP.createAnnotationWidget.addedAnnotation", + "timeupdate", + "seeked", + "loadedmetadata" + ]; + for (var _i = 0; _i < _events.length; _i++) { + this.player.popcorn.listen(_events[_i], this.throttledRefresh); + } + + this.throttledRefresh(); + +}; diff -r 38b65761a7d5 -r 43629caa77bc src/widgets/Controller.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/Controller.css Mon Apr 23 19:11:08 2012 +0200 @@ -0,0 +1,178 @@ +/* Player Widget */ + +.Ldt-Ctrl { + font-size: 10px; + font-family: "Trebuchet MS", "Helvetica", "Arial", "Verdana", "sans-serif"; + background:url('img/player_gradient.png') repeat-x transparent ; + height: 25px; + border: 1px solid #b6b8b8; + position: relative; +} + +.Ldt-Ctrl-Left { + float:left; +} + +.Ldt-Ctrl-Right { + float: right; +} + +.Ldt-Ctrl-button { + float: left; + width: 30px; height: 25px; + background: url('img/player-sprites.png'); + cursor: pointer; +} + +.Ldt-Ctrl-spacer { + float: left; width: 1px; height: 25px; background: #b6b8b8; +} + +.Ldt-Ctrl-Play { + margin: 0 15px; +} + +.Ldt-Ctrl-Play-PlayState { + background-position: 0 0; +} + +.Ldt-Ctrl-Play-PlayState:hover { + background-position: 0 -25px; +} + +.Ldt-Ctrl-Play-PlayState:active { + background-position: 0 -50px; +} + +.Ldt-Ctrl-Play-PauseState { + background-position: -30px 0; +} + +.Ldt-Ctrl-Play-PauseState:hover { + background-position: -30px -25px; +} + +.Ldt-Ctrl-Play-PauseState:active { + background-position: -30px -50px; +} + +.Ldt-Ctrl-Annotate { + margin: 0 2px; + background-position: -60px 0; +} + +.Ldt-Ctrl-Annotate:hover { + background-position: -60px -25px; +} + +.Ldt-Ctrl-Annotate:active { + background-position: -60px -50px; +} + +.Ldt-Ctrl-SearchBtn { + margin: 0 2px; + background-position: -90px 0; +} + +.Ldt-Ctrl-SearchBtn:hover { + background-position: -90px -25px; +} + +.Ldt-Ctrl-SearchBtn:active { + background-position: -90px -50px; +} + +.Ldt-Ctrl-Search { + display: none; + width: 165px; + height: 25px; + border: 1px; + border-color: #CFCFCF; + float: left; + text-align: center; +} + +.Ldt-Ctrl-Time { + float: left; + margin: 5px; + font-size: 12px; + font-family: Arial, Verdana, sans-serif; +} + +.Ldt-Ctrl-Time-Elapsed { + float: left; + color: #4a4a4a; +} + +.Ldt-Ctrl-Time-Separator { + margin: 0 4px; + float: left; +} + +.Ldt-Ctrl-Time-Total { + float: left; + color: #b2b2b2; +} + +.Ldt-Ctrl-Sound { + margin: 0 2px; +} + +.Ldt-Ctrl-Sound-Full { + background-position: -120px 0; +} + +.Ldt-Ctrl-Sound-Full:hover { + background-position: -120px -25px; +} + +.Ldt-Ctrl-Sound-Full:active { + background-position: -120px -50px; +} + +.Ldt-Ctrl-Sound-Mute { + background-position: -150px 0; +} + +.Ldt-Ctrl-Sound-Mute:hover { + background-position: -150px -25px; +} + +.Ldt-Ctrl-Sound-Mute:active { + background-position: -150px -50px; +} + +.Ldt-Ctrl-Sound-Half { + background-position: -180px 0; +} + +.Ldt-Ctrl-Sound-Half:hover { + background-position: -180px -25px; +} + +.Ldt-Ctrl-Sound-Half:active { + background-position: -180px -50px; +} + +.Ldt-Ctrl-Volume-Control { + display: none; + position: absolute; + background:url('img/player_gradient.png') repeat-x transparent ; + height: 25px; + width: 100px; top: 25px; right: -1px; z-index: 100; + padding: 0 2px; + border: 1px solid #b6b8b8; +} + +.Ldt-Ctrl-Volume-Bar { + height: 5px; margin: 9px 3px 0; background: #cccccc; border: 1px solid #999999; border-radius: 2px; +} + +.Ldt-Ctrl-Volume-Control .ui-slider-handle { + width: 6px; height: 19px; background: #a8a8a8; border: 1px solid #999999; border-radius: 2px; top: -8px; margin-left: -4px; + cursor: pointer; +} + +.Ldt-Ctrl-Volume-Control:hover .ui-slider-handle { + background: #F7268E; +} \ No newline at end of file diff -r 38b65761a7d5 -r 43629caa77bc src/widgets/Controller.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/Controller.js Mon Apr 23 19:11:08 2012 +0200 @@ -0,0 +1,293 @@ +/* Displays Play and Pause buttons, Search Button and Form, Volume Control */ + +IriSP.Widgets.Controller = function(player, config) { + IriSP.Widgets.Widget.call(this, player, config); + + this._searchLastValue = ""; +}; + +IriSP.Widgets.Controller.prototype = new IriSP.Widgets.Widget(); + +IriSP.Widgets.Controller.prototype.defaults = {} + +IriSP.Widgets.Controller.prototype.template = + '
' + + '
' + + '
' + + '
' + + '{{^disable_annotate_btn}}' + + '
' + + '
' + + '{{/disable_annotate_btn}}' + + '{{^disable_search_btn}}' + + '
' + + '
' + + '{{/disable_search_btn}}' + + '' + + '
' + + '
' + + '
' + + '
' + + '
00:00
' + + '
/
' + + '
00:00
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
'; + +IriSP.Widgets.Controller.prototype.messages = { + "en": { + "play_pause": "Play/Pause", + "mute_unmute": "Mute/Unmute", + "play": "Play", + "pause": "Pause", + "mute": "Mute", + "unmute": "Unmute", + "annotate": "Annotate", + "search": "Search", + "elapsed_time": "Elapsed time", + "total_time": "Total time", + "volume": "Volume", + "volume_control": "Volume control" + }, + "fr": { + "play_pause": "Lecture/Pause", + "mute_unmute": "Couper/Activer le son", + "play": "Lecture", + "pause": "Pause", + "mute": "Couper le son", + "unmute": "Activer le son", + "annotate": "Annoter", + "search": "Rechercher", + "elapsed_time": "Durée écoulée", + "total_time": "Durée totale", + "volume": "Niveau sonore", + "volume_control": "Réglage du niveau sonore" + } +}; + +IriSP.Widgets.Controller.prototype.draw = function() { + var _this = this; + this.renderTemplate(); + + // Define blocks + this.$playButton = this.$.find(".Ldt-Ctrl-Play"); + this.$searchBlock = this.$.find(".Ldt-Ctrl-Search"); + this.$searchInput = this.$.find(".Ldt-Ctrl-SearchInput"); + this.$volumeBar = this.$.find(".Ldt-Ctrl-Volume-Bar"); + + // handle events + this.bindPopcorn("play","playButtonUpdater"); + this.bindPopcorn("pause","playButtonUpdater"); + this.bindPopcorn("volumechange","volumeUpdater"); + this.bindPopcorn("timeupdate","timeDisplayUpdater"); + this.bindPopcorn("loadedmetadata","timeDisplayUpdater"); + this.bindPopcorn("IriSP.search.matchFound","searchMatch"); + this.bindPopcorn("IriSP.search.noMatchFound","searchNoMatch"); + this.bindPopcorn("IriSP.search.triggeredSearch","triggeredSearch"); + + // handle clicks + this.$playButton.click(this.functionWrapper("playHandler")); + + this.$.find(".Ldt-Ctrl-Annotate").click(function() { + _this.player.popcorn.trigger("IriSP.Player.AnnotateButton.clicked"); + }); + this.$.find(".Ldt-Ctrl-SearchBtn").click(this.functionWrapper("searchButtonHandler")); + + this.$searchInput.keyup(this.functionWrapper("searchHandler") ); + + var _volctrl = this.$.find(".Ldt-Ctrl-Volume-Control"); + this.$.find('.Ldt-Ctrl-Sound') + .click(this.functionWrapper("muteHandler")) + .mouseover(function() { + _volctrl.show(); + }) + .mouseout(function() { + _volctrl.hide(); + }); + _volctrl.mouseover(function() { + _volctrl.show(); + }).mouseout(function() { + _volctrl.hide(); + }); + + + // Allow Volume Cursor Dragging + this.$volumeBar.slider({ + slide: function(event, ui) { + _this.$volumeBar.attr("title",this.l10n.volume+': ' + ui.value + '%'); + _this.player.popcorn.volume(ui.value / 100); + }, + stop: this.functionWrapper("volumeUpdater") + }); + + // trigger an IriSP.Player.MouseOver to the widgets that are interested (i.e : sliderWidget) + this.$.hover( + function() { + _this.player.popcorn.trigger("IriSP.Player.MouseOver"); + }, + function() { + _this.player.popcorn.trigger("IriSP.Player.MouseOut"); + }); + setTimeout(this.functionWrapper("volumeUpdater"), 1000); + /* some players - including jwplayer - save the state of the mute button between sessions */ +}; + +/* Update the elasped time div */ +IriSP.Widgets.Controller.prototype.timeDisplayUpdater = function() { + var _curTime = this.player.popcorn.roundTime(); + if (typeof this._previousSecond !== "undefined" && _curTime === this._previousSecond) { + return; + } + + // we get it at each call because it may change. + var _totalTime = this.source.getDuration(), + _elapsedTime = new IriSP.Model.Time(); + + _elapsedTime.setSeconds(_curTime); + + this.$.find(".Ldt-Ctrl-Time-Elapsed").html(_elapsedTime.toString()); + this.$.find(".Ldt-Ctrl-Time-Total").html(_totalTime.toString()); + this._previousSecond = _curTime; +}; + +/* update the icon of the button - separate function from playHandler + because in some cases (for instance, when the user directly clicks on + the jwplayer window) we have to change the icon without playing/pausing +*/ +IriSP.Widgets.Controller.prototype.playButtonUpdater = function() { + + var status = this.player.popcorn.media.paused; + + if (status) { + /* the background sprite is changed by adding/removing the correct classes */ + this.$playButton + .attr("title", this.l10n.play) + .removeClass("Ldt-Ctrl-Play-PauseState") + .addClass("Ldt-Ctrl-Play-PlayState"); + } else { + this.$playButton + .attr("title", this.l10n.pause) + .removeClass("Ldt-Ctrl-Play-PlayState") + .addClass("Ldt-Ctrl-Play-PauseState"); + } +}; + + +IriSP.Widgets.Controller.prototype.playHandler = function() { + + var status = this.player.popcorn.media.paused; + + if (status) { + this.player.popcorn.play(); + } else { + this.player.popcorn.pause(); + } +}; + +IriSP.Widgets.Controller.prototype.muteHandler = function() { + this.player.popcorn.mute(!this.player.popcorn.muted()); +}; + +IriSP.Widgets.Controller.prototype.volumeUpdater = function() { + var _muted = this.player.popcorn.muted(), + _vol = this.player.popcorn.volume(); + if (_vol === false) { + _vol = .5; + } + var _soundCtl = this.$.find(".Ldt-Ctrl-Sound"); + _soundCtl.removeClass("Ldt-Ctrl-Sound-Mute Ldt-Ctrl-Sound-Half Ldt-Ctrl-Sound-Full"); + if (_muted) { + _soundCtl.attr("title", this.l10n.unmute) + .addClass("Ldt-Ctrl-Sound-Mute"); + } else { + _soundCtl.attr("title", this.l10n.mute) + .addClass(_vol < .5 ? "Ldt-Ctrl-Sound-Half" : "Ldt-Ctrl-Sound-Full" ) + } + this.$volumeBar.slider("value", _muted ? 0 : 100 * _vol); +}; + +IriSP.Widgets.Controller.prototype.showSearchBlock = function() { + this.$searchBlock.show("blind", { direction: "horizontal"}, 100); + this.$searchInput.css('background-color','#fff'); + + this.$searchInput.focus(); + + // we need this variable because some widgets can find a match in + // their data while at the same time others don't. As we want the + // search field to become green when there's a match, we need a + // variable to remember that we had one. + this._positiveMatch = false; + + // tell the world the field is open + this.player.popcorn.trigger("IriSP.search.open"); +}; + +IriSP.Widgets.Controller.prototype.hideSearchBlock = function() { + this._searchLastValue = this.$searchInput.val(); + this.$searchInput.val(''); + this.$searchBlock.hide("blind", { direction: "horizontal"}, 75); + + this._positiveMatch = false; + + this.player.popcorn.trigger("IriSP.search.closed"); +}; + +/** react to clicks on the search button */ +IriSP.Widgets.Controller.prototype.searchButtonHandler = function() { + if ( this.$searchBlock.is(":hidden") ) { + this.showSearchBlock(); + this.$searchInput.val(this._searchLastValue); + this.player.popcorn.trigger("IriSP.search", this._searchLastValue); // trigger the search to make it more natural. + } else { + this.hideSearchBlock(); + } +}; + +/** this handler is called whenever the content of the search + field changes */ +IriSP.Widgets.Controller.prototype.searchHandler = function() { + this._searchLastValue = this.$searchInput.val(); + this._positiveMatch = false; + + // do nothing if the search field is empty, instead of highlighting everything. + if (this._searchLastValue == "") { + this.player.popcorn.trigger("IriSP.search.cleared"); + this.$searchInput.css('background-color',''); + } else { + this.player.popcorn.trigger("IriSP.search", this._searchLastValue); + } +}; + +/** + handler for the IriSP.search.found message, which is sent by some views when they + highlight a match. +*/ +IriSP.Widgets.Controller.prototype.searchMatch = function() { + this._positiveMatch = true; + this.$searchInput.css('background-color','#e1ffe1'); +}; + +/** the same, except that no value could be found */ +IriSP.Widgets.Controller.prototype.searchNoMatch = function() { + if (this._positiveMatch !== true) { + this.$searchInput.css('background-color', "#d62e3a"); + } +}; + +/** react to an IriSP.Player.triggeredSearch - that is, when + a widget ask the.Player to do a search on his behalf */ +IriSP.Widgets.Controller.prototype.triggeredSearch = function(searchString) { + this.showSearchBlock(); + this.$searchInput.attr('value', searchString); + this.player.popcorn.trigger("IriSP.search", searchString); // trigger the search to make it more natural. +}; + + diff -r 38b65761a7d5 -r 43629caa77bc src/widgets/HelloWorld.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/HelloWorld.css Mon Apr 23 19:11:08 2012 +0200 @@ -0,0 +1,3 @@ +.Ldt-HelloWorld p { + text-align: center; font-size: 12px; margin: 2px 0; font-family: Helvetica, Arial, sans-serif; +} diff -r 38b65761a7d5 -r 43629caa77bc src/widgets/HelloWorld.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/HelloWorld.js Mon Apr 23 19:11:08 2012 +0200 @@ -0,0 +1,33 @@ +/* Shows an example of a widget, with : + * - Use of source data + * - Use of templating + * - Use of internationalization + */ + +IriSP.Widgets.HelloWorld = function(player, config) { + console.log("Calling IriSP.Widget's constructor from IriSP.HelloWorldWidget"); + IriSP.Widgets.Widget.call(this, player, config); +} + +IriSP.Widgets.HelloWorld.prototype = new IriSP.Widgets.Widget(); + +IriSP.Widgets.HelloWorld.prototype.defaults = { + text: "world" +} + +IriSP.Widgets.HelloWorld.prototype.template = + '

{{l10n.Hello}} {{text}}

Looks like we have {{source.contents.annotation.length}} annotations in this feed

'; + +IriSP.Widgets.HelloWorld.prototype.messages = { + "fr": { + "Hello" : "Bonjour," + }, + "en" : { + "Hello" : "Hello," + } +} + +IriSP.Widgets.HelloWorld.prototype.draw = function() { + this.renderTemplate(); + console.log("HelloWorldWidget was drawn"); +} \ No newline at end of file diff -r 38b65761a7d5 -r 43629caa77bc src/widgets/Polemic.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/Polemic.css Mon Apr 23 19:11:08 2012 +0200 @@ -0,0 +1,9 @@ +.Ldt-Polemic-Position { + background: #fc00ff; + position: absolute; + top: 0; + left: 0; + margin-left: -1px; + width: 2px; + height: 100%; +} \ No newline at end of file diff -r 38b65761a7d5 -r 43629caa77bc src/widgets/Polemic.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/Polemic.js Mon Apr 23 19:11:08 2012 +0200 @@ -0,0 +1,207 @@ +IriSP.Widgets.Polemic = function(player, config) { + IriSP.Widgets.Widget.call(this, player, config); +}; + +IriSP.Widgets.Polemic.prototype = new IriSP.Widgets.Widget(); + +IriSP.Widgets.Polemic.prototype.defaults = { + element_width : 5, + element_height : 5, + annotation_type : "tweet", + defaultcolor : "#585858", + foundcolor : "#fc00ff", + tags : [ + { + "keywords" : [ "++" ], + "description" : "positif", + "color" : "#1D973D" + }, + { + "keywords" : [ "--" ], + "description" : "negatif", + "color" : "#CE0A15" + }, + { + "keywords" : [ "==" ], + "description" : "reference", + "color" : "#C5A62D" + }, + { + "keywords" : [ "??" ], + "description" : "question", + "color" : "#036AAE" + } + ], + requires : [ + { + type: "Tooltip" + } + ] +}; + +IriSP.Widgets.Polemic.prototype.searchHandler = function(searchString) { + this.searchString = typeof searchString !== "undefined" ? searchString : ''; + var _found = 0, + _re = IriSP.Model.regexpFromTextOrArray(searchString) + _this = this; + this.$tweets.each(function() { + var _el = IriSP.jQuery(this); + if (_this.searchString) { + if (_re.test(_el.attr("tweet-title"))) { + _el.css({ + "background" : _this.foundcolor, + "opacity" : 1 + }); + _found++; + } else { + _el.css({ + "background" : _el.attr("polemic-color"), + "opacity" : .5 + }); + } + } else { + _el.css({ + "background" : _el.attr("polemic-color"), + "opacity" : 1 + }); + } + }); + if (this.searchString) { + if (_found) { + this.player.popcorn.trigger("IriSP.search.matchFound"); + } else { + this.player.popcorn.trigger("IriSP.search.noMatchFound"); + } + } +} + +IriSP.Widgets.Polemic.prototype.draw = function() { + + this.bindPopcorn("IriSP.search", "searchHandler"); + this.bindPopcorn("IriSP.search.closed", "searchHandler"); + this.bindPopcorn("IriSP.search.cleared", "searchHandler"); + this.bindPopcorn("timeupdate", "onTimeupdate"); + this.$zone = IriSP.jQuery('
'); + this.$.append(this.$zone); + + var _slices = [], + _slice_count = Math.floor( this.width / this.element_width ), + _duration = this.source.getDuration(), + _max = 0, + _list = this.annotation_type ? this.source.getAnnotationsByTypeTitle(this.annotation_type) : this.source.getAnnotations(); + + for (var _i = 0; _i < _slice_count; _i++) { + var _begin = new IriSP.Model.Time( _i * _duration / _slice_count ), + _end = new IriSP.Model.Time( ( _i + 1 ) * _duration / _slice_count ), + _count = 0, + _res = { + annotations : _list.filter(function(_annotation) { + return _annotation.begin >= _begin && _annotation.end < _end; + }), + polemicStacks : [] + } + + for (var _j = 0; _j < this.tags.length; _j++) { + var _polemic = _res.annotations.searchByDescription(this.tags[_j].keywords); + _count += _polemic.length; + _res.polemicStacks.push(_polemic); + } + for (var _j = 0; _j < this.tags.length; _j++) { + _res.annotations.removeElements(_res.polemicStacks[_j]); + } + _count += _res.annotations.length; + _max = Math.max(_max, _count); + _slices.push(_res); + } + this.height = (_max ? (_max + 2) * this.element_height : 0); + this.$zone.css({ + width: this.width + "px", + height: this.height + "px", + position: "relative" + }); + + this.$elapsed = IriSP.jQuery('
') + .css({ + background: '#cccccc', + position: "absolute", + top: 0, + left: 0, + width: 0, + height: "100%" + }); + + this.$zone.append(this.$elapsed); + + var _x = 0, + _this = this; + + function displayElement(_x, _y, _color, _id, _title) { + var _el = IriSP.jQuery('
') + .attr({ + "tweet-title" : _title, + "pos-x" : Math.floor(_x + (_this.element_width - 1) / 2), + "pos-y" : _y, + "polemic-color" : _color, + "annotation-id" : _id + }) + .css({ + position: "absolute", + width: (_this.element_width-1) + "px", + height: _this.element_height + "px", + left: _x + "px", + top: _y + "px", + background: _color + }) + .addClass("Ldt-Polemic-TweetDiv"); + _this.$zone.append(_el); + return _el; + } + + IriSP._(_slices).forEach(function(_slice) { + var _y = _this.height; + _slice.annotations.forEach(function(_annotation) { + _y -= _this.element_height; + displayElement(_x, _y, _this.defaultcolor, _annotation.namespacedId.name, _annotation.title); + }); + IriSP._(_slice.polemicStacks).forEach(function(_annotations, _j) { + var _color = _this.tags[_j].color; + _annotations.forEach(function(_annotation) { + _y -= _this.element_height; + displayElement(_x, _y, _color, _annotation.namespacedId.name, _annotation.title); + }); + }); + _x += _this.element_width; + }); + + this.$tweets = this.$.find(".Ldt-Polemic-TweetDiv"); + + this.$position = IriSP.jQuery('
').addClass("Ldt-Polemic-Position"); + + this.$zone.append(this.$position); + + this.$tweets + .mouseover(function() { + var _el = IriSP.jQuery(this); + _this.tooltip.show(_el.attr("pos-x"), _el.attr("pos-y"), _el.attr("tweet-title"), _el.attr("polemic-color")); + }) + .mouseout(function() { + _this.tooltip.hide(); + }); + + //TODO: Display Tweet in Tweet Widget on click + + this.$zone.click(function(_e) { + var _x = _e.pageX - _this.$zone.offset().left; + _this.player.popcorn.currentTime(_this.source.getDuration().getSeconds() * _x / _this.width); + }); +} + +IriSP.Widgets.Polemic.prototype.onTimeupdate = function() { + var _x = Math.floor( this.width * this.player.popcorn.currentTime() / this.source.getDuration().getSeconds()); + this.$elapsed.css({ + width: _x + "px" + }); + this.$position.css({ + left: _x + "px" + }) +} diff -r 38b65761a7d5 -r 43629caa77bc src/widgets/Segments.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/Segments.css Mon Apr 23 19:11:08 2012 +0200 @@ -0,0 +1,25 @@ +.Ldt-Segments-List { + width: 100%; height: 100%; +} + +.Ldt-Segments-Segment { + position: absolute; height: 100%; opacity: .7; filter:alpha(opacity=70); margin-left: -1px; border-left: 1px solid #ffffff; +} + +.Ldt-Segments-Segment.active { + opacity: 1; filter:alpha(opacity=100); +} + +.Ldt-Segments-Segment.inactive { + opacity: .4; filter:alpha(opacity=40); +} + +.Ldt-Segments-Position { + background: #fc00ff; + position: absolute; + top: 0; + left: 0; + margin-left: -1px; + width: 2px; + height: 100%; +} \ No newline at end of file diff -r 38b65761a7d5 -r 43629caa77bc src/widgets/Segments.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/Segments.js Mon Apr 23 19:11:08 2012 +0200 @@ -0,0 +1,61 @@ +IriSP.Widgets.Segments = function(player, config) { + IriSP.Widgets.Widget.call(this, player, config); +}; + +IriSP.Widgets.Segments.prototype = new IriSP.Widgets.Widget(); + +IriSP.Widgets.Segments.prototype.defaults = { + annotation_type : "chap", + colors: ["#1f77b4","#aec7e8","#ff7f0e","#ffbb78","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5","#8c564b","#c49c94","#e377c2","#f7b6d2","#7f7f7f","#c7c7c7","#bcbd22","#dbdb8d","#17becf","#9edae5"], + requires : [ + { + type: "Tooltip" + } + ], + height: 10 +}; + +IriSP.Widgets.Segments.prototype.template = + '
{{#segments}}' + + '
' + + '{{/segments}}
' + + '
'; + +IriSP.Widgets.Segments.prototype.draw = function() { + var _list = this.annotation_type ? this.source.getAnnotationsByTypeTitle(this.annotation_type) : this.source.getAnnotations(), + _this = this, + _scale = this.width / this.source.getDuration(); + this.$.css({ + width : this.width + "px", + height : this.height + "px" + }); + this.$.append(Mustache.to_html(this.template, { + segments : _list.map(function(_annotation, _k) { + var _left = _annotation.begin * _scale, + _width = ( _annotation.end - _annotation.begin ) * _scale, + _center = _left + _width / 2; + return { + text : _annotation.title + ( _annotation.description ? '
' + _annotation.description.replace(/(^.{120,140})[\s].+$/,'$1…') : ''), + color : ( typeof _annotation.color !== "undefined" && _annotation.color ? _annotation.color : _this.colors[_k % _this.colors.length] ), + left : Math.floor( _left ), + width : Math.floor( _width ), + center : Math.floor( _center ), + id : _annotation.namespacedId.name + } + }) + })); + var _seglist = this.$.find('.Ldt-Segments-Segment'); + + _seglist.mouseover(function() { + var _el = IriSP.jQuery(this); + _seglist.removeClass("active").addClass("inactive"); + _this.tooltip.show( _el.attr("center-pos"), 0, _el.attr("segment-text"), _el.attr("segment-color")); + _el.removeClass("inactive").addClass("active"); + }).mouseout(function() { + _seglist.removeClass("inactive active"); + }); +} + +IriSP.Widgets.Segments.prototype.searchHandler = function(searchString) { + +} \ No newline at end of file diff -r 38b65761a7d5 -r 43629caa77bc src/widgets/Slider.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/Slider.css Mon Apr 23 19:11:08 2012 +0200 @@ -0,0 +1,14 @@ +/* Slider Widget */ + +.Ldt-Slider { + border: none; border-radius: 0; padding: 0; margin: 0; background: #B6B8B8; +} + +.Ldt-Slider .ui-slider-handle { + border-radius: 8px; top: -2px; background: #fc00ff; border: 1px solid #ffffff; +} + +.Ldt-Slider .ui-slider-range { + background: #747474; +} + diff -r 38b65761a7d5 -r 43629caa77bc src/widgets/Slider.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/Slider.js Mon Apr 23 19:11:08 2012 +0200 @@ -0,0 +1,111 @@ +/* + The Slider Widget fits right under the video + */ + +IriSP.Widgets.Slider = function(player, config) { + IriSP.Widgets.Widget.call(this, player, config); + this.bindPopcorn("timeupdate","onTimeupdate"); + this.bindPopcorn("IriSP.PlayerWidget.MouseOver","onMouseover"); + this.bindPopcorn("IriSP.PlayerWidget.MouseOut","onMouseout"); +}; + +IriSP.Widgets.Slider.prototype = new IriSP.Widgets.Widget(); + +IriSP.Widgets.Slider.prototype.defaults = { + minimized_height : 4, + maximized_height : 10, + minimize_timeout : 1500 // time before minimizing slider after mouseout +}; + +IriSP.Widgets.Slider.prototype.draw = function() { + + this.$slider = IriSP.jQuery('
') + .addClass("Ldt-Slider") + .css(this.calculateSliderCss(this.minimized_height)); + + this.$.append(this.$slider); + + var _this = this; + + this.$slider.slider({ + range: "min", + value: 0, + min: 0, + max: this.source.getDuration().getSeconds(), + slide: function(event, ui) { + _this.player.popcorn.currentTime(ui.value); + } + }); + + this.$handle = this.$slider.find('.ui-slider-handle'); + + this.$handle.css(this.calculateHandleCss(this.minimized_height)); + + this.$ + .mouseover(this.functionWrapper("onMouseover")) + .mouseout(this.functionWrapper("onMouseout")); + + this.maximized = false; + this.timeoutId = false; +}; + +IriSP.Widgets.Slider.prototype.onTimeupdate = function() { + this.$slider.slider("value",this.player.popcorn.currentTime()); +} + +IriSP.Widgets.Slider.prototype.onMouseover = function() { + if (this.timeoutId) { + window.clearTimeout(this.timeoutId); + this.timeoutId = false; + } + if (!this.maximized) { + this.animateToHeight(this.maximized_height); + this.maximized = true; + } +} + +IriSP.Widgets.Slider.prototype.onMouseout = function() { + if (this.timeoutId) { + window.clearTimeout(this.timeoutId); + this.timeoutId = false; + } + var _this = this; + this.timeoutId = window.setTimeout(function() { + if (_this.maximized) { + _this.animateToHeight(_this.minimized_height); + _this.maximized = false; + } + _this.timeoutId = false; + }, this.minimize_timeout); + +} + +IriSP.Widgets.Slider.prototype.animateToHeight = function(_height) { + this.$slider.stop().animate( + this.calculateSliderCss(_height), + 500, + function() { + IriSP.jQuery(this).css("overflow","visible"); + }); + this.$handle.stop().animate( + this.calculateHandleCss(_height), + 500, + function() { + IriSP.jQuery(this).css("overflow","visible"); + }); +} + +IriSP.Widgets.Slider.prototype.calculateSliderCss = function(_size) { + return { + height: _size + "px", + "margin-top": (this.minimized_height - _size) + "px" + }; +} + +IriSP.Widgets.Slider.prototype.calculateHandleCss = function(_size) { + return { + height: (2 + _size) + "px", + width: (2 + _size) + "px", + "margin-left": -Math.ceil(2 + _size / 2) + "px" + } +} \ No newline at end of file diff -r 38b65761a7d5 -r 43629caa77bc src/widgets/Sparkline.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/Sparkline.css Mon Apr 23 19:11:08 2012 +0200 @@ -0,0 +1,3 @@ +/* + * + */ \ No newline at end of file diff -r 38b65761a7d5 -r 43629caa77bc src/widgets/Sparkline.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/Sparkline.js Mon Apr 23 19:11:08 2012 +0200 @@ -0,0 +1,85 @@ +IriSP.Widgets.Sparkline = function(player, config) { + IriSP.Widgets.Widget.call(this, player, config); + //this.bindPopcorn("timeupdate", "onTimeupdate"); +}; + +IriSP.Widgets.Sparkline.prototype = new IriSP.Widgets.Widget(); + +IriSP.Widgets.Sparkline.prototype.defaults = { + lineColor : "#7492b4", + fillColor : "#aeaeb8", + lineWidth : 2, + slice_count : 20, + height : 50, + margin : 5 +}; + +IriSP.Widgets.Sparkline.prototype.draw = function() { + var _slices = [], + _duration = this.source.getDuration(), + _max = 0, + _list = this.annotation_type ? this.source.getAnnotationsByTypeTitle(this.annotation_type) : this.source.getAnnotations(); + + for (var _i = 0; _i < this.slice_count; _i++) { + var _begin = new IriSP.Model.Time(_i*_duration/this.slice_count), + _end = new IriSP.Model.Time((_i+1)*_duration/this.slice_count), + _annotations = _list.filter(function(_annotation) { + return _annotation.begin >= _begin && _annotation.end < _end; + }).length; + _max = Math.max(_max, _annotations); + _slices.push(_annotations); + } + if (!_max) { + return; + } + this.paper = new Raphael(this.$[0], this.width, this.height); + var _scale = (this.height - this.margin) / _max, + _width = this.width / this.slice_count, + _this = this, + _y = IriSP._(_slices).map(function(_v) { + return _this.margin + _this.height - (_scale * _v); + }), + _d = IriSP._(_y).reduce(function(_memo, _v, _k) { + return _memo + ( _k + ? 'C' + (_k * _width) + ' ' + _y[_k - 1] + ' ' + (_k * _width) + ' ' + _v + ' ' + ((_k + .5) * _width) + ' ' + _v + : 'M0 ' + _v + 'L' + (.5*_width) + ' ' + _v ) + },'') + 'L' + this.width + ' ' + _y[_y.length - 1], + _d2 = _d + 'L' + this.width + ' ' + this.height + 'L0 ' + this.height; + + this.paper.path(_d2).attr({ + "stroke" : "none", + "fill" : this.fillColor + }); + + this.paper.path(_d).attr({ + "fill" : "none", + "stroke" : this.lineColor, + "stroke-width" : this.lineWidth + }); + + this.rectangleProgress = this.paper.rect(0,0,0,this.height) + .attr({ + "stroke" : "none", + "fill" : "#808080", + "opacity" : .3 + }); + + this.ligneProgress = this.paper.path("M0 0L0 "+this.height).attr({"stroke":"#ff00ff", "line-width" : 2}); + + this.$.click(function(_e) { + var _x = _e.pageX - _this.$.offset().left; + _this.player.popcorn.currentTime(_this.source.getDuration().getSeconds() * _x / _this.width); + }); + + this.bindPopcorn("timeupdate","onTimeupdate"); +} + +IriSP.Widgets.Sparkline.prototype.onTimeupdate = function() { + var _x = Math.floor( this.width * this.player.popcorn.currentTime() / this.source.getDuration().getSeconds()); + this.rectangleProgress.attr({ + "width" : _x + }); + this.ligneProgress.attr({ + "path" : "M" + _x + " 0L" + _x + " " + this.height + }); +} diff -r 38b65761a7d5 -r 43629caa77bc src/widgets/Tooltip.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/Tooltip.css Mon Apr 23 19:11:08 2012 +0200 @@ -0,0 +1,25 @@ +/* ToolTip Widget */ + +.Ldt-Tooltip { + position: absolute; + padding : 3px; + z-index: 10000000000; + max-width: 200px; + background: transparent url("img/white_arrow_long.png"); + font-size: 12px; + height: 115px; + width: 180px; + padding: 15px 15px 20px; + color: black; + font-family: "Trebuchet MS", "Helvetica", "Arial", "Verdana", "sans-serif"; + overflow:hidden; +} + +.Ldt-Tooltip-Color { + float: left; margin: 2px 4px 2px 0; width: 10px; height: 10px; +} + +.Ldt-Tooltip img { + max-width: 140px; max-height: 70px; margin: 0 20px; +} + diff -r 38b65761a7d5 -r 43629caa77bc src/widgets/Tooltip.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/widgets/Tooltip.js Mon Apr 23 19:11:08 2012 +0200 @@ -0,0 +1,42 @@ +/* this widget displays a small tooltip */ +IriSP.Widgets.Tooltip = function(Popcorn, config, Serializer) { + IriSP.Widgets.Widget.call(this, Popcorn, config, Serializer); +}; + +IriSP.Widgets.Tooltip.prototype = new IriSP.Widgets.Widget(); + +IriSP.Widgets.Tooltip.prototype.template = '
'; + +IriSP.Widgets.Tooltip.prototype.draw = function() { + _this = this; + this.$.html(this.template); + this.$.parent().css({ + "position" : "relative" + }); + this.$tip = this.$.find(".Ldt-Tooltip"); + this.$.mouseover(function() { + _this.$tip.hide(); + }); + this.hide(); +}; + +IriSP.Widgets.Tooltip.prototype.show = function(x, y, text, color) { + + if (typeof color !== "undefined") { + this.$.find(".Ldt-Tooltip-Color").show().css("background-color", color); + } else { + this.$.find(".Ldt-Tooltip-Color").hide(); + } + + this.$.find(".Ldt-Tooltip-Text").html(text); + + this.$tip.show(); + this.$tip.css({ + "left" : Math.floor(x - this.$tip.outerWidth() / 2) + "px", + "top" : Math.floor(y - this.$tip.outerHeight() - 5) + "px" + }); +}; + +IriSP.Widgets.Tooltip.prototype.hide = function() { + this.$tip.hide(); +}; diff -r 38b65761a7d5 -r 43629caa77bc src/widgets/img/player-sprites.png Binary file src/widgets/img/player-sprites.png has changed diff -r 38b65761a7d5 -r 43629caa77bc src/widgets/img/player_gradient.png Binary file src/widgets/img/player_gradient.png has changed diff -r 38b65761a7d5 -r 43629caa77bc src/widgets/img/white_arrow_long.png Binary file src/widgets/img/white_arrow_long.png has changed diff -r 38b65761a7d5 -r 43629caa77bc test/integration/polemic.htm --- a/test/integration/polemic.htm Fri Apr 20 19:13:11 2012 +0200 +++ b/test/integration/polemic.htm Mon Apr 23 19:11:08 2012 +0200 @@ -15,13 +15,14 @@ - +