mirror of
https://github.com/flarum/framework.git
synced 2025-03-15 00:05:12 +08:00
change some typings, rename $.fn.animatedScrollTop to $.fn.animateScrollTop
This commit is contained in:
parent
83d0345e93
commit
0dc846bc4a
3
js/dist/admin.js
vendored
3
js/dist/admin.js
vendored
@ -11812,7 +11812,7 @@ $.fn.hover = function (hover, leave) {
|
||||
}; // add animated scroll
|
||||
|
||||
|
||||
$.fn.animatedScrollTop = function (to, duration, callback) {
|
||||
$.fn.animateScrollTop = function (to, duration, callback) {
|
||||
if (duration === void 0) {
|
||||
duration = $.fx.speeds._default;
|
||||
}
|
||||
@ -11848,7 +11848,6 @@ $.fn.extend = $.extend.bind($);
|
||||
* Enable special events on Zepto
|
||||
* @license Original Copyright 2013 Enideo. Released under dual MIT and GPL licenses.
|
||||
*/
|
||||
// @ts-ignore
|
||||
|
||||
$.event.special = $.event.special || {};
|
||||
var bindBeforeSpecialEvents = $.fn.bind;
|
||||
|
2
js/dist/admin.js.map
vendored
2
js/dist/admin.js.map
vendored
File diff suppressed because one or more lines are too long
104
js/dist/forum.js
vendored
104
js/dist/forum.js
vendored
@ -12767,13 +12767,16 @@ var Application = /*#__PURE__*/function () {
|
||||
basePath = '';
|
||||
}
|
||||
|
||||
m.mount(document.getElementById('modal'), this.modal = new _components_ModalManager__WEBPACK_IMPORTED_MODULE_19__["default"]());
|
||||
m.mount(document.getElementById('alerts'), this.alerts = new _components_AlertManager__WEBPACK_IMPORTED_MODULE_22__["default"]({
|
||||
var $modal = document.getElementById('modal');
|
||||
var $alerts = document.getElementById('alerts');
|
||||
var $content = document.getElementById('content');
|
||||
if ($modal) m.mount($modal, this.modal = new _components_ModalManager__WEBPACK_IMPORTED_MODULE_19__["default"]());
|
||||
if ($alerts) m.mount($alerts, this.alerts = new _components_AlertManager__WEBPACK_IMPORTED_MODULE_22__["default"]({
|
||||
oninit: function oninit(vnode) {
|
||||
return _this3.alerts = vnode.state;
|
||||
}
|
||||
}));
|
||||
m.route(document.getElementById('content'), basePath + '/', Object(_utils_mapRoutes__WEBPACK_IMPORTED_MODULE_6__["default"])(this.routes, basePath)); // Add a class to the body which indicates that the page has been scrolled
|
||||
if ($content) m.route($content, basePath + '/', Object(_utils_mapRoutes__WEBPACK_IMPORTED_MODULE_6__["default"])(this.routes, basePath)); // Add a class to the body which indicates that the page has been scrolled
|
||||
// down.
|
||||
|
||||
new _utils_ScrollListener__WEBPACK_IMPORTED_MODULE_10__["default"](function (top) {
|
||||
@ -13128,8 +13131,6 @@ __webpack_require__.r(__webpack_exports__);
|
||||
/**
|
||||
* The `Model` class represents a local data resource. It provides methods to
|
||||
* persist changes via the API.
|
||||
*
|
||||
* @abstract
|
||||
*/
|
||||
var Model = /*#__PURE__*/function () {
|
||||
/**
|
||||
@ -13151,18 +13152,14 @@ var Model = /*#__PURE__*/function () {
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {Object} data A resource object from the API.
|
||||
* @param {Store} store The data store that this model should be persisted to.
|
||||
* @param data A resource object from the API.
|
||||
* @param store The data store that this model should be persisted to.
|
||||
*/
|
||||
function Model(data, store) {
|
||||
if (data === void 0) {
|
||||
data = {};
|
||||
}
|
||||
|
||||
if (store === void 0) {
|
||||
store = null;
|
||||
}
|
||||
|
||||
this.data = void 0;
|
||||
this.payload = void 0;
|
||||
this.freshness = void 0;
|
||||
@ -13197,7 +13194,6 @@ var Model = /*#__PURE__*/function () {
|
||||
* Merge new data into this model locally.
|
||||
*
|
||||
* @param data A resource object to merge into this model
|
||||
* @public
|
||||
*/
|
||||
;
|
||||
|
||||
@ -13232,7 +13228,7 @@ var Model = /*#__PURE__*/function () {
|
||||
/**
|
||||
* Merge new attributes into this model locally.
|
||||
*
|
||||
* @param {Object} attributes The attributes to merge.
|
||||
* @param attributes The attributes to merge.
|
||||
*/
|
||||
;
|
||||
|
||||
@ -13247,7 +13243,6 @@ var Model = /*#__PURE__*/function () {
|
||||
* @param attributes The attributes to save. If a 'relationships' key
|
||||
* exists, it will be extracted and relationships will also be saved.
|
||||
* @param [options]
|
||||
* @return {Promise}
|
||||
*/
|
||||
;
|
||||
|
||||
@ -13358,7 +13353,7 @@ var Model = /*#__PURE__*/function () {
|
||||
/**
|
||||
* Generate a function which returns the value of the given attribute.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param name
|
||||
* @param [transform] A function to transform the attribute value
|
||||
*/
|
||||
;
|
||||
@ -13384,7 +13379,7 @@ var Model = /*#__PURE__*/function () {
|
||||
if (this.data.relationships) {
|
||||
var relationship = this.data.relationships[name];
|
||||
|
||||
if (relationship) {
|
||||
if (relationship && !Array.isArray(relationship.data)) {
|
||||
return app.store.getById(relationship.data.type, relationship.data.id);
|
||||
}
|
||||
}
|
||||
@ -13407,7 +13402,7 @@ var Model = /*#__PURE__*/function () {
|
||||
if (this.data.relationships) {
|
||||
var relationship = this.data.relationships[name];
|
||||
|
||||
if (relationship) {
|
||||
if (relationship && Array.isArray(relationship.data)) {
|
||||
return relationship.data.map(function (data) {
|
||||
return app.store.getById(data.type, data.id);
|
||||
});
|
||||
@ -13724,10 +13719,6 @@ var Translator = /*#__PURE__*/function () {
|
||||
};
|
||||
|
||||
_proto.trans = function trans(id, parameters) {
|
||||
if (parameters === void 0) {
|
||||
parameters = null;
|
||||
}
|
||||
|
||||
var translation = this.translations[id];
|
||||
|
||||
if (translation) {
|
||||
@ -13738,10 +13729,6 @@ var Translator = /*#__PURE__*/function () {
|
||||
};
|
||||
|
||||
_proto.transText = function transText(id, parameters) {
|
||||
if (parameters === void 0) {
|
||||
parameters = null;
|
||||
}
|
||||
|
||||
return Object(_utils_extractText__WEBPACK_IMPORTED_MODULE_2__["default"])(this.trans(id, parameters));
|
||||
};
|
||||
|
||||
@ -13749,7 +13736,6 @@ var Translator = /*#__PURE__*/function () {
|
||||
var translation = this.translations[id];
|
||||
|
||||
if (translation) {
|
||||
number = parseInt(number, 10);
|
||||
translation = this.pluralize(translation, number);
|
||||
return this.apply(translation, parameters || {});
|
||||
}
|
||||
@ -17256,7 +17242,7 @@ $.fn.hover = function (hover, leave) {
|
||||
}; // add animated scroll
|
||||
|
||||
|
||||
$.fn.animatedScrollTop = function (to, duration, callback) {
|
||||
$.fn.animateScrollTop = function (to, duration, callback) {
|
||||
if (duration === void 0) {
|
||||
duration = $.fx.speeds._default;
|
||||
}
|
||||
@ -17292,7 +17278,6 @@ $.fn.extend = $.extend.bind($);
|
||||
* Enable special events on Zepto
|
||||
* @license Original Copyright 2013 Enideo. Released under dual MIT and GPL licenses.
|
||||
*/
|
||||
// @ts-ignore
|
||||
|
||||
$.event.special = $.event.special || {};
|
||||
var bindBeforeSpecialEvents = $.fn.bind;
|
||||
@ -18815,8 +18800,8 @@ var DiscussionPage = /*#__PURE__*/function (_Page) {
|
||||
}
|
||||
|
||||
_this = _Page.call.apply(_Page, [this].concat(args)) || this;
|
||||
_this.discussion = void 0;
|
||||
_this.near = void 0;
|
||||
_this.discussion = null;
|
||||
_this.near = null;
|
||||
_this.stream = void 0;
|
||||
_this.scrubber = void 0;
|
||||
_this.includedPosts = [];
|
||||
@ -18999,23 +18984,19 @@ var DiscussionPage = /*#__PURE__*/function (_Page) {
|
||||
var $list = $(vnode.dom); // When the mouse enters and leaves the discussions pane, we want to show
|
||||
// and hide the pane respectively. We also create a 10px 'hot edge' on the
|
||||
// left of the screen to activate the pane.
|
||||
|
||||
var pane = app.pane;
|
||||
$list.hover(pane.show.bind(pane), pane.onmouseleave.bind(pane));
|
||||
|
||||
var hotEdge = function hotEdge(e) {
|
||||
if (e.pageX < 10) pane.show();
|
||||
};
|
||||
|
||||
$(document).on('mousemove', hotEdge);
|
||||
|
||||
vnode.dom.onunload = function () {
|
||||
return $(document).off('mousemove', hotEdge);
|
||||
}; // If the discussion we are viewing is listed in the discussion list, then
|
||||
// TODO pane
|
||||
// const pane = app.pane;
|
||||
// $list.hover(pane.show.bind(pane), pane.onmouseleave.bind(pane));
|
||||
//
|
||||
// const hotEdge = e => {
|
||||
// if (e.pageX < 10) pane.show();
|
||||
// };
|
||||
// $(document).on('mousemove', hotEdge);
|
||||
// vnode.dom.onunload = () => $(document).off('mousemove', hotEdge);
|
||||
// If the discussion we are viewing is listed in the discussion list, then
|
||||
// we will make sure it is visible in the viewport – if it is not we will
|
||||
// scroll the list down to it.
|
||||
|
||||
|
||||
var $discussion = $list.find('.DiscussionListItem.active');
|
||||
|
||||
if ($discussion.length) {
|
||||
@ -21633,7 +21614,7 @@ var PostStream = /*#__PURE__*/function (_Component) {
|
||||
$container.scrollTop(top);
|
||||
resolve();
|
||||
} else if (top !== scrollTop) {
|
||||
$container.animatedScrollTop(top, 'fast', resolve);
|
||||
$container.animateScrollTop(top, 'fast', resolve);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
@ -21876,6 +21857,10 @@ var PostStreamScrubber = /*#__PURE__*/function (_Component) {
|
||||
;
|
||||
|
||||
_proto.update = function update(scrollTop) {
|
||||
if (scrollTop === void 0) {
|
||||
scrollTop = 0;
|
||||
}
|
||||
|
||||
var stream = this.stream;
|
||||
var marginTop = stream.getMarginTop();
|
||||
var viewportTop = scrollTop + marginTop;
|
||||
@ -21924,6 +21909,7 @@ var PostStreamScrubber = /*#__PURE__*/function (_Component) {
|
||||
|
||||
var time = $this.data('time');
|
||||
if (time) period = time;
|
||||
return true;
|
||||
});
|
||||
this.index = index;
|
||||
this.visible = visible;
|
||||
@ -22544,11 +22530,11 @@ var Search = /*#__PURE__*/function (_Component) {
|
||||
_this = _Component.call.apply(_Component, [this].concat(args)) || this;
|
||||
_this.value = m.prop('');
|
||||
_this.hasFocus = false;
|
||||
_this.sources = null;
|
||||
_this.sources = void 0;
|
||||
_this.loadingSources = 0;
|
||||
_this.searched = [];
|
||||
_this.index = 0;
|
||||
_this.navigator = void 0;
|
||||
_this.navigator = new _utils_KeyboardNavigatable__WEBPACK_IMPORTED_MODULE_4__["default"]();
|
||||
_this.searchTimeout = void 0;
|
||||
return _this;
|
||||
}
|
||||
@ -22619,7 +22605,6 @@ var Search = /*#__PURE__*/function (_Component) {
|
||||
search.setIndex(search.selectableItems().index(this));
|
||||
});
|
||||
var $input = this.$('input');
|
||||
this.navigator = new _utils_KeyboardNavigatable__WEBPACK_IMPORTED_MODULE_4__["default"]();
|
||||
this.navigator.onUp(function () {
|
||||
return _this3.setIndex(_this3.getCurrentNumericIndex() - 1, true);
|
||||
}).onDown(function () {
|
||||
@ -22633,7 +22618,7 @@ var Search = /*#__PURE__*/function (_Component) {
|
||||
search.searchTimeout = setTimeout(function () {
|
||||
if (search.searched.indexOf(query) !== -1) return;
|
||||
|
||||
if (query.length >= 3) {
|
||||
if (query.length >= 3 && search.sources) {
|
||||
search.sources.map(function (source) {
|
||||
if (!source.search) return;
|
||||
search.loadingSources++;
|
||||
@ -22655,8 +22640,6 @@ var Search = /*#__PURE__*/function (_Component) {
|
||||
}
|
||||
/**
|
||||
* Get the active search in the app's current controller.
|
||||
*
|
||||
* @return {String}
|
||||
*/
|
||||
;
|
||||
|
||||
@ -22709,8 +22692,6 @@ var Search = /*#__PURE__*/function (_Component) {
|
||||
}
|
||||
/**
|
||||
* Get all of the search result items that are selectable.
|
||||
*
|
||||
* @return {jQuery}
|
||||
*/
|
||||
;
|
||||
|
||||
@ -22719,8 +22700,6 @@ var Search = /*#__PURE__*/function (_Component) {
|
||||
}
|
||||
/**
|
||||
* Get the position of the currently selected search result item.
|
||||
*
|
||||
* @return {Integer}
|
||||
*/
|
||||
;
|
||||
|
||||
@ -22729,9 +22708,6 @@ var Search = /*#__PURE__*/function (_Component) {
|
||||
}
|
||||
/**
|
||||
* Get the <li> in the search results with the given index (numeric or named).
|
||||
*
|
||||
* @param {String} index
|
||||
* @return {DOMElement}
|
||||
*/
|
||||
;
|
||||
|
||||
@ -22767,7 +22743,7 @@ var Search = /*#__PURE__*/function (_Component) {
|
||||
}
|
||||
|
||||
var $item = $items.removeClass('active').eq(fixedIndex).addClass('active');
|
||||
this.index = $item.attr('data-index') || fixedIndex;
|
||||
this.index = Number($item.attr('data-index') || fixedIndex);
|
||||
|
||||
if (scrollToItem) {
|
||||
var dropdownScroll = $dropdown.scrollTop();
|
||||
@ -22784,9 +22760,7 @@ var Search = /*#__PURE__*/function (_Component) {
|
||||
}
|
||||
|
||||
if (typeof scrollTop !== 'undefined') {
|
||||
$dropdown.animate({
|
||||
scrollTop: scrollTop
|
||||
}, 100);
|
||||
$dropdown.animateScrollTop(scrollTop, 100);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -24215,9 +24189,9 @@ var History = /*#__PURE__*/function () {
|
||||
/**
|
||||
* Push an item to the top of the stack.
|
||||
*
|
||||
* @param {String} name The name of the route.
|
||||
* @param {String} title The title of the route.
|
||||
* @param {String} [url] The URL of the route. The current URL will be used if
|
||||
* @param name The name of the route.
|
||||
* @param title The title of the route.
|
||||
* @param [url] The URL of the route. The current URL will be used if
|
||||
* not provided.
|
||||
*/
|
||||
;
|
||||
|
2
js/dist/forum.js.map
vendored
2
js/dist/forum.js.map
vendored
File diff suppressed because one or more lines are too long
@ -139,11 +139,15 @@ export default abstract class Application {
|
||||
}
|
||||
|
||||
mount(basePath = '') {
|
||||
m.mount(document.getElementById('modal'), (this.modal = new ModalManager()));
|
||||
const $modal = document.getElementById('modal');
|
||||
const $alerts = document.getElementById('alerts');
|
||||
const $content = document.getElementById('content');
|
||||
|
||||
m.mount(document.getElementById('alerts'), (this.alerts = new AlertManager({ oninit: vnode => (this.alerts = vnode.state) })));
|
||||
if ($modal) m.mount($modal, (this.modal = new ModalManager()));
|
||||
|
||||
m.route(document.getElementById('content'), basePath + '/', mapRoutes(this.routes, basePath));
|
||||
if ($alerts) m.mount($alerts, (this.alerts = new AlertManager({ oninit: vnode => (this.alerts = vnode.state) })));
|
||||
|
||||
if ($content) m.route($content, basePath + '/', mapRoutes(this.routes, basePath));
|
||||
|
||||
// Add a class to the body which indicates that the page has been scrolled
|
||||
// down.
|
||||
@ -210,7 +214,7 @@ export default abstract class Application {
|
||||
if (params.hasOwnProperty(key) && !params[key]) delete params[key];
|
||||
}
|
||||
|
||||
const queryString = m.buildQueryString(params);
|
||||
const queryString = m.buildQueryString(params as Mithril.Params);
|
||||
const prefix = m.route.prefix === '' ? this.forum.attribute('basePath') : '';
|
||||
|
||||
return prefix + url + (queryString ? '?' + queryString : '');
|
||||
@ -221,8 +225,8 @@ export default abstract class Application {
|
||||
*
|
||||
* @see https://mithril.js.org/request.html
|
||||
*/
|
||||
request(originalOptions: Mithril.RequestOptions | any): Promise<any> {
|
||||
const options: Mithril.RequestOptions = Object.assign({}, originalOptions);
|
||||
request(originalOptions: Mithril.RequestOptions<JSON> | any): Promise<any> {
|
||||
const options: Mithril.RequestOptions<JSON> | any = Object.assign({}, originalOptions);
|
||||
|
||||
// Set some default options if they haven't been overridden. We want to
|
||||
// authenticate all requests with the session token. We also want all
|
||||
@ -230,7 +234,7 @@ export default abstract class Application {
|
||||
// prevent redraws from occurring.
|
||||
options.background = options.background || true;
|
||||
|
||||
extend(options, 'config', (result, xhr: XMLHttpRequest) => xhr.setRequestHeader('X-CSRF-Token', this.session.csrfToken));
|
||||
extend(options, 'config', (result, xhr: XMLHttpRequest) => xhr.setRequestHeader('X-CSRF-Token', this.session.csrfToken!));
|
||||
|
||||
// If the method is something like PATCH or DELETE, which not all servers
|
||||
// and clients support, then we'll send it as a POST request with the
|
||||
@ -347,7 +351,7 @@ export default abstract class Application {
|
||||
}
|
||||
|
||||
private showDebug(error: RequestError) {
|
||||
this.alerts.dismiss(this.requestError.alert);
|
||||
this.alerts.dismiss(this.requestError!.alert);
|
||||
|
||||
this.modal.show(RequestErrorModal, { error });
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ export default class Component<T extends ComponentProps = any> implements ClassC
|
||||
}
|
||||
|
||||
render() {
|
||||
return m(this.constructor, this.props);
|
||||
return m(this.constructor as typeof Component, this.props);
|
||||
}
|
||||
|
||||
static component(props: ComponentProps | any = {}, children?: Mithril.Children) {
|
||||
|
@ -1,9 +1,3 @@
|
||||
/**
|
||||
* The `Model` class represents a local data resource. It provides methods to
|
||||
* persist changes via the API.
|
||||
*
|
||||
* @abstract
|
||||
*/
|
||||
import Store from './Store';
|
||||
|
||||
export interface Identifier {
|
||||
@ -16,7 +10,11 @@ export interface Data extends Identifier {
|
||||
relationships?: { [key: string]: { data: Identifier | Identifier[] } };
|
||||
}
|
||||
|
||||
export default class Model {
|
||||
/**
|
||||
* The `Model` class represents a local data resource. It provides methods to
|
||||
* persist changes via the API.
|
||||
*/
|
||||
export default abstract class Model {
|
||||
/**
|
||||
* The resource object from the API.
|
||||
*/
|
||||
@ -39,13 +37,13 @@ export default class Model {
|
||||
/**
|
||||
* The data store that this resource should be persisted to.
|
||||
*/
|
||||
protected store: Store;
|
||||
protected store?: Store;
|
||||
|
||||
/**
|
||||
* @param {Object} data A resource object from the API.
|
||||
* @param {Store} store The data store that this model should be persisted to.
|
||||
* @param data A resource object from the API.
|
||||
* @param store The data store that this model should be persisted to.
|
||||
*/
|
||||
constructor(data = {}, store = null) {
|
||||
constructor(data = <Data>{}, store?: Store) {
|
||||
this.data = data;
|
||||
this.store = store;
|
||||
|
||||
@ -73,9 +71,8 @@ export default class Model {
|
||||
* Merge new data into this model locally.
|
||||
*
|
||||
* @param data A resource object to merge into this model
|
||||
* @public
|
||||
*/
|
||||
pushData(data: {}) {
|
||||
public pushData(data: {}) {
|
||||
// Since most of the top-level items in a resource object are objects
|
||||
// (e.g. relationships, attributes), we'll need to check and perform the
|
||||
// merge at the second level if that's the case.
|
||||
@ -105,7 +102,7 @@ export default class Model {
|
||||
/**
|
||||
* Merge new attributes into this model locally.
|
||||
*
|
||||
* @param {Object} attributes The attributes to merge.
|
||||
* @param attributes The attributes to merge.
|
||||
*/
|
||||
pushAttributes(attributes: any) {
|
||||
this.pushData({ attributes });
|
||||
@ -117,7 +114,6 @@ export default class Model {
|
||||
* @param attributes The attributes to save. If a 'relationships' key
|
||||
* exists, it will be extracted and relationships will also be saved.
|
||||
* @param [options]
|
||||
* @return {Promise}
|
||||
*/
|
||||
save(attributes: any, options: any = {}): Promise<Model | Model[]> {
|
||||
const data: Data = {
|
||||
@ -208,7 +204,7 @@ export default class Model {
|
||||
)
|
||||
.then(() => {
|
||||
this.exists = false;
|
||||
this.store.remove(this);
|
||||
this.store!.remove(this);
|
||||
});
|
||||
}
|
||||
|
||||
@ -229,7 +225,7 @@ export default class Model {
|
||||
/**
|
||||
* Generate a function which returns the value of the given attribute.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param name
|
||||
* @param [transform] A function to transform the attribute value
|
||||
*/
|
||||
static attribute(name: string, transform?: Function): () => any {
|
||||
@ -253,7 +249,7 @@ export default class Model {
|
||||
if (this.data.relationships) {
|
||||
const relationship = this.data.relationships[name];
|
||||
|
||||
if (relationship) {
|
||||
if (relationship && !Array.isArray(relationship.data)) {
|
||||
return app.store.getById(relationship.data.type, relationship.data.id);
|
||||
}
|
||||
}
|
||||
@ -275,7 +271,7 @@ export default class Model {
|
||||
if (this.data.relationships) {
|
||||
const relationship = this.data.relationships[name];
|
||||
|
||||
if (relationship) {
|
||||
if (relationship && Array.isArray(relationship.data)) {
|
||||
return relationship.data.map(data => app.store.getById(data.type, data.id));
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ export default class Store {
|
||||
* @param query
|
||||
* @param options
|
||||
*/
|
||||
find<T extends Model = Model>(type: string, id?: number | number[] | any, query = {}, options = {}): Promise<T[]> {
|
||||
find<T extends Model = Model>(type: string, id?: number | number[] | any, query = {}, options = {}): Promise<T | T[]> {
|
||||
let params = query;
|
||||
let url = `${app.forum.attribute('apiUrl')}/${type}`;
|
||||
|
||||
@ -87,7 +87,7 @@ export default class Store {
|
||||
url += `/${id}`;
|
||||
}
|
||||
|
||||
return <Promise<T[]>>app
|
||||
return <Promise<T | T[]>>app
|
||||
.request(
|
||||
Object.assign(
|
||||
{
|
||||
|
@ -15,7 +15,7 @@ export default class Translator {
|
||||
Object.assign(this.translations, translations);
|
||||
}
|
||||
|
||||
trans(id: string, parameters = null) {
|
||||
trans(id: string, parameters?: any): string | any[] {
|
||||
const translation = this.translations[id];
|
||||
|
||||
if (translation) {
|
||||
@ -25,16 +25,14 @@ export default class Translator {
|
||||
return id;
|
||||
}
|
||||
|
||||
transText(id: string, parameters = null) {
|
||||
transText(id: string, parameters?: any): string {
|
||||
return extractText(this.trans(id, parameters));
|
||||
}
|
||||
|
||||
transChoice(id: string, number: string | number, parameters: any) {
|
||||
let translation = this.translations[id];
|
||||
transChoice(id: string, number: number, parameters: any): string | any[] {
|
||||
let translation: string = this.translations[id];
|
||||
|
||||
if (translation) {
|
||||
number = parseInt(number, 10);
|
||||
|
||||
translation = this.pluralize(translation, number);
|
||||
|
||||
return this.apply(translation, parameters || {});
|
||||
@ -77,7 +75,7 @@ export default class Translator {
|
||||
return hydrated.filter(part => part);
|
||||
}
|
||||
|
||||
pluralize(translation: string, number: number) {
|
||||
pluralize(translation: string, number: number): string | undefined {
|
||||
const sPluralRegex = new RegExp(/^\w+\: +(.+)$/),
|
||||
cPluralRegex = new RegExp(
|
||||
/^\s*((\{\s*(\-?\d+[\s*,\s*\-?\d+]*)\s*\})|([\[\]])\s*(-Inf|\-?\d+)\s*,\s*(\+?Inf|\-?\d+)\s*([\[\]]))\s?(.+?)$/
|
||||
@ -137,7 +135,7 @@ export default class Translator {
|
||||
return parseInt(number, 10);
|
||||
}
|
||||
|
||||
pluralPosition(number: number, locale: string) {
|
||||
pluralPosition(number: number, locale: string): number {
|
||||
if ('pt_BR' === locale) {
|
||||
locale = 'xbr';
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
* @param element The element to anchor the scroll position to.
|
||||
* @param callback The callback to run that will change page content.
|
||||
*/
|
||||
export default function anchorScroll(element: Element, callback: Function) {
|
||||
export default function anchorScroll(element: HTMLElement, callback: Function) {
|
||||
const $window = $(window);
|
||||
const $el = $(element);
|
||||
|
||||
|
@ -3,7 +3,7 @@ import Tooltip from 'tooltip.js';
|
||||
|
||||
// add $.fn.tooltip
|
||||
$.fn.tooltip = function(option) {
|
||||
return this.each(function() {
|
||||
return this.each(function(this: HTMLElement) {
|
||||
const $this = $(this);
|
||||
let data = $this.data('bs.tooltip');
|
||||
const options = (typeof option === 'object' && option) || {};
|
||||
@ -59,7 +59,7 @@ $.fn.hover = function(hover, leave) {
|
||||
};
|
||||
|
||||
// add animated scroll
|
||||
$.fn.animatedScrollTop = function(to, duration = $.fx.speeds._default, callback) {
|
||||
$.fn.animateScrollTop = function(to, duration = $.fx.speeds._default, callback) {
|
||||
if (typeof to === 'number') to -= window.scrollY || window.pageYOffset;
|
||||
|
||||
jump(to, {
|
||||
@ -94,7 +94,6 @@ $.fn.extend = $.extend.bind($);
|
||||
* Enable special events on Zepto
|
||||
* @license Original Copyright 2013 Enideo. Released under dual MIT and GPL licenses.
|
||||
*/
|
||||
// @ts-ignore
|
||||
$.event.special = $.event.special || {};
|
||||
|
||||
const bindBeforeSpecialEvents = $.fn.bind;
|
||||
|
@ -18,12 +18,12 @@ export default class DiscussionPage extends Page {
|
||||
/**
|
||||
* The discussion that is being viewed.
|
||||
*/
|
||||
discussion?: Discussion;
|
||||
discussion: Discussion | null = null;
|
||||
|
||||
/**
|
||||
* The number of the first post that is currently visible in the viewport.
|
||||
*/
|
||||
near?: number;
|
||||
near: number | null = null;
|
||||
|
||||
stream!: PostStream;
|
||||
scrubber!: PostStreamScrubber;
|
||||
@ -155,7 +155,7 @@ export default class DiscussionPage extends Page {
|
||||
// component for the first time on page load, then any calls to m.redraw
|
||||
// will be ineffective and thus any configs (scroll code) will be run
|
||||
// before stuff is drawn to the page.
|
||||
setTimeout(this.show.bind(this, preloadedDiscussion), 0);
|
||||
setTimeout(this.show.bind(this, preloadedDiscussion as Discussion), 0);
|
||||
} else {
|
||||
const params = this.requestParams();
|
||||
|
||||
@ -219,14 +219,16 @@ export default class DiscussionPage extends Page {
|
||||
// When the mouse enters and leaves the discussions pane, we want to show
|
||||
// and hide the pane respectively. We also create a 10px 'hot edge' on the
|
||||
// left of the screen to activate the pane.
|
||||
const pane = app.pane;
|
||||
$list.hover(pane.show.bind(pane), pane.onmouseleave.bind(pane));
|
||||
|
||||
const hotEdge = e => {
|
||||
if (e.pageX < 10) pane.show();
|
||||
};
|
||||
$(document).on('mousemove', hotEdge);
|
||||
vnode.dom.onunload = () => $(document).off('mousemove', hotEdge);
|
||||
// TODO pane
|
||||
// const pane = app.pane;
|
||||
// $list.hover(pane.show.bind(pane), pane.onmouseleave.bind(pane));
|
||||
//
|
||||
// const hotEdge = e => {
|
||||
// if (e.pageX < 10) pane.show();
|
||||
// };
|
||||
// $(document).on('mousemove', hotEdge);
|
||||
// vnode.dom.onunload = () => $(document).off('mousemove', hotEdge);
|
||||
|
||||
// If the discussion we are viewing is listed in the discussion list, then
|
||||
// we will make sure it is visible in the viewport – if it is not we will
|
||||
|
@ -13,7 +13,7 @@ export default class PostMeta extends Component<PostProp> {
|
||||
|
||||
// When the dropdown menu is shown, select the contents of the permalink
|
||||
// input so that the user can quickly copy the URL.
|
||||
const selectPermalink = function(this: Element) {
|
||||
const selectPermalink = function(this: HTMLElement) {
|
||||
setTimeout(() =>
|
||||
$(this)
|
||||
.parent()
|
||||
|
@ -470,7 +470,7 @@ class PostStream<T extends PostStreamProps = PostStreamProps> extends Component<
|
||||
let startNumber;
|
||||
let endNumber;
|
||||
|
||||
this.$('.PostStream-item').each((index, item: Element) => {
|
||||
this.$('.PostStream-item').each((index, item: HTMLElement) => {
|
||||
const $item = $(item);
|
||||
const top = $item.offset().top;
|
||||
const height = $item.outerHeight(true);
|
||||
@ -557,7 +557,7 @@ class PostStream<T extends PostStreamProps = PostStreamProps> extends Component<
|
||||
$container.scrollTop(top);
|
||||
resolve();
|
||||
} else if (top !== scrollTop) {
|
||||
$container.animatedScrollTop(top, 'fast', resolve);
|
||||
$container.animateScrollTop(top, 'fast', resolve);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import SubtreeRetainer from '../../common/utils/SubtreeRetainer';
|
||||
import formatNumber from '../../common/utils/formatNumber';
|
||||
import PostStream from './PostStream';
|
||||
import { EventHandler } from '../../common/utils/Evented';
|
||||
|
||||
/**
|
||||
* The `PostStreamScrubber` component displays a scrubber which can be used to
|
||||
* navigate/scrub through a post stream.
|
||||
@ -176,7 +177,7 @@ export default class PostStreamScrubber extends Component {
|
||||
* Update the index/visible/description properties according to the window's
|
||||
* current scroll position.
|
||||
*/
|
||||
update(scrollTop?: number) {
|
||||
update(scrollTop: number = 0) {
|
||||
const stream = this.stream;
|
||||
|
||||
const marginTop = stream.getMarginTop();
|
||||
@ -195,7 +196,7 @@ export default class PostStreamScrubber extends Component {
|
||||
// Now loop through each of the items in the discussion. An 'item' is
|
||||
// either a single post or a 'gap' of one or more posts that haven't
|
||||
// been loaded yet.
|
||||
$items.each(function() {
|
||||
$items.each(function(this: HTMLElement) {
|
||||
const $this = $(this);
|
||||
const top = $this.offset().top;
|
||||
const height = $this.outerHeight(true);
|
||||
@ -228,6 +229,8 @@ export default class PostStreamScrubber extends Component {
|
||||
// scrollbar's current period to a formatted version of this time.
|
||||
const time = $this.data('time');
|
||||
if (time) period = time;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
this.index = index;
|
||||
@ -269,7 +272,7 @@ export default class PostStreamScrubber extends Component {
|
||||
|
||||
this.$('.Scrubber-handle')
|
||||
.css('cursor', 'move')
|
||||
.on('mousedown touchstart', this.onmousedown.bind(this))
|
||||
.on('mousedown touchstart', this.onmousedown.bind(this) as ZeptoEventHandler)
|
||||
|
||||
// Exempt the scrollbar handle from the 'jump to' click event.
|
||||
.click(e => e.stopPropagation());
|
||||
@ -279,7 +282,7 @@ export default class PostStreamScrubber extends Component {
|
||||
// some event handlers. These handlers will move the scrollbar/stream-
|
||||
// content as appropriate.
|
||||
$(document)
|
||||
.on('mousemove touchmove', (this.handlers.onmousemove = this.onmousemove.bind(this)))
|
||||
.on('mousemove touchmove', (this.handlers.onmousemove = this.onmousemove.bind(this) as ZeptoEventHandler))
|
||||
.on('mouseup touchend', (this.handlers.onmouseup = this.onmouseup.bind(this)));
|
||||
}
|
||||
|
||||
@ -310,7 +313,7 @@ export default class PostStreamScrubber extends Component {
|
||||
$scrubber.find('.Scrubber-description').text(this.description);
|
||||
$scrubber.toggleClass('disabled', this.disabled());
|
||||
|
||||
const heights = {};
|
||||
const heights: { before?: number; handle?: number; after?: number } = {};
|
||||
heights.before = Math.max(0, percentPerPost.index * Math.min(index, count - visible));
|
||||
heights.handle = Math.min(100 - heights.before, percentPerPost.visible * visible);
|
||||
heights.after = 100 - heights.before - heights.handle;
|
||||
|
@ -32,7 +32,7 @@ export default class Search extends Component {
|
||||
/**
|
||||
* An array of SearchSources.
|
||||
*/
|
||||
sources: SearchSource[] = null;
|
||||
sources?: SearchSource[];
|
||||
|
||||
/**
|
||||
* The number of sources that are still loading results.
|
||||
@ -50,11 +50,11 @@ export default class Search extends Component {
|
||||
* around as new results load), but otherwise it will be numeric (the
|
||||
* sequential position within the list).
|
||||
*/
|
||||
index: string | number = 0;
|
||||
index: number = 0;
|
||||
|
||||
navigator: KeyboardNavigatable;
|
||||
navigator: KeyboardNavigatable = new KeyboardNavigatable();
|
||||
|
||||
searchTimeout: number;
|
||||
searchTimeout?: number;
|
||||
|
||||
view() {
|
||||
const currentSearch = this.getCurrentSearch();
|
||||
@ -124,14 +124,12 @@ export default class Search extends Component {
|
||||
.on('click', () => this.$('input').blur())
|
||||
|
||||
// Whenever the mouse is hovered over a search result, highlight it.
|
||||
.on('mouseenter', '> li:not(.Dropdown-header)', function() {
|
||||
.on('mouseenter', '> li:not(.Dropdown-header)', function(this: HTMLElement) {
|
||||
search.setIndex(search.selectableItems().index(this));
|
||||
});
|
||||
|
||||
const $input = this.$('input');
|
||||
|
||||
this.navigator = new KeyboardNavigatable();
|
||||
|
||||
this.navigator
|
||||
.onUp(() => this.setIndex(this.getCurrentNumericIndex() - 1, true))
|
||||
.onDown(() => this.setIndex(this.getCurrentNumericIndex() + 1, true))
|
||||
@ -150,7 +148,7 @@ export default class Search extends Component {
|
||||
search.searchTimeout = setTimeout(() => {
|
||||
if (search.searched.indexOf(query) !== -1) return;
|
||||
|
||||
if (query.length >= 3) {
|
||||
if (query.length >= 3 && search.sources) {
|
||||
search.sources.map(source => {
|
||||
if (!source.search) return;
|
||||
|
||||
@ -168,7 +166,7 @@ export default class Search extends Component {
|
||||
}, 250);
|
||||
})
|
||||
|
||||
.on('focus', function() {
|
||||
.on('focus', function(this: HTMLElement) {
|
||||
$(this)
|
||||
.one('mouseup', e => e.preventDefault())
|
||||
.select();
|
||||
@ -177,10 +175,8 @@ export default class Search extends Component {
|
||||
|
||||
/**
|
||||
* Get the active search in the app's current controller.
|
||||
*
|
||||
* @return {String}
|
||||
*/
|
||||
getCurrentSearch() {
|
||||
getCurrentSearch(): string | false {
|
||||
return app.current && typeof app.current.searching === 'function' && app.current.searching();
|
||||
}
|
||||
|
||||
@ -233,8 +229,6 @@ export default class Search extends Component {
|
||||
|
||||
/**
|
||||
* Get all of the search result items that are selectable.
|
||||
*
|
||||
* @return {jQuery}
|
||||
*/
|
||||
selectableItems() {
|
||||
return this.$('.Search-results > li:not(.Dropdown-header)');
|
||||
@ -242,20 +236,15 @@ export default class Search extends Component {
|
||||
|
||||
/**
|
||||
* Get the position of the currently selected search result item.
|
||||
*
|
||||
* @return {Integer}
|
||||
*/
|
||||
getCurrentNumericIndex() {
|
||||
getCurrentNumericIndex(): number {
|
||||
return this.selectableItems().index(this.getItem(this.index));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <li> in the search results with the given index (numeric or named).
|
||||
*
|
||||
* @param {String} index
|
||||
* @return {DOMElement}
|
||||
*/
|
||||
getItem(index) {
|
||||
getItem(index: number): ZeptoCollection {
|
||||
const $items = this.selectableItems();
|
||||
let $item = $items.filter(`[data-index="${index}"]`);
|
||||
|
||||
@ -290,7 +279,7 @@ export default class Search extends Component {
|
||||
.eq(fixedIndex)
|
||||
.addClass('active');
|
||||
|
||||
this.index = $item.attr('data-index') || fixedIndex;
|
||||
this.index = Number($item.attr('data-index') || fixedIndex);
|
||||
|
||||
if (scrollToItem) {
|
||||
const dropdownScroll = $dropdown.scrollTop();
|
||||
@ -307,7 +296,7 @@ export default class Search extends Component {
|
||||
}
|
||||
|
||||
if (typeof scrollTop !== 'undefined') {
|
||||
$dropdown.animate({ scrollTop }, 100);
|
||||
$dropdown.animateScrollTop(scrollTop, 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
export interface StackItem {
|
||||
name: string;
|
||||
title: string;
|
||||
url?: string;
|
||||
title?: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -38,9 +38,9 @@ export default class History {
|
||||
/**
|
||||
* Push an item to the top of the stack.
|
||||
*
|
||||
* @param {String} name The name of the route.
|
||||
* @param {String} title The title of the route.
|
||||
* @param {String} [url] The URL of the route. The current URL will be used if
|
||||
* @param name The name of the route.
|
||||
* @param title The title of the route.
|
||||
* @param [url] The URL of the route. The current URL will be used if
|
||||
* not provided.
|
||||
*/
|
||||
push(name: string, title?: string, url: string = m.route.get()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user