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...
|
||||
.pipe(shell('node gulp/typescript/typescript-definition-generator.js'))
|
||||
// ...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.
|
||||
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.
|
||||
const data = JSON.parse(fs.readFileSync(__dirname + '/typescript-definition-data.json', 'utf8'));
|
||||
const classes = data.classes;
|
||||
let globals = data.global.properties;
|
||||
|
||||
// Format classes.
|
||||
classes.forEach(cls => {
|
||||
|
@ -32,7 +31,7 @@ classes.forEach(cls => {
|
|||
.filter(filter)
|
||||
.map(it => ({
|
||||
name: it._name,
|
||||
type: formatType(it.type),
|
||||
type: formatType(it.type, { isProperty: true, isSettableProperty: !it.readOnly }),
|
||||
static: formatStatic(it.isStatic),
|
||||
readOnly: formatReadOnly(it.readOnly),
|
||||
comment: formatComment(it.comment)
|
||||
|
@ -48,7 +47,7 @@ classes.forEach(cls => {
|
|||
name: name,
|
||||
// Constructors don't need return type.
|
||||
type: !it.isConstructor
|
||||
? formatType(getMethodReturnType(it), true)
|
||||
? formatType(getMethodReturnType(it), { isMethodReturnType: true })
|
||||
: '',
|
||||
static: formatStatic(it.isStatic),
|
||||
// This flag is only used below to filter methods.
|
||||
|
@ -89,21 +88,25 @@ classes.forEach(cls => {
|
|||
cls.hasStaticConstructors = cls.staticConstructors.length > 0;
|
||||
});
|
||||
|
||||
// Format global vriables.
|
||||
globals = globals
|
||||
// Filter global variables that make no sense in type definition.
|
||||
.filter(it => !/^on/.test(it._name) && it._name !== 'paper')
|
||||
.map(it => ({
|
||||
name: it._name,
|
||||
type: formatType(it.type),
|
||||
comment: formatComment(it.comment)
|
||||
}));
|
||||
// PaperScope class needs to be handled slightly differently because it "owns"
|
||||
// all the other classes as properties. Eg. we can do `new paperScope.Path()`.
|
||||
// So we add a `classesPointers` property that the template will use.
|
||||
const paperScopeClass = classes.find(_ => _.className === 'PaperScope');
|
||||
paperScopeClass.classesPointers = classes.filter(_ => _.className !== 'PaperScope').map(_ => ({ name: _.className }));
|
||||
|
||||
// Since paper.js module is at the same time a PaperScope instance, we need to
|
||||
// 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.
|
||||
// Prepare data for the template.
|
||||
const context = {
|
||||
paperInstance: paperInstance,
|
||||
classes: classes,
|
||||
globals: globals,
|
||||
version: data.version,
|
||||
date: data.date,
|
||||
// {{#doc}} blocks are used in template to automatically generate a JSDoc
|
||||
|
@ -130,48 +133,69 @@ function formatStatic(isStatic) {
|
|||
return isStatic ? 'static ' : null;
|
||||
}
|
||||
|
||||
function formatType(type, isMethodReturnType, staticConstructorClass) {
|
||||
return ': ' + parseType(type, isMethodReturnType, staticConstructorClass);
|
||||
function formatType(type, options) {
|
||||
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
|
||||
// `void` for method return type and `any` for the rest.
|
||||
if (!type) {
|
||||
return isMethodReturnType ? 'void' : 'any';
|
||||
}
|
||||
if (type === '*') {
|
||||
return 'any';
|
||||
return options.isMethodReturnType ? 'void' : 'any';
|
||||
}
|
||||
// Prefer `any[]` over `Array<any>` to be more consistent with other types.
|
||||
if (type === 'Array') {
|
||||
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
|
||||
// back parsed types.
|
||||
return type.split('|').map(type => {
|
||||
// Handle rest parameter pattern: `...Type` => `Type[]`
|
||||
const matches = type.match(/^\.\.\.(.+)$/);
|
||||
if (matches) {
|
||||
return parseType(matches[1]) + '[]';
|
||||
}
|
||||
type = type.split('|').map(splittedType => {
|
||||
// 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
|
||||
// example, in `Path.Rectangle(rectangle: Rectangle)` method,
|
||||
// `rectangle` parameter type must be mapped to `paper.Rectangle` as it
|
||||
// is declared inside a `Path` namespace and would otherwise be wrongly
|
||||
// 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
|
||||
// typescript best practices.
|
||||
return ['Number', 'String', 'Boolean', 'Object'].indexOf(singleType) >= 0
|
||||
? type.toLowerCase()
|
||||
: type;
|
||||
if (['Number', 'String', 'Boolean', 'Object'].indexOf(singleType) >= 0) {
|
||||
splittedType = splittedType.toLowerCase();
|
||||
}
|
||||
// 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(' | ');
|
||||
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) {
|
||||
|
@ -195,7 +219,7 @@ function formatParameter(param, staticConstructorClass) {
|
|||
if (param.isOptional) {
|
||||
content += '?';
|
||||
}
|
||||
content += formatType(param.type, false, staticConstructorClass);
|
||||
content += formatType(param.type, { staticConstructorClass });
|
||||
return content;
|
||||
}
|
||||
|
||||
|
@ -306,11 +330,9 @@ function sortMethods(methodA, methodB) {
|
|||
if (methodB.params === 'object: object') {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (aIsContructor) {
|
||||
} else if (aIsContructor) {
|
||||
return -1;
|
||||
}
|
||||
else if (bIsContructor) {
|
||||
} else if (bIsContructor) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -15,11 +15,19 @@
|
|||
*/
|
||||
|
||||
declare module paper {
|
||||
{{#globals}}
|
||||
{{#paperInstance}}
|
||||
{{#properties}}
|
||||
{{#doc}}4{{/doc}}
|
||||
let {{name}}{{type}}
|
||||
|
||||
{{/globals}}
|
||||
{{/properties}}
|
||||
|
||||
{{#methods}}
|
||||
{{#doc}}4{{/doc}}
|
||||
function {{name}}({{params}}){{type}}
|
||||
|
||||
{{/methods}}
|
||||
{{/paperInstance}}
|
||||
|
||||
{{#classes}}
|
||||
|
||||
|
@ -30,6 +38,9 @@ declare module paper {
|
|||
{{static}}{{readOnly}}{{name}}{{type}}
|
||||
|
||||
{{/properties}}
|
||||
{{#classesPointers}}
|
||||
{{name}}: typeof {{name}}
|
||||
{{/classesPointers}}
|
||||
|
||||
{{#methods}}
|
||||
{{#doc}}8{{/doc}}
|
||||
|
|
|
@ -13,17 +13,6 @@
|
|||
import * as paper from 'paper';
|
||||
|
||||
|
||||
//
|
||||
// Global
|
||||
//
|
||||
|
||||
paper.project;
|
||||
paper.projects;
|
||||
paper.view;
|
||||
paper.tool;
|
||||
paper.tools;
|
||||
|
||||
|
||||
//
|
||||
// Utility variables
|
||||
//
|
||||
|
@ -368,6 +357,7 @@ item.strokeScaling;
|
|||
item.dashArray;
|
||||
item.miterLimit;
|
||||
item.fillColor;
|
||||
item.fillColor && item.fillColor.red;
|
||||
item.fillRule;
|
||||
item.shadowColor;
|
||||
item.shadowBlur;
|
||||
|
@ -538,6 +528,8 @@ raster.source;
|
|||
raster.crossOrigin;
|
||||
raster.smoothing;
|
||||
raster.onLoad;
|
||||
raster.onLoad = () => {};
|
||||
raster.onLoad = null;
|
||||
raster.onError;
|
||||
raster.getSubCanvas(rectangle);
|
||||
raster.getSubRaster(rectangle);
|
||||
|
@ -662,6 +654,9 @@ path.length;
|
|||
path.area;
|
||||
path.fullySelected;
|
||||
path.add(segment);
|
||||
path.add(point);
|
||||
path.add([0,0]);
|
||||
path.add(segment, point, [0,0]);
|
||||
path.insert(0, segment);
|
||||
path.addSegments([ segment ]);
|
||||
path.insertSegments(0, [ segment ]);
|
||||
|
@ -1048,6 +1043,7 @@ view.responds('');
|
|||
|
||||
event.timeStamp;
|
||||
event.modifiers;
|
||||
event.modifiers.shift;
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
event.stop();
|
||||
|
@ -1128,6 +1124,7 @@ keyEvent.toString();
|
|||
new paper.PaperScope();
|
||||
paperScope.version;
|
||||
paperScope.settings;
|
||||
paperScope.settings = null;
|
||||
paperScope.project;
|
||||
paperScope.projects;
|
||||
paperScope.view;
|
||||
|
@ -1141,6 +1138,60 @@ paperScope.setup({} as HTMLCanvasElement);
|
|||
paperScope.setup(size);
|
||||
paperScope.activate();
|
||||
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.
|
||||
*
|
||||
* @type String
|
||||
* @readonly
|
||||
*/
|
||||
version: /*#=*/__options.version,
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
*
|
||||
* @name 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
|
||||
* this path.
|
||||
*
|
||||
* @param {Segment|Point} segment the segment or point to be added.
|
||||
* @return {Segment} the added segment. This is not necessarily the same
|
||||
* object, e.g. if the segment to be added already belongs to another path
|
||||
* @param {...(Segment|Point|Number[])} segment the segment or point to be
|
||||
* added.
|
||||
* @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}
|
||||
* // Adding segments to a path using point objects:
|
||||
|
|
Loading…
Reference in a new issue