mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Speed up and upgrade build.
Summary:
- Upgrades to build-related packages:
- Upgrade typescript, related libraries and typings.
- Upgrade webpack, eslint; add tsc-watch, node-dev, eslint_d.
- Build organization changes:
- Build webpack from original typescript, transpiling only; with errors still
reported by a background tsc watching process.
- Typescript-related changes:
- Reduce imports of AWS dependencies (very noticeable speedup)
- Avoid auto-loading global @types
- Client code is now built with isolatedModules flag (for safe transpilation)
- Use allowJs to avoid copying JS files manually.
- Linting changes
- Enhance Arcanist ESLintLinter to run before/after commands, and set up to use eslint_d
- Update eslint config, and include .eslintignore to avoid linting generated files.
- Include a bunch of eslint-prompted and eslint-generated fixes
- Add no-unused-expression rule to eslint, and fix a few warnings about it
- Other items:
- Refactor cssInput to avoid circular dependency
- Remove a bit of unused code, libraries, dependencies
Test Plan: No behavior changes, all existing tests pass. There are 30 tests fewer reported because `test_gpath.py` was removed (it's been unused for years)
Reviewers: paulfitz
Reviewed By: paulfitz
Subscribers: paulfitz
Differential Revision: https://phab.getgrist.com/D3498
This commit is contained in:
@@ -29,7 +29,7 @@ export class ChoiceTextBox extends NTextBox {
|
||||
private _choiceValues: Computed<string[]>;
|
||||
private _choiceValuesSet: Computed<Set<string>>;
|
||||
private _choiceOptions: KoSaveableObservable<ChoiceOptions | null | undefined>;
|
||||
private _choiceOptionsByName: Computed<ChoiceOptionsByName>
|
||||
private _choiceOptionsByName: Computed<ChoiceOptionsByName>;
|
||||
|
||||
constructor(field: ViewFieldRec) {
|
||||
super(field);
|
||||
|
||||
@@ -17,6 +17,9 @@ export interface IMargins {
|
||||
right: number;
|
||||
}
|
||||
|
||||
export type IRect = ISize & IMargins;
|
||||
|
||||
|
||||
// edgeMargin is how many pixels to leave before the edge of the browser window by default.
|
||||
// This is added to margins that may be passed into the constructor.
|
||||
const edgeMargin = 12;
|
||||
@@ -37,8 +40,8 @@ export class EditorPlacement extends Disposable {
|
||||
public readonly onReposition = this.autoDispose(new Emitter());
|
||||
|
||||
private _editorRoot: HTMLElement;
|
||||
private _maxRect: ClientRect|DOMRect;
|
||||
private _cellRect: ClientRect|DOMRect;
|
||||
private _maxRect: IRect;
|
||||
private _cellRect: IRect;
|
||||
private _margins: IMargins;
|
||||
|
||||
// - editorDom is the DOM to attach. It gets destroyed when EditorPlacement is disposed.
|
||||
@@ -141,7 +144,7 @@ export class EditorPlacement extends Disposable {
|
||||
|
||||
// Get the bounding rect of elem excluding borders. This allows the editor to match cellElem more
|
||||
// closely which is more visible in case of DetailView.
|
||||
function rectWithoutBorders(elem: Element): ClientRect {
|
||||
function rectWithoutBorders(elem: Element): IRect {
|
||||
const rect = elem.getBoundingClientRect();
|
||||
const style = getComputedStyle(elem, null);
|
||||
const bTop = parseFloat(style.getPropertyValue('border-top-width'));
|
||||
|
||||
@@ -55,6 +55,7 @@ function getTypeDefinition(type: string | false) {
|
||||
}
|
||||
|
||||
type ComputedStyle = {style?: Style; error?: true} | null | undefined;
|
||||
|
||||
/**
|
||||
* Builds a font option computed property.
|
||||
*/
|
||||
@@ -62,12 +63,13 @@ function buildFontOptions(
|
||||
builder: FieldBuilder,
|
||||
computedRule: ko.Computed<ComputedStyle>,
|
||||
optionName: keyof Style) {
|
||||
return koUtil.withKoUtils(ko.computed(function() {
|
||||
|
||||
return koUtil.withKoUtils(ko.computed(() => {
|
||||
if (builder.isDisposed()) { return false; }
|
||||
const style = computedRule()?.style;
|
||||
const styleFlag = style?.[optionName] || this.field[optionName]();
|
||||
const styleFlag = style?.[optionName] || builder.field[optionName]();
|
||||
return styleFlag;
|
||||
}, builder)).onlyNotifyUnequal();
|
||||
})).onlyNotifyUnequal();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,9 +133,9 @@ export class FieldBuilder extends Disposable {
|
||||
});
|
||||
|
||||
// Observable which evaluates to a *function* that decides if a value is valid.
|
||||
this._isRightType = ko.pureComputed(function() {
|
||||
this._isRightType = ko.pureComputed<(value: CellValue, options?: any) => boolean>(() => {
|
||||
return gristTypes.isRightType(this._readOnlyPureType()) || _.constant(false);
|
||||
}, this);
|
||||
});
|
||||
|
||||
// Returns a boolean indicating whether the column is type Reference or ReferenceList.
|
||||
this._isRef = this.autoDispose(ko.computed(() => {
|
||||
@@ -154,7 +156,7 @@ export class FieldBuilder extends Disposable {
|
||||
}
|
||||
}));
|
||||
|
||||
this.widget = ko.pureComputed({
|
||||
this.widget = ko.pureComputed<object>({
|
||||
owner: this,
|
||||
read() { return this.options().widget; },
|
||||
write(widget) {
|
||||
@@ -196,10 +198,10 @@ export class FieldBuilder extends Disposable {
|
||||
this._rowMap = new Map();
|
||||
|
||||
// Returns the constructor for the widget, and only notifies subscribers on changes.
|
||||
this._widgetCons = this.autoDispose(koUtil.withKoUtils(ko.computed(function() {
|
||||
this._widgetCons = this.autoDispose(koUtil.withKoUtils(ko.computed(() => {
|
||||
return UserTypeImpl.getWidgetConstructor(this.options().widget,
|
||||
this._readOnlyPureType());
|
||||
}, this)).onlyNotifyUnequal());
|
||||
})).onlyNotifyUnequal());
|
||||
|
||||
// Computed builder for the widget.
|
||||
this.widgetImpl = this.autoDispose(koUtil.computedBuilder(() => {
|
||||
@@ -467,28 +469,28 @@ export class FieldBuilder extends Disposable {
|
||||
return { style : new CombinedStyle(styles, flags) };
|
||||
}, this).extend({ deferred: true })).previousOnUndefined();
|
||||
|
||||
const widgetObs = koUtil.withKoUtils(ko.computed(function() {
|
||||
const widgetObs = koUtil.withKoUtils(ko.computed(() => {
|
||||
// TODO: Accessing row values like this doesn't always work (row and field might not be updated
|
||||
// simultaneously).
|
||||
if (this.isDisposed()) { return null; } // Work around JS errors during field removal.
|
||||
const value = row.cells[this.field.colId()];
|
||||
const cell = value && value();
|
||||
if (value && this._isRightType()(cell, this.options) || row._isAddRow.peek()) {
|
||||
if ((value) && this._isRightType()(cell, this.options) || row._isAddRow.peek()) {
|
||||
return this.widgetImpl();
|
||||
} else if (gristTypes.isVersions(cell)) {
|
||||
return this.diffImpl;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}, this).extend({ deferred: true })).onlyNotifyUnequal();
|
||||
}).extend({ deferred: true })).onlyNotifyUnequal();
|
||||
|
||||
const textColor = koUtil.withKoUtils(ko.computed(function() {
|
||||
const textColor = koUtil.withKoUtils(ko.computed(() => {
|
||||
if (this.isDisposed()) { return null; }
|
||||
const fromRules = computedRule()?.style?.textColor;
|
||||
return fromRules || this.field.textColor() || '';
|
||||
}, this)).onlyNotifyUnequal();
|
||||
})).onlyNotifyUnequal();
|
||||
|
||||
const fillColor = koUtil.withKoUtils(ko.computed(function() {
|
||||
const fillColor = koUtil.withKoUtils(ko.computed(() => {
|
||||
if (this.isDisposed()) { return null; }
|
||||
const fromRules = computedRule()?.style?.fillColor;
|
||||
let fill = fromRules || this.field.fillColor();
|
||||
@@ -496,7 +498,7 @@ export class FieldBuilder extends Disposable {
|
||||
// If there is no color we are using fully transparent white color (for tests mainly).
|
||||
fill = fill ? fill.toUpperCase() : fill;
|
||||
return (fill === '#FFFFFF' ? '' : fill) || '#FFFFFF00';
|
||||
}, this)).onlyNotifyUnequal();
|
||||
})).onlyNotifyUnequal();
|
||||
|
||||
const fontBold = buildFontOptions(this, computedRule, 'fontBold');
|
||||
const fontItalic = buildFontOptions(this, computedRule, 'fontItalic');
|
||||
|
||||
@@ -135,6 +135,7 @@ export class NTextEditor extends NewBaseEditor {
|
||||
// but we got same enough spaces, we will force browser to check the available space once more time.
|
||||
if (enoughSpace(rect, size) && hasScroll(textInput)) {
|
||||
textInput.style.overflow = "hidden";
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
textInput.clientHeight; // just access metrics is enough to repaint
|
||||
textInput.style.overflow = "auto";
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
dom,
|
||||
DomContents,
|
||||
fromKo,
|
||||
IDisposableOwnerT,
|
||||
Observable,
|
||||
} from 'grainjs';
|
||||
|
||||
@@ -30,8 +31,13 @@ export abstract class NewAbstractWidget extends Disposable {
|
||||
/**
|
||||
* Override the create() method to match the parameters of create() expected by FieldBuilder.
|
||||
*/
|
||||
public static create(field: ViewFieldRec) {
|
||||
return Disposable.create.call(this as any, null, field);
|
||||
// We copy Disposable.create() signature (the second one) to pacify typescript, but code must
|
||||
// use the first signature, which is compatible with old-style constructors.
|
||||
public static create<T extends new (...args: any[]) => any>(field: ViewFieldRec): InstanceType<T>;
|
||||
public static create<T extends new (...args: any[]) => any>(
|
||||
this: T, owner: IDisposableOwnerT<InstanceType<T>>|null, ...args: ConstructorParameters<T>): InstanceType<T>;
|
||||
public static create(...args: any[]) {
|
||||
return Disposable.create.call(this as any, null, ...args);
|
||||
}
|
||||
|
||||
protected options: SaveableObjObservable<any>;
|
||||
|
||||
Reference in New Issue
Block a user