commit/galaxy-central: carlfeberhard: Pages: allow registry visualizations to display within an iframe; Refactor embed_item.less and minor style fixes
1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/31f05a12912b/ Changeset: 31f05a12912b User: carlfeberhard Date: 2014-11-12 18:45:38+00:00 Summary: Pages: allow registry visualizations to display within an iframe; Refactor embed_item.less and minor style fixes Affected #: 7 files diff -r f26c2543ff053b9ff31617bc03f99d505302ecda -r 31f05a12912be544f59a85239e584eeac15a4b98 lib/galaxy/webapps/galaxy/controllers/page.py --- a/lib/galaxy/webapps/galaxy/controllers/page.py +++ b/lib/galaxy/webapps/galaxy/controllers/page.py @@ -755,6 +755,28 @@ user_is_owner=user_is_owner, history_dict=history_dictionary, hda_dicts=hda_dictionaries ) return filled + def _get_embedded_visualization_html( self, trans, id ): + """ + Returns html suitable for embedding visualizations in another page. + """ + visualization = self.get_visualization( trans, id, False, True ) + visualization.annotation = self.get_item_annotation_str( trans.sa_session, visualization.user, visualization ) + if not visualization: + return None + + # Fork to template based on visualization.type (registry or builtin). + if( ( trans.app.visualizations_registry and visualization.type in trans.app.visualizations_registry.plugins ) + and ( visualization.type not in trans.app.visualizations_registry.BUILT_IN_VISUALIZATIONS ) ): + # if a registry visualization, load a version into an iframe :( + #TODO: simplest path from A to B but not optimal - will be difficult to do reg visualizations any other way + #TODO: this will load the visualization twice (once above, once when the iframe src calls 'saved') + encoded_visualization_id = trans.security.encode_id( visualization.id ) + return trans.fill_template( 'visualization/embed_in_frame.mako', + item=visualization, encoded_visualization_id=encoded_visualization_id, + content_only=True ) + + return trans.fill_template( "visualization/embed.mako", item=visualization, item_data=None ) + def _get_embed_html( self, trans, item_class, item_id ): """ Returns HTML for embedding an item in a page. """ item_class = self.get_class( item_class ) @@ -776,10 +798,7 @@ return trans.fill_template( "workflow/embed.mako", item=workflow, item_data=workflow.latest_workflow.steps ) elif item_class == model.Visualization: - visualization = self.get_visualization( trans, item_id, False, True ) - visualization.annotation = self.get_item_annotation_str( trans.sa_session, visualization.user, visualization ) - if visualization: - return trans.fill_template( "visualization/embed.mako", item=visualization, item_data=None ) + return self._get_embedded_visualization_html( trans, item_id ) elif item_class == model.Page: pass diff -r f26c2543ff053b9ff31617bc03f99d505302ecda -r 31f05a12912be544f59a85239e584eeac15a4b98 lib/galaxy/webapps/galaxy/controllers/visualization.py --- a/lib/galaxy/webapps/galaxy/controllers/visualization.py +++ b/lib/galaxy/webapps/galaxy/controllers/visualization.py @@ -585,7 +585,7 @@ user_item_rating = 0 ave_item_rating, num_ratings = self.get_ave_item_rating_data( trans.sa_session, visualization ) - # Display. + # Fork to template based on visualization.type (registry or builtin). if( ( trans.app.visualizations_registry and visualization.type in trans.app.visualizations_registry.plugins ) and ( visualization.type not in trans.app.visualizations_registry.BUILT_IN_VISUALIZATIONS ) ): # if a registry visualization, load a version of display.mako that will load the vis into an iframe :( diff -r f26c2543ff053b9ff31617bc03f99d505302ecda -r 31f05a12912be544f59a85239e584eeac15a4b98 static/style/blue/embed_item.css --- a/static/style/blue/embed_item.css +++ b/static/style/blue/embed_item.css @@ -1,19 +1,14 @@ -.embedded-item{margin:0em auto;width:90%;-moz-border-radius:0.5em;-webkit-border-radius:0.5em;border-radius:0.5em} -.embedded-item.display{padding:5px 10px 10px 10px} -.embedded-item.history{background-color:#c1c9e5} -.embedded-item.history p{background:#c1c9e5 no-repeat 2px 2px;margin-top:0;margin-bottom:0} -.embedded-item.dataset{background-color:#cfc} -.embedded-item.dataset p{background:#cfc no-repeat 2px 2px;margin-top:0;margin-bottom:0} -.embedded-item.workflow{background-color:#fbddb3} -.embedded-item.workflow p{background:#fbddb3 no-repeat 2px 2px;margin-top:0;margin-bottom:0} -.embedded-item.visualization{background-color:#bbb} -.embedded-item.visualization p{background:#bbb no-repeat 2px 2px;margin-top:0;margin-bottom:0} -.embedded-item .expanded-content{display:none;background-color:white;padding:5px} -.embedded-item .item-content{max-height:25em;overflow:auto} -.embedded-item.visualization .item-content{overflow:hidden} +.embedded-item{margin:0em auto;width:90%;-moz-border-radius:0.5em;-webkit-border-radius:0.5em;border-radius:0.5em}.embedded-item .expanded-content{display:none;background-color:white} +.embedded-item .item-content{max-height:45em;overflow:auto} .embedded-item>.title{vertical-align:top;text-align:center;font-weight:bold;padding-bottom:5px} .embedded-item.placeholder .content{padding:0.5em 0.5em;font-style:italic;text-align:center} -table.annotated-item{width:100%;border-collapse:collapse} -table.annotated-item td,th{padding:0} -table.annotated-item .annotation{padding-left:2em;width:40%} -table.annotated-item td.annotation{vertical-align:text-top;padding-top:1em} +.embedded-item p{background:inherit;margin-top:0;margin-bottom:0} +.embedded-item table.annotated-item{width:100%;border-collapse:collapse} +.embedded-item table.annotated-item td,.embedded-item th{padding:0} +.embedded-item table.annotated-item .annotation{padding-left:2em;width:40%} +.embedded-item table.annotated-item td.annotation{vertical-align:text-top;padding-top:1em} +.embedded-item.display{padding:5px 10px 10px 10px} +.embedded-item.history{background-color:#C1C9E5} +.embedded-item.dataset{background-color:#CFC}.embedded-item.dataset .item-content{padding:5px} +.embedded-item.workflow{background-color:#FBDDB3}.embedded-item.workflow .item-content{padding:5px} +.embedded-item.visualization{background-color:#BBBBBB}.embedded-item.visualization .item-content{overflow:hidden;height:100%}.embedded-item.visualization .item-content iframe{min-height:320px;margin-bottom:-4px} diff -r f26c2543ff053b9ff31617bc03f99d505302ecda -r 31f05a12912be544f59a85239e584eeac15a4b98 static/style/src/less/embed_item.less --- a/static/style/src/less/embed_item.less +++ b/static/style/src/less/embed_item.less @@ -4,6 +4,54 @@ -moz-border-radius: 0.5em; -webkit-border-radius: 0.5em; border-radius: 0.5em; + + .expanded-content { + display: none; + background-color: white; + } + + .item-content { + max-height: 45em; + overflow: auto; + } + + & > .title { + vertical-align: top; + text-align: center; + font-weight: bold; + padding-bottom: 5px; + } + + &.placeholder .content { + padding: 0.5em 0.5em; + font-style: italic; + text-align: center; + } + + p { + background: inherit; + margin-top:0; + margin-bottom:0; + } + + table.annotated-item { + width: 100%; + border-collapse: collapse; + } + + table.annotated-item td,th { + padding: 0; + } + + table.annotated-item .annotation { + padding-left: 2em; + width: 40%; + } + + table.annotated-item td.annotation { + vertical-align: text-top; + padding-top: 1em; + } } .embedded-item.display { @@ -11,89 +59,32 @@ } .embedded-item.history { - background-color:#C1C9E5 -} - -.embedded-item.history p { - background:#C1C9E5 no-repeat 2px 2px; - margin-top:0; - margin-bottom:0; + background-color: #C1C9E5; } .embedded-item.dataset { - background-color:#CFC -} - -.embedded-item.dataset p { - background:#CFC no-repeat 2px 2px; - margin-top:0;margin-bottom:0; + background-color: #CFC; + .item-content { + padding: 5px; + } } .embedded-item.workflow { - background-color:#FBDDB3 -} - -.embedded-item.workflow p { - background:#FBDDB3 no-repeat 2px 2px; - margin-top:0; - margin-bottom:0; + background-color: #FBDDB3; + .item-content { + padding: 5px; + } } .embedded-item.visualization { - background-color:#BBBBBB + background-color: #BBBBBB; + .item-content { + overflow: hidden; + height: 100%; + iframe { + min-height: 320px; + //TODO: hack to fix small gap after iframe + margin-bottom: -4px; + } + } } - -.embedded-item.visualization p { - background:#BBBBBB no-repeat 2px 2px; - margin-top:0; - margin-bottom:0; -} - -.embedded-item.placeholder{} - -.embedded-item .expanded-content { - display: none; - background-color: white; - padding: 5px; -} - -.embedded-item .item-content { - max-height: 25em; - overflow: auto; -} - -.embedded-item.visualization .item-content { - overflow: hidden; -} - -.embedded-item > .title { - vertical-align: top; - text-align: center; - font-weight: bold; - padding-bottom: 5px; -} - -.embedded-item.placeholder .content { - padding: 0.5em 0.5em; - font-style: italic; - text-align: center; -} - -table.annotated-item { - width: 100%; - border-collapse: collapse; -} - -table.annotated-item td,th { - padding: 0; -} - -table.annotated-item .annotation { - padding-left: 2em; - width: 40%; -} - -table.annotated-item td.annotation { - vertical-align: text-top; - padding-top: 1em; -} diff -r f26c2543ff053b9ff31617bc03f99d505302ecda -r 31f05a12912be544f59a85239e584eeac15a4b98 templates/webapps/galaxy/history/embed.mako --- a/templates/webapps/galaxy/history/embed.mako +++ b/templates/webapps/galaxy/history/embed.mako @@ -1,4 +1,3 @@ -##<%inherit file="/embed_base.mako"/><%namespace file="/display_common.mako" import="*" /> ## Some duplication with embed_base here, needed a way to override the main embedded-item html for histories diff -r f26c2543ff053b9ff31617bc03f99d505302ecda -r 31f05a12912be544f59a85239e584eeac15a4b98 templates/webapps/galaxy/page/display.mako --- a/templates/webapps/galaxy/page/display.mako +++ b/templates/webapps/galaxy/page/display.mako @@ -10,7 +10,8 @@ // (b) ... $('.embedded-item').each( function() { var container = $(this); - if( container.hasClass( 'history' ) ){ return; } + if( container.hasClass( 'history' ) + || container.hasClass( 'visualization' ) ){ return; } // Show embedded item. var show_embedded_item = function() { @@ -119,10 +120,6 @@ .embedded-item.history .toggle { display: inline; } - .embedded-item.history .expanded-content { - /* generates a fake wide border */ - padding: 4px; - } /** wraps around the history */ .embedded-item.history .item-content { background-color: white; @@ -138,6 +135,11 @@ .annotated-history-panel .history-controls { margin: 0px 0px 16px 0px; } + + /* ---------------------------- visualizations */ + .embedded-item.visualization .item-content { + max-height: none; + } </style></%def> diff -r f26c2543ff053b9ff31617bc03f99d505302ecda -r 31f05a12912be544f59a85239e584eeac15a4b98 templates/webapps/galaxy/visualization/embed_in_frame.mako --- /dev/null +++ b/templates/webapps/galaxy/visualization/embed_in_frame.mako @@ -0,0 +1,78 @@ +<%namespace file="/display_common.mako" import="*" /> + +<% + import_href = h.url_for( controller='visualization', action='imp', id=encoded_visualization_id ) + display_href = h.url_for( controller='visualization', action='display_by_username_and_slug', + username=item.user.username, slug=item.slug ) +%> +<div id="visualization-${encoded_visualization_id}" class='embedded-item display visualization'> + <div class='title'> + <div style="float: left"> + <a class="expand-content-btn icon-button toggle-expand" href="${display_href}" + title="Show or hide visualization"></a> + </div> + <div style="float: right;"> + <a title="Import" class="icon-button import" href="${import_href}"></a> + <a title="View" class="icon-button go-to-full-screen" href="${display_href}"></a> + </div> + <h4> + <a class="toggle-embed" href="${display_href}" title="Show or hide visualization"> + Galaxy Visualization | ${get_item_name( item )} + </a> + </h4> + %if hasattr( item, "annotation") and item.annotation: + <div class="annotation">${item.annotation}</div> + %endif + </div> + ##<div class='summary-content'> + ## currently, no summary content for visualization + ## could do the title or caption, whatever... + ##</div> + <div class='expanded-content'> + <div class='item-content'> + </div> + </div> +</div> + +<script type="text/javascript"> +// Embedding the same visualization more than once will confuse DOM ids. +// In order to handle this, find this script and cache the previous node (the div above). +// (Since we need thisScript to be locally scoped or it will get overwritten, enclose in self-calling function) +(function(){ + var scripts = document.getElementsByTagName( 'script' ), + // this is executed immediately, so the last script will be this script + thisScript = scripts[ scripts.length - 1 ], + $embeddedObj = $( thisScript ).prev(); + + /** check for an existing iframe for this visualization, adding one to the item-content if needed */ + function addVisualizationIFrame(){ + var $embeddedObj = $( thisScript ).prev(), + $itemContent = $embeddedObj.find( '.expanded-content .item-content' ), + $iframe = $itemContent.find( 'iframe' ); + if( $iframe.size() ){ return $iframe; } + return $itemContent.html([ + '<iframe frameborder="0" width="100%" height="100%" ', + 'sandbox="allow-forms allow-same-origin allow-scripts" ', + 'src="/visualization/saved?id=${encoded_visualization_id}&embedded=True">', + '</iframe>' + ].join('')).find( 'iframe' ); + } + + /** 4 elements change when expanding - toggle them all, add the iframe and prevent the url change */ + function toggleExpanded( ev ){ + var $embeddedObj = $( thisScript ).prev(); + $embeddedObj.find( '.expand-content-btn' ).toggleClass( 'toggle-expand' ).toggleClass( 'toggle' ); + $embeddedObj.find( ".summary-content" ).slideToggle( "fast" ); + $embeddedObj.find( ".annotation" ).slideToggle( "fast" ); + $embeddedObj.find( ".expanded-content" ).slideToggle( "fast" ); + addVisualizationIFrame(); + ev.preventDefault(); + } + + // add expansion to +/- btn and title + $(function(){ + $embeddedObj.find( '.expand-content-btn' ).click( toggleExpanded ); + $embeddedObj.find( '.toggle-embed' ).click( toggleExpanded ); + }); +})(); +</script> Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.
participants (1)
-
commits-noreply@bitbucket.org