Commit: 813ca5b119f4d1e57f15726a1e4731d8faf11b81
Author: Stewart Lord <[email protected]> Tue, 28 Dec 2010 08:46:56
+0000
Parents: 3116e87f408b98d55cdceac0e23156039c6a4e29
Branches: master
Link:
http://git.php.net/?p=web/php.git;a=commitdiff;h=813ca5b119f4d1e57f15726a1e4731d8faf11b81
Log:
Fixed the scoring of results in search auto-complete. This required an upgrade
to jQuery 1.4.4 and the inclusion of jQuery UI 1.8.7 (both linked to Google's
Ajax APIs CDN) as the auto-complete plugin has been rolled into the standard
jQuery UI library.
We now supply a source callback function to the auto-complete plugin (instead
of a JS array). This callback mimics the quick-ref logic for ranking manual
pages based on where the user's search term appears in the name of the doc
entry. However, it lacks the similar_text() component since that function is
not available in JS (doesn't seem like a significant loss).
Tweaked auto-complete related CSS rules to accommodate different markup
produced by the new version of the auto-complete plugin.
Changed paths:
M include/header.inc
M js/common.js
D js/jquery.autocomplete.js
D js/jquery.autocomplete.pack.js
M styles/structure.css
M styles/theme.css
diff --git a/include/header.inc b/include/header.inc
index 1f6997e..2f9a392 100644
--- a/include/header.inc
+++ b/include/header.inc
@@ -18,9 +18,9 @@
<link rel="stylesheet" type="text/css" href="/styles/doc.css<?php echo $v?>"
media="screen" />
<link rel="stylesheet" type="text/css" href="/styles/theme.css<?php echo
$v?>" media="screen" />
- <script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
+ <script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
+<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.min.js"></script>
<script type="text/javascript"
src="/js/jquery.hoverIntent.minified.js"></script>
- <script type="text/javascript" src="/js/jquery.autocomplete.js"></script>
<script type="text/javascript" src="/js/common.js<?php echo $v?>"></script>
<base href="<?php echo $_SERVER["BASE_PAGE"] ?>" />
diff --git a/js/common.js b/js/common.js
index bf3d814..4dba57f 100644
--- a/js/common.js
+++ b/js/common.js
@@ -20,20 +20,46 @@ $(document).ready(function() {
});
// load the search index and enable auto-complete.
- jQuery.getScript("/js/search-index-" + getLanguage() + ".js", function(){
- $('#headsearch-keywords').autocomplete(searchIndex, {
- matchContains: true,
- scrollHeight: 240,
- formatItem: function(item) {
- return item.name;
+ jQuery.getScript("js/search-index-" + getLanguage() + ".js", function(){
+ $('#headsearch-keywords').autocomplete({
+ delay: 50,
+ minScore: 75,
+ maxResults: 50,
+ source: function(request, response){
+ // sort the search index by similarity to the user's query
+ var term = request.term;
+ var score = function(item){
+ var match = item.name.search(new RegExp(term, "i"));
+ if (match < 0) return 0;
+ return 100 - (match * 2) - (item.name.length -
term.length);
+ };
+ searchIndex.sort(function(a, b){
+ return score(b) - score(a);
+ });
+
+ // display the best matches
+ var results = [];
+ for (var i = 0; i < this.options.maxResults; i++){
+ var item = searchIndex[i];
+ if (item && score(item) > this.options.minScore){
+ results.push({
+ label: item.name,
+ value: item.page
+ });
+ }
+ }
+ response(results);
+ },
+ focus: function(event, ui) {
+ $('#headsearch-keywords').val(ui.item.label);
+ return false;
+ },
+ select: function(event, ui){
+ $('#headsearch-keywords').val(ui.item.label);
+ if (ui.item.value)
+ window.location = '/manual/' + getLanguage() + '/' +
ui.item.value;
}
- }).result(
- function(event, item){
- alert("User selected: " + item['name'] + "\n" +
- "Direct user to: " + item['page']);
- window.location = '/manual/' + getLanguage() + '/' +
item['page'];
- }
- );
+ });
});
if ($("#quicktoc").length) {
var l = "";
diff --git a/js/jquery.autocomplete.js b/js/jquery.autocomplete.js
deleted file mode 100644
index 9d12a29..0000000
--- a/js/jquery.autocomplete.js
+++ /dev/null
@@ -1,808 +0,0 @@
-/*
- * jQuery Autocomplete plugin 1.1
- *
- * Copyright (c) 2009 Jörn Zaefferer
- *
- * Dual licensed under the MIT and GPL licenses:
- * http://www.opensource.org/licenses/mit-license.php
- * http://www.gnu.org/licenses/gpl.html
- *
- * Revision: $Id: jquery.autocomplete.js 15 2009-08-22 10:30:27Z
joern.zaefferer $
- */
-
-;(function($) {
-
-$.fn.extend({
- autocomplete: function(urlOrData, options) {
- var isUrl = typeof urlOrData == "string";
- options = $.extend({}, $.Autocompleter.defaults, {
- url: isUrl ? urlOrData : null,
- data: isUrl ? null : urlOrData,
- delay: isUrl ? $.Autocompleter.defaults.delay : 10,
- max: options && !options.scroll ? 10 : 150
- }, options);
-
- // if highlight is set to false, replace it with a do-nothing
function
- options.highlight = options.highlight || function(value) {
return value; };
-
- // if the formatMatch option is not specified, then use
formatItem for backwards compatibility
- options.formatMatch = options.formatMatch || options.formatItem;
-
- return this.each(function() {
- new $.Autocompleter(this, options);
- });
- },
- result: function(handler) {
- return this.bind("result", handler);
- },
- search: function(handler) {
- return this.trigger("search", [handler]);
- },
- flushCache: function() {
- return this.trigger("flushCache");
- },
- setOptions: function(options){
- return this.trigger("setOptions", [options]);
- },
- unautocomplete: function() {
- return this.trigger("unautocomplete");
- }
-});
-
-$.Autocompleter = function(input, options) {
-
- var KEY = {
- UP: 38,
- DOWN: 40,
- DEL: 46,
- TAB: 9,
- RETURN: 13,
- ESC: 27,
- COMMA: 188,
- PAGEUP: 33,
- PAGEDOWN: 34,
- BACKSPACE: 8
- };
-
- // Create $ object for input element
- var $input = $(input).attr("autocomplete",
"off").addClass(options.inputClass);
-
- var timeout;
- var previousValue = "";
- var cache = $.Autocompleter.Cache(options);
- var hasFocus = 0;
- var lastKeyPressCode;
- var config = {
- mouseDownOnSelect: false
- };
- var select = $.Autocompleter.Select(options, input, selectCurrent,
config);
-
- var blockSubmit;
-
- // prevent form submit in opera when selecting with return key
- $.browser.opera && $(input.form).bind("submit.autocomplete", function()
{
- if (blockSubmit) {
- blockSubmit = false;
- return false;
- }
- });
-
- // only opera doesn't trigger keydown multiple times while pressed,
others don't work with keypress at all
- $input.bind(($.browser.opera ? "keypress" : "keydown") +
".autocomplete", function(event) {
- // a keypress means the input has focus
- // avoids issue where input had focus before the autocomplete
was applied
- hasFocus = 1;
- // track last key pressed
- lastKeyPressCode = event.keyCode;
- switch(event.keyCode) {
-
- case KEY.UP:
- event.preventDefault();
- if ( select.visible() ) {
- select.prev();
- } else {
- onChange(0, true);
- }
- break;
-
- case KEY.DOWN:
- event.preventDefault();
- if ( select.visible() ) {
- select.next();
- } else {
- onChange(0, true);
- }
- break;
-
- case KEY.PAGEUP:
- event.preventDefault();
- if ( select.visible() ) {
- select.pageUp();
- } else {
- onChange(0, true);
- }
- break;
-
- case KEY.PAGEDOWN:
- event.preventDefault();
- if ( select.visible() ) {
- select.pageDown();
- } else {
- onChange(0, true);
- }
- break;
-
- // matches also semicolon
- case options.multiple &&
$.trim(options.multipleSeparator) == "," && KEY.COMMA:
- case KEY.TAB:
- case KEY.RETURN:
- if( selectCurrent() ) {
- // stop default to prevent a form
submit, Opera needs special handling
- event.preventDefault();
- blockSubmit = true;
- return false;
- }
- break;
-
- case KEY.ESC:
- select.hide();
- break;
-
- default:
- clearTimeout(timeout);
- timeout = setTimeout(onChange, options.delay);
- break;
- }
- }).focus(function(){
- // track whether the field has focus, we shouldn't process any
- // results if the field no longer has focus
- hasFocus++;
- }).blur(function() {
- hasFocus = 0;
- if (!config.mouseDownOnSelect) {
- hideResults();
- }
- }).click(function() {
- // show select when clicking in a focused field
- if ( hasFocus++ > 1 && !select.visible() ) {
- onChange(0, true);
- }
- }).bind("search", function() {
- // TODO why not just specifying both arguments?
- var fn = (arguments.length > 1) ? arguments[1] : null;
- function findValueCallback(q, data) {
- var result;
- if( data && data.length ) {
- for (var i=0; i < data.length; i++) {
- if( data[i].result.toLowerCase() ==
q.toLowerCase() ) {
- result = data[i];
- break;
- }
- }
- }
- if( typeof fn == "function" ) fn(result);
- else $input.trigger("result", result && [result.data,
result.value]);
- }
- $.each(trimWords($input.val()), function(i, value) {
- request(value, findValueCallback, findValueCallback);
- });
- }).bind("flushCache", function() {
- cache.flush();
- }).bind("setOptions", function() {
- $.extend(options, arguments[1]);
- // if we've updated the data, repopulate
- if ( "data" in arguments[1] )
- cache.populate();
- }).bind("unautocomplete", function() {
- select.unbind();
- $input.unbind();
- $(input.form).unbind(".autocomplete");
- });
-
-
- function selectCurrent() {
- var selected = select.selected();
- if( !selected )
- return false;
-
- var v = selected.result;
- previousValue = v;
-
- if ( options.multiple ) {
- var words = trimWords($input.val());
- if ( words.length > 1 ) {
- var seperator =
options.multipleSeparator.length;
- var cursorAt = $(input).selection().start;
- var wordAt, progress = 0;
- $.each(words, function(i, word) {
- progress += word.length;
- if (cursorAt <= progress) {
- wordAt = i;
- return false;
- }
- progress += seperator;
- });
- words[wordAt] = v;
- // TODO this should set the cursor to the right
position, but it gets overriden somewhere
- //$.Autocompleter.Selection(input, progress +
seperator, progress + seperator);
- v = words.join( options.multipleSeparator );
- }
- v += options.multipleSeparator;
- }
-
- $input.val(v);
- hideResultsNow();
- $input.trigger("result", [selected.data, selected.value]);
- return true;
- }
-
- function onChange(crap, skipPrevCheck) {
- if( lastKeyPressCode == KEY.DEL ) {
- select.hide();
- return;
- }
-
- var currentValue = $input.val();
-
- if ( !skipPrevCheck && currentValue == previousValue )
- return;
-
- previousValue = currentValue;
-
- currentValue = lastWord(currentValue);
- if ( currentValue.length >= options.minChars) {
- $input.addClass(options.loadingClass);
- if (!options.matchCase)
- currentValue = currentValue.toLowerCase();
- request(currentValue, receiveData, hideResultsNow);
- } else {
- stopLoading();
- select.hide();
- }
- };
-
- function trimWords(value) {
- if (!value)
- return [""];
- if (!options.multiple)
- return [$.trim(value)];
- return $.map(value.split(options.multipleSeparator),
function(word) {
- return $.trim(value).length ? $.trim(word) : null;
- });
- }
-
- function lastWord(value) {
- if ( !options.multiple )
- return value;
- var words = trimWords(value);
- if (words.length == 1)
- return words[0];
- var cursorAt = $(input).selection().start;
- if (cursorAt == value.length) {
- words = trimWords(value)
- } else {
- words =
trimWords(value.replace(value.substring(cursorAt), ""));
- }
- return words[words.length - 1];
- }
-
- // fills in the input box w/the first match (assumed to be the best
match)
- // q: the term entered
- // sValue: the first matching result
- function autoFill(q, sValue){
- // autofill in the complete box w/the first match as long as
the user hasn't entered in more data
- // if the last user key pressed was backspace, don't autofill
- if( options.autoFill && (lastWord($input.val()).toLowerCase()
== q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {
- // fill in the value (keep the case the user has typed)
- $input.val($input.val() +
sValue.substring(lastWord(previousValue).length));
- // select the portion of the value not typed by the
user (so the next character will erase)
- $(input).selection(previousValue.length,
previousValue.length + sValue.length);
- }
- };
-
- function hideResults() {
- clearTimeout(timeout);
- timeout = setTimeout(hideResultsNow, 200);
- };
-
- function hideResultsNow() {
- var wasVisible = select.visible();
- select.hide();
- clearTimeout(timeout);
- stopLoading();
- if (options.mustMatch) {
- // call search and run callback
- $input.search(
- function (result){
- // if no value found, clear the input
box
- if( !result ) {
- if (options.multiple) {
- var words =
trimWords($input.val()).slice(0, -1);
- $input.val(
words.join(options.multipleSeparator) + (words.length ?
options.multipleSeparator : "") );
- }
- else {
- $input.val( "" );
-
$input.trigger("result", null);
- }
- }
- }
- );
- }
- };
-
- function receiveData(q, data) {
- if ( data && data.length && hasFocus ) {
- stopLoading();
- select.display(data, q);
- autoFill(q, data[0].value);
- select.show();
- } else {
- hideResultsNow();
- }
- };
-
- function request(term, success, failure) {
- if (!options.matchCase)
- term = term.toLowerCase();
- var data = cache.load(term);
- // recieve the cached data
- if (data && data.length) {
- success(term, data);
- // if an AJAX url has been supplied, try loading the data now
- } else if( (typeof options.url == "string") &&
(options.url.length > 0) ){
-
- var extraParams = {
- timestamp: +new Date()
- };
- $.each(options.extraParams, function(key, param) {
- extraParams[key] = typeof param == "function" ?
param() : param;
- });
-
- $.ajax({
- // try to leverage ajaxQueue plugin to abort
previous requests
- mode: "abort",
- // limit abortion to this input
- port: "autocomplete" + input.name,
- dataType: options.dataType,
- url: options.url,
- data: $.extend({
- q: lastWord(term),
- limit: options.max
- }, extraParams),
- success: function(data) {
- var parsed = options.parse &&
options.parse(data) || parse(data);
- cache.add(term, parsed);
- success(term, parsed);
- }
- });
- } else {
- // if we have a failure, we need to empty the list --
this prevents the the [TAB] key from selecting the last successful match
- select.emptyList();
- failure(term);
- }
- };
-
- function parse(data) {
- var parsed = [];
- var rows = data.split("\n");
- for (var i=0; i < rows.length; i++) {
- var row = $.trim(rows[i]);
- if (row) {
- row = row.split("|");
- parsed[parsed.length] = {
- data: row,
- value: row[0],
- result: options.formatResult &&
options.formatResult(row, row[0]) || row[0]
- };
- }
- }
- return parsed;
- };
-
- function stopLoading() {
- $input.removeClass(options.loadingClass);
- };
-
-};
-
-$.Autocompleter.defaults = {
- inputClass: "ac_input",
- resultsClass: "ac_results",
- loadingClass: "ac_loading",
- minChars: 1,
- delay: 400,
- matchCase: false,
- matchSubset: true,
- matchContains: false,
- cacheLength: 10,
- max: 100,
- mustMatch: false,
- extraParams: {},
- selectFirst: true,
- formatItem: function(row) { return row[0]; },
- formatMatch: null,
- autoFill: false,
- width: 0,
- multiple: false,
- multipleSeparator: ", ",
- highlight: function(value, term) {
- return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" +
term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") +
")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
- },
- scroll: true,
- scrollHeight: 180
-};
-
-$.Autocompleter.Cache = function(options) {
-
- var data = {};
- var length = 0;
-
- function matchSubset(s, sub) {
- if (!options.matchCase)
- s = s.toLowerCase();
- var i = s.indexOf(sub);
- if (options.matchContains == "word"){
- i = s.toLowerCase().search("\\b" + sub.toLowerCase());
- }
- if (i == -1) return false;
- return i == 0 || options.matchContains;
- };
-
- function add(q, value) {
- if (length > options.cacheLength){
- flush();
- }
- if (!data[q]){
- length++;
- }
- data[q] = value;
- }
-
- function populate(){
- if( !options.data ) return false;
- // track the matches
- var stMatchSets = {},
- nullData = 0;
-
- // no url was specified, we need to adjust the cache length to
make sure it fits the local data store
- if( !options.url ) options.cacheLength = 1;
-
- // track all options for minChars = 0
- stMatchSets[""] = [];
-
- // loop through the array and create a lookup structure
- for ( var i = 0, ol = options.data.length; i < ol; i++ ) {
- var rawValue = options.data[i];
- // if rawValue is a string, make an array otherwise
just reference the array
- rawValue = (typeof rawValue == "string") ? [rawValue] :
rawValue;
-
- var value = options.formatMatch(rawValue, i+1,
options.data.length);
- if ( value === false )
- continue;
-
- var firstChar = value.charAt(0).toLowerCase();
- // if no lookup array for this character exists, look
it up now
- if( !stMatchSets[firstChar] )
- stMatchSets[firstChar] = [];
-
- // if the match is a string
- var row = {
- value: value,
- data: rawValue,
- result: options.formatResult &&
options.formatResult(rawValue) || value
- };
-
- // push the current match into the set list
- stMatchSets[firstChar].push(row);
-
- // keep track of minChars zero items
- if ( nullData++ < options.max ) {
- stMatchSets[""].push(row);
- }
- };
-
- // add the data items to the cache
- $.each(stMatchSets, function(i, value) {
- // increase the cache size
- options.cacheLength++;
- // add to the cache
- add(i, value);
- });
- }
-
- // populate any existing data
- setTimeout(populate, 25);
-
- function flush(){
- data = {};
- length = 0;
- }
-
- return {
- flush: flush,
- add: add,
- populate: populate,
- load: function(q) {
- if (!options.cacheLength || !length)
- return null;
- /*
- * if dealing w/local data and matchContains than we
must make sure
- * to loop through all the data collections looking for
matches
- */
- if( !options.url && options.matchContains ){
- // track all matches
- var csub = [];
- // loop through all the data grids for matches
- for( var k in data ){
- // don't search through the
stMatchSets[""] (minChars: 0) cache
- // this prevents duplicates
- if( k.length > 0 ){
- var c = data[k];
- $.each(c, function(i, x) {
- // if we've got a
match, add it to the array
- if
(matchSubset(x.value, q)) {
- csub.push(x);
- }
- });
- }
- }
- return csub;
- } else
- // if the exact item exists, use it
- if (data[q]){
- return data[q];
- } else
- if (options.matchSubset) {
- for (var i = q.length - 1; i >=
options.minChars; i--) {
- var c = data[q.substr(0, i)];
- if (c) {
- var csub = [];
- $.each(c, function(i, x) {
- if
(matchSubset(x.value, q)) {
-
csub[csub.length] = x;
- }
- });
- return csub;
- }
- }
- }
- return null;
- }
- };
-};
-
-$.Autocompleter.Select = function (options, input, select, config) {
- var CLASSES = {
- ACTIVE: "ac_over"
- };
-
- var listItems,
- active = -1,
- data,
- term = "",
- needsInit = true,
- element,
- list;
-
- // Create results
- function init() {
- if (!needsInit)
- return;
- element = $("<div/>")
- .hide()
- .addClass(options.resultsClass)
- .css("position", "absolute")
- .appendTo(document.body);
-
- list = $("<ul/>").appendTo(element).mouseover( function(event) {
- if(target(event).nodeName &&
target(event).nodeName.toUpperCase() == 'LI') {
- active = $("li",
list).removeClass(CLASSES.ACTIVE).index(target(event));
- $(target(event)).addClass(CLASSES.ACTIVE);
- }
- }).click(function(event) {
- $(target(event)).addClass(CLASSES.ACTIVE);
- select();
- // TODO provide option to avoid setting focus again
after selection? useful for cleanup-on-focus
- input.focus();
- return false;
- }).mousedown(function() {
- config.mouseDownOnSelect = true;
- }).mouseup(function() {
- config.mouseDownOnSelect = false;
- });
-
- if( options.width > 0 )
- element.css("width", options.width);
-
- needsInit = false;
- }
-
- function target(event) {
- var element = event.target;
- while(element && element.tagName != "LI")
- element = element.parentNode;
- // more fun with IE, sometimes event.target is empty, just
ignore it then
- if(!element)
- return [];
- return element;
- }
-
- function moveSelect(step) {
- listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
- movePosition(step);
- var activeItem = listItems.slice(active, active +
1).addClass(CLASSES.ACTIVE);
- if(options.scroll) {
- var offset = 0;
- listItems.slice(0, active).each(function() {
- offset += this.offsetHeight;
- });
- if((offset + activeItem[0].offsetHeight - list.scrollTop()) >
list[0].clientHeight) {
- list.scrollTop(offset + activeItem[0].offsetHeight -
list.innerHeight());
- } else if(offset < list.scrollTop()) {
- list.scrollTop(offset);
- }
- }
- };
-
- function movePosition(step) {
- active += step;
- if (active < 0) {
- active = listItems.size() - 1;
- } else if (active >= listItems.size()) {
- active = 0;
- }
- }
-
- function limitNumberOfItems(available) {
- return options.max && options.max < available
- ? options.max
- : available;
- }
-
- function fillList() {
- list.empty();
- var max = limitNumberOfItems(data.length);
- for (var i=0; i < max; i++) {
- if (!data[i])
- continue;
- var formatted = options.formatItem(data[i].data, i+1,
max, data[i].value, term);
- if ( formatted === false )
- continue;
- var li = $("<li/>").html( options.highlight(formatted,
term) ).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
- $.data(li, "ac_data", data[i]);
- }
- listItems = list.find("li");
- if ( options.selectFirst ) {
- listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
- active = 0;
- }
- // apply bgiframe if available
- if ( $.fn.bgiframe )
- list.bgiframe();
- }
-
- return {
- display: function(d, q) {
- init();
- data = d;
- term = q;
- fillList();
- },
- next: function() {
- moveSelect(1);
- },
- prev: function() {
- moveSelect(-1);
- },
- pageUp: function() {
- if (active != 0 && active - 8 < 0) {
- moveSelect( -active );
- } else {
- moveSelect(-8);
- }
- },
- pageDown: function() {
- if (active != listItems.size() - 1 && active + 8 >
listItems.size()) {
- moveSelect( listItems.size() - 1 - active );
- } else {
- moveSelect(8);
- }
- },
- hide: function() {
- element && element.hide();
- listItems && listItems.removeClass(CLASSES.ACTIVE);
- active = -1;
- },
- visible : function() {
- return element && element.is(":visible");
- },
- current: function() {
- return this.visible() && (listItems.filter("." +
CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
- },
- show: function() {
- var offset = $(input).offset();
- element.css({
- width: typeof options.width == "string" ||
options.width > 0 ? options.width : $(input).width(),
- top: offset.top + input.offsetHeight,
- left: offset.left
- }).show();
- if(options.scroll) {
- list.scrollTop(0);
- list.css({
- maxHeight: options.scrollHeight,
- overflow: 'auto'
- });
-
- if($.browser.msie && typeof document.body.style.maxHeight ===
"undefined") {
- var listHeight = 0;
- listItems.each(function() {
- listHeight += this.offsetHeight;
- });
- var scrollbarsVisible = listHeight >
options.scrollHeight;
- list.css('height', scrollbarsVisible ?
options.scrollHeight : listHeight );
- if (!scrollbarsVisible) {
- // IE doesn't recalculate width
when scrollbar disappears
- listItems.width( list.width() -
parseInt(listItems.css("padding-left")) -
parseInt(listItems.css("padding-right")) );
- }
- }
-
- }
- },
- selected: function() {
- var selected = listItems && listItems.filter("." +
CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
- return selected && selected.length &&
$.data(selected[0], "ac_data");
- },
- emptyList: function (){
- list && list.empty();
- },
- unbind: function() {
- element && element.remove();
- }
- };
-};
-
-$.fn.selection = function(start, end) {
- if (start !== undefined) {
- return this.each(function() {
- if( this.createTextRange ){
- var selRange = this.createTextRange();
- if (end === undefined || start == end) {
- selRange.move("character", start);
- selRange.select();
- } else {
- selRange.collapse(true);
- selRange.moveStart("character", start);
- selRange.moveEnd("character", end);
- selRange.select();
- }
- } else if( this.setSelectionRange ){
- this.setSelectionRange(start, end);
- } else if( this.selectionStart ){
- this.selectionStart = start;
- this.selectionEnd = end;
- }
- });
- }
- var field = this[0];
- if ( field.createTextRange ) {
- var range = document.selection.createRange(),
- orig = field.value,
- teststring = "<->",
- textLength = range.text.length;
- range.text = teststring;
- var caretAt = field.value.indexOf(teststring);
- field.value = orig;
- this.selection(caretAt, caretAt + textLength);
- return {
- start: caretAt,
- end: caretAt + textLength
- }
- } else if( field.selectionStart !== undefined ){
- return {
- start: field.selectionStart,
- end: field.selectionEnd
- }
- }
-};
-
-})(jQuery);
\ No newline at end of file
diff --git a/js/jquery.autocomplete.pack.js b/js/jquery.autocomplete.pack.js
deleted file mode 100644
index 2d09b00..0000000
--- a/js/jquery.autocomplete.pack.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * jQuery Autocomplete plugin 1.1
- *
- * Copyright (c) 2009 Jörn Zaefferer
- *
- * Dual licensed under the MIT and GPL licenses:
- * http://www.opensource.org/licenses/mit-license.php
- * http://www.gnu.org/licenses/gpl.html
- *
- * Revision: $Id: jquery.autocomplete.js 15 2009-08-22 10:30:27Z
joern.zaefferer $
- */
-eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return
r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new
RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}(';(3($){$.2e.1u({19:3(b,d){5 c=W
b=="1B";d=$.1u({},$.M.1T,{Y:c?b:P,y:c?P:b,1J:c?$.M.1T.1J:10,X:d&&!d.1D?10:48},d);d.1y=d.1y||3(a){6
a};d.1v=d.1v||d.1R;6 A.I(3(){1M $.M(A,d)})},L:3(a){6 A.11("L",a)},1k:3(a){6
A.14("1k",[a])},2b:3(){6 A.14("2b")},28:3(a){6 A.14("28",[a])},24:3(){6
A.14("24")}});$.M=3(o,r){5
t={2Y:38,2S:40,2N:46,2I:9,2E:13,2B:27,2x:3I,2v:33,2p:34,2n:8};5
u=$(o).3r("19","3o").Q(r.2Q);5 p;5 m="";5 n=$.M.3c(r);5 s=0;5 k;5 h={1F:C};5
l=$.M.32(r,o,1Z,h);5 j;$.1Y.2X&&$(o.2U).11("45.19",3(){4(j){j=C;6
C}});u.11(($.1Y.2X?"43":"42")+".19",3(a){s=1;k=a.2M;3V(a.2M){O
t.2Y:a.1d();4(l.N()){l.30()}w{12(0,D)}R;O
t.2S:a.1d();4(l.N()){l.2D()}w{12(0,D)}R;O
t.2v:a.1d();4(l.N()){l.2C()}w{12(0,D)}R;O
t.2p:a.1d();4(l.N()){l.2A()}w{12(0,D)}R;O r.17&&$.1c(r.S)==","&&t.2x:O t.2I:O
t.2E:4(1Z()){a.1d();j=D;6 C}R;O
t.2B:l.Z();R;3J:1P(p);p=1O(12,r.1J);R}}).2t(3(){s++}).3E(3(){s=0;4(!h.1F){2r()}}).2q(3(){4(s++>1&&!l.N()){12(0,D)}}).11("1k",3(){5
c=(1r.7>1)?1r[1]:P;3 1N(q,a){5 b;4(a&&a.7){16(5
i=0;i<a.7;i++){4(a[i].L.J()==q.J()){b=a[i];R}}}4(W c=="3")c(b);w
u.14("L",b&&[b.y,b.F])}$.I(15(u.K()),3(i,a){21(a,1N,1N)})}).11("2b",3(){n.1o()}).11("28",3(){$.1u(r,1r[1]);4("y"2h
1r[1])n.1e()}).11("24",3(){l.1p();u.1p();$(o.2U).1p(".19")});3 1Z(){5
e=l.2g();4(!e)6 C;5 v=e.L;m=v;4(r.17){5 b=15(u.K());4(b.7>1){5 f=r.S.7;5
c=$(o).18().1I;5 d,1H=0;$.I(b,3(i,a){1H+=a.7;4(c<=1H){d=i;6
C}1H+=f});b[d]=v;v=b.3f(r.S)}v+=r.S}u.K(v);1l();u.14("L",[e.y,e.F]);6 D}3
12(b,c){4(k==t.2N){l.Z();6}5
a=u.K();4(!c&&a==m)6;m=a;a=1m(a);4(a.7>=r.29){u.Q(r.26);4(!r.1s)a=a.J();21(a,3a,1l)}w{1q();l.Z()}};3
15(b){4(!b)6[""];4(!r.17)6[$.1c(b)];6 $.4h(b.23(r.S),3(a){6
$.1c(b).7?$.1c(a):P})}3 1m(a){4(!r.17)6 a;5 c=15(a);4(c.7==1)6 c[0];5
b=$(o).18().1I;4(b==a.7){c=15(a)}w{c=15(a.22(a.37(b),""))}6 c[c.7-1]}3
1G(q,a){4(r.1G&&(1m(u.K()).J()==q.J())&&k!=t.2n){u.K(u.K()+a.37(1m(m).7));$(o).18(m.7,m.7+a.7)}};3
2r(){1P(p);p=1O(1l,4g)};3 1l(){5
c=l.N();l.Z();1P(p);1q();4(r.36){u.1k(3(a){4(!a){4(r.17){5
b=15(u.K()).1n(0,-1);u.K(b.3f(r.S)+(b.7?r.S:""))}w{u.K("");u.14("L",P)}}})}};3
3a(q,a){4(a&&a.7&&s){1q();l.35(a,q);1G(q,a[0].F);l.20()}w{1l()}};3
21(f,d,g){4(!r.1s)f=f.J();5 e=n.31(f);4(e&&e.7){d(f,e)}w 4((W
r.Y=="1B")&&(r.Y.7>0)){5 c={4f:+1M 4e()};$.I(r.2Z,3(a,b){c[a]=W
b=="3"?b():b});$.4d({4c:"4b",4a:"19"+o.49,2V:r.2V,Y:r.Y,y:$.1u({q:1m(f),47:r.X},c),44:3(a){5
b=r.1A&&r.1A(a)||1A(a);n.1i(f,b);d(f,b)}})}w{l.2T();g(f)}};3 1A(c){5 d=[];5
b=c.23("\\n");16(5 i=0;i<b.7;i++){5
a=$.1c(b[i]);4(a){a=a.23("|");d[d.7]={y:a,F:a[0],L:r.1z&&r.1z(a,a[0])||a[0]}}}6
d};3
1q(){u.1h(r.26)}};$.M.1T={2Q:"41",2P:"3Z",26:"3Y",29:1,1J:3W,1s:C,1f:D,1w:C,1g:10,X:3U,36:C,2Z:{},1X:D,1R:3(a){6
a[0]},1v:P,1G:C,E:0,17:C,S:", ",1y:3(b,a){6 b.22(1M
3T("(?![^&;]+;)(?!<[^<>]*)("+a.22(/([\\^\\$\\(\\)\\[\\]\\{\\}\\*\\.\\+\\?\\|\\\\])/2K,"\\\\$1")+")(?![^<>]*>)(?![^&;]+;)","2K"),"<2J>$1</2J>")},1D:D,1E:3S};$.M.3c=3(g){5
h={};5 j=0;3 1f(s,a){4(!g.1s)s=s.J();5
i=s.2H(a);4(g.1w=="3R"){i=s.J().1k("\\\\b"+a.J())}4(i==-1)6 C;6 i==0||g.1w};3
1i(q,a){4(j>g.1g){1o()}4(!h[q]){j++}h[q]=a}3 1e(){4(!g.y)6 C;5
f={},2G=0;4(!g.Y)g.1g=1;f[""]=[];16(5 i=0,2F=g.y.7;i<2F;i++){5 c=g.y[i];c=(W
c=="1B")?[c]:c;5 d=g.1v(c,i+1,g.y.7);4(d===C)1V;5
e=d.3Q(0).J();4(!f[e])f[e]=[];5
b={F:d,y:c,L:g.1z&&g.1z(c)||d};f[e].1U(b);4(2G++<g.X){f[""].1U(b)}};$.I(f,3(i,a){g.1g++;1i(i,a)})}1O(1e,25);3
1o(){h={};j=0}6{1o:1o,1i:1i,1e:1e,31:3(q){4(!g.1g||!j)6 P;4(!g.Y&&g.1w){5
a=[];16(5 k 2h h){4(k.7>0){5 c=h[k];$.I(c,3(i,x){4(1f(x.F,q)){a.1U(x)}})}}6 a}w
4(h[q]){6 h[q]}w 4(g.1f){16(5 i=q.7-1;i>=g.29;i--){5 c=h[q.3O(0,i)];4(c){5
a=[];$.I(c,3(i,x){4(1f(x.F,q)){a[a.7]=x}});6 a}}}6 P}}};$.M.32=3(e,g,f,k){5
h={H:"3N"};5 j,z=-1,y,1t="",1S=D,G,B;3
2y(){4(!1S)6;G=$("<3M/>").Z().Q(e.2P).T("3L","3K").1Q(1K.2w);B=$("<3H/>").1Q(G).3G(3(a){4(U(a).2u&&U(a).2u.3F()==\'2s\'){z=$("1L",B).1h(h.H).3D(U(a));$(U(a)).Q(h.H)}}).2q(3(a){$(U(a)).Q(h.H);f();g.2t();6
C}).3C(3(){k.1F=D}).3B(3(){k.1F=C});4(e.E>0)G.T("E",e.E);1S=C}3 U(a){5
b=a.U;3A(b&&b.3z!="2s")b=b.3y;4(!b)6[];6 b}3 V(b){j.1n(z,z+1).1h(h.H);2o(b);5
a=j.1n(z,z+1).Q(h.H);4(e.1D){5
c=0;j.1n(0,z).I(3(){c+=A.1a});4((c+a[0].1a-B.1b())>B[0].3x){B.1b(c+a[0].1a-B.3w())}w
4(c<B.1b()){B.1b(c)}}};3 2o(a){z+=a;4(z<0){z=j.1j()-1}w 4(z>=j.1j()){z=0}}3
2m(a){6 e.X&&e.X<a?e.X:a}3 2l(){B.2z();5 b=2m(y.7);16(5
i=0;i<b;i++){4(!y[i])1V;5 a=e.1R(y[i].y,i+1,b,y[i].F,1t);4(a===C)1V;5
c=$("<1L/>").3v(e.1y(a,1t)).Q(i%2==0?"3u":"3P").1Q(B)[0];$.y(c,"2k",y[i])}j=B.3t("1L");4(e.1X){j.1n(0,1).Q(h.H);z=0}4($.2e.2W)B.2W()}6{35:3(d,q){2y();y=d;1t=q;2l()},2D:3(){V(1)},30:3(){V(-1)},2C:3(){4(z!=0&&z-8<0){V(-z)}w{V(-8)}},2A:3(){4(z!=j.1j()-1&&z+8>j.1j()){V(j.1j()-1-z)}w{V(8)}},Z:3(){G&&G.Z();j&&j.1h(h.H);z=-1},N:3(){6
G&&G.3s(":N")},3q:3(){6 A.N()&&(j.2j("."+h.H)[0]||e.1X&&j[0])},20:3(){5
a=$(g).3p();G.T({E:W
e.E=="1B"||e.E>0?e.E:$(g).E(),2i:a.2i+g.1a,1W:a.1W}).20();4(e.1D){B.1b(0);B.T({2L:e.1E,3n:\'3X\'});4($.1Y.3m&&W
1K.2w.3l.2L==="1x"){5 c=0;j.I(3(){c+=A.1a});5
b=c>e.1E;B.T(\'3k\',b?e.1E:c);4(!b){j.E(B.E()-2R(j.T("2O-1W"))-2R(j.T("2O-3j")))}}}},2g:3(){5
a=j&&j.2j("."+h.H).1h(h.H);6
a&&a.7&&$.y(a[0],"2k")},2T:3(){B&&B.2z()},1p:3(){G&&G.3i()}}};$.2e.18=3(b,f){4(b!==1x){6
A.I(3(){4(A.2d){5
a=A.2d();4(f===1x||b==f){a.4n("2c",b);a.3h()}w{a.4m(D);a.4l("2c",b);a.4k("2c",f);a.3h()}}w
4(A.3g){A.3g(b,f)}w 4(A.1C){A.1C=b;A.3e=f}})}5 c=A[0];4(c.2d){5
e=1K.18.4j(),3d=c.F,2a="<->",2f=e.3b.7;e.3b=2a;5
d=c.F.2H(2a);c.F=3d;A.18(d,d+2f);6{1I:d,39:d+2f}}w
4(c.1C!==1x){6{1I:c.1C,39:c.3e}}}})(4i);',62,272,'|||function|if|var|return|length|||||||||||||||||||||||||else||data|active|this|list|false|true|width|value|element|ACTIVE|each|toLowerCase|val|result|Autocompleter|visible|case|null|addClass|break|multipleSeparator|css|target|moveSelect|typeof|max|url|hide||bind|onChange||trigger|trimWords|for|multiple|selection|autocomplete|offsetHeight|scrollTop|trim|preventDefault|populate|matchSubset|cacheLength|removeClass|add|size|search|hideResultsNow|lastWord|slice|flush|unbind|stopLoading|arguments|matchCase|term|extend|formatMatch|matchContains|undefined|highlight|formatResult|parse|string|selectionStart|scroll|scrollHeight|mouseDownOnSelect|autoFill|progress|start|delay|document|li|new|findValueCallback|setTimeout|clearTimeout|appendTo|formatItem|needsInit|defaults|push|continue|left|selectFirst|browser|selectCurrent|show|request|replace|split|unautocomplete||loadingClass||setOptions|minChars|teststring|flushCache|character|createTextRange|fn|textLength|selected|in|top|filter|ac_data|fillList|limitNumberOfItems|BACKSPACE|movePosition|PAGEDOWN|click|hideResults|LI|focus|nodeName|PAGEUP|body|COMMA|init|empty|pageDown|ESC|pageUp|next|RETURN|ol|nullData|indexOf|TAB|strong|gi|maxHeight|keyCode|DEL|padding|resultsClass|inputClass|parseInt|DOWN|emptyList|form|dataType|bgiframe|opera|UP|extraParams|prev|load|Select|||display|mustMatch|substring||end|receiveData|text|Cache|orig|selectionEnd|join|setSelectionRange|select|remove|right|height|style|msie|overflow|off|offset|current|attr|is|find|ac_even|html|innerHeight|clientHeight|parentNode|tagName|while|mouseup|mousedown|index|blur|toUpperCase|mouseover|ul|188|default|absolute|position|div|ac_over|substr|ac_odd|charAt|word|180|RegExp|100|switch|400|auto|ac_loading|ac_results||ac_input|keydown|keypress|success|submit||limit|150|name|port|abort|mode|ajax|Date|timestamp|200|map|jQuery|createRange|moveEnd|moveStart|collapse|move'.split('|'),0,{}))
\ No newline at end of file
diff --git a/styles/structure.css b/styles/structure.css
index b9c4fdd..fc80bd9 100644
--- a/styles/structure.css
+++ b/styles/structure.css
@@ -175,28 +175,24 @@ footer .footmenu li {
}
/**
- * Auto-complete (.ac)
+ * Auto-complete
*/
-.ac_results {
- padding: 1px 3px 3px 3px;
- overflow: hidden;
- z-index: 99999;
- margin: 0 0 0 1px;
-}
-
-.ac_results ul {
+.ui-autocomplete {
+ width: 187px;
+ max-height: 250px;
+ overflow-y: auto;
+ overflow-x: hidden;
list-style-position: outside;
list-style: none;
- padding: 0 0 5px 0;
margin: 0;
+ padding: 0 0 5px 0;
border: 1px solid;
- border-top: none;
+ z-index: 99999;
}
-.ac_results li {
+.ui-autocomplete li {
margin: 0px;
- padding: 2px 5px;
- cursor: default;
+ cursor: pointer;
display: block;
/*
if width will be 100% horizontal scrollbar will apear
@@ -213,6 +209,11 @@ footer .footmenu li {
overflow: hidden;
}
+.ui-autocomplete a {
+ display: block;
+ padding: 2px 5px;
+}
+
aside.tips {
padding-left: 12px;
diff --git a/styles/theme.css b/styles/theme.css
index 7d5637a..3e430df 100644
--- a/styles/theme.css
+++ b/styles/theme.css
@@ -166,20 +166,10 @@ h1 a:hover {
}
/**
- * Auto-complete (.ac)
+ * Auto-complete
*/
-.ac_results {
- background: url('/images/shade.png');
- -moz-border-radius-bottomleft: 5px;
- -moz-border-radius-bottomright: 5px;
- -webkit-border-bottom-left-radius: 5px;
- -webkit-border-bottom-right-radius: 5px;
- border-bottom-left-radius: 5px;
- border-bottom-right-radius: 5px;
-}
-
-.ac_results ul {
- border-color: #604080;
+.ui-autocomplete {
+ border-color: #987db3;
background-color: white;
-moz-border-radius-bottomleft: 5px;
-moz-border-radius-bottomright: 5px;
@@ -187,9 +177,13 @@ h1 a:hover {
-webkit-border-bottom-right-radius: 5px;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
+ border-top: 1px solid #f6f6f6;
+ box-shadow: 0px 3px 3px #ccc;
+ -webkit-box-shadow: 0px 3px 3px #ccc;
+ -moz-box-shadow: 0px 3px 3px #ccc;
}
-.ac_over {
+.ui-autocomplete .ui-state-hover {
background-color: #604080;
color: white;
}--
PHP Webmaster List Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php