diff --git a/samples/js-extend-gulp/.editorconfig b/samples/js-extend-gulp/.editorconfig new file mode 100644 index 000000000..8ffcdc4ec --- /dev/null +++ b/samples/js-extend-gulp/.editorconfig @@ -0,0 +1,25 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# editorconfig.org + +root = true + + +[*] + +# change these settings to your own preference +indent_style = space +indent_size = 2 + +# we recommend you to keep these unchanged +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false + +[{package,bower}.json] +indent_style = space +indent_size = 2 \ No newline at end of file diff --git a/samples/js-extend-gulp/.gitattributes b/samples/js-extend-gulp/.gitattributes new file mode 100644 index 000000000..212566614 --- /dev/null +++ b/samples/js-extend-gulp/.gitattributes @@ -0,0 +1 @@ +* text=auto \ No newline at end of file diff --git a/samples/js-extend-gulp/.gitignore b/samples/js-extend-gulp/.gitignore new file mode 100644 index 000000000..b19bbe123 --- /dev/null +++ b/samples/js-extend-gulp/.gitignore @@ -0,0 +1,32 @@ +# Logs +logs +*.log +npm-debug.log* + +# Dependency directories +node_modules + +# Build generated files +dist +lib +solution +temp +*.sppkg + +# Coverage directory used by tools like istanbul +coverage + +# OSX +.DS_Store + +# Visual Studio files +.ntvs_analysis.dat +.vs +bin +obj + +# Resx Generated Code +*.resx.ts + +# Styles Generated Code +*.scss.ts diff --git a/samples/js-extend-gulp/.npmignore b/samples/js-extend-gulp/.npmignore new file mode 100644 index 000000000..2c93a9384 --- /dev/null +++ b/samples/js-extend-gulp/.npmignore @@ -0,0 +1,14 @@ +# Folders +.vscode +coverage +node_modules +sharepoint +src +temp + +# Files +*.csproj +.git* +.yo-rc.json +gulpfile.js +tsconfig.json diff --git a/samples/js-extend-gulp/.yo-rc.json b/samples/js-extend-gulp/.yo-rc.json new file mode 100644 index 000000000..a3a29d2cf --- /dev/null +++ b/samples/js-extend-gulp/.yo-rc.json @@ -0,0 +1,7 @@ +{ + "@microsoft/generator-sharepoint": { + "libraryName": "js-extend-gulp", + "libraryId": "ff250e08-bd51-498e-8b3f-a296db4f0c2c", + "framework": "none" + } +} \ No newline at end of file diff --git a/samples/js-extend-gulp/README.md b/samples/js-extend-gulp/README.md new file mode 100644 index 000000000..e92d7749d --- /dev/null +++ b/samples/js-extend-gulp/README.md @@ -0,0 +1,73 @@ +# Extending webpack in the SharePoint Framework toolchain + +## Summary +SharePoint client-side development tools use gulp as the build process task runner to: + +- Bundle and minify JavaScript and CSS files. +- Run tools to call the bundling and minification tasks before each build. +- Compile LESS or SASS files to CSS. +- Compile TypeScript files to JavaScript. + +One common task you would want add to the SharePoint Framework toolchain is to integrate your custom gulp tasks and execute them. + +This sample shows how to integrate custom gulp tasks using the [gulp-image-resize](https://www.npmjs.com/package/gulp-image-resize) task that resizes images. + +Read the following documentation for detailed information on integrating gulp tasks in SharePoint Framework: + +- [Integrate custom gulp tasks in the SharePoint Framework toolchain](https://aka.ms/spfx-extend-gulp) + +## Applies to + +* [SharePoint Framework Developer Preview](http://dev.office.com/sharepoint/docs/spfx/sharepoint-framework-overview) +* [Office 365 First Release Tenants](http://dev.office.com/sharepoint/docs/spfx/set-up-your-developer-tenant) + +## Pre-requisites + +### GraphicsMagick or ImageMagick +Make sure GraphicsMagick or ImageMagick is installed on your system and properly set up in your PATH. + +#### Ubuntu: + +``` +apt-get install imagemagick +apt-get install graphicsmagick +``` + +#### Mac OS X (using Homebrew): + +``` +brew install imagemagick +brew install graphicsmagick +``` + +#### Windows & others: + +http://www.imagemagick.org/script/binary-releases.php + +Confirm that ImageMagick is properly set up by executing convert -help in a terminal. + +## Solution + +Solution|Author(s) +--------|--------- +js-extend-gulp | Chakkaradeep Chandran (@chakkaradeep) + +## Version history + +Version|Date|Comments +-------|----|-------- +1.0|January 25th, 2017|Initial release + +## Disclaimer +**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.** + +--- + +## Minimal Path to Awesome + +- Clone this repository +- in the command line run: + - `npm install` + - `gulp serve` + + \ No newline at end of file diff --git a/samples/js-extend-gulp/config/config.json b/samples/js-extend-gulp/config/config.json new file mode 100644 index 000000000..601197195 --- /dev/null +++ b/samples/js-extend-gulp/config/config.json @@ -0,0 +1,13 @@ +{ + "entries": [ + { + "entry": "./lib/webparts/extendGulp/ExtendGulpWebPart.js", + "manifest": "./src/webparts/extendGulp/ExtendGulpWebPart.manifest.json", + "outputPath": "./dist/extend-gulp.bundle.js" + } + ], + "externals": {}, + "localizedResources": { + "extendGulpStrings": "webparts/extendGulp/loc/{locale}.js" + } +} diff --git a/samples/js-extend-gulp/config/deploy-azure-storage.json b/samples/js-extend-gulp/config/deploy-azure-storage.json new file mode 100644 index 000000000..844236f2a --- /dev/null +++ b/samples/js-extend-gulp/config/deploy-azure-storage.json @@ -0,0 +1,6 @@ +{ + "workingDir": "./temp/deploy/", + "account": "", + "container": "js-extend-gulp", + "accessKey": "" +} \ No newline at end of file diff --git a/samples/js-extend-gulp/config/package-solution.json b/samples/js-extend-gulp/config/package-solution.json new file mode 100644 index 000000000..6af827c87 --- /dev/null +++ b/samples/js-extend-gulp/config/package-solution.json @@ -0,0 +1,10 @@ +{ + "solution": { + "name": "js-extend-gulp-client-side-solution", + "id": "ff250e08-bd51-498e-8b3f-a296db4f0c2c", + "version": "1.0.0.0" + }, + "paths": { + "zippedPackage": "solution/js-extend-gulp.sppkg" + } +} diff --git a/samples/js-extend-gulp/config/prepare-deploy.json b/samples/js-extend-gulp/config/prepare-deploy.json new file mode 100644 index 000000000..6aca63656 --- /dev/null +++ b/samples/js-extend-gulp/config/prepare-deploy.json @@ -0,0 +1,3 @@ +{ + "deployCdnPath": "temp/deploy" +} diff --git a/samples/js-extend-gulp/config/serve.json b/samples/js-extend-gulp/config/serve.json new file mode 100644 index 000000000..087899637 --- /dev/null +++ b/samples/js-extend-gulp/config/serve.json @@ -0,0 +1,9 @@ +{ + "port": 4321, + "initialPage": "https://localhost:5432/workbench", + "https": true, + "api": { + "port": 5432, + "entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/" + } +} diff --git a/samples/js-extend-gulp/config/tslint.json b/samples/js-extend-gulp/config/tslint.json new file mode 100644 index 000000000..0010b6105 --- /dev/null +++ b/samples/js-extend-gulp/config/tslint.json @@ -0,0 +1,50 @@ +{ + // Display errors as warnings + "displayAsWarning": true, + // The TSLint task may have been configured with several custom lint rules + // before this config file is read (for example lint rules from the tslint-microsoft-contrib + // project). If true, this flag will deactivate any of these rules. + "removeExistingRules": true, + // When true, the TSLint task is configured with some default TSLint "rules.": + "useDefaultConfigAsBase": false, + // Since removeExistingRules=true and useDefaultConfigAsBase=false, there will be no lint rules + // which are active, other than the list of rules below. + "lintConfig": { + // Opt-in to Lint rules which help to eliminate bugs in JavaScript + "rules": { + "class-name": false, + "export-name": false, + "forin": false, + "label-position": false, + "label-undefined": false, + "member-access": true, + "no-arg": false, + "no-console": false, + "no-construct": false, + "no-duplicate-case": true, + "no-duplicate-key": false, + "no-duplicate-variable": true, + "no-eval": false, + "no-function-expression": true, + "no-internal-module": true, + "no-shadowed-variable": true, + "no-switch-case-fall-through": true, + "no-unnecessary-semicolons": true, + "no-unused-expression": true, + "no-unused-imports": true, + "no-unused-variable": true, + "no-unreachable": true, + "no-use-before-declare": true, + "no-with-statement": true, + "semicolon": true, + "trailing-comma": false, + "typedef": false, + "typedef-whitespace": false, + "use-named-parameter": true, + "valid-typeof": true, + "variable-name": false, + "whitespace": false, + "prefer-const": true + } + } +} \ No newline at end of file diff --git a/samples/js-extend-gulp/config/write-manifests.json b/samples/js-extend-gulp/config/write-manifests.json new file mode 100644 index 000000000..0a4bafb06 --- /dev/null +++ b/samples/js-extend-gulp/config/write-manifests.json @@ -0,0 +1,3 @@ +{ + "cdnBasePath": "" +} \ No newline at end of file diff --git a/samples/js-extend-gulp/gulpfile.js b/samples/js-extend-gulp/gulpfile.js new file mode 100644 index 000000000..f03654025 --- /dev/null +++ b/samples/js-extend-gulp/gulpfile.js @@ -0,0 +1,22 @@ +'use strict'; + +const gulp = require('gulp'); +const build = require('@microsoft/sp-build-web'); +const path = require('path'); +var imageResize = require('gulp-image-resize'); + +let imageResizeSubTask = build.subTask('image-resize-subtask', function(gulp, buildOptions, done){ + return gulp.src('images/*.jpg') + .pipe(imageResize({ + width: 100, + height: 100, + crop: false + })) + .pipe(gulp.dest(path.join(buildOptions.libFolder, 'images'))) +}); + +let imageResizeTask = build.task('resize-images', imageResizeSubTask); + +build.rig.addPostTypescriptTask(imageResizeTask); + +build.initialize(gulp); diff --git a/samples/js-extend-gulp/images/image1.jpg b/samples/js-extend-gulp/images/image1.jpg new file mode 100644 index 000000000..292f0be9f Binary files /dev/null and b/samples/js-extend-gulp/images/image1.jpg differ diff --git a/samples/js-extend-gulp/images/image2.jpg b/samples/js-extend-gulp/images/image2.jpg new file mode 100644 index 000000000..17fdcb6d8 Binary files /dev/null and b/samples/js-extend-gulp/images/image2.jpg differ diff --git a/samples/js-extend-gulp/images/image3.jpg b/samples/js-extend-gulp/images/image3.jpg new file mode 100644 index 000000000..2320b17d2 Binary files /dev/null and b/samples/js-extend-gulp/images/image3.jpg differ diff --git a/samples/js-extend-gulp/images/license.md b/samples/js-extend-gulp/images/license.md new file mode 100644 index 000000000..37b5cc8b2 --- /dev/null +++ b/samples/js-extend-gulp/images/license.md @@ -0,0 +1,5 @@ +Pictures downloaded from [Pixabay](https://pixabay.com). + +On Pixabay you may find and share images free of copyrights. All pictures are released under [Creative Commons CC0](https://pixabay.com/service/terms/#usage) into the public domain. + +For more information visit [Pixabay FAQ](https://pixabay.com/en/service/faq/). \ No newline at end of file diff --git a/samples/js-extend-gulp/package.json b/samples/js-extend-gulp/package.json new file mode 100644 index 000000000..205c1434a --- /dev/null +++ b/samples/js-extend-gulp/package.json @@ -0,0 +1,29 @@ +{ + "name": "js-extend-gulp", + "version": "0.0.1", + "private": true, + "engines": { + "node": ">=0.10.0" + }, + "dependencies": { + "@microsoft/sp-client-base": "~0.7.0", + "@microsoft/sp-core-library": "~0.1.2", + "@microsoft/sp-webpart-base": "~0.4.0", + "@microsoft/sp-client-preview": "~0.9.0", + "@types/webpack-env": ">=1.12.1 <1.14.0" + }, + "devDependencies": { + "@microsoft/sp-build-web": "~0.9.0", + "@microsoft/sp-module-interfaces": "~0.7.0", + "@microsoft/sp-webpart-workbench": "~0.8.0", + "@types/chai": ">=3.4.34 <3.6.0", + "@types/mocha": ">=2.2.33 <2.6.0", + "gulp": "~3.9.1", + "gulp-image-resize": "^0.11.0" + }, + "scripts": { + "build": "gulp bundle", + "clean": "gulp clean", + "test": "gulp test" + } +} diff --git a/samples/js-extend-gulp/src/tests.js b/samples/js-extend-gulp/src/tests.js new file mode 100644 index 000000000..cb4bb5cf2 --- /dev/null +++ b/samples/js-extend-gulp/src/tests.js @@ -0,0 +1,5 @@ +var context = require.context('.', true, /.+\.test\.js?$/); + +context.keys().forEach(context); + +module.exports = context; diff --git a/samples/js-extend-gulp/src/webparts/extendGulp/ExtendGulp.module.scss b/samples/js-extend-gulp/src/webparts/extendGulp/ExtendGulp.module.scss new file mode 100644 index 000000000..1ed27277a --- /dev/null +++ b/samples/js-extend-gulp/src/webparts/extendGulp/ExtendGulp.module.scss @@ -0,0 +1,39 @@ +@import "~/office-ui-fabric-react/dist/sass/Fabric.Common"; + +.row { + @include ms-Grid-row; + @include ms-bgColor-themeDark; + @include ms-fontColor-white; + + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1); + max-width: 700px; + margin: 0 auto; + padding: 20px; +} + +.column { + @include ms-Grid-col; + @include ms-u-lg10; + @include ms-u-xl8; + @include ms-u-lgPush1; + @include ms-u-xlPush2; +} + +.title { + @include ms-font-xl; + @include ms-fontColor-white; +} + +.subtitle { + @include ms-font-l; + @include ms-fontColor-white; +} + +.description { + @include ms-font-l; + @include ms-fontColor-white; +} + +.button { + text-decoration: none; +} diff --git a/samples/js-extend-gulp/src/webparts/extendGulp/ExtendGulpWebPart.manifest.json b/samples/js-extend-gulp/src/webparts/extendGulp/ExtendGulpWebPart.manifest.json new file mode 100644 index 000000000..8fe5b3885 --- /dev/null +++ b/samples/js-extend-gulp/src/webparts/extendGulp/ExtendGulpWebPart.manifest.json @@ -0,0 +1,20 @@ +{ + "$schema": "../../../node_modules/@microsoft/sp-module-interfaces/lib/manifestSchemas/jsonSchemas/clientSideComponentManifestSchema.json", + + "id": "f05d025a-808f-4533-859d-47016c13235a", + "alias": "ExtendGulpWebPart", + "componentType": "WebPart", + "version": "0.0.1", + "manifestVersion": 2, + + "preconfiguredEntries": [{ + "groupId": "f05d025a-808f-4533-859d-47016c13235a", + "group": { "default": "Under Development" }, + "title": { "default": "ExtendGulp" }, + "description": { "default": "Extend gulp in SPFx toolchain" }, + "officeFabricIconFontName": "Page", + "properties": { + "description": "ExtendGulp" + } + }] +} diff --git a/samples/js-extend-gulp/src/webparts/extendGulp/ExtendGulpWebPart.ts b/samples/js-extend-gulp/src/webparts/extendGulp/ExtendGulpWebPart.ts new file mode 100644 index 000000000..406bf4b55 --- /dev/null +++ b/samples/js-extend-gulp/src/webparts/extendGulp/ExtendGulpWebPart.ts @@ -0,0 +1,62 @@ +import { Version } from '@microsoft/sp-core-library'; +import { + BaseClientSideWebPart, + IPropertyPaneConfiguration, + PropertyPaneTextField +} from '@microsoft/sp-webpart-base'; +import { escape } from '@microsoft/sp-lodash-subset'; + +import styles from './ExtendGulp.module.scss'; +import * as strings from 'extendGulpStrings'; +import { IExtendGulpWebPartProps } from './IExtendGulpWebPartProps'; + +export default class ExtendGulpWebPart extends BaseClientSideWebPart { + + public render(): void { + this.domElement.innerHTML = ` +
+
+ + Welcome to SharePoint! + +

+ Customize SharePoint experiences using Web Parts. +

+

+ ${escape(this.properties.description)} +

+ + + Learn more + + +
+
`; + } + + protected get dataVersion(): Version { + return Version.parse('1.0'); + } + + protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration { + return { + pages: [ + { + header: { + description: strings.PropertyPaneDescription + }, + groups: [ + { + groupName: strings.BasicGroupName, + groupFields: [ + PropertyPaneTextField('description', { + label: strings.DescriptionFieldLabel + }) + ] + } + ] + } + ] + }; + } +} diff --git a/samples/js-extend-gulp/src/webparts/extendGulp/IExtendGulpWebPartProps.ts b/samples/js-extend-gulp/src/webparts/extendGulp/IExtendGulpWebPartProps.ts new file mode 100644 index 000000000..c8a23ab5e --- /dev/null +++ b/samples/js-extend-gulp/src/webparts/extendGulp/IExtendGulpWebPartProps.ts @@ -0,0 +1,3 @@ +export interface IExtendGulpWebPartProps { + description: string; +} diff --git a/samples/js-extend-gulp/src/webparts/extendGulp/loc/en-us.js b/samples/js-extend-gulp/src/webparts/extendGulp/loc/en-us.js new file mode 100644 index 000000000..89f98bc1e --- /dev/null +++ b/samples/js-extend-gulp/src/webparts/extendGulp/loc/en-us.js @@ -0,0 +1,7 @@ +define([], function() { + return { + "PropertyPaneDescription": "Description", + "BasicGroupName": "Group Name", + "DescriptionFieldLabel": "Description Field" + } +}); \ No newline at end of file diff --git a/samples/js-extend-gulp/src/webparts/extendGulp/loc/mystrings.d.ts b/samples/js-extend-gulp/src/webparts/extendGulp/loc/mystrings.d.ts new file mode 100644 index 000000000..3abf590a4 --- /dev/null +++ b/samples/js-extend-gulp/src/webparts/extendGulp/loc/mystrings.d.ts @@ -0,0 +1,10 @@ +declare interface IExtendGulpStrings { + PropertyPaneDescription: string; + BasicGroupName: string; + DescriptionFieldLabel: string; +} + +declare module 'extendGulpStrings' { + const strings: IExtendGulpStrings; + export = strings; +} diff --git a/samples/js-extend-gulp/src/webparts/extendGulp/tests/ExtendGulp.test.ts b/samples/js-extend-gulp/src/webparts/extendGulp/tests/ExtendGulp.test.ts new file mode 100644 index 000000000..1ff1e8cab --- /dev/null +++ b/samples/js-extend-gulp/src/webparts/extendGulp/tests/ExtendGulp.test.ts @@ -0,0 +1,9 @@ +/// + +import { assert } from 'chai'; + +describe('ExtendGulpWebPart', () => { + it('should do something', () => { + assert.ok(true); + }); +}); diff --git a/samples/js-extend-gulp/tsconfig.json b/samples/js-extend-gulp/tsconfig.json new file mode 100644 index 000000000..dadbf6f8f --- /dev/null +++ b/samples/js-extend-gulp/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "es5", + "forceConsistentCasingInFileNames": true, + "module": "commonjs", + "jsx": "react", + "declaration": true, + "sourceMap": true, + "types": [ + "webpack-env" + ] + } +} diff --git a/samples/js-extend-gulp/typings/@ms/odsp.d.ts b/samples/js-extend-gulp/typings/@ms/odsp.d.ts new file mode 100644 index 000000000..077127131 --- /dev/null +++ b/samples/js-extend-gulp/typings/@ms/odsp.d.ts @@ -0,0 +1,5 @@ +// Type definitions for Microsoft ODSP projects +// Project: ODSP + +/* Global definition for UNIT_TEST builds */ +declare const UNIT_TEST: boolean; \ No newline at end of file diff --git a/samples/js-extend-gulp/typings/assertion-error/assertion-error.d.ts b/samples/js-extend-gulp/typings/assertion-error/assertion-error.d.ts new file mode 100644 index 000000000..08217c9e5 --- /dev/null +++ b/samples/js-extend-gulp/typings/assertion-error/assertion-error.d.ts @@ -0,0 +1,15 @@ +// Type definitions for assertion-error 1.0.0 +// Project: https://github.com/chaijs/assertion-error +// Definitions by: Bart van der Schoor +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +declare module 'assertion-error' { + class AssertionError implements Error { + constructor(message: string, props?: any, ssf?: Function); + name: string; + message: string; + showDiff: boolean; + stack: string; + } + export = AssertionError; +} diff --git a/samples/js-extend-gulp/typings/knockout/knockout.d.ts b/samples/js-extend-gulp/typings/knockout/knockout.d.ts new file mode 100644 index 000000000..267f3174c --- /dev/null +++ b/samples/js-extend-gulp/typings/knockout/knockout.d.ts @@ -0,0 +1,631 @@ +// Type definitions for Knockout v3.2.0 +// Project: http://knockoutjs.com +// Definitions by: Boris Yankov , Igor Oleinikov , Clément Bourgeois +// Definitions: https://github.com/borisyankov/DefinitelyTyped + + +interface KnockoutSubscribableFunctions { + [key: string]: KnockoutBindingHandler; + + notifySubscribers(valueToWrite?: T, event?: string): void; +} + +interface KnockoutComputedFunctions { + [key: string]: KnockoutBindingHandler; +} + +interface KnockoutObservableFunctions { + [key: string]: KnockoutBindingHandler; + + equalityComparer(a: any, b: any): boolean; +} + +interface KnockoutObservableArrayFunctions { + // General Array functions + indexOf(searchElement: T, fromIndex?: number): number; + slice(start: number, end?: number): T[]; + splice(start: number): T[]; + splice(start: number, deleteCount: number, ...items: T[]): T[]; + pop(): T; + push(...items: T[]): void; + shift(): T; + unshift(...items: T[]): number; + reverse(): KnockoutObservableArray; + sort(): KnockoutObservableArray; + sort(compareFunction: (left: T, right: T) => number): KnockoutObservableArray; + + // Ko specific + [key: string]: KnockoutBindingHandler; + + replace(oldItem: T, newItem: T): void; + + remove(item: T): T[]; + remove(removeFunction: (item: T) => boolean): T[]; + removeAll(items: T[]): T[]; + removeAll(): T[]; + + destroy(item: T): void; + destroy(destroyFunction: (item: T) => boolean): void; + destroyAll(items: T[]): void; + destroyAll(): void; +} + +interface KnockoutSubscribableStatic { + fn: KnockoutSubscribableFunctions; + + new (): KnockoutSubscribable; +} + +interface KnockoutSubscription { + dispose(): void; +} + +interface KnockoutSubscribable extends KnockoutSubscribableFunctions { + subscribe(callback: (newValue: T) => void, target?: any, event?: string): KnockoutSubscription; + subscribe(callback: (newValue: TEvent) => void, target: any, event: string): KnockoutSubscription; + extend(requestedExtenders: { [key: string]: any; }): KnockoutSubscribable; + getSubscriptionsCount(): number; +} + +interface KnockoutComputedStatic { + fn: KnockoutComputedFunctions; + + (): KnockoutComputed; + (func: () => T, context?: any, options?: any): KnockoutComputed; + (def: KnockoutComputedDefine, context?: any): KnockoutComputed; +} + +interface KnockoutComputed extends KnockoutObservable, KnockoutComputedFunctions { + fn: KnockoutComputedFunctions; + + dispose(): void; + isActive(): boolean; + getDependenciesCount(): number; + extend(requestedExtenders: { [key: string]: any; }): KnockoutComputed; +} + +interface KnockoutObservableArrayStatic { + fn: KnockoutObservableArrayFunctions; + + (value?: T[]): KnockoutObservableArray; +} + +interface KnockoutObservableArray extends KnockoutObservable, KnockoutObservableArrayFunctions { + extend(requestedExtenders: { [key: string]: any; }): KnockoutObservableArray; +} + +interface KnockoutObservableStatic { + fn: KnockoutObservableFunctions; + + (value?: T): KnockoutObservable; +} + +interface KnockoutObservable extends KnockoutSubscribable, KnockoutObservableFunctions { + (): T; + (value: T): void; + + peek(): T; + valueHasMutated?:{(): void;}; + valueWillMutate?:{(): void;}; + extend(requestedExtenders: { [key: string]: any; }): KnockoutObservable; +} + +interface KnockoutComputedDefine { + read(): T; + write? (value: T): void; + disposeWhenNodeIsRemoved?: Node; + disposeWhen? (): boolean; + owner?: any; + deferEvaluation?: boolean; + pure?: boolean; +} + +interface KnockoutBindingContext { + $parent: any; + $parents: any[]; + $root: any; + $data: any; + $rawData: any | KnockoutObservable; + $index?: KnockoutObservable; + $parentContext?: KnockoutBindingContext; + $component: any; + $componentTemplateNodes: Node[]; + + extend(properties: any): any; + createChildContext(dataItemOrAccessor: any, dataItemAlias?: any, extendCallback?: Function): any; +} + +interface KnockoutAllBindingsAccessor { + (): any; + get(name: string): any; + has(name: string): boolean; +} + +interface KnockoutBindingHandler { + after?: Array; + init?: (element: any, valueAccessor: () => any, allBindingsAccessor?: KnockoutAllBindingsAccessor, viewModel?: any, bindingContext?: KnockoutBindingContext) => void | { controlsDescendantBindings: boolean; }; + update?: (element: any, valueAccessor: () => any, allBindingsAccessor?: KnockoutAllBindingsAccessor, viewModel?: any, bindingContext?: KnockoutBindingContext) => void; + options?: any; + preprocess?: (value: string, name: string, addBindingCallback?: (name: string, value: string) => void) => string; +} + +interface KnockoutBindingHandlers { + [bindingHandler: string]: KnockoutBindingHandler; + + // Controlling text and appearance + visible: KnockoutBindingHandler; + text: KnockoutBindingHandler; + html: KnockoutBindingHandler; + css: KnockoutBindingHandler; + style: KnockoutBindingHandler; + attr: KnockoutBindingHandler; + + // Control Flow + foreach: KnockoutBindingHandler; + if: KnockoutBindingHandler; + ifnot: KnockoutBindingHandler; + with: KnockoutBindingHandler; + + // Working with form fields + click: KnockoutBindingHandler; + event: KnockoutBindingHandler; + submit: KnockoutBindingHandler; + enable: KnockoutBindingHandler; + disable: KnockoutBindingHandler; + value: KnockoutBindingHandler; + textInput: KnockoutBindingHandler; + hasfocus: KnockoutBindingHandler; + checked: KnockoutBindingHandler; + options: KnockoutBindingHandler; + selectedOptions: KnockoutBindingHandler; + uniqueName: KnockoutBindingHandler; + + // Rendering templates + template: KnockoutBindingHandler; + + // Components (new for v3.2) + component: KnockoutBindingHandler; +} + +interface KnockoutMemoization { + memoize(callback: () => string): string; + unmemoize(memoId: string, callbackParams: any[]): boolean; + unmemoizeDomNodeAndDescendants(domNode: any, extraCallbackParamsArray: any[]): boolean; + parseMemoText(memoText: string): string; +} + +interface KnockoutVirtualElement {} + +interface KnockoutVirtualElements { + allowedBindings: { [bindingName: string]: boolean; }; + emptyNode(node: KnockoutVirtualElement ): void; + firstChild(node: KnockoutVirtualElement ): KnockoutVirtualElement; + insertAfter( container: KnockoutVirtualElement, nodeToInsert: Node, insertAfter: Node ): void; + nextSibling(node: KnockoutVirtualElement): Node; + prepend(node: KnockoutVirtualElement, toInsert: Node ): void; + setDomNodeChildren(node: KnockoutVirtualElement, newChildren: { length: number;[index: number]: Node; } ): void; + childNodes(node: KnockoutVirtualElement ): Node[]; +} + +interface KnockoutExtenders { + throttle(target: any, timeout: number): KnockoutComputed; + notify(target: any, notifyWhen: string): any; + + rateLimit(target: any, timeout: number): any; + rateLimit(target: any, options: { timeout: number; method?: string; }): any; + + trackArrayChanges(target: any): any; +} + +// +// NOTE TO MAINTAINERS AND CONTRIBUTORS : pay attention to only include symbols that are +// publicly exported in the minified version of ko, without that you can give the false +// impression that some functions will be available in production builds. +// +interface KnockoutUtils { + ////////////////////////////////// + // utils.domData.js + ////////////////////////////////// + + domData: { + get (node: Element, key: string): any; + + set (node: Element, key: string, value: any): void; + + getAll(node: Element, createIfNotFound: boolean): any; + + clear(node: Element): boolean; + }; + + ////////////////////////////////// + // utils.domNodeDisposal.js + ////////////////////////////////// + + domNodeDisposal: { + addDisposeCallback(node: Element, callback: Function): void; + + removeDisposeCallback(node: Element, callback: Function): void; + + cleanNode(node: Node): Element; + + removeNode(node: Node): void; + }; + + addOrRemoveItem(array: T[] | KnockoutObservable, value: T, included: T): void; + + arrayFilter(array: T[], predicate: (item: T) => boolean): T[]; + + arrayFirst(array: T[], predicate: (item: T) => boolean, predicateOwner?: any): T; + + arrayForEach(array: T[], action: (item: T, index: number) => void): void; + + arrayGetDistinctValues(array: T[]): T[]; + + arrayIndexOf(array: T[], item: T): number; + + arrayMap(array: T[], mapping: (item: T) => U): U[]; + + arrayPushAll(array: T[] | KnockoutObservableArray, valuesToPush: T[]): T[]; + + arrayRemoveItem(array: any[], itemToRemove: any): void; + + compareArrays(a: T[], b: T[]): Array>; + + extend(target: Object, source: Object): Object; + + fieldsIncludedWithJsonPost: any[]; + + getFormFields(form: any, fieldName: string): any[]; + + objectForEach(obj: any, action: (key: any, value: any) => void): void; + + parseHtmlFragment(html: string): any[]; + + parseJson(jsonString: string): any; + + postJson(urlOrForm: any, data: any, options: any): void; + + peekObservable(value: KnockoutObservable): T; + + range(min: any, max: any): any; + + registerEventHandler(element: any, eventType: any, handler: Function): void; + + setHtml(node: Element, html: () => string): void; + + setHtml(node: Element, html: string): void; + + setTextContent(element: any, textContent: string | KnockoutObservable): void; + + stringifyJson(data: any, replacer?: Function, space?: string): string; + + toggleDomNodeCssClass(node: any, className: string, shouldHaveClass: boolean): void; + + triggerEvent(element: any, eventType: any): void; + + unwrapObservable(value: KnockoutObservable | T): T; + + // NOT PART OF THE MINIFIED API SURFACE (ONLY IN knockout-{version}.debug.js) https://github.com/SteveSanderson/knockout/issues/670 + // forceRefresh(node: any): void; + // ieVersion: number; + // isIe6: boolean; + // isIe7: boolean; + // jQueryHtmlParse(html: string): any[]; + // makeArray(arrayLikeObject: any): any[]; + // moveCleanedNodesToContainerElement(nodes: any[]): HTMLElement; + // replaceDomNodes(nodeToReplaceOrNodeArray: any, newNodesArray: any[]): void; + // setDomNodeChildren(domNode: any, childNodes: any[]): void; + // setElementName(element: any, name: string): void; + // setOptionNodeSelectionState(optionNode: any, isSelected: boolean): void; + // simpleHtmlParse(html: string): any[]; + // stringStartsWith(str: string, startsWith: string): boolean; + // stringTokenize(str: string, delimiter: string): string[]; + // stringTrim(str: string): string; + // tagNameLower(element: any): string; +} + +interface KnockoutArrayChange { + status: string; + value: T; + index: number; + moved?: number; +} + +////////////////////////////////// +// templateSources.js +////////////////////////////////// + +interface KnockoutTemplateSourcesDomElement { + text(): any; + text(value: any): void; + + data(key: string): any; + data(key: string, value: any): any; +} + +interface KnockoutTemplateAnonymous extends KnockoutTemplateSourcesDomElement { + nodes(): any; + nodes(value: any): void; +} + +interface KnockoutTemplateSources { + + domElement: { + prototype: KnockoutTemplateSourcesDomElement + new (element: Element): KnockoutTemplateSourcesDomElement + }; + + anonymousTemplate: { + prototype: KnockoutTemplateAnonymous; + new (element: Element): KnockoutTemplateAnonymous; + }; +} + +////////////////////////////////// +// nativeTemplateEngine.js +////////////////////////////////// + +interface KnockoutNativeTemplateEngine { + + renderTemplateSource(templateSource: Object, bindingContext?: KnockoutBindingContext, options?: Object): any[]; +} + +////////////////////////////////// +// templateEngine.js +////////////////////////////////// + +interface KnockoutTemplateEngine extends KnockoutNativeTemplateEngine { + + createJavaScriptEvaluatorBlock(script: string): string; + + makeTemplateSource(template: any, templateDocument?: Document): any; + + renderTemplate(template: any, bindingContext: KnockoutBindingContext, options: Object, templateDocument: Document): any; + + isTemplateRewritten(template: any, templateDocument: Document): boolean; + + rewriteTemplate(template: any, rewriterCallback: Function, templateDocument: Document): void; +} + +///////////////////////////////// + +interface KnockoutStatic { + utils: KnockoutUtils; + memoization: KnockoutMemoization; + + bindingHandlers: KnockoutBindingHandlers; + getBindingHandler(handler: string): KnockoutBindingHandler; + + virtualElements: KnockoutVirtualElements; + extenders: KnockoutExtenders; + + applyBindings(viewModelOrBindingContext?: any, rootNode?: any): void; + applyBindingsToDescendants(viewModelOrBindingContext: any, rootNode: any): void; + applyBindingAccessorsToNode(node: Node, bindings: (bindingContext: KnockoutBindingContext, node: Node) => {}, bindingContext: KnockoutBindingContext): void; + applyBindingAccessorsToNode(node: Node, bindings: {}, bindingContext: KnockoutBindingContext): void; + applyBindingAccessorsToNode(node: Node, bindings: (bindingContext: KnockoutBindingContext, node: Node) => {}, viewModel: any): void; + applyBindingAccessorsToNode(node: Node, bindings: {}, viewModel: any): void; + applyBindingsToNode(node: Node, bindings: any, viewModelOrBindingContext?: any): any; + + subscribable: KnockoutSubscribableStatic; + observable: KnockoutObservableStatic; + + computed: KnockoutComputedStatic; + pureComputed(evaluatorFunction: () => T, context?: any): KnockoutComputed; + pureComputed(options: KnockoutComputedDefine, context?: any): KnockoutComputed; + + observableArray: KnockoutObservableArrayStatic; + + contextFor(node: any): any; + isSubscribable(instance: any): boolean; + toJSON(viewModel: any, replacer?: Function, space?: any): string; + toJS(viewModel: any): any; + isObservable(instance: any): boolean; + isWriteableObservable(instance: any): boolean; + isComputed(instance: any): boolean; + dataFor(node: any): any; + removeNode(node: Element): void; + cleanNode(node: Element): Element; + renderTemplate(template: Function, viewModel: any, options?: any, target?: any, renderMode?: any): any; + renderTemplate(template: string, viewModel: any, options?: any, target?: any, renderMode?: any): any; + unwrap(value: KnockoutObservable | T): T; + + computedContext: KnockoutComputedContext; + + ////////////////////////////////// + // templateSources.js + ////////////////////////////////// + + templateSources: KnockoutTemplateSources; + + ////////////////////////////////// + // templateEngine.js + ////////////////////////////////// + + templateEngine: { + + prototype: KnockoutTemplateEngine; + + new (): KnockoutTemplateEngine; + }; + + ////////////////////////////////// + // templateRewriting.js + ////////////////////////////////// + + templateRewriting: { + + ensureTemplateIsRewritten(template: Node, templateEngine: KnockoutTemplateEngine, templateDocument: Document): any; + ensureTemplateIsRewritten(template: string, templateEngine: KnockoutTemplateEngine, templateDocument: Document): any; + + memoizeBindingAttributeSyntax(htmlString: string, templateEngine: KnockoutTemplateEngine): any; + + applyMemoizedBindingsToNextSibling(bindings: any, nodeName: string): string; + }; + + ////////////////////////////////// + // nativeTemplateEngine.js + ////////////////////////////////// + + nativeTemplateEngine: { + + prototype: KnockoutNativeTemplateEngine; + + new (): KnockoutNativeTemplateEngine; + + instance: KnockoutNativeTemplateEngine; + }; + + ////////////////////////////////// + // jqueryTmplTemplateEngine.js + ////////////////////////////////// + + jqueryTmplTemplateEngine: { + + prototype: KnockoutTemplateEngine; + + renderTemplateSource(templateSource: Object, bindingContext: KnockoutBindingContext, options: Object): Node[]; + + createJavaScriptEvaluatorBlock(script: string): string; + + addTemplate(templateName: string, templateMarkup: string): void; + }; + + ////////////////////////////////// + // templating.js + ////////////////////////////////// + + setTemplateEngine(templateEngine: KnockoutNativeTemplateEngine): void; + + renderTemplate(template: Function, dataOrBindingContext: KnockoutBindingContext, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any; + renderTemplate(template: any, dataOrBindingContext: KnockoutBindingContext, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any; + renderTemplate(template: Function, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any; + renderTemplate(template: any, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any; + renderTemplate(template: Function, dataOrBindingContext: KnockoutBindingContext, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any; + renderTemplate(template: any, dataOrBindingContext: KnockoutBindingContext, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any; + renderTemplate(template: Function, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any; + renderTemplate(template: any, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any; + + renderTemplateForEach(template: Function, arrayOrObservableArray: any[], options: Object, targetNode: Node, parentBindingContext: KnockoutBindingContext): any; + renderTemplateForEach(template: any, arrayOrObservableArray: any[], options: Object, targetNode: Node, parentBindingContext: KnockoutBindingContext): any; + renderTemplateForEach(template: Function, arrayOrObservableArray: KnockoutObservable, options: Object, targetNode: Node, parentBindingContext: KnockoutBindingContext): any; + renderTemplateForEach(template: any, arrayOrObservableArray: KnockoutObservable, options: Object, targetNode: Node, parentBindingContext: KnockoutBindingContext): any; + + expressionRewriting: { + bindingRewriteValidators: any; + parseObjectLiteral: { (objectLiteralString: string): any[] } + }; + + ///////////////////////////////// + + bindingProvider: { + instance: KnockoutBindingProvider; + new (): KnockoutBindingProvider; + } + + ///////////////////////////////// + // selectExtensions.js + ///////////////////////////////// + + selectExtensions: { + + readValue(element: HTMLElement): any; + + writeValue(element: HTMLElement, value: any): void; + }; + + components: KnockoutComponents; +} + +interface KnockoutBindingProvider { + nodeHasBindings(node: Node): boolean; + getBindings(node: Node, bindingContext: KnockoutBindingContext): {}; + getBindingAccessors?(node: Node, bindingContext: KnockoutBindingContext): { [key: string]: string; }; +} + +interface KnockoutComputedContext { + getDependenciesCount(): number; + isInitial: () => boolean; + isSleeping: boolean; +} + +// +// refactored types into a namespace to reduce global pollution +// and used Union Types to simplify overloads (requires TypeScript 1.4) +// +declare module KnockoutComponentTypes { + + interface Config { + viewModel?: ViewModelFunction | ViewModelSharedInstance | ViewModelFactoryFunction | AMDModule; + template: string | Node[]| DocumentFragment | TemplateElement | AMDModule; + synchronous?: boolean; + } + + interface ComponentConfig { + viewModel?: ViewModelFunction | ViewModelSharedInstance | ViewModelFactoryFunction | AMDModule; + template: any; + createViewModel?: any; + } + + interface EmptyConfig { + } + + // common AMD type + interface AMDModule { + require: string; + } + + // viewmodel types + interface ViewModelFunction { + (params?: any): any; + } + + interface ViewModelSharedInstance { + instance: any; + } + + interface ViewModelFactoryFunction { + createViewModel: (params?: any, componentInfo?: ComponentInfo) => any; + } + + interface ComponentInfo { + element: Node; + templateNodes: Node[]; + } + + interface TemplateElement { + element: string | Node; + } + + interface Loader { + getConfig? (componentName: string, callback: (result: ComponentConfig) => void): void; + loadComponent? (componentName: string, config: ComponentConfig, callback: (result: Definition) => void): void; + loadTemplate? (componentName: string, templateConfig: any, callback: (result: Node[]) => void): void; + loadViewModel? (componentName: string, viewModelConfig: any, callback: (result: any) => void): void; + suppressLoaderExceptions?: boolean; + } + + interface Definition { + template: Node[]; + createViewModel? (params: any, options: { element: Node; }): any; + } +} + +interface KnockoutComponents { + // overloads for register method: + register(componentName: string, config: KnockoutComponentTypes.Config | KnockoutComponentTypes.EmptyConfig): void; + + isRegistered(componentName: string): boolean; + unregister(componentName: string): void; + get(componentName: string, callback: (definition: KnockoutComponentTypes.Definition) => void): void; + clearCachedDefinition(componentName: string): void + defaultLoader: KnockoutComponentTypes.Loader; + loaders: KnockoutComponentTypes.Loader[]; + getComponentNameForNode(node: Node): string; +} + +declare var ko: KnockoutStatic; + +declare module "knockout" { + export = ko; +} diff --git a/samples/js-extend-gulp/typings/tsd.d.ts b/samples/js-extend-gulp/typings/tsd.d.ts new file mode 100644 index 000000000..151048618 --- /dev/null +++ b/samples/js-extend-gulp/typings/tsd.d.ts @@ -0,0 +1,3 @@ +/// +/// +///