Index: trunk/extensions/UsabilityInitiative/css/suggestions.css |
— | — | @@ -62,6 +62,7 @@ |
63 | 63 | color: white; |
64 | 64 | color: HighlightText; |
65 | 65 | } |
66 | | -.autoellipsis-matched { |
| 66 | +.autoellipsis-matched, |
| 67 | +.highlight { |
67 | 68 | font-weight: bold; |
68 | 69 | } |
\ No newline at end of file |
Index: trunk/extensions/UsabilityInitiative/css/combined.css |
— | — | @@ -62,7 +62,8 @@ |
63 | 63 | color: white; |
64 | 64 | color: HighlightText; |
65 | 65 | } |
66 | | -.autoellipsis-matched { |
| 66 | +.autoellipsis-matched, |
| 67 | +.highlight { |
67 | 68 | font-weight: bold; |
68 | 69 | }/* Prototype code to show collapsing left nav options */ |
69 | 70 | #mw-panel.collapsible-nav div.portal { |
Index: trunk/extensions/UsabilityInitiative/css/combined.min.css |
— | — | @@ -60,7 +60,8 @@ |
61 | 61 | color:white; |
62 | 62 | color:HighlightText; |
63 | 63 | } |
64 | | -.autoellipsis-matched{ |
| 64 | +.autoellipsis-matched, |
| 65 | +.highlight{ |
65 | 66 | font-weight:bold; |
66 | 67 | } |
67 | 68 | #mw-panel.collapsible-nav div.portal{ |
Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php |
— | — | @@ -31,11 +31,11 @@ |
32 | 32 | array( 'src' => 'css/vector/jquery-ui-1.7.2.css', 'version' => '1.7.2y' ), |
33 | 33 | ), |
34 | 34 | 'combined' => array( |
35 | | - array( 'src' => 'css/combined.css', 'version' => 114 ), |
| 35 | + array( 'src' => 'css/combined.css', 'version' => 115 ), |
36 | 36 | array( 'src' => 'css/vector/jquery-ui-1.7.2.css', 'version' => '1.7.2y' ), |
37 | 37 | ), |
38 | 38 | 'minified' => array( |
39 | | - array( 'src' => 'css/combined.min.css', 'version' => 114 ), |
| 39 | + array( 'src' => 'css/combined.min.css', 'version' => 115 ), |
40 | 40 | array( 'src' => 'css/vector/jquery-ui-1.7.2.css', 'version' => '1.7.2y' ), |
41 | 41 | ), |
42 | 42 | ) |
— | — | @@ -58,13 +58,14 @@ |
59 | 59 | |
60 | 60 | // Core functionality of extension scripts |
61 | 61 | array( 'src' => 'js/plugins/jquery.async.js', 'version' => 3 ), |
62 | | - array( 'src' => 'js/plugins/jquery.autoEllipsis.js', 'version' => 16 ), |
| 62 | + array( 'src' => 'js/plugins/jquery.autoEllipsis.js', 'version' => 17 ), |
63 | 63 | array( 'src' => 'js/plugins/jquery.browser.js', 'version' => 9 ), |
64 | 64 | array( 'src' => 'js/plugins/jquery.collapsibleTabs.js', 'version' => 6 ), |
65 | 65 | array( 'src' => 'js/plugins/jquery.color.js', 'version' => 1 ), |
66 | 66 | array( 'src' => 'js/plugins/jquery.cookie.js', 'version' => 4 ), |
67 | 67 | array( 'src' => 'js/plugins/jquery.delayedBind.js', 'version' => 1 ), |
68 | 68 | array( 'src' => 'js/plugins/jquery.expandableField.js', 'version' => 17 ), |
| 69 | + array( 'src' => 'js/plugins/jquery.highlightText.js', 'version' => 1 ), |
69 | 70 | array( 'src' => 'js/plugins/jquery.suggestions.js', 'version' => 32 ), |
70 | 71 | array( 'src' => 'js/plugins/jquery.textSelection.js', 'version' => 36 ), |
71 | 72 | array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 196 ), |
— | — | @@ -82,10 +83,10 @@ |
83 | 84 | array( 'src' => 'js/thirdparty/contentCollector.js', 'version' => 2 ), |
84 | 85 | ), |
85 | 86 | 'combined' => array( |
86 | | - array( 'src' => 'js/plugins.combined.js', 'version' => 449 ), |
| 87 | + array( 'src' => 'js/plugins.combined.js', 'version' => 450 ), |
87 | 88 | ), |
88 | 89 | 'minified' => array( |
89 | | - array( 'src' => 'js/plugins.combined.min.js', 'version' => 460 ), |
| 90 | + array( 'src' => 'js/plugins.combined.min.js', 'version' => 461 ), |
90 | 91 | ), |
91 | 92 | ), |
92 | 93 | ); |
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.suggestions.js |
— | — | @@ -167,7 +167,7 @@ |
168 | 168 | } else { |
169 | 169 | // Add <span> with text |
170 | 170 | if( context.config.highlightInput ) { |
171 | | - matchedText = text.substr( 0, context.data.prevText.length ); |
| 171 | + matchedText = context.data.prevText; |
172 | 172 | } |
173 | 173 | $result.append( $( '<span />' ) |
174 | 174 | .css( 'whiteSpace', 'nowrap' ) |
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.highlightText.js |
— | — | @@ -0,0 +1,57 @@ |
| 2 | +/** |
| 3 | + * Plugin that highlights matched word partials in a given element |
| 4 | + * TODO: add a function for restoring the previous text |
| 5 | + * TODO: |
| 6 | + */ |
| 7 | +( function( $ ) { |
| 8 | + |
| 9 | +$.highlightText = { |
| 10 | + |
| 11 | + // Split our pattern string at spaces and run our highlight function on the results |
| 12 | + splitAndHighlight: function( node, pat ) { |
| 13 | + var patArray = pat.split(" "); |
| 14 | + for ( var i = 0; i < patArray.length; i++ ) { |
| 15 | + if ( patArray[i].length == 0 ) continue; |
| 16 | + $.highlightText.innerHighlight( node, patArray[i] ); |
| 17 | + } |
| 18 | + return node; |
| 19 | + }, |
| 20 | + // adapted from Johann Burkard's highlight plugin |
| 21 | + // http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html |
| 22 | + // scans a node looking for the pattern and wraps a span around each match |
| 23 | + innerHighlight: function( node, pat ) { |
| 24 | + var skip = 0; |
| 25 | + if ( node.nodeType == 3 ) { |
| 26 | + // TODO - need to be smarter about the character matching here. |
| 27 | + // non latin characters can make regex think a new word has begun. |
| 28 | + var pos = node.data.search( new RegExp( "\\b" + RegExp.escape( pat ), "i" ) ); |
| 29 | + if ( pos >= 0 ) { |
| 30 | + var spannode = document.createElement( 'span' ); |
| 31 | + spannode.className = 'highlight'; |
| 32 | + var middlebit = node.splitText( pos ); |
| 33 | + var endbit = middlebit.splitText( pat.length ); |
| 34 | + var middleclone = middlebit.cloneNode( true ); |
| 35 | + spannode.appendChild( middleclone ); |
| 36 | + middlebit.parentNode.replaceChild( spannode, middlebit ); |
| 37 | + skip = 1; |
| 38 | + } |
| 39 | + } else if ( node.nodeType == 1 && node.childNodes && !/(script|style)/i.test( node.tagName ) |
| 40 | + && !( node.tagName.toLowerCase() == 'span' && node.classList.contains( 'highlight' ) ) ) { |
| 41 | + for ( var i = 0; i < node.childNodes.length; ++i ) { |
| 42 | + i += $.highlightText.innerHighlight( node.childNodes[i], pat ); |
| 43 | + } |
| 44 | + } |
| 45 | + return skip; |
| 46 | + } |
| 47 | +}; |
| 48 | + |
| 49 | +$.fn.highlightText = function( matchString ) { |
| 50 | + return $( this ).each( function() { |
| 51 | + var $this = $( this ); |
| 52 | + $this.data( 'highlightText', { originalText: $this.text() } ); |
| 53 | + $.highlightText.splitAndHighlight( this, matchString ); |
| 54 | + } ); |
| 55 | +}; |
| 56 | + |
| 57 | +} )( jQuery ); |
| 58 | + |
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.autoEllipsis.js |
— | — | @@ -33,32 +33,15 @@ |
34 | 34 | // protected text element - the width of this element is counted, but next is never trimmed from it |
35 | 35 | var $protectedText = null; |
36 | 36 | |
37 | | - if ( options.matchText ) { |
38 | | - var text = $this.text(); |
39 | | - var matchedText = options.matchText; |
40 | | - $trimmableText = $( '<span />' ) |
| 37 | + if ( options.hasSpan ) { |
| 38 | + $trimmableText = $this.children( options.selector ); |
| 39 | + } else { |
| 40 | + $trimmableText = $( '<span />' ) |
41 | 41 | .css( 'whiteSpace', 'nowrap' ) |
42 | | - .addClass( 'autoellipsis-trimmed' ) |
43 | | - .text( $this.text().substr( matchedText.length, $this.text().length ) ); |
44 | | - $protectedText = $( '<span />' ) |
45 | | - .addClass( 'autoellipsis-matched' ) |
46 | | - .css( 'whiteSpace', 'nowrap' ) |
47 | | - .text( options.matchText ); |
48 | | - $container |
| 42 | + .text( $this.text() ); |
| 43 | + $this |
49 | 44 | .empty() |
50 | | - .append( $protectedText ) |
51 | 45 | .append( $trimmableText ); |
52 | | - } else { |
53 | | - if ( options.hasSpan ) { |
54 | | - $trimmableText = $this.children( options.selector ); |
55 | | - } else { |
56 | | - $trimmableText = $( '<span />' ) |
57 | | - .css( 'whiteSpace', 'nowrap' ) |
58 | | - .text( $this.text() ); |
59 | | - $this |
60 | | - .empty() |
61 | | - .append( $trimmableText ); |
62 | | - } |
63 | 46 | } |
64 | 47 | |
65 | 48 | var text = $container.text(); |
— | — | @@ -136,6 +119,7 @@ |
137 | 120 | $container.attr( 'title', text ); |
138 | 121 | } |
139 | 122 | if ( options.matchText ) { |
| 123 | + $container.highlightText( options.matchText ); |
140 | 124 | matchTextCache[text][options.matchText][w] = $container.html(); |
141 | 125 | } else { |
142 | 126 | cache[text][w] = $container.html(); |
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.js |
— | — | @@ -245,32 +245,15 @@ |
246 | 246 | // protected text element - the width of this element is counted, but next is never trimmed from it |
247 | 247 | var $protectedText = null; |
248 | 248 | |
249 | | - if ( options.matchText ) { |
250 | | - var text = $this.text(); |
251 | | - var matchedText = options.matchText; |
252 | | - $trimmableText = $( '<span />' ) |
| 249 | + if ( options.hasSpan ) { |
| 250 | + $trimmableText = $this.children( options.selector ); |
| 251 | + } else { |
| 252 | + $trimmableText = $( '<span />' ) |
253 | 253 | .css( 'whiteSpace', 'nowrap' ) |
254 | | - .addClass( 'autoellipsis-trimmed' ) |
255 | | - .text( $this.text().substr( matchedText.length, $this.text().length ) ); |
256 | | - $protectedText = $( '<span />' ) |
257 | | - .addClass( 'autoellipsis-matched' ) |
258 | | - .css( 'whiteSpace', 'nowrap' ) |
259 | | - .text( options.matchText ); |
260 | | - $container |
| 254 | + .text( $this.text() ); |
| 255 | + $this |
261 | 256 | .empty() |
262 | | - .append( $protectedText ) |
263 | 257 | .append( $trimmableText ); |
264 | | - } else { |
265 | | - if ( options.hasSpan ) { |
266 | | - $trimmableText = $this.children( options.selector ); |
267 | | - } else { |
268 | | - $trimmableText = $( '<span />' ) |
269 | | - .css( 'whiteSpace', 'nowrap' ) |
270 | | - .text( $this.text() ); |
271 | | - $this |
272 | | - .empty() |
273 | | - .append( $trimmableText ); |
274 | | - } |
275 | 258 | } |
276 | 259 | |
277 | 260 | var text = $container.text(); |
— | — | @@ -348,6 +331,7 @@ |
349 | 332 | $container.attr( 'title', text ); |
350 | 333 | } |
351 | 334 | if ( options.matchText ) { |
| 335 | + $container.highlightText( options.matchText ); |
352 | 336 | matchTextCache[text][options.matchText][w] = $container.html(); |
353 | 337 | } else { |
354 | 338 | cache[text][w] = $container.html(); |
— | — | @@ -1145,7 +1129,7 @@ |
1146 | 1130 | } else { |
1147 | 1131 | // Add <span> with text |
1148 | 1132 | if( context.config.highlightInput ) { |
1149 | | - matchedText = text.substr( 0, context.data.prevText.length ); |
| 1133 | + matchedText = context.data.prevText; |
1150 | 1134 | } |
1151 | 1135 | $result.append( $( '<span />' ) |
1152 | 1136 | .css( 'whiteSpace', 'nowrap' ) |
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.min.js |
— | — | @@ -20,7 +20,7 @@ |
21 | 21 | {var val=array[i];return loop.call(val,i++,val);}}));} |
22 | 22 | $.fn.eachAsync=function(opts) |
23 | 23 | {$.eachAsync(this,opts);return this;}})(jQuery);(function($){var cache={};var matchTextCache={};$.fn.autoEllipsis=function(options){options=$.extend({'position':'center','tooltip':false,'restoreText':false,'hasSpan':false,'matchText':null},options);$(this).each(function(){var $this=$(this);if(options.restoreText){if(!$this.data('autoEllipsis.originalText')){$this.data('autoEllipsis.originalText',$this.text());}else{$this.text($this.data('autoEllipsis.originalText'));}} |
24 | | -var $container=$this;var $trimmableText=null;var $protectedText=null;if(options.matchText){var text=$this.text();var matchedText=options.matchText;$trimmableText=$('<span />').css('whiteSpace','nowrap').addClass('autoellipsis-trimmed').text($this.text().substr(matchedText.length,$this.text().length));$protectedText=$('<span />').addClass('autoellipsis-matched').css('whiteSpace','nowrap').text(options.matchText);$container.empty().append($protectedText).append($trimmableText);}else{if(options.hasSpan){$trimmableText=$this.children(options.selector);}else{$trimmableText=$('<span />').css('whiteSpace','nowrap').text($this.text());$this.empty().append($trimmableText);}} |
| 24 | +var $container=$this;var $trimmableText=null;var $protectedText=null;if(options.hasSpan){$trimmableText=$this.children(options.selector);}else{$trimmableText=$('<span />').css('whiteSpace','nowrap').text($this.text());$this.empty().append($trimmableText);} |
25 | 25 | var text=$container.text();var trimmableText=$trimmableText.text();var w=$container.width();var pw=$protectedText?$protectedText.width():0;if(!(text in cache)){cache[text]={};} |
26 | 26 | if(options.matchText&&!(text in matchTextCache)){matchTextCache[text]={};} |
27 | 27 | if(options.matchText&&!(options.matchText in matchTextCache[text])){matchTextCache[text][options.matchText]={};} |
— | — | @@ -32,7 +32,7 @@ |
33 | 33 | break;case'left':var r=0;while($trimmableText.outerWidth()+pw>w&&r<trimmableText.length){$trimmableText.text('...'+trimmableText.substr(r));r++;} |
34 | 34 | break;}} |
35 | 35 | if(options.tooltip){$container.attr('title',text);} |
36 | | -if(options.matchText){matchTextCache[text][options.matchText][w]=$container.html();}else{cache[text][w]=$container.html();}});};})(jQuery);(function($){$.browserTest=function(a,z){var u='unknown',x='X',m=function(r,h){for(var i=0;i<h.length;i=i+1){r=r.replace(h[i][0],h[i][1]);} |
| 36 | +if(options.matchText){$container.highlightText(options.matchText);matchTextCache[text][options.matchText][w]=$container.html();}else{cache[text][w]=$container.html();}});};})(jQuery);(function($){$.browserTest=function(a,z){var u='unknown',x='X',m=function(r,h){for(var i=0;i<h.length;i=i+1){r=r.replace(h[i][0],h[i][1]);} |
37 | 37 | return r;},c=function(i,a,b,c){var r={name:m((a.exec(i)||[u,u])[1],b)};r[r.name]=true;r.version=(c.exec(i)||[x,x,x,x])[3];if(r.name.match(/safari/)&&r.version>400){r.version='2.0';} |
38 | 38 | if(r.name==='presto'){r.version=($.browser.version>9.27)?'futhark':'linear_b';} |
39 | 39 | if(r.name==='opera'&&$.browser.version>=9.8){r.version=i.match(/version\/([0-9\.]*)/i)[1]||10;} |
— | — | @@ -64,7 +64,7 @@ |
65 | 65 | if(delayed){context.data.timerID=setTimeout(maybeFetch,context.config.delay);}else{maybeFetch();} |
66 | 66 | $.suggestions.special(context);},special:function(context){if(typeof context.config.special.render=='function'){setTimeout(function(){$special=context.data.$container.find('.suggestions-special');context.config.special.render.call($special,context.data.$textbox.val());},1);}},configure:function(context,property,value){switch(property){case'fetch':case'cancel':case'special':case'result':case'$region':context.config[property]=value;break;case'suggestions':context.config[property]=value;if(typeof context.data!=='undefined'){if(context.data.$textbox.val().length==0){context.data.$container.hide();}else{context.data.$container.show();var newCSS={'top':context.config.$region.offset().top+context.config.$region.outerHeight(),'bottom':'auto','width':context.config.$region.outerWidth(),'height':'auto'} |
67 | 67 | if(context.config.positionFromLeft){newCSS['left']=context.config.$region.offset().left;newCSS['right']='auto';}else{newCSS['left']='auto';newCSS['right']=$('body').width()-(context.config.$region.offset().left+context.config.$region.outerWidth());} |
68 | | -context.data.$container.css(newCSS);var $results=context.data.$container.children('.suggestions-results');$results.empty();var expWidth=-1;var $autoEllipseMe=$([]);var matchedText=null;for(var i=0;i<context.config.suggestions.length;i++){var text=context.config.suggestions[i];var $result=$('<div />').addClass('suggestions-result').attr('rel',i).data('text',context.config.suggestions[i]).mousemove(function(e){context.data.selectedWithMouse=true;$.suggestions.highlight(context,$(this).closest('.suggestions-results div'),false);}).appendTo($results);if(typeof context.config.result.render=='function'){context.config.result.render.call($result,context.config.suggestions[i]);}else{if(context.config.highlightInput){matchedText=text.substr(0,context.data.prevText.length);} |
| 68 | +context.data.$container.css(newCSS);var $results=context.data.$container.children('.suggestions-results');$results.empty();var expWidth=-1;var $autoEllipseMe=$([]);var matchedText=null;for(var i=0;i<context.config.suggestions.length;i++){var text=context.config.suggestions[i];var $result=$('<div />').addClass('suggestions-result').attr('rel',i).data('text',context.config.suggestions[i]).mousemove(function(e){context.data.selectedWithMouse=true;$.suggestions.highlight(context,$(this).closest('.suggestions-results div'),false);}).appendTo($results);if(typeof context.config.result.render=='function'){context.config.result.render.call($result,context.config.suggestions[i]);}else{if(context.config.highlightInput){matchedText=context.data.prevText;} |
69 | 69 | $result.append($('<span />').css('whiteSpace','nowrap').text(text));var $span=$result.children('span');if($span.outerWidth()>$result.width()&&$span.outerWidth()>expWidth){expWidth=$span.outerWidth()+(context.data.$container.width()-$span.parent().width());} |
70 | 70 | $autoEllipseMe=$autoEllipseMe.add($result);}} |
71 | 71 | if(expWidth>context.data.$container.width()){var maxWidth=context.config.maxExpandFactor*context.data.$textbox.width();context.data.$container.width(Math.min(expWidth,maxWidth));} |