initial support for auto complete in model and parts
also move part creation out of model, into partcreator, which can then also contain dependencies for creating the auto completer.
This commit is contained in:
parent
7507d0d7e1
commit
1330b438d6
2 changed files with 131 additions and 22 deletions
|
@ -14,6 +14,8 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import AutocompleteWrapperModel from "./autocomplete";
|
||||
|
||||
class BasePart {
|
||||
constructor(text = "") {
|
||||
this._text = text;
|
||||
|
@ -39,12 +41,10 @@ class BasePart {
|
|||
|
||||
// removes len chars, or returns the plain text this part should be replaced with
|
||||
// if the part would become invalid if it removed everything.
|
||||
|
||||
// TODO: this should probably return the Part and caret position within this should be replaced with
|
||||
remove(offset, len) {
|
||||
// validate
|
||||
const strWithRemoval = this.text.substr(0, offset) + this.text.substr(offset + len);
|
||||
for(let i = offset; i < (len + offset); ++i) {
|
||||
for (let i = offset; i < (len + offset); ++i) {
|
||||
const chr = this.text.charAt(i);
|
||||
if (!this.acceptsRemoval(i, chr)) {
|
||||
return strWithRemoval;
|
||||
|
@ -55,7 +55,7 @@ class BasePart {
|
|||
|
||||
// append str, returns the remaining string if a character was rejected.
|
||||
appendUntilRejected(str) {
|
||||
for(let i = 0; i < str.length; ++i) {
|
||||
for (let i = 0; i < str.length; ++i) {
|
||||
const chr = str.charAt(i);
|
||||
if (!this.acceptsInsertion(chr)) {
|
||||
this._text = this._text + str.substr(0, i);
|
||||
|
@ -68,7 +68,7 @@ class BasePart {
|
|||
// inserts str at offset if all the characters in str were accepted, otherwise don't do anything
|
||||
// return whether the str was accepted or not.
|
||||
insertAll(offset, str) {
|
||||
for(let i = 0; i < str.length; ++i) {
|
||||
for (let i = 0; i < str.length; ++i) {
|
||||
const chr = str.charAt(i);
|
||||
if (!this.acceptsInsertion(chr)) {
|
||||
return false;
|
||||
|
@ -80,6 +80,7 @@ class BasePart {
|
|||
return true;
|
||||
}
|
||||
|
||||
createAutoComplete() {}
|
||||
|
||||
trim(len) {
|
||||
const remaining = this._text.substr(len);
|
||||
|
@ -94,7 +95,7 @@ class BasePart {
|
|||
|
||||
export class PlainPart extends BasePart {
|
||||
acceptsInsertion(chr) {
|
||||
return chr !== "@" && chr !== "#";
|
||||
return chr !== "@" && chr !== "#" && chr !== ":";
|
||||
}
|
||||
|
||||
toDOMNode() {
|
||||
|
@ -126,6 +127,11 @@ export class PlainPart extends BasePart {
|
|||
}
|
||||
|
||||
class PillPart extends BasePart {
|
||||
constructor(resourceId, label) {
|
||||
super(label);
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
acceptsInsertion(chr) {
|
||||
return chr !== " ";
|
||||
}
|
||||
|
@ -162,6 +168,10 @@ class PillPart extends BasePart {
|
|||
}
|
||||
|
||||
export class RoomPillPart extends PillPart {
|
||||
constructor(displayAlias) {
|
||||
super(displayAlias, displayAlias);
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "room-pill";
|
||||
}
|
||||
|
@ -172,3 +182,51 @@ export class UserPillPart extends PillPart {
|
|||
return "user-pill";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class PillCandidatePart extends PlainPart {
|
||||
constructor(text, autoCompleteCreator) {
|
||||
super(text);
|
||||
this._autoCompleteCreator = autoCompleteCreator;
|
||||
}
|
||||
|
||||
createAutoComplete(updateCallback) {
|
||||
return this._autoCompleteCreator(updateCallback);
|
||||
}
|
||||
|
||||
acceptsInsertion(chr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
acceptsRemoval(position, chr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "pill-candidate";
|
||||
}
|
||||
}
|
||||
|
||||
export class PartCreator {
|
||||
constructor(getAutocompleterComponent, updateQuery) {
|
||||
this._autoCompleteCreator = (updateCallback) => {
|
||||
return new AutocompleteWrapperModel(updateCallback, getAutocompleterComponent, updateQuery);
|
||||
};
|
||||
}
|
||||
|
||||
createPartForInput(input) {
|
||||
switch (input[0]) {
|
||||
case "#":
|
||||
case "@":
|
||||
case ":":
|
||||
return new PillCandidatePart("", this._autoCompleteCreator);
|
||||
default:
|
||||
return new PlainPart();
|
||||
}
|
||||
}
|
||||
|
||||
createDefaultPart(text) {
|
||||
return new PlainPart(text);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue