mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2024-12-29 09:22:22 -05:00
Fix typescript definition issues (#1669)
Closes #1667 Closes #1664 Closes #1663 Closes #1659
This commit is contained in:
parent
e5d7bafd39
commit
b24e9b3835
10 changed files with 17564 additions and 295 deletions
1
dist/paper-full.js
vendored
1
dist/paper-full.js
vendored
|
@ -1 +0,0 @@
|
||||||
../src/load.js
|
|
17081
dist/paper-full.js
vendored
Normal file
17081
dist/paper-full.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
572
dist/paper.d.ts
vendored
572
dist/paper.d.ts
vendored
File diff suppressed because it is too large
Load diff
|
@ -78,7 +78,7 @@ gulp.task('docs:typescript:build', function() {
|
||||||
// ...then generate definition from parsed data...
|
// ...then generate definition from parsed data...
|
||||||
.pipe(shell('node gulp/typescript/typescript-definition-generator.js'))
|
.pipe(shell('node gulp/typescript/typescript-definition-generator.js'))
|
||||||
// ...finally test the definition by compiling a typescript file.
|
// ...finally test the definition by compiling a typescript file.
|
||||||
.pipe(shell('node node_modules/typescript/bin/tsc gulp/typescript/typescript-definition-test.ts'));
|
.pipe(shell('node node_modules/typescript/bin/tsc --project gulp/typescript'));
|
||||||
});
|
});
|
||||||
// ...finally remove all unneeded temporary files that were used for building.
|
// ...finally remove all unneeded temporary files that were used for building.
|
||||||
gulp.task('docs:typescript:clean:after', function() {
|
gulp.task('docs:typescript:clean:after', function() {
|
||||||
|
|
9
gulp/typescript/tsconfig.json
Normal file
9
gulp/typescript/tsconfig.json
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES5",
|
||||||
|
"strictNullChecks": true
|
||||||
|
},
|
||||||
|
"files" : [
|
||||||
|
"typescript-definition-test.ts"
|
||||||
|
]
|
||||||
|
}
|
|
@ -9,7 +9,6 @@ const mustache = require('mustache');
|
||||||
// Retrieve JSDoc data.
|
// Retrieve JSDoc data.
|
||||||
const data = JSON.parse(fs.readFileSync(__dirname + '/typescript-definition-data.json', 'utf8'));
|
const data = JSON.parse(fs.readFileSync(__dirname + '/typescript-definition-data.json', 'utf8'));
|
||||||
const classes = data.classes;
|
const classes = data.classes;
|
||||||
let globals = data.global.properties;
|
|
||||||
|
|
||||||
// Format classes.
|
// Format classes.
|
||||||
classes.forEach(cls => {
|
classes.forEach(cls => {
|
||||||
|
@ -32,7 +31,7 @@ classes.forEach(cls => {
|
||||||
.filter(filter)
|
.filter(filter)
|
||||||
.map(it => ({
|
.map(it => ({
|
||||||
name: it._name,
|
name: it._name,
|
||||||
type: formatType(it.type),
|
type: formatType(it.type, { isProperty: true, isSettableProperty: !it.readOnly }),
|
||||||
static: formatStatic(it.isStatic),
|
static: formatStatic(it.isStatic),
|
||||||
readOnly: formatReadOnly(it.readOnly),
|
readOnly: formatReadOnly(it.readOnly),
|
||||||
comment: formatComment(it.comment)
|
comment: formatComment(it.comment)
|
||||||
|
@ -48,7 +47,7 @@ classes.forEach(cls => {
|
||||||
name: name,
|
name: name,
|
||||||
// Constructors don't need return type.
|
// Constructors don't need return type.
|
||||||
type: !it.isConstructor
|
type: !it.isConstructor
|
||||||
? formatType(getMethodReturnType(it), true)
|
? formatType(getMethodReturnType(it), { isMethodReturnType: true })
|
||||||
: '',
|
: '',
|
||||||
static: formatStatic(it.isStatic),
|
static: formatStatic(it.isStatic),
|
||||||
// This flag is only used below to filter methods.
|
// This flag is only used below to filter methods.
|
||||||
|
@ -89,21 +88,25 @@ classes.forEach(cls => {
|
||||||
cls.hasStaticConstructors = cls.staticConstructors.length > 0;
|
cls.hasStaticConstructors = cls.staticConstructors.length > 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Format global vriables.
|
// PaperScope class needs to be handled slightly differently because it "owns"
|
||||||
globals = globals
|
// all the other classes as properties. Eg. we can do `new paperScope.Path()`.
|
||||||
// Filter global variables that make no sense in type definition.
|
// So we add a `classesPointers` property that the template will use.
|
||||||
.filter(it => !/^on/.test(it._name) && it._name !== 'paper')
|
const paperScopeClass = classes.find(_ => _.className === 'PaperScope');
|
||||||
.map(it => ({
|
paperScopeClass.classesPointers = classes.filter(_ => _.className !== 'PaperScope').map(_ => ({ name: _.className }));
|
||||||
name: it._name,
|
|
||||||
type: formatType(it.type),
|
// Since paper.js module is at the same time a PaperScope instance, we need to
|
||||||
comment: formatComment(it.comment)
|
// duplicate PaperScope instance properties and methods in the module scope.
|
||||||
}));
|
// For that, we expose a special variable to the template.
|
||||||
|
const paperInstance = { ...paperScopeClass };
|
||||||
|
// We filter static properties and methods for module scope.
|
||||||
|
paperInstance.properties = paperInstance.properties.filter(_ => !_.static);
|
||||||
|
paperInstance.methods = paperInstance.methods.filter(_ => !_.static && _.name !== 'constructor');
|
||||||
|
|
||||||
// Format data trough a mustache template.
|
// Format data trough a mustache template.
|
||||||
// Prepare data for the template.
|
// Prepare data for the template.
|
||||||
const context = {
|
const context = {
|
||||||
|
paperInstance: paperInstance,
|
||||||
classes: classes,
|
classes: classes,
|
||||||
globals: globals,
|
|
||||||
version: data.version,
|
version: data.version,
|
||||||
date: data.date,
|
date: data.date,
|
||||||
// {{#doc}} blocks are used in template to automatically generate a JSDoc
|
// {{#doc}} blocks are used in template to automatically generate a JSDoc
|
||||||
|
@ -130,48 +133,69 @@ function formatStatic(isStatic) {
|
||||||
return isStatic ? 'static ' : null;
|
return isStatic ? 'static ' : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatType(type, isMethodReturnType, staticConstructorClass) {
|
function formatType(type, options) {
|
||||||
return ': ' + parseType(type, isMethodReturnType, staticConstructorClass);
|
return ': ' + parseType(type, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseType(type, isMethodReturnType, staticConstructorClass) {
|
function parseType(type, options) {
|
||||||
// Always return a type even if input type is empty. In that case, return
|
// Always return a type even if input type is empty. In that case, return
|
||||||
// `void` for method return type and `any` for the rest.
|
// `void` for method return type and `any` for the rest.
|
||||||
if (!type) {
|
if (!type) {
|
||||||
return isMethodReturnType ? 'void' : 'any';
|
return options.isMethodReturnType ? 'void' : 'any';
|
||||||
}
|
|
||||||
if (type === '*') {
|
|
||||||
return 'any';
|
|
||||||
}
|
}
|
||||||
// Prefer `any[]` over `Array<any>` to be more consistent with other types.
|
// Prefer `any[]` over `Array<any>` to be more consistent with other types.
|
||||||
if (type === 'Array') {
|
if (type === 'Array') {
|
||||||
return 'any[]';
|
return 'any[]';
|
||||||
}
|
}
|
||||||
|
// Handle any type: `*` => `any`
|
||||||
|
type = type.replace('*', 'any');
|
||||||
|
// Check if type is a "rest" type (meaning that an infinite number of
|
||||||
|
// parameter of this type can be passed). In that case, we need to remove
|
||||||
|
// `...` prefix and add `[]` as a suffix:
|
||||||
|
// - `...Type` => `Type[]`
|
||||||
|
// - `...(TypeA|TypeB)` => `(TypeA|TypeB)[]`
|
||||||
|
const isRestType = type.startsWith('...');
|
||||||
|
if (isRestType) {
|
||||||
|
type = type.replace(/^\.\.\./, '');
|
||||||
|
}
|
||||||
// Handle multiple types possibility by splitting on `|` then re-joining
|
// Handle multiple types possibility by splitting on `|` then re-joining
|
||||||
// back parsed types.
|
// back parsed types.
|
||||||
return type.split('|').map(type => {
|
type = type.split('|').map(splittedType => {
|
||||||
// Handle rest parameter pattern: `...Type` => `Type[]`
|
|
||||||
const matches = type.match(/^\.\.\.(.+)$/);
|
|
||||||
if (matches) {
|
|
||||||
return parseType(matches[1]) + '[]';
|
|
||||||
}
|
|
||||||
// Get type without array suffix `[]` for easier matching.
|
// Get type without array suffix `[]` for easier matching.
|
||||||
const singleType = type.replace(/(\[\])+$/, '');
|
const singleType = splittedType.replace(/(\[\])+$/, '');
|
||||||
// Handle eventual type conflict in static constructors block. For
|
// Handle eventual type conflict in static constructors block. For
|
||||||
// example, in `Path.Rectangle(rectangle: Rectangle)` method,
|
// example, in `Path.Rectangle(rectangle: Rectangle)` method,
|
||||||
// `rectangle` parameter type must be mapped to `paper.Rectangle` as it
|
// `rectangle` parameter type must be mapped to `paper.Rectangle` as it
|
||||||
// is declared inside a `Path` namespace and would otherwise be wrongly
|
// is declared inside a `Path` namespace and would otherwise be wrongly
|
||||||
// assumed as being the type of `Path.Rectangle` class.
|
// assumed as being the type of `Path.Rectangle` class.
|
||||||
if (staticConstructorClass && staticConstructorClass.methods.find(it => it.isStatic && it.isConstructor && formatMethodName(it._name) === singleType)
|
if (options.staticConstructorClass && options.staticConstructorClass.methods.find(it => it.isStatic && it.isConstructor && formatMethodName(it._name) === singleType)
|
||||||
) {
|
) {
|
||||||
return 'paper.' + type;
|
return 'paper.' + splittedType;
|
||||||
}
|
}
|
||||||
// Convert primitive types to their lowercase equivalent to suit
|
// Convert primitive types to their lowercase equivalent to suit
|
||||||
// typescript best practices.
|
// typescript best practices.
|
||||||
return ['Number', 'String', 'Boolean', 'Object'].indexOf(singleType) >= 0
|
if (['Number', 'String', 'Boolean', 'Object'].indexOf(singleType) >= 0) {
|
||||||
? type.toLowerCase()
|
splittedType = splittedType.toLowerCase();
|
||||||
: type;
|
}
|
||||||
|
// Properties `object` type need to be turned into `any` to avoid
|
||||||
|
// errors when reading object properties. Eg. if `property` is of type
|
||||||
|
// `object`, `property.key` access is forbidden.
|
||||||
|
if (options.isProperty && splittedType === 'object') {
|
||||||
|
return 'any';
|
||||||
|
}
|
||||||
|
return splittedType;
|
||||||
}).join(' | ');
|
}).join(' | ');
|
||||||
|
if (isRestType) {
|
||||||
|
type += '[]';
|
||||||
|
}
|
||||||
|
|
||||||
|
// We declare settable properties as nullable to be compatible with
|
||||||
|
// TypeScript `strictNullChecks` option (#1664).
|
||||||
|
if (options.isSettableProperty && type !== 'any') {
|
||||||
|
type += ' | null';
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatMethodName(methodName) {
|
function formatMethodName(methodName) {
|
||||||
|
@ -195,7 +219,7 @@ function formatParameter(param, staticConstructorClass) {
|
||||||
if (param.isOptional) {
|
if (param.isOptional) {
|
||||||
content += '?';
|
content += '?';
|
||||||
}
|
}
|
||||||
content += formatType(param.type, false, staticConstructorClass);
|
content += formatType(param.type, { staticConstructorClass });
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,11 +330,9 @@ function sortMethods(methodA, methodB) {
|
||||||
if (methodB.params === 'object: object') {
|
if (methodB.params === 'object: object') {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
} else if (aIsContructor) {
|
||||||
else if (aIsContructor) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
} else if (bIsContructor) {
|
||||||
else if (bIsContructor) {
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -15,11 +15,19 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
declare module paper {
|
declare module paper {
|
||||||
{{#globals}}
|
{{#paperInstance}}
|
||||||
|
{{#properties}}
|
||||||
{{#doc}}4{{/doc}}
|
{{#doc}}4{{/doc}}
|
||||||
let {{name}}{{type}}
|
let {{name}}{{type}}
|
||||||
|
|
||||||
{{/globals}}
|
{{/properties}}
|
||||||
|
|
||||||
|
{{#methods}}
|
||||||
|
{{#doc}}4{{/doc}}
|
||||||
|
function {{name}}({{params}}){{type}}
|
||||||
|
|
||||||
|
{{/methods}}
|
||||||
|
{{/paperInstance}}
|
||||||
|
|
||||||
{{#classes}}
|
{{#classes}}
|
||||||
|
|
||||||
|
@ -30,6 +38,9 @@ declare module paper {
|
||||||
{{static}}{{readOnly}}{{name}}{{type}}
|
{{static}}{{readOnly}}{{name}}{{type}}
|
||||||
|
|
||||||
{{/properties}}
|
{{/properties}}
|
||||||
|
{{#classesPointers}}
|
||||||
|
{{name}}: typeof {{name}}
|
||||||
|
{{/classesPointers}}
|
||||||
|
|
||||||
{{#methods}}
|
{{#methods}}
|
||||||
{{#doc}}8{{/doc}}
|
{{#doc}}8{{/doc}}
|
||||||
|
|
|
@ -13,17 +13,6 @@
|
||||||
import * as paper from 'paper';
|
import * as paper from 'paper';
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Global
|
|
||||||
//
|
|
||||||
|
|
||||||
paper.project;
|
|
||||||
paper.projects;
|
|
||||||
paper.view;
|
|
||||||
paper.tool;
|
|
||||||
paper.tools;
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Utility variables
|
// Utility variables
|
||||||
//
|
//
|
||||||
|
@ -368,6 +357,7 @@ item.strokeScaling;
|
||||||
item.dashArray;
|
item.dashArray;
|
||||||
item.miterLimit;
|
item.miterLimit;
|
||||||
item.fillColor;
|
item.fillColor;
|
||||||
|
item.fillColor && item.fillColor.red;
|
||||||
item.fillRule;
|
item.fillRule;
|
||||||
item.shadowColor;
|
item.shadowColor;
|
||||||
item.shadowBlur;
|
item.shadowBlur;
|
||||||
|
@ -538,6 +528,8 @@ raster.source;
|
||||||
raster.crossOrigin;
|
raster.crossOrigin;
|
||||||
raster.smoothing;
|
raster.smoothing;
|
||||||
raster.onLoad;
|
raster.onLoad;
|
||||||
|
raster.onLoad = () => {};
|
||||||
|
raster.onLoad = null;
|
||||||
raster.onError;
|
raster.onError;
|
||||||
raster.getSubCanvas(rectangle);
|
raster.getSubCanvas(rectangle);
|
||||||
raster.getSubRaster(rectangle);
|
raster.getSubRaster(rectangle);
|
||||||
|
@ -662,6 +654,9 @@ path.length;
|
||||||
path.area;
|
path.area;
|
||||||
path.fullySelected;
|
path.fullySelected;
|
||||||
path.add(segment);
|
path.add(segment);
|
||||||
|
path.add(point);
|
||||||
|
path.add([0,0]);
|
||||||
|
path.add(segment, point, [0,0]);
|
||||||
path.insert(0, segment);
|
path.insert(0, segment);
|
||||||
path.addSegments([ segment ]);
|
path.addSegments([ segment ]);
|
||||||
path.insertSegments(0, [ segment ]);
|
path.insertSegments(0, [ segment ]);
|
||||||
|
@ -1048,6 +1043,7 @@ view.responds('');
|
||||||
|
|
||||||
event.timeStamp;
|
event.timeStamp;
|
||||||
event.modifiers;
|
event.modifiers;
|
||||||
|
event.modifiers.shift;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.stop();
|
event.stop();
|
||||||
|
@ -1128,6 +1124,7 @@ keyEvent.toString();
|
||||||
new paper.PaperScope();
|
new paper.PaperScope();
|
||||||
paperScope.version;
|
paperScope.version;
|
||||||
paperScope.settings;
|
paperScope.settings;
|
||||||
|
paperScope.settings = null;
|
||||||
paperScope.project;
|
paperScope.project;
|
||||||
paperScope.projects;
|
paperScope.projects;
|
||||||
paperScope.view;
|
paperScope.view;
|
||||||
|
@ -1141,6 +1138,60 @@ paperScope.setup({} as HTMLCanvasElement);
|
||||||
paperScope.setup(size);
|
paperScope.setup(size);
|
||||||
paperScope.activate();
|
paperScope.activate();
|
||||||
paper.PaperScope.get(0);
|
paper.PaperScope.get(0);
|
||||||
|
new paperScope.Color('');
|
||||||
|
new paperScope.CompoundPath('');
|
||||||
|
new paperScope.Curve(segment, segment);
|
||||||
|
new paperScope.CurveLocation(curve, 0);
|
||||||
|
new paperScope.Event();
|
||||||
|
new paperScope.Gradient();
|
||||||
|
new paperScope.GradientStop();
|
||||||
|
new paperScope.Group();
|
||||||
|
new paperScope.HitResult();
|
||||||
|
new paperScope.Item();
|
||||||
|
new paperScope.Key();
|
||||||
|
new paperScope.KeyEvent();
|
||||||
|
new paperScope.Layer();
|
||||||
|
new paperScope.Matrix();
|
||||||
|
new paperScope.MouseEvent();
|
||||||
|
new paperScope.PaperScript();
|
||||||
|
new paperScope.Path();
|
||||||
|
new paperScope.PathItem();
|
||||||
|
new paperScope.Point(0, 0);
|
||||||
|
new paperScope.PointText(point);
|
||||||
|
new paperScope.Project(size);
|
||||||
|
new paperScope.Raster();
|
||||||
|
new paperScope.Rectangle(point, size);
|
||||||
|
new paperScope.Segment();
|
||||||
|
new paperScope.Shape();
|
||||||
|
new paperScope.Size(0,0);
|
||||||
|
new paperScope.Style(object);
|
||||||
|
new paperScope.SymbolDefinition(item);
|
||||||
|
new paperScope.SymbolItem(symbolDefinition);
|
||||||
|
new paperScope.TextItem();
|
||||||
|
new paperScope.Tool();
|
||||||
|
new paperScope.ToolEvent();
|
||||||
|
new paperScope.Tween(object, object, object, 0);
|
||||||
|
new paperScope.View();
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Global PaperScope instance
|
||||||
|
//
|
||||||
|
|
||||||
|
paper.version;
|
||||||
|
paper.settings;
|
||||||
|
paper.project;
|
||||||
|
paper.projects;
|
||||||
|
paper.view;
|
||||||
|
paper.tool;
|
||||||
|
paper.tools;
|
||||||
|
paper.execute('');
|
||||||
|
paper.execute('', object);
|
||||||
|
paper.install(object);
|
||||||
|
paper.setup('');
|
||||||
|
paper.setup({} as HTMLCanvasElement);
|
||||||
|
paper.setup(size);
|
||||||
|
paper.activate();
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -112,6 +112,7 @@ var PaperScope = Base.extend(/** @lends PaperScope# */{
|
||||||
* The version of Paper.js, as a string.
|
* The version of Paper.js, as a string.
|
||||||
*
|
*
|
||||||
* @type String
|
* @type String
|
||||||
|
* @readonly
|
||||||
*/
|
*/
|
||||||
version: /*#=*/__options.version,
|
version: /*#=*/__options.version,
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,7 @@
|
||||||
*
|
*
|
||||||
* @name view
|
* @name view
|
||||||
* @type View
|
* @type View
|
||||||
|
* @readonly
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -483,9 +483,11 @@ var Path = PathItem.extend(/** @lends Path# */{
|
||||||
* Adds one or more segments to the end of the {@link #segments} array of
|
* Adds one or more segments to the end of the {@link #segments} array of
|
||||||
* this path.
|
* this path.
|
||||||
*
|
*
|
||||||
* @param {Segment|Point} segment the segment or point to be added.
|
* @param {...(Segment|Point|Number[])} segment the segment or point to be
|
||||||
* @return {Segment} the added segment. This is not necessarily the same
|
* added.
|
||||||
* object, e.g. if the segment to be added already belongs to another path
|
* @return {Segment|Segment[]} the added segment(s). This is not necessarily
|
||||||
|
* the same object, e.g. if the segment to be added already belongs to
|
||||||
|
* another path.
|
||||||
*
|
*
|
||||||
* @example {@paperscript}
|
* @example {@paperscript}
|
||||||
* // Adding segments to a path using point objects:
|
* // Adding segments to a path using point objects:
|
||||||
|
|
Loading…
Reference in a new issue