зеркало из https://github.com/mozilla/gecko-dev.git
More work on autocomplete. Add support for text selection
This commit is contained in:
Родитель
342581ae7f
Коммит
6c4f66646a
|
@ -5,11 +5,11 @@
|
|||
xmlns:html="http://www.w3.org/TR/REC-html40"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<binding id="autocomplete" extends="xul:box">
|
||||
<binding id="autocomplete" extends="resource:/chrome/xulBindings.xml#textfield">
|
||||
<content excludes="template,observes,menupopup">
|
||||
<xul:box
|
||||
<xul:box flex="1"
|
||||
onkeydown=" me = this.parentNode;
|
||||
me.callListener(me, event, 'stopLookup');
|
||||
me.callListener(me, 'stopLookup');
|
||||
if (me.autoCompleteTimer) {
|
||||
clearTimeout(me.autoCompleteTimer);
|
||||
me.autoCompleteTimer = 0;
|
||||
|
@ -19,10 +19,10 @@
|
|||
clearTimeout(me.autoCompleteTimer);
|
||||
if (event.which != 13) {
|
||||
me.needToAutocomplete = true;
|
||||
me.autoCompleteTimer = setTimeout(me.callListener, me.timeout, me, event, 'startLookup');
|
||||
me.autoCompleteTimer = setTimeout(me.callListener, me.timeout, me, 'startLookup');
|
||||
}"
|
||||
>
|
||||
<xul:textfield class="addressingWidget" inherits="value,timeout"/>
|
||||
<html:input flex="1" inherits="value,type,maxlength,disabled,size,readonly"/>
|
||||
<xul:popupset>
|
||||
<xul:popup>
|
||||
</xul:popup>
|
||||
|
@ -31,19 +31,19 @@
|
|||
</content>
|
||||
|
||||
<interface>
|
||||
<property name="value" onset="return this.anonymousContent[0].firstChild.value = val;"
|
||||
onget="return this.anonymousContent[0].firstChild.value;"/>
|
||||
|
||||
<property name="timeout" onset="return this.setAttribute('timeout', val);"
|
||||
onget="return this.getAttribute('timeout');"/>
|
||||
|
||||
<property name="autoCompleteSession">
|
||||
<![CDATA[
|
||||
if (this.getAttribute('searchSessionClass') != "") {
|
||||
searchSession = 'component://' + unescape(this.getAttribute('searchSessionClass'));
|
||||
if (this.getAttribute('searchSessionType') != "") {
|
||||
searchSession = unescape('component:%2F%2Fnetscape%2FautocompleteSession%26type=');
|
||||
searchSession = searchSession + this.getAttribute('searchSessionType');
|
||||
try {
|
||||
Components.classes[searchSession].getService(Components.interfaces.nsIAutoCompleteSession);
|
||||
} catch (e) {}
|
||||
// var session = Components.classes[searchSession].createInstance();
|
||||
// session.QueryInterface(Components.interfaces.nsIAutoCompleteSession);
|
||||
} catch (e) {dump("### ERROR, cannot create a search session. " + e + "\n");}
|
||||
}
|
||||
]]>
|
||||
</property>
|
||||
|
@ -54,12 +54,31 @@
|
|||
]]>
|
||||
</property>
|
||||
|
||||
<property name="lastResults">
|
||||
<![CDATA[
|
||||
var results = Components.classes["component://netscape/autocomplete/results"].createInstance();
|
||||
results.QueryInterface(Components.interfaces.nsIAutoCompleteResults);
|
||||
]]>
|
||||
</property>
|
||||
|
||||
<property name="autoCompleteListener">
|
||||
<![CDATA[
|
||||
({
|
||||
onAutoComplete: function(result, status) {
|
||||
dump("onAutoComplete, result=" + result + ", status=" + status + "\n");
|
||||
this.param.lastResult = result;
|
||||
if (status == Components.interfaces.nsIAutoCompleteStatus.failed)
|
||||
return;
|
||||
|
||||
this.param.lastResults = result;
|
||||
if (status == Components.interfaces.nsIAutoCompleteStatus.ignored ||
|
||||
status == Components.interfaces.nsIAutoCompleteStatus.noMatch)
|
||||
return;
|
||||
|
||||
if (result == null && result.items.Count() == 0)
|
||||
return;
|
||||
|
||||
if (result.defaultItemIndex > result.items.Count())
|
||||
result.defaultItemIndex = 0;
|
||||
|
||||
item = result.items.QueryElementAt(result.defaultItemIndex, Components.interfaces.nsIAutoCompleteItem);
|
||||
|
||||
//Time to build the new edit field value
|
||||
|
@ -69,7 +88,7 @@
|
|||
|
||||
match = item.value.toLowerCase();
|
||||
entry = this.param.value.toLowerCase();
|
||||
inputElement = this.param.anonymousContent[0].firstChild.anonymousContent[0].firstChild;
|
||||
inputElement = this.param.anonymousContent[0].firstChild;
|
||||
|
||||
if (entry != match)
|
||||
{
|
||||
|
@ -77,17 +96,17 @@
|
|||
{
|
||||
this.param.value = this.param.value + item.value.substring(entry.length, match.length);
|
||||
inputElement.setSelectionRange(entry.length, match.length);
|
||||
this.param.noDirectMatch = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
dump("oops, no direct match!\n");
|
||||
// this.param.value = this.param.value + " " + item.value;
|
||||
// inputElement.setSelectionRange(entry.length + 1, this.param.value.length);
|
||||
this.param.value = this.param.value + " >> " + item.value;
|
||||
inputElement.setSelectionRange(entry.length, this.param.value.length);
|
||||
this.param.noDirectMatch = true;
|
||||
}
|
||||
}
|
||||
|
||||
popupset = this.param.anonymousContent[0].childNodes[1];
|
||||
dump("popupset=" + popupset + ", popup=" + popupset.firstChild + "\n");
|
||||
|
||||
//Now, build the popup content
|
||||
popupElement = popupset.firstChild.cloneNode(false);
|
||||
|
@ -98,11 +117,11 @@
|
|||
menuitem.setAttribute('id', i);
|
||||
menuitem.setAttribute('value', item.value);
|
||||
popupElement.appendChild(menuitem);
|
||||
dump(" match=" + item.value + "\n");
|
||||
}
|
||||
popupset.replaceChild(popupElement, popupset.firstChild);
|
||||
//TODO: Select the default item
|
||||
// popupset.selectedItem = result.defaultItemIndex;
|
||||
|
||||
// popupset.selectedItem = result.defaultItemIndex;
|
||||
// popupset.firstChild.openPopup(this.param.anonymousContent[0].firstChild, -1, -1, "popup", "bottomleft", "topleft");
|
||||
},
|
||||
|
||||
|
@ -113,30 +132,26 @@
|
|||
|
||||
<method name="callListener">
|
||||
<argument name="me"/>
|
||||
<argument name="event"/>
|
||||
<argument name="action"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
dump("callListener, action=" + action + ", me=" + me + "\n");
|
||||
switch (action) {
|
||||
case 'startLookup':
|
||||
dump('>>> startLookup...\n');
|
||||
me.autoCompleteSession.onStartLookup(event, me.value, me.lastResult, me.autoCompleteListener);
|
||||
if (!me.lastResults || me.value != me.lastResults.searchString)
|
||||
me.autoCompleteSession.onStartLookup(me.value, me.lastResults, me.autoCompleteListener);
|
||||
break;
|
||||
|
||||
case 'stopLookup':
|
||||
dump('>>> stopLookup...\n');
|
||||
//TODO: hide the popup menu now. How do we to that?
|
||||
me.autoCompleteSession.onStopLookup(event);
|
||||
me.autoCompleteSession.onStopLookup();
|
||||
break;
|
||||
|
||||
case 'autoComplete':
|
||||
dump('>>> autoComplete...\n');
|
||||
if (me.autoCompleteTimer) {
|
||||
clearTimeout(me.autoCompleteTimer);
|
||||
me.autoCompleteTimer = 0;
|
||||
}
|
||||
me.autoCompleteSession.onAutoComplete(event, me.value, me.lastResult, me.autoCompleteListener);
|
||||
me.autoCompleteSession.onAutoComplete(me.value, me.lastResults, me.autoCompleteListener);
|
||||
me.needToAutocomplete = false;
|
||||
break;
|
||||
}
|
||||
|
@ -145,22 +160,25 @@
|
|||
</method>
|
||||
|
||||
<method name="finishAutoComplete">
|
||||
<argument name="event"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
inputElement = this.anonymousContent[0].firstChild.anonymousContent[0].firstChild;
|
||||
inputElement = this.anonymousContent[0].firstChild;
|
||||
entry = this.value.substring(0, inputElement.selectionStart) + this.value.substring(inputElement.selectionEnd, this.value.length);
|
||||
|
||||
if (this.lastResult)
|
||||
if (this.lastResults)
|
||||
{
|
||||
if (this.lastResult.searchString == entry)
|
||||
if (this.lastResults.searchString == entry)
|
||||
{
|
||||
dump('dont need to autocomplete again, just use previous result\n');
|
||||
this.value = this.lastResult.items.QueryElementAt(this.lastResult.defaultItemIndex, Components.interfaces.nsIAutoCompleteItem).value;
|
||||
try {
|
||||
this.value = this.lastResults.items.QueryElementAt(this.lastResults.defaultItemIndex, Components.interfaces.nsIAutoCompleteItem).value;
|
||||
} catch(e) {};
|
||||
inputElement.setSelectionRange(inputElement.value.length, inputElement.value.length);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.callListener(this, event, 'autoComplete');
|
||||
this.callListener(this, 'autoComplete');
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
@ -168,16 +186,15 @@
|
|||
</interface>
|
||||
|
||||
<handlers>
|
||||
<handler type="keypress" keycode="vk_return" value="this.finishAutoComplete();"/>
|
||||
<handler type="keydown" keycode="vk_return" value="this.finishAutoComplete(event);"/>
|
||||
|
||||
<handler type="focus" value="this.needToAutocomplete = false;"/>
|
||||
|
||||
<handler type="blur" value="
|
||||
if (this.needToAutocomplete)
|
||||
this.finishAutoComplete();
|
||||
this.finishAutoComplete(event);
|
||||
"/>
|
||||
</handlers>
|
||||
|
||||
</binding>
|
||||
|
||||
</bindings>
|
||||
</bindings>
|
||||
|
|
|
@ -16,19 +16,35 @@
|
|||
<html:script language="JavaScript">
|
||||
|
||||
var AutoCompleteSession = {
|
||||
onStartLookup: function(event, value, prevResult, listener)
|
||||
onStartLookup: function(value, prevResult, listener)
|
||||
{
|
||||
dump("Search Session: onStartLookup\n");
|
||||
|
||||
var results = Components.classes["component://netscape/autocomplete/results"].createInstance();
|
||||
results = results.QueryInterface(Components.interfaces.nsIAutoCompleteResults);
|
||||
results.searchString = value;
|
||||
results.defaultItemIndex = 0;
|
||||
results.param = null;
|
||||
|
||||
var item = Components.classes["component://netscape/autocomplete/item"].createInstance();
|
||||
item = item.QueryInterface(Components.interfaces.nsIAutoCompleteItem);
|
||||
item.value = "Jean-Francois Ducarroz";
|
||||
item.comment = "[put your comment here]";
|
||||
item.className = "";
|
||||
item.param = null;
|
||||
|
||||
results.items.AppendElement(item);
|
||||
listener.onAutoComplete(results, Components.interfaces.nsIAutoCompleteStatus.matchFound);
|
||||
},
|
||||
|
||||
onStopLookup: function(event)
|
||||
onStopLookup: function()
|
||||
{
|
||||
dump("Search Session: onStopLookup\n");
|
||||
},
|
||||
|
||||
onAutoComplete: function(event, value, prevResult, listener)
|
||||
onAutoComplete: function(value, prevResult, listener)
|
||||
{
|
||||
dump("Search Session: onAutoComplete, value =" + value +"\n");
|
||||
dump("Search Session: onAutoComplete, value =" + value + "\n");
|
||||
|
||||
var results = Components.classes["component://netscape/autocomplete/results"].createInstance();
|
||||
results = results.QueryInterface(Components.interfaces.nsIAutoCompleteResults);
|
||||
|
@ -58,9 +74,45 @@ var AutoCompleteSession = {
|
|||
}
|
||||
};
|
||||
|
||||
function function1()
|
||||
{
|
||||
var myAutoComplete = document.getElementById("test");
|
||||
value = myAutoComplete.value;
|
||||
match = "Jean-Francois Ducarroz";
|
||||
|
||||
lmatch = match.toLowerCase();
|
||||
lvalue = value.toLowerCase();
|
||||
|
||||
dump("value = " + lvalue + ", match = " + lmatch + "\n");
|
||||
|
||||
if (lvalue == lmatch)
|
||||
dump("exact match\n");
|
||||
else
|
||||
{
|
||||
dump("substring = " + lmatch.substring(0, lvalue.length) + "\n");
|
||||
if (lmatch.substring(0, lvalue.length) == lvalue)
|
||||
{
|
||||
dump("Ok, we can merge\n");
|
||||
myAutoComplete.value = value + match.substring(value.length, match.length);
|
||||
// myAutoComplete.anonymousContent[0].firstChild.anonymousContent[0].firstChild.setSelectionRange(value.length, match.length);
|
||||
}
|
||||
else
|
||||
{
|
||||
dump("oops, no match!\n");
|
||||
myAutoComplete.value = value + " " + match;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function Initialize()
|
||||
{
|
||||
dump("Initialize\n");
|
||||
dump("Initialize!!\n");
|
||||
var secondAutoComplete = document.getElementById("test2");
|
||||
abSession = secondAutoComplete.autoCompleteSession.QueryInterface(Components.interfaces.nsIAbAutoCompleteSession)
|
||||
dump("abSession = " + secondAutoComplete + ", abSession = " + secondAutoComplete.autoCompleteSession + "\n");
|
||||
abSession.defaultDomain = "mozilla.org";
|
||||
|
||||
var myAutoComplete = document.getElementById("test");
|
||||
dump("myAutoComplete = " + myAutoComplete + ", session = " + myAutoComplete.autoCompleteSession + "\n");
|
||||
myAutoComplete.autoCompleteSession = AutoCompleteSession;
|
||||
|
@ -68,11 +120,19 @@ function Initialize()
|
|||
|
||||
</html:script>
|
||||
|
||||
<!--autocomplete id="test" timeout="300" /-->
|
||||
|
||||
<autocomplete id="test" timeout="300" />
|
||||
<autocomplete id="test2"
|
||||
searchSessionType="addrbook"
|
||||
timeout="300"
|
||||
onkeypress="if (event.which == 13) dump('Done, value=' + this.value + '\n');"
|
||||
/>
|
||||
|
||||
<<<<<<< autocomplete_test.xul
|
||||
</window>=======
|
||||
<!--autocomplete
|
||||
searchSessionClass="netscape%2Fmessenger%2Fautocomplete%26type%3Daddrbook"
|
||||
timeout="300"
|
||||
/-->
|
||||
</window>
|
||||
>>>>>>> 1.2
|
||||
|
|
Загрузка…
Ссылка в новой задаче