| Author | Dave Jarvis <email> |
|---|---|
| Date | 2014-12-29 01:54:32 GMT-0800 |
| Commit | 58b21e8769642f8dd7c52afc4b7f468158d696a8 |
| Parent | 772f4d5 |
| Delta | 131 lines added, 270 lines removed, 139-line decrease |
|---|
| +@charset "utf-8"; | ||
| @import url( "css/support.css" ); | ||
| -/* *********************************************************************** | ||
| +/** | ||
| * | ||
| - * Sets up the tag editor code. | ||
| + * Cascading columns styling. | ||
| * | ||
| - * ***********************************************************************/ | ||
| -div.breadcrumb { | ||
| - margin-top: 1em; | ||
| - border-top-left-radius: 0.4em 0.4em; | ||
| - border-top-right-radius: 0.4em 0.4em; | ||
| -} | ||
| - | ||
| -div.toolbar { | ||
| - margin-bottom: 1em; | ||
| - border-bottom-left-radius: 0.4em 0.4em; | ||
| - border-bottom-right-radius: 0.4em 0.4em; | ||
| -} | ||
| - | ||
| + */ | ||
| div.columns { | ||
| float: left; | ||
| } | ||
| -div.column { | ||
| +/* Display the lists as columns in blocks. */ | ||
| +ul.column { | ||
| + display: inline-block; | ||
| + | ||
| vertical-align: top; | ||
| overflow: hidden; | ||
| - display: inline-block; | ||
| + margin: 0 auto; | ||
| + | ||
| border-right: 1px solid #666; | ||
| - font-size: 0.9em; | ||
| - font-family: Arial; | ||
| background-color: white; | ||
| - | ||
| white-space: normal; | ||
| + | ||
| + font-size: 0.9em; | ||
| } | ||
| -div.collapsed { | ||
| +/* Setting a list container class to "collapsed" will hide the column. */ | ||
| +ul.column.collapsed { | ||
| display: none; | ||
| } | ||
| -li.parent:hover { | ||
| - color: black; | ||
| - background-color: #DDE4E8; | ||
| +/* Put some space between the column's list entries. */ | ||
| +ul.column > li { | ||
| + list-style: none; | ||
| + padding-left: 0.5em; | ||
| + padding-right: 0.5em; | ||
| + padding-top: 0.25em; | ||
| + padding-bottom: 0.25em; | ||
| + | ||
| + min-width: 200px; | ||
| } | ||
| -/* Ensure the selection hierarchy is highlighted. */ | ||
| -li.selection { | ||
| - background-color: #08C !important; | ||
| - color: white !important; | ||
| +ul.column > li.parent::after { | ||
| + content: "▶"; | ||
| + float: right; | ||
| } | ||
| -div.breadcrumb, div.toolbar { | ||
| - height: 1.25em; | ||
| +/* Zebra stripes, which can be overridden. */ | ||
| +ul.column > li:nth-child(odd) { | ||
| + background-color: #EEE; | ||
| } | ||
| -div.breadcrumb, div.toolbar { | ||
| - background: linear-gradient(#f0f0f0, #d8d8d8); | ||
| +/* Highlight while hovering, without allowing selected items to override. */ | ||
| +ul.column > li:hover { | ||
| + color: black; | ||
| + background-color: #DDE4E8; | ||
| +} | ||
| + | ||
| +/* Ensure all selected nodes in the hierarchy are easily seen. */ | ||
| +ul.column > li.selection { | ||
| + background-color: #08C; | ||
| + color: white; | ||
| } | ||
| +/** | ||
| + * | ||
| + * Breadcrumb styling. | ||
| + * | ||
| + */ | ||
| div.breadcrumb { | ||
| + margin-top: 1em; | ||
| + border-top-left-radius: 0.4em 0.4em; | ||
| + border-top-right-radius: 0.4em 0.4em; | ||
| + | ||
| border-bottom: 1px solid #666; | ||
| } | ||
| div.breadcrumb > span { | ||
| height: 1.25em; | ||
| line-height: 1.25em; | ||
| -} | ||
| - | ||
| -div.toolbar { | ||
| - clear: both; | ||
| - border-top: 1px solid #666; | ||
| -} | ||
| -div.breadcrumb > span { | ||
| font-size: 0.7em; | ||
| font-weight: bold; | ||
| padding-left: 0.25em; | ||
| color: #666; | ||
| } | ||
| div.breadcrumb > span::after { | ||
| - content: " \25B8"; | ||
| + content: " ▸"; | ||
| } | ||
| div.breadcrumb > span:first-child { | ||
| padding-left: 1em; | ||
| } | ||
| div.breadcrumb > span:last-child:after { | ||
| content: ""; | ||
| -} | ||
| - | ||
| -ul { | ||
| - padding: 0; | ||
| - margin: 0; | ||
| - overflow: auto; | ||
| -} | ||
| - | ||
| -li { | ||
| - list-style: none; | ||
| - padding-left: 0.5em; | ||
| - padding-right: 0.5em; | ||
| - padding-top: 0.25em; | ||
| - padding-bottom: 0.25em; | ||
| - min-width: 150px; | ||
| } | ||
| -/* Use an arrow to indicate that the parent has child elements. */ | ||
| -li.parent:after { | ||
| - content: "\25B8"; | ||
| - float: right; | ||
| -} | ||
| +/** | ||
| + * | ||
| + * Toolbar styling. | ||
| + * | ||
| + */ | ||
| +div.toolbar { | ||
| + margin-bottom: 1em; | ||
| + border-bottom-left-radius: 0.4em 0.4em; | ||
| + border-bottom-right-radius: 0.4em 0.4em; | ||
| -/* Zebra stripes. */ | ||
| -li:nth-child(odd) { | ||
| - background-color: #EEE; | ||
| + clear: both; | ||
| + border-top: 1px solid #666; | ||
| } | ||
| } | ||
| -/* *********************************************************************** | ||
| +/** | ||
| * | ||
| - * Sets up the remainder of the web page. | ||
| + * Breadcrumb and toolbar styling. | ||
| * | ||
| - * ***********************************************************************/ | ||
| -h1 { | ||
| - font-size: 1.5em; | ||
| - padding-bottom: 0.5em; | ||
| + */ | ||
| +div.breadcrumb, div.toolbar { | ||
| + height: 1.25em; | ||
| + background: linear-gradient(#f0f0f0, #d8d8d8); | ||
| } | ||
| -/* *************************************************************************** | ||
| - * | ||
| - * Miller Columns | ||
| - * | ||
| - * Transforms an arbitrarily nested unordered list into a series of | ||
| - * Miller Columns. The purpose of Miller Columns is to provide a | ||
| - * straightforward means to edit hierarchical data. In theory, the | ||
| - * same data set could be displayed as a collapsable tree. | ||
| - * | ||
| - * List items are employed for semantic reasons. | ||
| - * | ||
| - * The id's must be unique. Usage example: | ||
| - * | ||
| - * <div class="columns"> | ||
| - * <ul> | ||
| - * <li id="1">Item A</li> | ||
| - * <li id="2">Item B</li> | ||
| - * <li id="3">Item C | ||
| - * <ul> | ||
| - * <li id="31">Item CA</li> | ||
| - * <li id="32">Item CB</li> | ||
| - * <li id="33">Item CC | ||
| - * <ul> | ||
| - * <li id="331">Item CCA</li> | ||
| - * <li id="332">Item CCB</li> | ||
| - * <li id="333">Item CCC</li> | ||
| - * </ul> | ||
| - * </li> | ||
| - * <li id="34">Item CD</li> | ||
| - * <li id="35">Item CE</li> | ||
| - * </ul> | ||
| - * </li> | ||
| - * </ul> | ||
| - * </div> | ||
| - * | ||
| - * Requirements | ||
| - * - jQuery 1.11.1 | ||
| - * - tags.css | ||
| - * | ||
| - * ***************************************************************************/ | ||
| (function( $ ) { | ||
| $.fn.millerColumns = function() { | ||
| - var $list = $(this).first(); | ||
| - var $columns = $(this); | ||
| + return this.each( function() { | ||
| + $(this).before( $("<div>").addClass( "breadcrumb" ) ); | ||
| + $(this).after( $("<div>").addClass( "toolbar" ) ); | ||
| + unnest( $(this) ); | ||
| + collapse(); | ||
| - // Breadth-first traversal to rearrange list items into | ||
| - // consecutively ordered div wrapper elements. | ||
| - while( ($list = $list.children()).length ) { | ||
| - $list.each( function( index, element ) { | ||
| - var $parent = $(element).parent(); | ||
| + // Expand the requested child node on click. | ||
| + $(this).find( "li" ).on( "click", function() { | ||
| + collapse(); | ||
| + $(this).addClass( "selection" ).siblings().removeClass( "selection" ); | ||
| - if( $(element).is( "li" ) ) { | ||
| - $parent = $parent.parent(); | ||
| + var $descendant = $(this).data( "descendants" ); | ||
| + | ||
| + if( $descendant !== undefined ) { | ||
| + $descendant.removeClass( "collapsed" ); | ||
| + $descendant.children().removeClass( "selection" ); | ||
| } | ||
| - // Store the parent id for showing child columns. | ||
| - var id = $parent.attr( "id" ); | ||
| + var $ancestor = $(this); | ||
| - if( $(element).is( "ul" ) ) { | ||
| - // The parent element shall be marked as 0. | ||
| - if( id === undefined ) { | ||
| - id = 0; | ||
| - } | ||
| + // Reveal (uncollapse) all ancestors to the clicked item. | ||
| + while( $ancestor !== undefined ) { | ||
| + $ancestor.parent().removeClass( "collapsed" ); | ||
| + $ancestor = $ancestor.data( "ancestor" ); | ||
| + } | ||
| - var $item = $("li#" + id); | ||
| - $item.addClass( "parent" ); | ||
| + breadcrumb(); | ||
| - $item.on( "click", function() { | ||
| - // Hide everything. | ||
| - $("div.column[data-parent!=0]").addClass( "collapsed" ); | ||
| - $("li").removeClass( "selection" ); | ||
| + // Ensure the viewport shows the entire newly expanded item. | ||
| + $column.parent().parent().animate( | ||
| + { scrollLeft: $column.offset().left }, | ||
| + 500 ); | ||
| + }); | ||
| + }); | ||
| + } | ||
| - // The "id" for the clicked list item becomes the start of | ||
| - // the ancestral chain. | ||
| - var $child = $("div.column[data-parent=" + id + "]" ); | ||
| - $child.removeClass( "collapsed" ); | ||
| + function breadcrumb() { | ||
| + var $breadcrumb = $("div.breadcrumb").empty(); | ||
| - var $li = $("li.parent[id=" + id + "]"); | ||
| - var $ancestor = $li.parent().parent(); | ||
| - var ancestor_id = $ancestor.attr( "data-parent" ); | ||
| + // Add the breadcrumb trail. | ||
| + $("li.selection").each( function( _, crumb ) { | ||
| + $breadcrumb.append( "<span>" + $(crumb).text() + "</span>" ); | ||
| + }); | ||
| + } | ||
| - while( ancestor_id !== undefined ) { | ||
| - $li.addClass( "selection" ); | ||
| - $ancestor.removeClass( "collapsed" ); | ||
| + /* Convert nested lists into columns using breadth-first traversal. */ | ||
| + function unnest( $columns ) { | ||
| + var queue = []; | ||
| - $li = $("li.parent[id=" + ancestor_id + "]"); | ||
| - $ancestor = $li.parent().parent(); | ||
| - ancestor_id = $ancestor.attr( "data-parent" ); | ||
| - } | ||
| + // Push the root unordered list item into the queue. | ||
| + queue.push( $columns.children() ); | ||
| - var $breadcrumb = $("div.breadcrumb").empty(); | ||
| + while( queue.length ) { | ||
| + var $node = queue.shift(); | ||
| - // Add the breadcrumb trail. | ||
| - $("li.selection").each( function( _, crumb ) { | ||
| - $breadcrumb.append( "<span>" + $(crumb).text() + "</span>" ); | ||
| - }); | ||
| - }); | ||
| - | ||
| - var $div = $("<div>").attr( "data-parent", id ); | ||
| - var $wrapped = $(element).wrapAll( $div ); | ||
| + $node.children().each( function( _, el ) { | ||
| + var $descendants = $(this).children(); | ||
| + var $ancestor = $(this).parent().parent(); | ||
| - // Unnest the list items into contiguous div elements. | ||
| - $wrapped.parent().detach().appendTo( $columns ).addClass( "column" ); | ||
| + // Retain item hierarchy (because it is lost after flattening). | ||
| + if( $ancestor.length && ($(this).data( "ancestor" ) === undefined) ) { | ||
| + $(this).siblings().addBack().data( "ancestor", $ancestor ); | ||
| } | ||
| - }); | ||
| - } | ||
| - | ||
| - // When the user clicks an item, select it. | ||
| - $(this).find( "li" ).on( "click", function() { | ||
| - $(this).addClass( "selection" ); | ||
| - }); | ||
| - $columns.before( $("<div>").addClass( "breadcrumb" ) ); | ||
| - $columns.after( $("<div>").addClass( "toolbar" ) ); | ||
| + if( $descendants.length > 0 ) { | ||
| + queue.push( $descendants ); | ||
| + $(this).data( "descendants", $descendants ); | ||
| + $(this).addClass( "parent" ); | ||
| + } | ||
| - // Hide all the columns except the root. | ||
| - $("div.column[data-parent!=0]").addClass( "collapsed" ); | ||
| + // Causes item siblings to have a flattened DOM lineage. | ||
| + $(this).parent().detach().appendTo( $columns ).addClass( "column" ); | ||
| + }); | ||
| + } | ||
| + } | ||
| - return this; | ||
| - }; | ||
| + /** Hide all the columns and deselect selected items. */ | ||
| + function collapse() { | ||
| + $(".column:gt(0)").addClass( "collapsed" ); | ||
| + } | ||
| +})(jQuery); | ||
| - $("div.columns").millerColumns(); | ||
| -}(jQuery)); | ||
| +$(document).ready( function() { $("div.columns").millerColumns(); }); | ||
| -div.columns { | ||
| - float: left; | ||
| - width: 100%; | ||
| - height: 200px; | ||
| - overflow-x: auto; | ||
| - overflow-y: hidden; | ||
| - white-space: nowrap; | ||
| - | ||
| - background-color: #949494; | ||
| -} | ||
| - | ||
| -ul.column { | ||
| - display: inline-block; | ||
| - float: left; | ||
| - padding: 0; | ||
| - margin: 0; | ||
| - | ||
| - vertical-align: top; | ||
| - overflow: hidden; | ||
| - border-right: 1px solid #666; | ||
| - font-size: 0.9em; | ||
| - font-family: Arial; | ||
| - background-color: white; | ||
| - | ||
| - white-space: normal; | ||
| -} | ||
| - | ||
| -ul.column.collapsed { | ||
| - display: none; | ||
| -} | ||
| - | ||
| -ul.column > li { | ||
| - list-style: none; | ||
| - padding-left: 0.5em; | ||
| - padding-right: 0.5em; | ||
| - padding-top: 0.25em; | ||
| - padding-bottom: 0.25em; | ||
| -} | ||
| - | ||
| -/* Zebra stripes. */ | ||
| -ul.column > li:nth-child(odd) { | ||
| - background-color: #EEE; | ||
| -} | ||
| - | ||
| -ul.column > li:hover { | ||
| - color: black; | ||
| - background-color: #DDE4E8; | ||
| -} | ||
| - | ||
| -/* Ensure the selection hierarchy is highlighted. */ | ||
| -ul.column > li.selection { | ||
| - background-color: #08C; | ||
| - color: white; | ||
| -} | ||
| - | ||
| -(function( $ ) { | ||
| - $.fn.millerColumns = function() { | ||
| - return this.each( function() { | ||
| - unnest( $(this) ); | ||
| - | ||
| - // Expand child node on click. | ||
| - $(this).find( "li" ).on( "click", function() { | ||
| - | ||
| - // In the end, there can only be one selected item per column. | ||
| - $(this).addClass( "selection" ); | ||
| - $(this).siblings().removeClass( "selection" ); | ||
| - }); | ||
| - }); | ||
| - } | ||
| - | ||
| - /** | ||
| - * | ||
| - */ | ||
| - function unnest( column_container ) { | ||
| - var queue = []; | ||
| - var $columns = column_container; | ||
| - | ||
| - queue.push( $columns.children( "ul" ) ); | ||
| - | ||
| - while( queue.length > 0 ) { | ||
| - var $child = queue.shift(); | ||
| - | ||
| - $child.children( "li" ).each( function( _, el ) { | ||
| - var $children = $(this).children( "ul" ); | ||
| - | ||
| - if( $children.length > 0 ) { | ||
| - queue.push( $children ); | ||
| - $(this).addClass( "parent" ); | ||
| - } | ||
| - | ||
| - $(this).parent().detach().appendTo( $columns ).addClass( "column" ); | ||
| - }); | ||
| - } | ||
| - | ||
| - // Hide all but the first column. | ||
| - $(".column:gt(0)").addClass( "collapsed" ); | ||
| - } | ||
| -})(jQuery); | ||
| </p> | ||
| </div> | ||
| - <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> | ||
| + <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> | ||
| </xsl:template> | ||