diff --git a/.gitignore b/.gitignore index 78d41c3..b586efa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,9 @@ bower_components/ .idea/ node_modules -*.iml \ No newline at end of file +*.iml +typings/ +*.map +*.js +src/*.js +.tscache/ diff --git a/Gruntfile.js b/Gruntfile.js index 5fb5ea4..9448ac5 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,39 +1,59 @@ -module.exports = function(grunt) { +module.exports = function (grunt) { grunt.loadNpmTasks('grunt-contrib-connect'); + grunt.loadNpmTasks("grunt-tslint"); + grunt.loadNpmTasks('grunt-ts'); // Project configuration. grunt.initConfig({ connect: { server: { options: { - port: 8000, - base: '.', - keepalive: true + port: 8000, + base: '.', + keepalive: true } } }, pkg: grunt.file.readJSON('package.json'), + ts: { + default: { + src: ["src/**/*.ts", "!node_modules/**"], + options: { + module: "amd", + moduleResolution: "node", + declaration: true, + compiler: './node_modules/typescript/bin/tsc' + }, + tsconfig: 'tsconfig.json', + } + }, uglify: { options: { banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %> */\n', sourceMap: true }, build: { - src: 'src/angular-intro.js', + src: ['src/ng-intro.component.js'], dest: 'build/angular-intro.min.js' } }, - jshint: { - lib: { - options: {}, - src: ['src/*.js'] + tslint: { + options: { + configuration: "tslint.json", + force: false, + fix: false + }, + files: { + src: [ + "src/ng-intro.component.ts" + ] } }, watch: { scripts: { - files: 'src/*.js', - tasks: ['jshint', 'uglify'], + files: 'src/*.ts', + tasks: ['ts', 'tslint', 'uglify'], options: { interrupt: true } @@ -48,8 +68,8 @@ module.exports = function(grunt) { require('load-grunt-tasks')(grunt); // Default task(s). - grunt.registerTask('default', ['jshint', 'uglify']); + grunt.registerTask('default', ['ts', 'tslint', 'uglify']); // Test - grunt.registerTask('test', ['jshint']); + grunt.registerTask('test', ['tslint']); }; diff --git a/README.md b/README.md index 01fcdfd..8607717 100644 --- a/README.md +++ b/README.md @@ -133,15 +133,14 @@ alternatively as Service, [as shown here](http://plnkr.co/edit/4JdONL) If you want to build or contribute, first, get the node modules needed (grunt, bower) - npm install + npm install + p.s.: this will run `bower install` after completes :) -Next, use bower to get the JS libraries needed - node_modules/.bin/bower install +Then, get grunt to build the typescript into .js and the minified angular-intro.min.js -Then, whenever you make any changes, get grunt to build the minified angular-intro.min.js - - node_modules/.bin/grunt + node_modules/.bin/grunt watch + p.s.: for faster build use `tsc --watch`, but you need run grunt after finish Finally, view the demo page to make sure everything's working; start a web server: @@ -151,7 +150,6 @@ And browse to `http://localhost:8000/example/index.html` - ## License Same as intro.js, this is [AGPL](LICENSE) diff --git a/build/angular-intro.min.js b/build/angular-intro.min.js index 2490f20..5560621 100644 --- a/build/angular-intro.min.js +++ b/build/angular-intro.min.js @@ -1,4 +1,4 @@ -/*! angular-intro.js - v3.1.3 - 2017-03-16 */ +/*! angular-intro.js - v3.2.0 - 2017-03-25 */ -!function(a,b){"function"==typeof define&&define.amd?define(["angular","intro.js"],b):"object"==typeof exports?module.exports=b(require("angular"),require("intro.js")):a.angularIntroJs=b(a.angular,a.introJs)}(this,function(a,b){function c(){this.message="Intro.js is not available. Make sure it is properly loaded.",this.name="IntroJsNotAvailable"}"object"==typeof b&&(b=b.introJs);var d=a.module("angular-intro",[]);return d.factory("ngIntroService",["$q",function(d){function e(b,c){a.isFunction(c)&&(B[b]=c)}function f(a){delete B[a]}function g(a){A.setOptions(a)}function h(a){"number"==typeof a?A.start().goToStep(a):A.start(),i("open")}function i(b){for(var c in B)B.hasOwnProperty(c)&&a.isFunction(B[c])&&B[c](b)}function j(){A.exit(),i("closed")}function k(){A.previousStep(),i("open")}function l(){A.nextStep(),i("open")}function m(){A.refresh()}function n(b){return A.oncomplete(function(){a.isFunction(b)&&b(),i("closed")})}function o(b){return A.onbeforechange(function(c){a.isFunction(b)&&b(c)})}function p(b){return A.onchange(function(c){a.isFunction(b)&&b(c)})}function q(c){return"undefined"!=typeof A&&A.exit(),A=new b,i("closed"),a.isFunction(c)&&c(),A}function r(b){return A.onafterchange(function(c){a.isFunction(b)&&b(c)})}function s(b){return A.onexit(function(){i("closed"),a.isFunction(b)&&b()})}function t(){return A.addHints()}function u(){return A.showHints()}function v(a){return A.hideHint(a)}function w(){return A.hideHints()}function x(b){A.onhintclick(function(){a.isFunction(b)&&b()})}function y(b){return A.onhintclose(function(){a.isFunction(b)&&b()})}function z(b){return A.onhintclose(function(){a.isFunction(b)&&b()})}if("function"!=typeof b)throw new c;var A,B={},C={addListener:e,removeListener:f,setOptions:g,start:h,exit:j,clear:q,previous:k,next:l,refresh:m,onComplete:n,onExit:s,onBeforeChange:o,onAfterChange:r,onChange:p,addHints:t,showHints:u,hideHint:v,hideHints:w,onHintClick:x,onHintClose:y,onHintsAdded:z};return Object.defineProperty(C,"intro",{get:function(){return A},enumerable:!0,configurable:!0}),q(),C}]).directive("ngIntroDisableButton",["ngIntroService","$compile",function(a,b){var c=0;return{restrict:"A",priority:1,scope:{introDisableButton:"="},link:function(b,d,e){var f="disabledBtn"+c++;a.addListener(f,function(a){"open"===a?e.$set("disabled","disabled"):(delete e.disabled,d.removeAttr("disabled"))}),b.$on("$destroy",function(){a.removeListener(f)})}}}]).directive("ngIntroOptions",["$timeout","ngIntroService",function(b,c){return{restrict:"A",scope:{ngIntroMethod:"=",ngIntroExitMethod:"=?",ngIntroNextMethod:"=?",ngIntroPreviousMethod:"=?",ngIntroRefreshMethod:"=?",ngIntroOptions:"=",ngIntroOncomplete:"=",ngIntroOnexit:"=",ngIntroOnchange:"=",ngIntroOnbeforechange:"=",ngIntroOnafterchange:"=",ngIntroAutostart:"=",ngIntroAutorefresh:"=",ngIntroHintsMethod:"=?",ngIntroOnhintsadded:"=",ngIntroOnhintclick:"=?",ngIntroOnhintclose:"=?",ngIntroShowHint:"=?",ngIntroShowHints:"=?",ngIntroHideHint:"=?",ngIntroHideHints:"=?"},link:function(d,e,f){function g(){for(var a=0;a>h.length;a++)h[a]()}var h=[];d.ngIntroOncomplete&&c.onComplete(d.ngIntroOncomplete),d.ngIntroOnexit&&c.onExit(d.ngIntroOnexit),d.ngIntroOnbeforechange&&c.onBeforeChange(d.ngIntroOnbeforechange),d.ngIntroOnchange&&c.onChange(d.ngIntroOnchange),d.ngIntroOnafterchange&&c.onAfterChange(d.ngIntroOnafterchange),d.ngIntroMethod=function(a){c.setOptions(d.ngIntroOptions),c.start(a)},d.ngIntroHintsMethod=function(){c.setOptions(d.ngIntroOptions),c.start(step),d.ngIntroOnhintsadded&&c.onHintsAdded(d.ngIntroOnbeforechange),d.ngIntroOnhintclick&&c.onHintClick(d.ngIntroOnbeforechange),d.ngIntroOnhintclose&&c.onHintClick(d.ngIntroOnbeforechange),intro.addHints()},d.ngIntroShowHint=function(a){c.showHint(a)},d.ngIntroShowHints=function(){c.showHints()},d.ngIntroHideHint=function(a){c.hideHint(a)},d.ngIntroHideHints=function(){c.hideHints()},d.ngIntroNextMethod=function(){c.next()},d.ngIntroPreviousMethod=function(){c.previous()},d.ngIntroExitMethod=function(b){c.exit(),a.isFunction(b)&&b()},d.ngIntroRefreshMethod=function(){c.refresh()};var i=d.$watch("ngIntroAutostart",function(){d.ngIntroAutostart&&b(function(){d.ngIntroMethod()}),i()});h.push(d.$on("$locationChangeStart",function(){c.exit()})),h.push(d.$on("$locationChangeSuccess",function(){c.exit()})),d.ngIntroAutorefresh&&h.push(d.$watch(function(){c.refresh()})),h.push(d.$on("$destroy",function(){c.exit()})),d.$on("$destroy",function(){g()})}}}]),d}); +!function(a,b){"function"==typeof window.define&&window.define.amd?window.define(["angular","intro.js"],b):"object"==typeof window.exports?window.module.exports=b(window.require("angular"),window.require("intro.js")):a.angularIntroJs=b(a.angular,a.introJs)}(this,function(a,b){var c={open:"open",closed:"closed"},d="angular-intro",e={},f=function(){function d(){this.intro=b()}return d.prototype.addListener=function(b,c){a.isFunction(c)&&(e[b]=c)},d.prototype.removeListener=function(a){delete e[a]},d.prototype.notifyListeners=function(b){for(var c in e)e.hasOwnProperty(c)&&a.isFunction(e[c])&&e[c](b)},d.prototype.setOptions=function(a){return this.intro.setOptions(a)},d.prototype.start=function(a){return"number"==typeof a?this.intro.start().goToStep(a):this.intro.start(),this.notifyListeners(c.open),this.intro},d.prototype.exit=function(){return this.notifyListeners(c.closed),this.intro.exit()},d.prototype.clear=function(d){return"undefined"!=typeof this.intro&&this.intro.exit(),this.intro=b(),this.notifyListeners(c.closed),a.isFunction(d)&&d(),this.intro},d.prototype.addHints=function(){return this.intro.addHints()},d.prototype.showHint=function(a){return this.intro.showHint(a)},d.prototype.showHints=function(){return this.intro.showHints()},d.prototype.hideHint=function(a){return this.intro.hideHint(a)},d.prototype.hideHints=function(){return this.intro.hideHints()},d.prototype.previous=function(){return this.notifyListeners(c.open),this.intro.previousStep()},d.prototype.next=function(){return this.notifyListeners(c.open),this.intro.nextStep()},d.prototype.refresh=function(){return this.intro.refresh()},d.prototype.onComplete=function(b){var d=this;return this.intro.oncomplete(function(){a.isFunction(b)&&b(),d.notifyListeners(c.closed)})},d.prototype.onExit=function(b){var d=this;return this.intro.onexit(function(){d.notifyListeners(c.closed),a.isFunction(b)&&b()})},d.prototype.onBeforeChange=function(b){return this.intro.onbeforechange(function(c){a.isFunction(b)&&b(c)})},d.prototype.onChange=function(b){return this.intro.onchange(function(c){a.isFunction(b)&&b(c)})},d.prototype.onAfterChange=function(b){return this.intro.onafterchange(function(c){a.isFunction(b)&&b(c)})},d.prototype.onHintClick=function(b){return this.intro.onhintclick(function(){a.isFunction(b)&&b()})},d.prototype.onHintClose=function(b){return this.intro.onhintclose(function(){a.isFunction(b)&&b()})},d.prototype.onHintsAdded=function(b){return this.intro.onhintclose(function(){a.isFunction(b)&&b()})},d}(),g=function(){function b(b,c){var d=this;this.restrict="A",this.scope={ngIntroMethod:"=",ngIntroExitMethod:"=?",ngIntroNextMethod:"=?",ngIntroPreviousMethod:"=?",ngIntroRefreshMethod:"=?",ngIntroOptions:"=",ngIntroOncomplete:"=",ngIntroOnexit:"=",ngIntroOnchange:"=",ngIntroOnbeforechange:"=",ngIntroOnafterchange:"=",ngIntroAutostart:"=",ngIntroAutorefresh:"=",ngIntroHintsMethod:"=?",ngIntroOnhintsadded:"=",ngIntroOnhintclick:"=?",ngIntroOnhintclose:"=?",ngIntroShowHint:"=?",ngIntroShowHints:"=?",ngIntroHideHint:"=?",ngIntroHideHints:"=?"},this.destroy=[],this.link=function(e,f,g){function h(){for(var a=0,b=this.destroy;a +declare namespace ngIntroJs { + interface INgIntroService { + intro: IntroJs.IntroJs; + addListener(name: string, callback: Function): void; + removeListener(name: string): void; + setOptions: IntroJs.Options; + start(stepId?: number): IntroJs.IntroJs; + exit(): IntroJs.IntroJs; + clear(callback: Function): IntroJs.IntroJs; + addHints(): IntroJs.IntroJs; + showHint(hintIdx: number): IntroJs.IntroJs; + showHints(): IntroJs.IntroJs; + hideHint(hintIdx: number): IntroJs.IntroJs; + hideHints(): IntroJs.IntroJs; + previous(): IntroJs.IntroJs; + next(): IntroJs.IntroJs; + refresh(): IntroJs.IntroJs; + onComplete(callback: Function): void; + onExit(callback: Function): void; + onBeforeChange(callback: Function): void; + onAfterChange(callback: Function): void; + onChange(callback: Function): void; + onHintClick(callback: Function): void; + onHintClose(callback: Function): void; + onHintsAdded(callback: Function): void; + } + interface INgIntroDirectiveScope extends ng.IScope { + ngIntroMethod(step?: number): void; + ngIntroExitMethod(cb?: Function): void; + ngIntroNextMethod(): void; + ngIntroPreviousMethod(): void; + ngIntroRefreshMethod(): void; + ngIntroOptions(): void; + ngIntroOncomplete(): void; + ngIntroOnexit(): void; + ngIntroOnchange(): void; + ngIntroOnbeforechange(): void; + ngIntroOnafterchange(): void; + ngIntroAutostart(): void; + ngIntroAutorefresh(): void; + ngIntroHintsMethod(): void; + ngIntroOnhintsadded(): void; + ngIntroOnhintclick(): void; + ngIntroOnhintclose(): void; + ngIntroShowHint(id: number): void; + ngIntroShowHints(): void; + ngIntroHideHint(id: number): void; + ngIntroHideHints(): void; + } + interface NotifyItem { + [name: string]: Function; + } +} diff --git a/example/app.js b/example/app.js index f15b54d..e1bbd08 100644 --- a/example/app.js +++ b/example/app.js @@ -124,4 +124,4 @@ app.controller('MyController', function ($scope,ngIntroService) { }) } }; -}); \ No newline at end of file +}); diff --git a/example/index.html b/example/index.html index f5deb1c..8224316 100644 --- a/example/index.html +++ b/example/index.html @@ -111,7 +111,7 @@

Ex - + diff --git a/package.json b/package.json index b09de99..d16b864 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,15 @@ { "name": "angular-intro.js", - "version": "3.1.3", + "version": "3.2.0", "description": "Angular directive to wrap intro.js", "main": "src/angular-intro.js", + "types": "build/ng-intro.component.d.ts", "directories": { "example": "example" }, "scripts": { - "test": "grunt test" + "test": "grunt test", + "postinstall": "./node_modules/.bin/bower install" }, "repository": { "type": "git", @@ -32,6 +34,15 @@ "grunt-contrib-jshint": "~1.0.0", "grunt-contrib-uglify": "~2.0.0", "grunt-contrib-watch": "~1.0.0", + "grunt-tslint": "^4.0.1", "load-grunt-tasks": "~3.5.2" + }, + "dependencies": { + "@types/angular": "^1.6.7", + "@types/intro.js": "^2.4.0", + "grunt-ts": "^6.0.0-beta.11", + "grunt-tslint": "^4.0.1", + "tslint": "^4.5.1", + "typescript": "^2.2.1" } } diff --git a/src/angular-intro.js b/src/[deprectable]angular-intro.js similarity index 100% rename from src/angular-intro.js rename to src/[deprectable]angular-intro.js diff --git a/src/ng-intro.component.ts b/src/ng-intro.component.ts new file mode 100644 index 0000000..8501da4 --- /dev/null +++ b/src/ng-intro.component.ts @@ -0,0 +1,401 @@ +namespace ngIntroJs { + export interface INgIntroService { + intro: IntroJs.IntroJs, + addListener(name: string, callback: Function): void + removeListener(name: string): void + setOptions: IntroJs.Options, + start(stepId?: number): IntroJs.IntroJs, + exit(): IntroJs.IntroJs, + clear(callback: Function): IntroJs.IntroJs, + + addHints(): IntroJs.IntroJs, + showHint(hintIdx: number): IntroJs.IntroJs, + showHints(): IntroJs.IntroJs, + hideHint(hintIdx: number): IntroJs.IntroJs, + hideHints(): IntroJs.IntroJs + + previous(): IntroJs.IntroJs, + next(): IntroJs.IntroJs, + + refresh(): IntroJs.IntroJs, + + onComplete(callback: Function): void + onExit(callback: Function): void + onBeforeChange(callback: Function): void + onAfterChange(callback: Function): void + onChange(callback: Function): void + onHintClick(callback: Function): void + onHintClose(callback: Function): void + onHintsAdded(callback: Function): void + } + export interface INgIntroDirectiveScope extends ng.IScope { + ngIntroMethod(step?: number): void + ngIntroExitMethod(cb?: Function): void + ngIntroNextMethod(): void + ngIntroPreviousMethod(): void + ngIntroRefreshMethod(): void + ngIntroOptions(): void + ngIntroOncomplete(): void + ngIntroOnexit(): void + ngIntroOnchange(): void + ngIntroOnbeforechange(): void + ngIntroOnafterchange(): void + ngIntroAutostart(): void + ngIntroAutorefresh(): void + + ngIntroHintsMethod(): void + ngIntroOnhintsadded(): void + ngIntroOnhintclick(): void + ngIntroOnhintclose(): void + ngIntroShowHint(id: number): void + ngIntroShowHints(): void + ngIntroHideHint(id: number): void + ngIntroHideHints(): void + } + export interface NotifyItem { + [name: string]: Function + } +} +(function (root, factory) { + // this is our custom loader + if (typeof (window).define === "function" && (window).define.amd) { + (window).define(["angular", "introJs"], factory); + } else if (typeof (window).exports === "object") { + (window).module.exports = factory((window).require("angular"), (window).require("introJs")); + } else { + root.angularIntroJs = factory(root.angular, root.introJs); + } +}(this, function (angular: ng.IAngularStatic, introJs: IntroJs.Factory) { + + let introStatus = { // i wanted to use enums, but for now it"ll work + open: "open", + closed: "closed" + } + let moduleName = "angular-intro"; + + + let notifyList: ngIntroJs.NotifyItem = {} // this is an objects that holds the current listeners. + ///when the intro opens or closes it"ll iterate through this list calling the callback; + + class NgIntroService implements ngIntroJs.INgIntroService { + public intro: IntroJs.IntroJs + // static $inject = [] + + constructor() { + this.intro = introJs(); + } + + /// adds into notifyList, if there"s a valid callback. + addListener(name: string, cb: Function) { + if (angular.isFunction(cb)) + notifyList[name] = cb; + } + // remove from notifyList. + removeListener(name: string) { + delete notifyList[name]; + } + + ///iterate through notifyList and call each callback. + private notifyListeners(status: string) { + for (let key in notifyList) { + if (notifyList.hasOwnProperty(key)) { + if (angular.isFunction(notifyList[key])) + notifyList[key](status); + } + } + } + + setOptions(options: IntroJs.Options) { + return this.intro.setOptions(options); + } + + start(step?: number) { + if (typeof (step) === "number") { + this.intro.start().goToStep(step); + } else { + this.intro.start(); + } + this.notifyListeners(introStatus.open); + + return this.intro; + } + + exit() { + this.notifyListeners(introStatus.closed); + return this.intro.exit(); + } + + clear(cb: Function) { + if (typeof (this.intro) !== "undefined") + this.intro.exit(); + + this.intro = introJs(); + + this.notifyListeners(introStatus.closed); + + if (angular.isFunction(cb)) cb(); + + return this.intro; + } + + addHints() { + return this.intro.addHints(); + } + showHint(hintIndex: number) { + return this.intro.showHint(hintIndex); + } + showHints() { + return this.intro.showHints(); + } + + hideHint(hintIndex: number) { + return this.intro.hideHint(hintIndex); + } + + hideHints() { + return this.intro.hideHints(); + } + + previous() { + this.notifyListeners(introStatus.open); + return this.intro.previousStep(); + } + next() { + this.notifyListeners(introStatus.open); + return this.intro.nextStep(); + + } + + refresh() { + return this.intro.refresh(); + } + + onComplete(cb: Function) { + return this.intro.oncomplete(() => { + if (angular.isFunction(cb)) cb(); + this.notifyListeners(introStatus.closed); + }); + } + onExit(cb: Function) { + return this.intro.onexit(() => { + this.notifyListeners(introStatus.closed); + if (angular.isFunction(cb)) cb(); + }); + } + onBeforeChange(cb: Function) { + return this.intro.onbeforechange((targetElement) => { + if (angular.isFunction(cb)) cb(targetElement); + }); + } + onChange(cb: Function) { + return this.intro.onchange((targetElement) => { + if (angular.isFunction(cb)) cb(targetElement); + }); + } + onAfterChange(cb: Function) { + return this.intro.onafterchange((targetElement) => { + if (angular.isFunction(cb)) cb(targetElement); + }); + } + + onHintClick(cb: Function) { + return this.intro.onhintclick(() => { + if (angular.isFunction(cb)) cb(); + }); + } + + onHintClose(cb: Function) { + return this.intro.onhintclose(() => { + if (angular.isFunction(cb)) cb(); + }); + } + onHintsAdded(cb: Function) { + return this.intro.onhintclose(() => { + if (angular.isFunction(cb)) cb(); + }); + } + + } + + class NgIntroDirective implements ng.IDirective { + public restrict = "A"; + public link: (scope: ngIntroJs.INgIntroDirectiveScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes) => void; + public scope = { + ngIntroMethod: "=", + ngIntroExitMethod: "=?", + ngIntroNextMethod: "=?", + ngIntroPreviousMethod: "=?", + ngIntroRefreshMethod: "=?", + ngIntroOptions: "=", + ngIntroOncomplete: "=", + ngIntroOnexit: "=", + ngIntroOnchange: "=", + ngIntroOnbeforechange: "=", + ngIntroOnafterchange: "=", + ngIntroAutostart: "=", + ngIntroAutorefresh: "=", + + ngIntroHintsMethod: "=?", + ngIntroOnhintsadded: "=", + ngIntroOnhintclick: "=?", + ngIntroOnhintclose: "=?", + ngIntroShowHint: "=?", + ngIntroShowHints: "=?", + ngIntroHideHint: "=?", + ngIntroHideHints: "=?" + }; + destroy: any = [] + + static factory(): ng.IDirectiveFactory { + const directive = (introService: NgIntroService, $timeout: ng.ITimeoutService) => new NgIntroDirective(introService, $timeout); + directive.$inject = ["ngIntroService", "$timeout"]; + return directive; + } + constructor(introService: NgIntroService, $timeout: ng.ITimeoutService) { + this.link = (scope: ngIntroJs.INgIntroDirectiveScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes) => { + if (scope.ngIntroOncomplete) { + introService.onComplete(scope.ngIntroOncomplete); + } + if (scope.ngIntroOnexit) { + introService.onExit(scope.ngIntroOnexit); + } + + if (scope.ngIntroOnbeforechange) { + introService.onBeforeChange(scope.ngIntroOnbeforechange); + } + + if (scope.ngIntroOnchange) { + introService.onChange(scope.ngIntroOnchange); + } + + if (scope.ngIntroOnafterchange) { + introService.onAfterChange(scope.ngIntroOnafterchange); + } + + scope.ngIntroMethod = (step) => { + introService.setOptions(scope.ngIntroOptions); + introService.start(step); + }; + + scope.ngIntroHintsMethod = (step?: number) => { + introService.setOptions(scope.ngIntroOptions); + introService.start(step); + + if (scope.ngIntroOnhintsadded) { + introService.onHintsAdded(scope.ngIntroOnbeforechange); + } + + if (scope.ngIntroOnhintclick) { + introService.onHintClick(scope.ngIntroOnbeforechange); + } + + if (scope.ngIntroOnhintclose) { + introService.onHintClick(scope.ngIntroOnbeforechange); + } + + introService.addHints(); + }; + + scope.ngIntroShowHint = (id) => { + introService.showHint(id); + }; + + scope.ngIntroShowHints = () => { + introService.showHints(); + }; + + scope.ngIntroHideHint = (id) => { + introService.hideHint(id); + }; + + scope.ngIntroHideHints = () => { + introService.hideHints(); + }; + + scope.ngIntroNextMethod = () => { + introService.next(); + }; + + scope.ngIntroPreviousMethod = () => { + introService.previous(); + }; + + scope.ngIntroExitMethod = (callback) => { + introService.exit(); + if (angular.isFunction(callback)) callback(); + }; + + scope.ngIntroRefreshMethod = () => { + introService.refresh(); + }; + + let autoStartWatch = scope.$watch("ngIntroAutostart", () => { + if (scope.ngIntroAutostart) { + $timeout(() => { + scope.ngIntroMethod(); + }); + } + autoStartWatch(); + }); + + this.destroy.push(scope.$on("$locationChangeStart", () => { + introService.exit(); + })); + + this.destroy.push(scope.$on("$locationChangeSuccess", () => { + introService.exit(); + })); + + if (scope.ngIntroAutorefresh) { + this.destroy.push(scope.$watch(() => { + introService.refresh(); + })); + } + + this.destroy.push(scope.$on("$destroy", () => { + introService.exit(); + })); + + scope.$on("$destroy", () => { + clearWatches(); + }); + + function clearWatches() { + for (let d of this.destroy) + d(); + } + }; + } + } + + angular.module(moduleName, []) + .service("ngIntroService", NgIntroService) + + // 1st way to create the directive using typescript. + .directive("ngIntroOptions", NgIntroDirective.factory()) + + /// this is another + .directive("ngIntroDisableButton", ["ngIntroService", function (ngIntroService) { + let id = 0; + return { + restrict: "A", + priority: 1, + link: function (scope, elm, attrs) { + let uniqueId = "disabledBtn" + id++; + ngIntroService.addListener(uniqueId, function (value: string) { + if (value === introStatus.open) { + attrs.$set("disabled", "disabled"); + } else { + delete attrs.disabled; + elm.removeAttr("disabled"); + } + }); + + scope.$on("$destroy", function () { + ngIntroService.removeListener(uniqueId); + }); + + } + }; + }]); +})) \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..302e353 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "module": "none", + "noImplicitAny": true, + "removeComments": true, + "preserveConstEnums": true, + "sourceMap": true, + "target": "es5", + "declaration": true, + "declarationDir": "build" + + }, + "include": [ + "src/**/*" + ] +} \ No newline at end of file diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000..1d31ebc --- /dev/null +++ b/tslint.json @@ -0,0 +1,89 @@ +{ + "rules": { + "class-name": true, + "comment-format": [ + true, + "check-space" + ], + "indent": [ + true, + "tabs" + ], + "no-duplicate-variable": true, + "no-eval": true, + "no-internal-module": true, + "no-trailing-whitespace": true, + "no-var-keyword": true, + "one-line": [ + true, + "check-open-brace", + "check-whitespace" + ], + "quotemark": [ + true, + "double" + ], + "semicolon": false, + "triple-equals": [ + true, + "allow-null-check" + ], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + } + ], + "variable-name": [ + true, + "ban-keywords" + ], + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ] + }, + "jsRules": { + "indent": [ + true, + "spaces" + ], + "no-duplicate-variable": true, + "no-eval": true, + "no-trailing-whitespace": true, + "one-line": [ + true, + "check-open-brace", + "check-whitespace" + ], + "quotemark": [ + true, + "double" + ], + "semicolon": false, + "triple-equals": [ + true, + "allow-null-check" + ], + "variable-name": [ + true, + "ban-keywords" + ], + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ] + } +} \ No newline at end of file