Explorar el Código

Fix chrome issue when changing audio/video progress

- Undo changes in video plugin that replaces the
  /courses/document to app/courses/document
- Add "Accept-Ranges: bytes"

See CT#8462  BT#14020
jmontoyaa hace 7 años
padre
commit
73ab7c5636

+ 25 - 6
main/inc/lib/document.lib.php

@@ -331,6 +331,9 @@ class DocumentManager
 
         $sendFileHeaders = api_get_configuration_value('enable_x_sendfile_headers');
 
+        // Allows chrome to make videos and audios seekable
+        header('Accept-Ranges: bytes');
+
         if ($forced) {
             // Force the browser to save the file instead of opening it
             if (isset($sendFileHeaders) &&
@@ -353,6 +356,12 @@ class DocumentManager
             header('Content-Description: '.$filename);
             header('Content-Transfer-Encoding: binary');
 
+            if (function_exists('ob_end_clean')) {
+                // Use ob_end_clean() to avoid weird buffering situations
+                // where file is sent broken/incomplete for download
+                ob_end_clean();
+            }
+
             $res = fopen($full_file_name, 'r');
             fpassthru($res);
 
@@ -370,24 +379,25 @@ class DocumentManager
             // Commented to avoid double caching declaration when playing with IE and HTTPS
             //header('Cache-Control: no-cache, must-revalidate');
             //header('Pragma: no-cache');
-            switch ($content_type) {
+            $contentType = self::file_get_mime_type($filename);
+            switch ($contentType) {
                 case 'text/html':
                     if (isset($lpFixedEncoding) && $lpFixedEncoding === 'true') {
-                        $content_type .= '; charset=UTF-8';
+                        $contentType .= '; charset=UTF-8';
                     } else {
                         $encoding = @api_detect_encoding_html(file_get_contents($full_file_name));
                         if (!empty($encoding)) {
-                            $content_type .= '; charset='.$encoding;
+                            $contentType .= '; charset='.$encoding;
                         }
                     }
                     break;
                 case 'text/plain':
                     if (isset($lpFixedEncoding) && $lpFixedEncoding === 'true') {
-                        $content_type .= '; charset=UTF-8';
+                        $contentType .= '; charset=UTF-8';
                     } else {
                         $encoding = @api_detect_encoding(strip_tags(file_get_contents($full_file_name)));
                         if (!empty($encoding)) {
-                            $content_type .= '; charset='.$encoding;
+                            $contentType .= '; charset='.$encoding;
                         }
                     }
                     break;
@@ -396,7 +406,7 @@ class DocumentManager
                     header('Content-type: application/octet-stream');
                     break;
             }
-            header('Content-type: '.$content_type);
+            header('Content-type: '.$contentType);
             header('Content-Length: '.$len);
             $user_agent = strtolower($_SERVER['HTTP_USER_AGENT']);
             if (strpos($user_agent, 'msie')) {
@@ -414,6 +424,15 @@ class DocumentManager
                 );
                 echo $content;
             } else {
+<<<<<<< HEAD
+=======
+                if (function_exists('ob_end_clean')) {
+                    // Use ob_end_clean() to avoid weird buffering situations
+                    // where file is sent broken/incomplete for download
+                    ob_end_clean();
+                }
+
+>>>>>>> 11ffa3a29f... Fix chrome issue when changing audio/video progress
                 readfile($full_file_name);
             }
 

+ 318 - 336
main/inc/lib/javascript/ckeditor/plugins/video/dialogs/video.js

@@ -1,372 +1,354 @@
 CKEDITOR.dialog.add( 'video', function ( editor )
 {
-	var lang = editor.lang.video;
+    var lang = editor.lang.video;
 
-	function commitValue( videoNode, extraStyles )
-	{
-		var value=this.getValue();
+    function commitValue( videoNode, extraStyles )
+    {
+        var value=this.getValue();
 
-		if ( !value && this.id=='id' )
-			value = generateId();
+        if ( !value && this.id=='id' )
+            value = generateId();
 
         if (value == '') {
             return;
         }
 
-		videoNode.setAttribute( this.id, value);
+        videoNode.setAttribute( this.id, value);
 
-		if ( !value )
-			return;
-		switch( this.id )
-		{
-			case 'poster':
-				extraStyles.backgroundImage = 'url(' + value + ')';
-				break;
-			case 'width':
-				extraStyles.width = value + 'px';
-				break;
-			case 'height':
-				extraStyles.height = value + 'px';
-				break;
-		}
-	}
+        if ( !value )
+            return;
+        switch( this.id )
+        {
+            case 'poster':
+                extraStyles.backgroundImage = 'url(' + value + ')';
+                break;
+            case 'width':
+                extraStyles.width = value + 'px';
+                break;
+            case 'height':
+                extraStyles.height = value + 'px';
+                break;
+        }
+    }
 
-	function commitSrc( videoNode, extraStyles, videos )
-	{
-		var match = this.id.match(/(\w+)(\d)/),
-			id = match[1],
-			number = parseInt(match[2], 10);
+    function commitSrc( videoNode, extraStyles, videos )
+    {
+        var match = this.id.match(/(\w+)(\d)/),
+            id = match[1],
+            number = parseInt(match[2], 10);
 
-		var video = videos[number] || (videos[number]={});
-		video[id] = this.getValue();
-	}
+        var video = videos[number] || (videos[number]={});
+        video[id] = this.getValue();
+    }
 
-	function loadValue( videoNode )
-	{
-		if ( videoNode )
-			this.setValue( videoNode.getAttribute( this.id ) );
-		else
-		{
-			if ( this.id == 'id')
-				this.setValue( generateId() );
-		}
-	}
+    function loadValue( videoNode )
+    {
+        if ( videoNode )
+            this.setValue( videoNode.getAttribute( this.id ) );
+        else
+        {
+            if ( this.id == 'id')
+                this.setValue( generateId() );
+        }
+    }
 
-	function loadSrc( videoNode, videos )
-	{
-		var match = this.id.match(/(\w+)(\d)/),
-			id = match[1],
-			number = parseInt(match[2], 10);
+    function loadSrc( videoNode, videos )
+    {
+        var match = this.id.match(/(\w+)(\d)/),
+            id = match[1],
+            number = parseInt(match[2], 10);
 
-		var video = videos[number];
-		if (!video)
-			return;
-		this.setValue( video[ id ] );
-	}
+        var video = videos[number];
+        if (!video)
+            return;
+        this.setValue( video[ id ] );
+    }
 
-	function generateId()
-	{
-		var now = new Date();
-		return 'video' + now.getFullYear() + now.getMonth() + now.getDate() + now.getHours() + now.getMinutes() + now.getSeconds();
-	}
+    function generateId()
+    {
+        var now = new Date();
+        return 'video' + now.getFullYear() + now.getMonth() + now.getDate() + now.getHours() + now.getMinutes() + now.getSeconds();
+    }
 
-	// To automatically get the dimensions of the poster image
-	var onImgLoadEvent = function()
-	{
-		// Image is ready.
-		var preview = this.previewImage;
-		preview.removeListener( 'load', onImgLoadEvent );
-		preview.removeListener( 'error', onImgLoadErrorEvent );
-		preview.removeListener( 'abort', onImgLoadErrorEvent );
+    // To automatically get the dimensions of the poster image
+    var onImgLoadEvent = function()
+    {
+        // Image is ready.
+        var preview = this.previewImage;
+        preview.removeListener( 'load', onImgLoadEvent );
+        preview.removeListener( 'error', onImgLoadErrorEvent );
+        preview.removeListener( 'abort', onImgLoadErrorEvent );
 
-		this.setValueOf( 'info', 'width', preview.$.width );
-		this.setValueOf( 'info', 'height', preview.$.height );
-	};
+        this.setValueOf( 'info', 'width', preview.$.width );
+        this.setValueOf( 'info', 'height', preview.$.height );
+    };
 
-	var onImgLoadErrorEvent = function()
-	{
-		// Error. Image is not loaded.
-		var preview = this.previewImage;
-		preview.removeListener( 'load', onImgLoadEvent );
-		preview.removeListener( 'error', onImgLoadErrorEvent );
-		preview.removeListener( 'abort', onImgLoadErrorEvent );
-	};
+    var onImgLoadErrorEvent = function()
+    {
+        // Error. Image is not loaded.
+        var preview = this.previewImage;
+        preview.removeListener( 'load', onImgLoadEvent );
+        preview.removeListener( 'error', onImgLoadErrorEvent );
+        preview.removeListener( 'abort', onImgLoadErrorEvent );
+    };
 
-	return {
-		title : lang.dialogTitle,
-		minWidth : 400,
-		minHeight : 200,
+    return {
+        title : lang.dialogTitle,
+        minWidth : 400,
+        minHeight : 200,
 
-		onShow : function()
-		{
-			// Clear previously saved elements.
-			this.fakeImage = this.videoNode = null;
-			// To get dimensions of poster image
-			this.previewImage = editor.document.createElement( 'img' );
+        onShow : function()
+        {
+            // Clear previously saved elements.
+            this.fakeImage = this.videoNode = null;
+            // To get dimensions of poster image
+            this.previewImage = editor.document.createElement( 'img' );
 
-			var fakeImage = this.getSelectedElement();
-			if ( fakeImage && fakeImage.data( 'cke-real-element-type' ) && fakeImage.data( 'cke-real-element-type' ) == 'video' )
-			{
-				this.fakeImage = fakeImage;
+            var fakeImage = this.getSelectedElement();
+            if ( fakeImage && fakeImage.data( 'cke-real-element-type' ) && fakeImage.data( 'cke-real-element-type' ) == 'video' )
+            {
+                this.fakeImage = fakeImage;
 
-				var videoNode = editor.restoreRealElement( fakeImage ),
-					videos = [],
-					sourceList = videoNode.getElementsByTag( 'source', '' );
-				if (sourceList.count()==0)
-					sourceList = videoNode.getElementsByTag( 'source', 'cke' );
+                var videoNode = editor.restoreRealElement( fakeImage ),
+                    videos = [],
+                    sourceList = videoNode.getElementsByTag( 'source', '' );
+                if (sourceList.count()==0)
+                    sourceList = videoNode.getElementsByTag( 'source', 'cke' );
 
-				for ( var i = 0, length = sourceList.count() ; i < length ; i++ )
-				{
-					var item = sourceList.getItem( i );
-					videos.push( {src : item.getAttribute( 'src' ), type: item.getAttribute( 'type' )} );
-				}
+                for ( var i = 0, length = sourceList.count() ; i < length ; i++ )
+                {
+                    var item = sourceList.getItem( i );
+                    videos.push( {src : item.getAttribute( 'src' ), type: item.getAttribute( 'type' )} );
+                }
 
-				this.videoNode = videoNode;
+                this.videoNode = videoNode;
 
-				this.setupContent( videoNode, videos );
-			}
-			else
-				this.setupContent( null, [] );
-		},
+                this.setupContent( videoNode, videos );
+            }
+            else
+                this.setupContent( null, [] );
+        },
 
-		onOk : function()
-		{
-			// If there's no selected element create one. Otherwise, reuse it
-			var videoNode = null;
-			if ( !this.fakeImage )
-			{
-				videoNode = CKEDITOR.dom.element.createFromHtml( '<cke:video></cke:video>', editor.document );
-				videoNode.setAttributes(
-					{
-						controls : 'controls'
-					} );
-			}
-			else
-			{
-				videoNode = this.videoNode;
-			}
+        onOk : function()
+        {
+            // If there's no selected element create one. Otherwise, reuse it
+            var videoNode = null;
+            if ( !this.fakeImage )
+            {
+                videoNode = CKEDITOR.dom.element.createFromHtml( '<cke:video></cke:video>', editor.document );
+                videoNode.setAttributes(
+                    {
+                        controls : 'controls'
+                    } );
+            }
+            else
+            {
+                videoNode = this.videoNode;
+            }
 
-			var extraStyles = {}, videos = [];
-			this.commitContent( videoNode, extraStyles, videos );
+            var extraStyles = {}, videos = [];
+            this.commitContent( videoNode, extraStyles, videos );
 
-			var innerHtml = '', links = '',
-				link = lang.linkTemplate || '',
-				fallbackTemplate = lang.fallbackTemplate || '';
-			for(var i=0; i<videos.length; i++)
-			{
-				var video = videos[i];
-				if ( !video || !video.src ) { continue; }
-				//local copy of video URL
-				var mySrc = video.src;
-				//Chrome is picky about the redirect, so point directly to app/courses/ if currently pointing to courses/
-				//See https://support.chamilo.org/issues/8462
-				var coursesPathIndex = mySrc.indexOf('courses');
-				var newHtmlTag = '<cke:source src="' + mySrc + '" type="' + video.type + '" />';
-				var newLinks = link.replace('%src%', mySrc).replace('%type%', video.type);
-				//is video saved on courses folder ?
-				if (coursesPathIndex >= 0) {
-					//test if real path is not already present (in case of video edition)
-					var myPath = mySrc.indexOf('app');
-					if (myPath==-1) {
-						//add real path (app/) to video.src...
-						var myChromeSrc = mySrc.slice(0, coursesPathIndex) + "app/" + mySrc.slice(coursesPathIndex);
-						//insert full path link...
-						newHtmlTag = '<cke:source src="' + myChromeSrc + '" type="' + video.type + '" />';
-						newLinks = link.replace('%src%', myChromeSrc).replace('%type%', video.type);
-					}
-				}
-				innerHtml += newHtmlTag;
-				links += newLinks;
-			}
-			videoNode.setHtml( innerHtml + fallbackTemplate.replace( '%links%', links ) );
+            var innerHtml = '', links = '',
+                link = lang.linkTemplate || '',
+                fallbackTemplate = lang.fallbackTemplate || '';
+            for(var i=0; i<videos.length; i++)
+            {
+                var video = videos[i];
+                if ( !video || !video.src )
+                    continue;
+                innerHtml += '<cke:source src="' + video.src + '" type="' + video.type + '" />';
+                links += link.replace('%src%', video.src).replace('%type%', video.type);
+            }
+            videoNode.setHtml( innerHtml + fallbackTemplate.replace( '%links%', links ) );
 
-			// Refresh the fake image.
-			var newFakeImage = editor.createFakeElement( videoNode, 'cke_video', 'video', false );
-			newFakeImage.setStyles( extraStyles );
-			if ( this.fakeImage )
-			{
-				newFakeImage.replace( this.fakeImage );
-				editor.getSelection().selectElement( newFakeImage );
-			}
-			else
-			{
-				// Insert it in a div
-				var div = new CKEDITOR.dom.element( 'DIV', editor.document );
-				editor.insertElement( div );
-				div.append( newFakeImage );
-			}
-		},
-		onHide : function()
-		{
-			if ( this.previewImage )
-			{
-				this.previewImage.removeListener( 'load', onImgLoadEvent );
-				this.previewImage.removeListener( 'error', onImgLoadErrorEvent );
-				this.previewImage.removeListener( 'abort', onImgLoadErrorEvent );
-				this.previewImage.remove();
-				this.previewImage = null;		// Dialog is closed.
-			}
-		},
+            // Refresh the fake image.
+            var newFakeImage = editor.createFakeElement( videoNode, 'cke_video', 'video', false );
+            newFakeImage.setStyles( extraStyles );
+            if ( this.fakeImage )
+            {
+                newFakeImage.replace( this.fakeImage );
+                editor.getSelection().selectElement( newFakeImage );
+            }
+            else
+            {
+                // Insert it in a div
+                var div = new CKEDITOR.dom.element( 'DIV', editor.document );
+                editor.insertElement( div );
+                div.append( newFakeImage );
+            }
+        },
+        onHide : function()
+        {
+            if ( this.previewImage )
+            {
+                this.previewImage.removeListener( 'load', onImgLoadEvent );
+                this.previewImage.removeListener( 'error', onImgLoadErrorEvent );
+                this.previewImage.removeListener( 'abort', onImgLoadErrorEvent );
+                this.previewImage.remove();
+                this.previewImage = null;		// Dialog is closed.
+            }
+        },
 
-		contents :
-		[
-			{
-				id : 'info',
-				elements :
-				[
-					{
-						type : 'hbox',
-						widths: [ '33%', '33%', '33%'],
-						children : [
-							{
-								type : 'text',
-								id : 'width',
-								label : editor.lang.common.width,
-								'default' : 400,
-								validate : CKEDITOR.dialog.validate.notEmpty( lang.widthRequired ),
-								commit : commitValue,
-								setup : loadValue
-							},
-							{
-								type : 'text',
-								id : 'height',
-								label : editor.lang.common.height,
-								'default' : 300,
-								//validate : CKEDITOR.dialog.validate.notEmpty(lang.heightRequired ),
-								commit : commitValue,
-								setup : loadValue
-							},
-							{
-								type : 'text',
-								id : 'id',
-								label : 'Id',
-								commit : commitValue,
-								setup : loadValue
-							}
-								]
-					},
-					{
-						type : 'hbox',
-						widths: [ '', '100px', '75px'],
-						children : [
-							{
-								type : 'text',
-								id : 'src0',
-								label : lang.sourceVideo,
-								commit : commitSrc,
-								setup : loadSrc
-							},
-							{
-								type : 'button',
-								id : 'browse',
-								hidden : 'true',
-								style : 'display:inline-block;margin-top:10px;',
-								filebrowser :
-								{
-									action : 'Browse',
-									target: 'info:src0',
-									url: editor.config.filebrowserVideoBrowseUrl || editor.config.filebrowserBrowseUrl
-								},
-								label : editor.lang.common.browseServer
-							},
-							{
-								id : 'type0',
-								label : lang.sourceType,
-								type : 'select',
-								'default' : 'video/mp4',
-								items :
-								[
-									[ 'MP4', 'video/mp4' ],
-									[ 'WebM', 'video/webm' ]
-								],
-								commit : commitSrc,
-								setup : loadSrc
-							}]
-					},
+        contents :
+            [
+                {
+                    id : 'info',
+                    elements :
+                        [
+                            {
+                                type : 'hbox',
+                                widths: [ '33%', '33%', '33%'],
+                                children : [
+                                    {
+                                        type : 'text',
+                                        id : 'width',
+                                        label : editor.lang.common.width,
+                                        'default' : 400,
+                                        validate : CKEDITOR.dialog.validate.notEmpty( lang.widthRequired ),
+                                        commit : commitValue,
+                                        setup : loadValue
+                                    },
+                                    {
+                                        type : 'text',
+                                        id : 'height',
+                                        label : editor.lang.common.height,
+                                        'default' : 300,
+                                        //validate : CKEDITOR.dialog.validate.notEmpty(lang.heightRequired ),
+                                        commit : commitValue,
+                                        setup : loadValue
+                                    },
+                                    {
+                                        type : 'text',
+                                        id : 'id',
+                                        label : 'Id',
+                                        commit : commitValue,
+                                        setup : loadValue
+                                    }
+                                ]
+                            },
+                            {
+                                type : 'hbox',
+                                widths: [ '', '100px', '75px'],
+                                children : [
+                                    {
+                                        type : 'text',
+                                        id : 'src0',
+                                        label : lang.sourceVideo,
+                                        commit : commitSrc,
+                                        setup : loadSrc
+                                    },
+                                    {
+                                        type : 'button',
+                                        id : 'browse',
+                                        hidden : 'true',
+                                        style : 'display:inline-block;margin-top:10px;',
+                                        filebrowser :
+                                            {
+                                                action : 'Browse',
+                                                target: 'info:src0',
+                                                url: editor.config.filebrowserVideoBrowseUrl || editor.config.filebrowserBrowseUrl
+                                            },
+                                        label : editor.lang.common.browseServer
+                                    },
+                                    {
+                                        id : 'type0',
+                                        label : lang.sourceType,
+                                        type : 'select',
+                                        'default' : 'video/mp4',
+                                        items :
+                                            [
+                                                [ 'MP4', 'video/mp4' ],
+                                                [ 'WebM', 'video/webm' ]
+                                            ],
+                                        commit : commitSrc,
+                                        setup : loadSrc
+                                    }]
+                            },
 
-					{
-						type : 'hbox',
-						widths: [ '', '100px', '75px'],
-						children : [
-							{
-								type : 'text',
-								id : 'src1',
-								label : lang.sourceVideo,
-								commit : commitSrc,
-								setup : loadSrc
-							},
-							{
-								type : 'button',
-								id : 'browse',
-								hidden : 'true',
-								style : 'display:inline-block;margin-top:10px;',
-								filebrowser :
-								{
-									action : 'Browse',
-									target: 'info:src1',
-									url: editor.config.filebrowserVideoBrowseUrl || editor.config.filebrowserBrowseUrl
-								},
-								label : editor.lang.common.browseServer
-							},
-							{
-								id : 'type1',
-								label : lang.sourceType,
-								type : 'select',
-								'default':'video/webm',
-								items :
-								[
-									[ 'MP4', 'video/mp4' ],
-									[ 'WebM', 'video/webm' ]
-								],
-								commit : commitSrc,
-								setup : loadSrc
-							}]
-					},
-					{
-						type : 'hbox',
-						widths: [ '', '100px'],
-						children : [
-							{
-								type : 'text',
-								id : 'poster',
-								label : lang.poster,
-								commit : commitValue,
-								setup : loadValue,
-								onChange : function()
-								{
-									var dialog = this.getDialog(),
-										newUrl = this.getValue();
+                            {
+                                type : 'hbox',
+                                widths: [ '', '100px', '75px'],
+                                children : [
+                                    {
+                                        type : 'text',
+                                        id : 'src1',
+                                        label : lang.sourceVideo,
+                                        commit : commitSrc,
+                                        setup : loadSrc
+                                    },
+                                    {
+                                        type : 'button',
+                                        id : 'browse',
+                                        hidden : 'true',
+                                        style : 'display:inline-block;margin-top:10px;',
+                                        filebrowser :
+                                            {
+                                                action : 'Browse',
+                                                target: 'info:src1',
+                                                url: editor.config.filebrowserVideoBrowseUrl || editor.config.filebrowserBrowseUrl
+                                            },
+                                        label : editor.lang.common.browseServer
+                                    },
+                                    {
+                                        id : 'type1',
+                                        label : lang.sourceType,
+                                        type : 'select',
+                                        'default':'video/webm',
+                                        items :
+                                            [
+                                                [ 'MP4', 'video/mp4' ],
+                                                [ 'WebM', 'video/webm' ]
+                                            ],
+                                        commit : commitSrc,
+                                        setup : loadSrc
+                                    }]
+                            },
+                            {
+                                type : 'hbox',
+                                widths: [ '', '100px'],
+                                children : [
+                                    {
+                                        type : 'text',
+                                        id : 'poster',
+                                        label : lang.poster,
+                                        commit : commitValue,
+                                        setup : loadValue,
+                                        onChange : function()
+                                        {
+                                            var dialog = this.getDialog(),
+                                                newUrl = this.getValue();
 
-									//Update preview image
-									if ( newUrl.length > 0 )	//Prevent from load before onShow
-									{
-										dialog = this.getDialog();
-										var preview = dialog.previewImage;
+                                            //Update preview image
+                                            if ( newUrl.length > 0 )	//Prevent from load before onShow
+                                            {
+                                                dialog = this.getDialog();
+                                                var preview = dialog.previewImage;
 
-										preview.on( 'load', onImgLoadEvent, dialog );
-										preview.on( 'error', onImgLoadErrorEvent, dialog );
-										preview.on( 'abort', onImgLoadErrorEvent, dialog );
-										preview.setAttribute( 'src', newUrl );
-									}
-								}
-							},
-							{
-								type : 'button',
-								id : 'browse',
-								hidden : 'true',
-								style : 'display:inline-block;margin-top:10px;',
-								filebrowser :
-								{
-									action : 'Browse',
-									target: 'info:poster',
-									url: editor.config.filebrowserImageBrowseUrl || editor.config.filebrowserBrowseUrl
-								},
-								label : editor.lang.common.browseServer
-							}]
-					}
-				]
-			}
+                                                preview.on( 'load', onImgLoadEvent, dialog );
+                                                preview.on( 'error', onImgLoadErrorEvent, dialog );
+                                                preview.on( 'abort', onImgLoadErrorEvent, dialog );
+                                                preview.setAttribute( 'src', newUrl );
+                                            }
+                                        }
+                                    },
+                                    {
+                                        type : 'button',
+                                        id : 'browse',
+                                        hidden : 'true',
+                                        style : 'display:inline-block;margin-top:10px;',
+                                        filebrowser :
+                                            {
+                                                action : 'Browse',
+                                                target: 'info:poster',
+                                                url: editor.config.filebrowserImageBrowseUrl || editor.config.filebrowserBrowseUrl
+                                            },
+                                        label : editor.lang.common.browseServer
+                                    }]
+                            }
+                        ]
+                }
 
-		]
-	};
+            ]
+    };
 } );

+ 7 - 12
main/template/default/layout/footer.js.tpl

@@ -1,21 +1,16 @@
 <script>
     /* Makes row highlighting possible */
     $(document).ready( function() {
-         $("[data-toggle=popover]").each(function(i, obj) {
-
+        $("[data-toggle=popover]").each(function(i, obj) {
             $(this).popover({
-              html: true,
-              content: function() {
-                var id = $(this).attr('id')
-                return $('#popover-content-' + id).html();
-              }
+                html: true,
+                content: function() {
+                    var id = $(this).attr('id')
+                    return $('#popover-content-' + id).html();
+                }
             });
-            
-            
-            
+        });
 
-            });
-        
         // Date time settings.
         moment.locale('{{ locale }}');
         $.datepicker.setDefaults($.datepicker.regional["{{ locale }}"]);