Extract autocomplete initialization to a function

Create a REGEXP_TAGS_REPLACE regex to remove a chained .replace call

Fix autocomplete positioning
This commit is contained in:
cpradio
2017-02-27 07:32:09 -05:00
parent 38d7234018
commit 59922a7899
5 changed files with 50 additions and 88 deletions

View File

@ -12,7 +12,7 @@ const REGEXP_IN_PREFIX = /^in:/ig;
const REGEXP_STATUS_PREFIX = /^status:/ig; const REGEXP_STATUS_PREFIX = /^status:/ig;
const REGEXP_MIN_POST_COUNT_PREFIX = /^min_post_count:/ig; const REGEXP_MIN_POST_COUNT_PREFIX = /^min_post_count:/ig;
const REGEXP_POST_TIME_PREFIX = /^(before|after):/ig; const REGEXP_POST_TIME_PREFIX = /^(before|after):/ig;
const REGEXP_TAGS_SUFFIX = /::tag\s?$/ig; const REGEXP_TAGS_REPLACE = /(^(tags?:|#(?=[a-z0-9\-]+::tag))|::tag\s?$)/ig;
const REGEXP_IN_MATCH = /^in:(posted|watching|tracking|bookmarks|first|pinned|unpinned)/ig; const REGEXP_IN_MATCH = /^in:(posted|watching|tracking|bookmarks|first|pinned|unpinned)/ig;
@ -230,7 +230,7 @@ export default Em.Component.extend({
if (match.length !== 0) { if (match.length !== 0) {
const existingInput = _.isArray(tags) ? tags.join(',') : tags; const existingInput = _.isArray(tags) ? tags.join(',') : tags;
const userInput = match[0].replace(REGEXP_TAGS_PREFIX, '').replace(REGEXP_TAGS_SUFFIX, ''); const userInput = match[0].replace(REGEXP_TAGS_REPLACE, '');
if (existingInput !== userInput) { if (existingInput !== userInput) {
this.set('searchedTerms.tags', (userInput.length !== 0) ? userInput.split(',') : []); this.set('searchedTerms.tags', (userInput.length !== 0) ? userInput.split(',') : []);

View File

@ -1,12 +1,7 @@
import computed from 'ember-addons/ember-computed-decorators'; import computed from 'ember-addons/ember-computed-decorators';
import { on } from 'ember-addons/ember-computed-decorators'; import { on } from 'ember-addons/ember-computed-decorators';
import TextField from 'discourse/components/text-field'; import TextField from 'discourse/components/text-field';
import { findRawTemplate } from 'discourse/lib/raw-templates'; import { applySearchAutocomplete } from "discourse/lib/search";
import { TAG_HASHTAG_POSTFIX } from 'discourse/lib/tag-hashtags';
import { SEPARATOR } from 'discourse/lib/category-hashtags';
import Category from 'discourse/models/category';
import { search as searchCategoryTag } from 'discourse/lib/category-tag-search';
import userSearch from 'discourse/lib/user-search';
export default TextField.extend({ export default TextField.extend({
@computed('searchService.searchContextEnabled') @computed('searchService.searchContextEnabled')
@ -16,51 +11,13 @@ export default TextField.extend({
@on("didInsertElement") @on("didInsertElement")
becomeFocused() { becomeFocused() {
const $searchInput = this.$();
applySearchAutocomplete($searchInput, this.siteSettings);
if (!this.get('hasAutofocus')) { return; } if (!this.get('hasAutofocus')) { return; }
// iOS is crazy, without this we will not be // iOS is crazy, without this we will not be
// at the top of the page // at the top of the page
$(window).scrollTop(0); $(window).scrollTop(0);
this.$().focus(); $searchInput.focus();
},
@on("didInsertElement")
applyAutoComplete() {
this._super();
const $searchInput = this.$();
this._applyCategoryHashtagAutocomplete($searchInput);
this._applyUsernameAutocomplete($searchInput);
},
_applyCategoryHashtagAutocomplete($searchInput) {
const siteSettings = this.siteSettings;
$searchInput.autocomplete({
template: findRawTemplate('category-tag-autocomplete'),
key: '#',
width: '100%',
treatAsTextarea: true,
transformComplete(obj) {
if (obj.model) {
return Category.slugFor(obj.model, SEPARATOR);
} else {
return `${obj.text}${TAG_HASHTAG_POSTFIX}`;
}
},
dataSource(term) {
return searchCategoryTag(term, siteSettings);
}
});
},
_applyUsernameAutocomplete($searchInput) {
$searchInput.autocomplete({
template: findRawTemplate('user-selector-autocomplete'),
dataSource: term => userSearch({ term, undefined, includeGroups: true }),
key: "@",
width: '100%',
treatAsTextarea: true,
transformComplete: v => v.username || v.name
});
} }
}); });

View File

@ -247,6 +247,13 @@ export default function(options) {
}; };
vOffset = -32; vOffset = -32;
hOffset = 0; hOffset = 0;
} if (options.treatAsTextarea) {
pos = me.caretPosition({
pos: completeStart,
key: options.key
});
hOffset = 27;
vOffset = -32;
} else { } else {
pos = me.caretPosition({ pos = me.caretPosition({
pos: completeStart, pos: completeStart,

View File

@ -1,9 +1,14 @@
import { ajax } from 'discourse/lib/ajax'; import { ajax } from 'discourse/lib/ajax';
import { findRawTemplate } from 'discourse/lib/raw-templates';
import { TAG_HASHTAG_POSTFIX } from 'discourse/lib/tag-hashtags';
import { SEPARATOR } from 'discourse/lib/category-hashtags';
import Category from 'discourse/models/category';
import { search as searchCategoryTag } from 'discourse/lib/category-tag-search';
import userSearch from 'discourse/lib/user-search';
export function translateResults(results, opts) { export function translateResults(results, opts) {
const User = require('discourse/models/user').default; const User = require('discourse/models/user').default;
const Category = require('discourse/models/category').default;
const Post = require('discourse/models/post').default; const Post = require('discourse/models/post').default;
const Topic = require('discourse/models/topic').default; const Topic = require('discourse/models/topic').default;
@ -124,3 +129,31 @@ export function isValidSearchTerm(searchTerm) {
return false; return false;
} }
}; };
export function applySearchAutocomplete($input, siteSettings) {
$input.autocomplete({
template: findRawTemplate('category-tag-autocomplete'),
key: '#',
width: '100%',
treatAsTextarea: true,
transformComplete(obj) {
if (obj.model) {
return Category.slugFor(obj.model, SEPARATOR);
} else {
return `${obj.text}${TAG_HASHTAG_POSTFIX}`;
}
},
dataSource(term) {
return searchCategoryTag(term, siteSettings);
}
});
$input.autocomplete({
template: findRawTemplate('user-selector-autocomplete'),
dataSource: term => userSearch({ term, undefined, includeGroups: true }),
key: "@",
width: '100%',
treatAsTextarea: true,
transformComplete: v => v.username || v.name
});
};

View File

@ -3,12 +3,7 @@ import { iconNode } from 'discourse/helpers/fa-icon-node';
import { avatarImg } from 'discourse/widgets/post'; import { avatarImg } from 'discourse/widgets/post';
import DiscourseURL from 'discourse/lib/url'; import DiscourseURL from 'discourse/lib/url';
import { wantsNewWindow } from 'discourse/lib/intercept-click'; import { wantsNewWindow } from 'discourse/lib/intercept-click';
import { findRawTemplate } from 'discourse/lib/raw-templates'; import { applySearchAutocomplete } from "discourse/lib/search";
import { TAG_HASHTAG_POSTFIX } from 'discourse/lib/tag-hashtags';
import { SEPARATOR } from 'discourse/lib/category-hashtags';
import Category from 'discourse/models/category';
import { search as searchCategoryTag } from 'discourse/lib/category-tag-search';
import userSearch from 'discourse/lib/user-search';
import { h } from 'virtual-dom'; import { h } from 'virtual-dom';
@ -265,7 +260,7 @@ export default createWidget('header', {
Ember.run.schedule('afterRender', () => { Ember.run.schedule('afterRender', () => {
const $searchInput = $('#search-term'); const $searchInput = $('#search-term');
$searchInput.focus().select(); $searchInput.focus().select();
this.applyAutocomplete($searchInput); applySearchAutocomplete($searchInput, this.siteSettings);
}); });
} }
}, },
@ -350,36 +345,6 @@ export default createWidget('header', {
return Ember.get(ctx, 'type'); return Ember.get(ctx, 'type');
} }
} }
},
applyAutocomplete($searchInput) {
const siteSettings = this.siteSettings;
$searchInput.autocomplete({
template: findRawTemplate('category-tag-autocomplete'),
key: '#',
width: '100%',
treatAsTextarea: true,
transformComplete(obj) {
if (obj.model) {
return Category.slugFor(obj.model, SEPARATOR);
} else {
return `${obj.text}${TAG_HASHTAG_POSTFIX}`;
}
},
dataSource(term) {
return searchCategoryTag(term, siteSettings);
}
});
$searchInput.autocomplete({
template: findRawTemplate('user-selector-autocomplete'),
dataSource: term => userSearch({ term, undefined, includeGroups: true }),
key: "@",
width: '100%',
treatAsTextarea: true,
transformComplete: v => v.username || v.name
});
} }
}); });