From 51e426d6dfe5d9e6dd5a60df25c8c48516ad8cc4 Mon Sep 17 00:00:00 2001 From: Brendan Dean Date: Thu, 29 Nov 2012 15:52:41 -0800 Subject: [PATCH 1/6] adding logic for persistent tooltips --- examples/tip.html | 7 ++++ scripts/components/Tip.js | 77 +++++++++++++++++++++++++-------------- 2 files changed, 57 insertions(+), 27 deletions(-) diff --git a/examples/tip.html b/examples/tip.html index 28efc0f..042d077 100644 --- a/examples/tip.html +++ b/examples/tip.html @@ -74,6 +74,13 @@ Pastrami boudin pig, swine filet mignon venison flank chuck. +
  • + Persistent Tip. +
    + Bresaola salami short loin tongue t-bone venison turkey fatback pancetta frankfurter swine hamburger. + close +
    +
  • diff --git a/scripts/components/Tip.js b/scripts/components/Tip.js index 6bbf0e7..598a0c5 100644 --- a/scripts/components/Tip.js +++ b/scripts/components/Tip.js @@ -85,6 +85,14 @@ Tip = Abstract.extend( function (Abstract){ */ className: 'tooltip', + /** + * Class of target that will close a persistent tip + * @property closeClass + * @type String + * @private + */ + closeClass: '.close', + /** * CSS styles for the Tip * @property style @@ -94,13 +102,13 @@ Tip = Abstract.extend( function (Abstract){ style: '', /** - * If set to true the tip will remain open until the mouse has left the tip. - * @property interactive + * If set to true the tip will remain open until the user clicks the close button. + * @property persistent * @type Boolean * @private * @default true */ - interactive: TRUE, + persistent: FALSE, /** * The buffer in pixels around the element to be used in determing if the user has stopped @@ -160,21 +168,13 @@ Tip = Abstract.extend( function (Abstract){ */ href, - /** - * An indicator of whether or not the tip should remain open - * @property stuck - * @type Boolean - * @private - */ - stuck, - /** * Whether the element is an input or not * @property isInput * @type Boolean * @private */ - isInput = ($element[0].tagName.toLowerCase() === 'input'), + isInput = ( $element[0].tagName.toLowerCase() === 'input' ), /** * Array of decorators to apply to a Tip instance @@ -241,8 +241,19 @@ Tip = Abstract.extend( function (Abstract){ function handleMouseEnter ( event ){ event.stopPropagation(); - //set up a listener on the document to be used in determing if the user has moused out of the threshold - $document.on( 'mousemove.lu.tip', handleMouseMove ); + if( !settings.persistent ) { + //set up a listener on the document to be used in determing if the user has moused out of the threshold + $document.on( 'mousemove.lu.tip', handleMouseMove ); + } else { + // if the user clicks outside of a persistent tip close it + $document.on( 'click', function( evt) { + var $target = $( evt.target ); + + if( $target.closest( '.' + settings.className ).length === 0 ) { + self.hide(); + } + } ); + } self.show(); } @@ -297,11 +308,13 @@ Tip = Abstract.extend( function (Abstract){ function handleFocus( event ){ event.stopPropagation(); - $element.on( 'blur.lu.tip', function( event ){ - event.stopPropagation(); - $element.off( 'blur.lu.tip' ); - self.hide(); - } ); + if( !settings.persistent ) { + $element.on( 'blur.lu.tip', function( event ){ + event.stopPropagation(); + $element.off( 'blur.lu.tip' ); + self.hide(); + } ); + } self.show(); } @@ -332,15 +345,16 @@ Tip = Abstract.extend( function (Abstract){ * @method hide * @return {Void} */ - this.hide = function(){ + this.hide = function( noDelay ){ var timeout; - if( rendered === TRUE ){ + + if( rendered === TRUE && !noDelay ){ timeout = window.setTimeout( function(){ - if( !stuck || !settings.interactive ){ - $tip.hide(); - window.clearTimeout( timeout ); - } + $tip.hide(); + window.clearTimeout( timeout ); }, settings.delay ); + } else if ( noDelay ) { + $tip.hide(); } }; @@ -383,8 +397,17 @@ Tip = Abstract.extend( function (Abstract){ } else { $element.on( 'focus', handleFocus ); } - // use losing focus on tip to enforce one tip at a time - $tip.on( 'blur', self.hide ); + + if( settings.persistent ) { + // close button for persistent tips + $tip.on( 'click', settings.closeClass, function( evt ) { + evt.preventDefault(); + self.hide( true ); // close tip with no delay + } ); + } else { + // use losing focus on tip to enforce one (non-persistent) tip at a time + $tip.on( 'blur', self.hide ); + } // === DECORATION === switch( settings.placement ){ From 4a5ac4f5229726d72a3f05bc327492e225c5fcd9 Mon Sep 17 00:00:00 2001 From: Brendan Dean Date: Thu, 29 Nov 2012 15:58:54 -0800 Subject: [PATCH 2/6] small cleanup for persistent tip --- scripts/components/Tip.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/scripts/components/Tip.js b/scripts/components/Tip.js index 598a0c5..70be425 100644 --- a/scripts/components/Tip.js +++ b/scripts/components/Tip.js @@ -102,7 +102,7 @@ Tip = Abstract.extend( function (Abstract){ style: '', /** - * If set to true the tip will remain open until the user clicks the close button. + * If set to true the tip will remain open until the user clicks the close button or outside of the tip * @property persistent * @type Boolean * @private @@ -348,13 +348,15 @@ Tip = Abstract.extend( function (Abstract){ this.hide = function( noDelay ){ var timeout; - if( rendered === TRUE && !noDelay ){ - timeout = window.setTimeout( function(){ + if( rendered === TRUE ){ + if( !noDelay ){ + timeout = window.setTimeout( function(){ + $tip.hide(); + window.clearTimeout( timeout ); + }, settings.delay ); + } else { $tip.hide(); - window.clearTimeout( timeout ); - }, settings.delay ); - } else if ( noDelay ) { - $tip.hide(); + } } }; From 30650d656d7b09bfd8e670920a2ce48c75c46e14 Mon Sep 17 00:00:00 2001 From: Brendan Dean Date: Fri, 30 Nov 2012 14:46:47 -0800 Subject: [PATCH 3/6] correcting and adding some additional tooltip tests --- test/tip/test.js | 112 ++++++++++++++++++++++++++++++++++------------ test/tip/tip.html | 23 +++++++++- 2 files changed, 104 insertions(+), 31 deletions(-) diff --git a/test/tip/test.js b/test/tip/test.js index 0b8fc67..785d3f5 100644 --- a/test/tip/test.js +++ b/test/tip/test.js @@ -2,38 +2,92 @@ function execute(){ var mouseTipEl = $( '#mouse-tip' ), mouseTipComponent = mouseTipEl.lu( 'getComponent', 'Tip' ), inputTipEl = $( '#input-tip' ), - inputTipComponent = inputTipEl.lu( 'getComponent', 'Tip' ); + inputTipComponent = inputTipEl.lu( 'getComponent', 'Tip' ), + persistentTipEl = $( '#persistent-tip' ), + persistentTipComponent = persistentTipEl.lu( 'getComponent', 'Tip' ); - QUnit.module( 'Lu Tips' ); + $.when.apply( $, [ mouseTipComponent.deferral, + inputTipComponent.deferral, + persistentTipComponent.deferral ] ).done( function () { - QUnit.asyncTest( 'Mouse triggered tip.' , function() { - mouseTipComponent.ready(function() { + QUnit.module( 'API Tests' ); + + test( 'Programmatic show', 1, function() { + mouseTipComponent.instance.show(); + if( $( '.mouse-tip' ).is( ':visible' ) ) { + ok( true, 'Tip is shown' ); + } + } ); + + test( 'Programmatic getPosition', 1, function() { + var position = mouseTipComponent.instance.getPosition(); + + if( position.top && position.left ) { + ok( true, 'Postion object has correct attributes' ); + } + } ); + + asyncTest( 'Programmatic hide', 1, function() { + mouseTipComponent.instance.hide(); + setTimeout( function() { + if( !$( '.mouse-tip' ).is( ':visible' ) ) { + ok( true, 'Tip is hidden' ); + start(); + } + }, 500 ); + } ); + + QUnit.module( 'Interaction Tests' ); + + test( 'Mouse over show', 2, function() { mouseTipEl.trigger( 'mouseenter' ); - expect( 2 ); - ok( $.trim( $( '.mouse-tip' ).html() ) === 'Fatback pork belly flank salami cow t-bone ground round pancetta short ribs jerky pig pork sausage.', 'Tip content is correct.' ); - start(); - $(document).trigger( 'mousemove' ); - stop(); - setTimeout(function() { - ok( $( '.mouse-tip' ).css('display') === 'none', 'Tip has been hidden.' ); - start(); - }, 300); - }); - }); - - QUnit.asyncTest( 'Focus triggered tip.' , function() { - inputTipComponent.ready(function() { + ok( $.trim( $( '.mouse-tip' ).html() ) === 'Mouse tooltip content.', 'Tip content is correct.' ); + if( $( '.mouse-tip' ).is( ':visible' ) ) { + ok( true, 'Tip is shown' ); + } + } ); + + asyncTest( 'Mouse leave hide', 1, function() { + $( document ).trigger( 'mousemove' ); + setTimeout( function() { + if( !$( '.mouse-tip' ).is( ':visible' ) ) { + ok( true, 'Tip is hidden' ); + start(); + } + }, 500 ); + } ); + + test( 'Focus show', 2, function() { inputTipEl.trigger( 'focus' ); - expect( 2 ); - ok( $.trim( $( '.input-tip' ).html() ) === 'Pastrami boudin pig, swine filet mignon venison flank chuck.', 'Tip content is correct.' ); - start(); - inputTipEl.trigger( 'blur' ); - stop(); - setTimeout(function() { - ok( $( '.input-tip' ).css( 'display' ) === 'none', 'Tip has been hidden.' ); - start(); - }, 300); - }); - }); + ok( $.trim( $( '.input-tip' ).html() ) === 'Input tooltip content.', 'Tip content is correct.' ); + if( $( '.input-tip' ).is( ':visible' ) ) { + ok( true, 'Tip is shown' ); + } + } ); + + asyncTest( 'Blur hide', 1, function() { + $( inputTipEl ).trigger( 'blur' ); + setTimeout( function() { + if( !$( '.input-tip' ).is( ':visible' ) ) { + ok( true, 'Tip is hidden' ); + start(); + } + }, 500 ); + } ); + + test( 'Show persistent tip', 1, function() { + persistentTipEl.trigger( 'mouseenter' ); + if( $( '.persistent-tip' ).is( ':visible' ) ) { + ok( true, 'Tip is shown' ); + } + } ); + + test( 'Hide persistent tip (with close button)', 1, function() { + $( '.persistent-tip .close' ).trigger( 'click' ); + if( !$( '.persistent-tip' ).is( ':visible' ) ) { + ok( true, 'Tip is hidden' ); + } + } ); + } ); } \ No newline at end of file diff --git a/test/tip/tip.html b/test/tip/tip.html index 5ebc063..1cbb657 100644 --- a/test/tip/tip.html +++ b/test/tip/tip.html @@ -4,6 +4,17 @@ Tip Tests + @@ -14,13 +25,21 @@
  • Mouse Tip.
    - Fatback pork belly flank salami cow t-bone ground round pancetta short ribs jerky pig pork sausage. + Mouse tooltip content.
  • - Pastrami boudin pig, swine filet mignon venison flank chuck. + Input tooltip content. +
    +
  • +
  • + Persistent Tip. +
    + Persistent tooltip content. + Close
  • From 7e00f7dafbaa868393dc10ab404368d6a3f64e3b Mon Sep 17 00:00:00 2001 From: Brendan Dean Date: Thu, 6 Dec 2012 12:04:13 -0800 Subject: [PATCH 4/6] removing outline on tip example --- examples/tip.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/tip.html b/examples/tip.html index 042d077..6b18a21 100644 --- a/examples/tip.html +++ b/examples/tip.html @@ -32,6 +32,9 @@ position: absolute; width: 200px; } + .tooltip:focus { + outline: 0; + } From 2733c88d8a64819141b21cdafb3aa0341a72b6d1 Mon Sep 17 00:00:00 2001 From: Brendan Dean Date: Thu, 6 Dec 2012 12:07:10 -0800 Subject: [PATCH 5/6] adding tip back into grunt.js --- grunt.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grunt.js b/grunt.js index d56b8ee..0ba38c1 100644 --- a/grunt.js +++ b/grunt.js @@ -41,7 +41,7 @@ module.exports = function(grunt) { 'http://localhost:1337/test/placeholder/placeholder.html', 'http://localhost:1337/test/$/$.html', 'http://localhost:1337/test/list/list.html', - //'http://localhost:1337/test/tip/tip.html', + 'http://localhost:1337/test/tip/tip.html', 'http://localhost:1337/test/carousel/carousel.html', 'http://localhost:1337/test/dropdown/dropdown.html', 'http://localhost:1337/test/switch/switch.html', From 87ef3702a05c43ffa0fd9d4774dea53c3842ea75 Mon Sep 17 00:00:00 2001 From: Brendan Dean Date: Thu, 6 Dec 2012 12:52:03 -0800 Subject: [PATCH 6/6] updating to match new container data expected on load --- scripts/components/Tip.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/components/Tip.js b/scripts/components/Tip.js index 70be425..6071eaf 100644 --- a/scripts/components/Tip.js +++ b/scripts/components/Tip.js @@ -329,7 +329,7 @@ Tip = Abstract.extend( function (Abstract){ */ this.show = function(){ if( rendered === FALSE ){ - TipContainer.trigger( 'load', [href] ); + TipContainer.trigger( 'load', { content: href } ); } else { $tip.css( self.getPosition() ); $tip.show();