├── .nvmrc
├── .gitignore
├── src
└── angularjs-facebook-sdk
│ ├── angularjs-facebook-sdk.suffix
│ ├── angularjs-facebook-sdk.prefix
│ ├── directives
│ ├── facebook_logout_directive.js
│ ├── facebook_share_directive.js
│ ├── facebook_follow_directive.js
│ ├── facebook_login_directive.js
│ ├── facebook_send_directive.js
│ ├── facebook_profile_pic_directive.js
│ ├── facebook_comments_directive.js
│ └── facebook_like_directive.js
│ ├── angularjs-facebook-sdk.js
│ └── services
│ ├── facebook_config_provider.js
│ └── facebook_service.js
├── .editorconfig
├── .jshintrc
├── bower.json
├── README.md
├── test
└── unit
│ └── angularjs-facebook-sdk
│ ├── angularjs-facebook-sdk.js
│ └── services
│ ├── facebook_service.js
│ └── facebook_config_provider.js
├── example
├── app.css
├── index.html
├── home.html
└── app.js
├── LICENSE
├── package.json
├── karma-unit.conf.js
├── Gruntfile.js
└── dist
├── angularjs-facebook-sdk.min.js
└── angularjs-facebook-sdk.js
/.nvmrc:
--------------------------------------------------------------------------------
1 | 0.10.0
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | bower_components/
3 | npm-debug.log
4 |
--------------------------------------------------------------------------------
/src/angularjs-facebook-sdk/angularjs-facebook-sdk.suffix:
--------------------------------------------------------------------------------
1 | })(window, document);
2 |
--------------------------------------------------------------------------------
/src/angularjs-facebook-sdk/angularjs-facebook-sdk.prefix:
--------------------------------------------------------------------------------
1 | (function(window, document) {
2 |
3 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 4
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "node": true,
3 | "es5": true,
4 | "esnext": true,
5 | "bitwise": true,
6 | "camelcase": true,
7 | "curly": true,
8 | "eqeqeq": true,
9 | "immed": true,
10 | "indent": 4,
11 | "latedef": true,
12 | "newcap": true,
13 | "noarg": true,
14 | "quotmark": "single",
15 | "regexp": true,
16 | "undef": true,
17 | "unused": true,
18 | "strict": true,
19 | "trailing": true,
20 | "smarttabs": true,
21 | "white": true
22 | }
23 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angularjs-facebook-sdk",
3 | "version": "1.1.0",
4 | "main": "dist/angularjs-facebook-sdk.js",
5 | "moduleType": [
6 | "global"
7 | ],
8 | "dependencies": {
9 | "jquery": "~2.1.0",
10 | "angular": "~1.6.4",
11 | "highlightjs": "^9.10.0",
12 | "cssreset": "^1.0.0",
13 | "angular-route": "1.6.4"
14 | },
15 | "ignore": [
16 | "bower_components",
17 | "test",
18 | "src",
19 | "example",
20 | "Gruntfile.js",
21 | "karma-unit.conf.js",
22 | "LICENSE",
23 | "package.json",
24 | "README.md",
25 | ".gitignore",
26 | ".jshintrc",
27 | ".editorconfig"
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/src/angularjs-facebook-sdk/directives/facebook_logout_directive.js:
--------------------------------------------------------------------------------
1 | function FacebookLogoutDirective(facebookService) {
2 | return {
3 | restrict: 'E',
4 | replace: true,
5 | template: '',
6 | scope: {
7 | label: '@label'
8 | },
9 | link: function (scope, element) {
10 | scope.dispatchLogout = function dispatchLogin() {
11 | facebookService.logout();
12 | };
13 | }
14 | };
15 | }
16 |
17 | FacebookLogoutDirective.$inject = ['facebookService'];
18 |
19 | angular.module('angularjs-facebook-sdk.directives')
20 | .directive('afbLogout', FacebookLogoutDirective);
21 |
--------------------------------------------------------------------------------
/src/angularjs-facebook-sdk/directives/facebook_share_directive.js:
--------------------------------------------------------------------------------
1 | function FacebookShareDirective(facebookService) {
2 | return {
3 | restrict: 'E',
4 | replace: true,
5 | template: '',
6 | scope: {
7 | href: '@href',
8 | type: '@type'
9 | },
10 | link: function (scope, element) {
11 | facebookService.ready.then(function () {
12 | FB.XFBML.parse(element[0]);
13 | });
14 | }
15 | };
16 | }
17 |
18 | FacebookShareDirective.$inject = ['facebookService'];
19 |
20 | angular.module('angularjs-facebook-sdk.directives')
21 | .directive('afbShareButton', FacebookShareDirective);
22 |
--------------------------------------------------------------------------------
/src/angularjs-facebook-sdk/directives/facebook_follow_directive.js:
--------------------------------------------------------------------------------
1 | function FacebookFollowDirective(facebookService) {
2 | return {
3 | restrict: 'E',
4 | replace: true,
5 | template: '',
6 | scope: {
7 | href: '@href',
8 | colorschema: '@colorschema',
9 | layout: '@layout',
10 | showFaces: '@showFaces'
11 | },
12 | link: function (scope, element) {
13 | facebookService.ready.then(function () {
14 | FB.XFBML.parse(element[0]);
15 | });
16 | }
17 | };
18 | }
19 |
20 | FacebookFollowDirective.$inject = ['facebookService'];
21 |
22 | angular.module('angularjs-facebook-sdk.directives')
23 | .directive('afbFollow', FacebookFollowDirective);
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | angularjs-facebook-sdk
2 | ======================
3 |
4 | Integration between AngularJS and Facebook SDK for Javascript.
5 |
6 | ### Documentation
7 |
8 | [wlepinski.github.io/angularjs-facebook-sdk/](http://wlepinski.github.io/angularjs-facebook-sdk/)
9 |
10 | ### Compiling from source
11 |
12 | You'll need [NodeJS](http://nodejs.org) installed to compile the source-code.
13 |
14 | Clone the project and run npm install && npm run build on the root folder.
15 | The compiled and minified files will be generated under dist folder
16 |
17 | ### Running the examples
18 |
19 | To see the examples run npm start ( Make sure you define your appId in the file examples/app.js ).
20 |
21 | ### Running tests
22 |
23 | To execute the unit tests run npm test.
24 |
25 | ### Contributing
26 |
27 | Use the issue tracker to send PRs.
28 |
--------------------------------------------------------------------------------
/src/angularjs-facebook-sdk/angularjs-facebook-sdk.js:
--------------------------------------------------------------------------------
1 | // Create all modules and define dependencies to make sure they exist
2 | // and are loaded in the correct order to satisfy dependency injection
3 | // before all nested files are concatenated by Grunt
4 |
5 | // Config
6 | angular.module('angularjs-facebook-sdk.config', [])
7 | .value('angularjs-facebook-sdk.config', {
8 | debug: true
9 | });
10 |
11 | // Modules
12 | angular.module('angularjs-facebook-sdk.directives', []);
13 | angular.module('angularjs-facebook-sdk.services', []);
14 | angular.module('angularjs-facebook-sdk', [
15 | 'angularjs-facebook-sdk.config',
16 | 'angularjs-facebook-sdk.directives',
17 | 'angularjs-facebook-sdk.services'
18 | ]);
19 |
20 | angular.module('angularjs-facebook-sdk').run(['facebookConfig',
21 | function (facebookConfig) {
22 | if (facebookConfig.autoInit) {
23 | facebookConfig.init();
24 | }
25 | }
26 | ]);
27 |
--------------------------------------------------------------------------------
/test/unit/angularjs-facebook-sdk/angularjs-facebook-sdk.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Set the jasmine fixture path
4 | // jasmine.getFixtures().fixturesPath = 'base/';
5 |
6 | describe('angularjs-facebook-sdk', function() {
7 |
8 | var module;
9 | var dependencies;
10 | dependencies = [];
11 |
12 | var hasModule = function(module) {
13 | return dependencies.indexOf(module) >= 0;
14 | };
15 |
16 | beforeEach(function() {
17 | module = angular.module('angularjs-facebook-sdk');
18 | dependencies = module.requires;
19 | });
20 |
21 | it('should load config module', function() {
22 | expect(hasModule('angularjs-facebook-sdk.config')).toBeTruthy();
23 | });
24 |
25 | it('should load directives module', function() {
26 | expect(hasModule('angularjs-facebook-sdk.directives')).toBeTruthy();
27 | });
28 |
29 | it('should load services module', function() {
30 | expect(hasModule('angularjs-facebook-sdk.services')).toBeTruthy();
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/example/app.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: Roboto, sans-serif;
3 | }
4 |
5 | body h1 {
6 | font-size: 40px;
7 | font-weight: 100;
8 | letter-spacing: -2px;
9 | margin: 20px;
10 | }
11 |
12 | .component {
13 | border: 1px solid #DDD;
14 | margin: 20px;
15 | border-radius: 5px;
16 | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
17 | }
18 |
19 | .component header h2 {
20 | font-size: 30px;
21 | font-weight: 300;
22 | line-height: 1;
23 | letter-spacing: -1px;
24 | padding: 10px;
25 | border-bottom: 1px dotted #DDD;
26 | }
27 |
28 | .component .result,
29 | .component .usage {
30 | position: relative;
31 | background: #EEE;
32 | padding: 29px 20px 10px;
33 | }
34 |
35 | .component .result h4,
36 | .component .usage h4 {
37 | background: #CCC;
38 | display: inline-block;
39 | position: absolute;
40 | top: -1px;
41 | left: 20px;
42 | padding: 3px 10px;
43 | font-weight: 100;
44 | font-size: 12px;
45 | }
46 |
47 | .component .usage {
48 | background: #FFF;
49 | border-radius: 5px;
50 | }
51 |
52 | .component .usage pre {
53 | min-height: 10px;
54 | }
55 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 William Albino Lepinski
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/test/unit/angularjs-facebook-sdk/services/facebook_service.js:
--------------------------------------------------------------------------------
1 | describe('FacebookService', function () {
2 | var _facebookService;
3 | var _$q;
4 |
5 | //excuted before each "it" is run.
6 | beforeEach(function () {
7 | // Initialize the service provider by injecting it to a fake module's config block
8 | angular.module('testApp', [])
9 | .config(function (facebookConfigProvider) {
10 | facebookConfigProvider.setAppId(12345);
11 | });
12 |
13 | //load the module.
14 | module('angularjs-facebook-sdk', 'testApp');
15 |
16 | //inject your service for testing.
17 | inject(function (facebookService, $q) {
18 | _facebookService = facebookService;
19 | _$q = $q;
20 | });
21 | });
22 |
23 | it('should export the correct api', function () {
24 | expect(_facebookService.ready).not.toBe(null);
25 | expect(_facebookService.api).toEqual(jasmine.any(Function));
26 | expect(_facebookService.ui).toEqual(jasmine.any(Function));
27 | expect(_facebookService.login).toEqual(jasmine.any(Function));
28 | expect(_facebookService.logout).toEqual(jasmine.any(Function));
29 | expect(_facebookService.getLoginStatus).toEqual(jasmine.any(Function));
30 | });
31 |
32 | it('should return a promise on the api method', function () {
33 | expect(_facebookService.api().then).toBeDefined();
34 | })
35 | });
36 |
--------------------------------------------------------------------------------
/src/angularjs-facebook-sdk/directives/facebook_login_directive.js:
--------------------------------------------------------------------------------
1 | function FacebookLoginDirective(facebookService) {
2 | return {
3 | restrict: 'E',
4 | replace: true,
5 | template: '',
6 | scope: {
7 | label: '@label',
8 | scope: '@scope',
9 | enableProfileSelector: '@enableProfileSelector',
10 | profileSelectorIds: '@profileSelectorIds'
11 | },
12 | compile: function (tElement, tAttrs) {
13 | var loginOpts = {};
14 |
15 | if (tAttrs.scope) {
16 | loginOpts.scope = tAttrs.scope;
17 | }
18 | if (tAttrs.enableProfileSelector) {
19 | loginOpts.enable_profile_selector = true;
20 | }
21 | if (tAttrs.profileSelectorIds) {
22 | loginOpts.profile_selector_ids = true;
23 | }
24 |
25 | return function linkFn(scope, element) {
26 | scope.dispatchLogin = function dispatchLogin() {
27 | facebookService.login(loginOpts);
28 | };
29 | };
30 | }
31 | };
32 | }
33 |
34 | FacebookLoginDirective.$inject = ['facebookService'];
35 |
36 | angular.module('angularjs-facebook-sdk.directives')
37 | .directive('afbLogin', FacebookLoginDirective);
38 |
--------------------------------------------------------------------------------
/src/angularjs-facebook-sdk/directives/facebook_send_directive.js:
--------------------------------------------------------------------------------
1 | function FacebookSendDirective(facebookService) {
2 | return {
3 | restrict: 'E',
4 | replace: true,
5 | template: '',
6 | scope: {
7 | href: '@href',
8 | colorschema: '@colorschema',
9 | width: '@width',
10 | height: '@height',
11 | // Events
12 | messageSend: '@onMessageSend'
13 | },
14 | link: function (scope, element) {
15 | function messageSendHandler(url) {
16 | if (url === scope.href) {
17 | // Call the scope event if the htmlElement match
18 | scope.messageSend({ url: url });
19 | }
20 | }
21 |
22 | facebookService.ready.then(function () {
23 | FB.XFBML.parse(element[0]);
24 | facebookService.Event.subscribe('message.send', messageSendHandler);
25 | });
26 |
27 | scope.$on('$destroy', function () {
28 | facebookService.Event.unsubscribe('message.send', messageSendHandler);
29 | });
30 | }
31 | };
32 | }
33 |
34 | FacebookSendDirective.$inject = ['facebookService'];
35 |
36 | angular.module('angularjs-facebook-sdk.directives')
37 | .directive('afbSend', FacebookSendDirective);
38 |
--------------------------------------------------------------------------------
/src/angularjs-facebook-sdk/directives/facebook_profile_pic_directive.js:
--------------------------------------------------------------------------------
1 | function FacebookProfilePicDirective(facebookService) {
2 | return {
3 | restrict: 'E',
4 | replace: true,
5 | template: '
',
6 | scope: {
7 | uid: '@uid',
8 | type: '@type',
9 | width: '@width',
10 | height: '@height'
11 | },
12 | compile: function compileFn(tElement, tAttrs) {
13 | return function linkFn(scope, element) {
14 | facebookService.ready.then(function () {
15 | var pictureUrl = (scope.uid) ? scope.uid + "/picture" : "/me/picture";
16 |
17 | var apiCall = facebookService.api(pictureUrl, {
18 | redirect: false,
19 | type: scope.type,
20 | width: scope.width,
21 | height: scope.height
22 | });
23 |
24 | apiCall.then(function (response) {
25 | if (response && !response.error) {
26 | element.attr('src', response.data.url);
27 | }
28 | });
29 | });
30 | };
31 | }
32 | };
33 | }
34 |
35 | FacebookProfilePicDirective.$inject = ['facebookService'];
36 |
37 | angular.module('angularjs-facebook-sdk.directives')
38 | .directive('afbProfilePic', FacebookProfilePicDirective);
39 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angularjs-facebook-sdk",
3 | "version": "1.1.0",
4 | "dependencies": {
5 | "jquery": "~2.1.0",
6 | "angular": "~1.4.4"
7 | },
8 | "repository": {
9 | "type": "git",
10 | "url": "https://github.com/wlepinski/angularjs-facebook-sdk"
11 | },
12 | "license": "MIT",
13 | "devDependencies": {
14 | "grunt": "~0.4.1",
15 | "grunt-contrib-copy": "~0.4.1",
16 | "grunt-contrib-concat": "~0.3.0",
17 | "grunt-contrib-coffee": "~0.7.0",
18 | "grunt-contrib-uglify": "~0.2.0",
19 | "grunt-contrib-compass": "~0.3.0",
20 | "grunt-contrib-jshint": "~0.6.0",
21 | "grunt-contrib-cssmin": "~0.6.0",
22 | "grunt-contrib-connect": "~0.6.0",
23 | "grunt-contrib-clean": "~0.4.1",
24 | "grunt-contrib-htmlmin": "~0.1.3",
25 | "grunt-contrib-imagemin": "~0.1.4",
26 | "grunt-contrib-watch": "~0.4.0",
27 | "grunt-usemin": "~0.1.11",
28 | "grunt-svgmin": "~0.2.0",
29 | "grunt-rev": "~0.1.0",
30 | "grunt-karma": "~0.4.3",
31 | "grunt-open": "~0.2.0",
32 | "grunt-concurrent": "~0.3.0",
33 | "matchdep": "~0.1.2",
34 | "connect-livereload": "~0.2.0",
35 | "grunt-google-cdn": "~0.2.0",
36 | "grunt-ngmin": "~0.0.2",
37 | "karma": "~0.9",
38 | "karma-jasmine": "~0.0.3",
39 | "karma-chrome-launcher": "~0.0.2",
40 | "angular-mocks": "~1.4.4",
41 | "angular-scenario": "~1.4.4"
42 | },
43 | "scripts": {
44 | "test": "karma start karma-unit.conf.js",
45 | "build": "grunt",
46 | "start": "grunt serve:examples"
47 | },
48 | "engines": {
49 | "node": ">=0.8.0"
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Angularjs-facebook-sdk example
6 |
7 |
8 |
9 |
10 |
11 |
15 |
16 |
17 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/angularjs-facebook-sdk/directives/facebook_comments_directive.js:
--------------------------------------------------------------------------------
1 | function FacebookCommentsDirective(facebookService) {
2 | return {
3 | restrict: 'E',
4 | replace: true,
5 | template: '',
6 | scope: {
7 | href: '@href',
8 | colorschema: '@colorschema',
9 | numposts: '@numposts',
10 | // Events
11 | commentCreated: '&onCommentCreated',
12 | commentRemoved: '&onCommentRemoved'
13 | },
14 | link: function (scope, element) {
15 | function commentCreatedHandler(data) {
16 | if (data.href === scope.href) {
17 | // Call the scope event if the htmlElement match
18 | scope.commentCreated(data);
19 | }
20 | }
21 |
22 | function commentRemovedHandler(data) {
23 | if (data.href === scope.href) {
24 | // Call the scope event if the htmlElement match
25 | scope.commentRemoved(data);
26 | }
27 | }
28 |
29 | facebookService.ready.then(function () {
30 | FB.XFBML.parse(element[0]);
31 |
32 | facebookService.Event.subscribe('comment.create', commentCreatedHandler);
33 | facebookService.Event.subscribe('comment.remove', commentRemovedHandler);
34 | });
35 |
36 | // Listen for scope removal and unsubscribe some previously added events.
37 | scope.$on('$destroy', function () {
38 | facebookService.Event.unsubscribe('comment.create', commentCreatedHandler);
39 | facebookService.Event.unsubscribe('comment.remove', commentRemovedHandler);
40 | });
41 | }
42 | };
43 | }
44 |
45 | FacebookCommentsDirective.$inject = ['facebookService'];
46 |
47 | angular.module('angularjs-facebook-sdk.directives')
48 | .directive('afbComments', FacebookCommentsDirective);
49 |
--------------------------------------------------------------------------------
/src/angularjs-facebook-sdk/directives/facebook_like_directive.js:
--------------------------------------------------------------------------------
1 | function FacebookLikeDirective(facebookService) {
2 | return {
3 | restrict: 'E',
4 | replace: true,
5 | template: '',
6 | scope: {
7 | href: '@href',
8 | layout: '@layout',
9 | action: '@action',
10 | show_faces: '@showFaces',
11 | share: '@share',
12 | // Events
13 | edgeCreated: '&onEdgeCreated',
14 | edgeRemoved: '&onEdgeRemoved'
15 | },
16 | link: function (scope, element, attrs) {
17 | function edgeCreatedHandler(url, htmlElement) {
18 | if (htmlElement === element[0]) {
19 | // Call the scope event if the htmlElement match
20 | scope.edgeCreated({url: url});
21 | }
22 | }
23 |
24 | function edgeRemovedHandler(url, htmlElement) {
25 | if (htmlElement === element[0]) {
26 | // Call the scope event if the htmlElement match
27 | scope.edgeRemoved({url: url});
28 | }
29 | }
30 |
31 | facebookService.ready.then(function () {
32 | FB.XFBML.parse(element[0]);
33 | facebookService.Event.subscribe('edge.create', edgeCreatedHandler);
34 | facebookService.Event.subscribe('edge.remove', edgeRemovedHandler);
35 | });
36 |
37 | // Listen for scope removal and unsubscribe some previously added events.
38 | scope.$on('$destroy', function () {
39 | facebookService.Event.unsubscribe('edge.create', edgeCreatedHandler);
40 | facebookService.Event.unsubscribe('edge.remove', edgeRemovedHandler);
41 | });
42 | }
43 | };
44 | }
45 |
46 | FacebookLikeDirective.$inject = ['facebookService'];
47 |
48 | angular.module('angularjs-facebook-sdk.directives')
49 | .directive('afbLike', FacebookLikeDirective);
50 |
--------------------------------------------------------------------------------
/karma-unit.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = function(config) {
2 | config.set({
3 |
4 | // base path, that will be used to resolve files and exclude
5 | basePath: '',
6 |
7 | frameworks: ['jasmine'],
8 |
9 | plugins: [
10 | 'karma-jasmine',
11 | 'karma-chrome-launcher'
12 | ],
13 |
14 | // list of files / patterns to load in the browser
15 | files: [
16 | 'node_modules/angular/angular.js',
17 | 'node_modules/angular-mocks/angular-mocks.js',
18 | 'src/angularjs-facebook-sdk/angularjs-facebook-sdk.js',
19 | 'src/angularjs-facebook-sdk/directives/*.js',
20 | 'src/angularjs-facebook-sdk/services/*.js',
21 | 'test/unit/**/*.js'
22 | ],
23 |
24 |
25 | // list of files to exclude
26 | exclude: [],
27 |
28 |
29 | // test results reporter to use
30 | // possible values: 'dots', 'progress', 'junit'
31 | reporters: ['progress'],
32 |
33 |
34 | // web server port
35 | port: 9876,
36 |
37 |
38 | // cli runner port
39 | runnerPort: 9100,
40 |
41 |
42 | // enable / disable colors in the output (reporters and logs)
43 | colors: true,
44 |
45 |
46 | // level of logging
47 | // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
48 | logLevel: config.LOG_INFO,
49 |
50 |
51 | // enable / disable watching file and executing tests whenever any file changes
52 | autoWatch: true,
53 |
54 |
55 | // Start these browsers, currently available:
56 | // - Chrome
57 | // - ChromeCanary
58 | // - Firefox
59 | // - Opera
60 | // - Safari (only Mac)
61 | // - PhantomJS
62 | // - IE (only Windows)
63 | browsers: ['Chrome'],
64 |
65 |
66 | // If browser does not capture in given timeout [ms], kill it
67 | captureTimeout: 60000,
68 |
69 |
70 | // Continuous Integration mode
71 | // if true, it capture browsers, run tests and exit
72 | singleRun: false
73 |
74 | });
75 | };
76 |
77 |
--------------------------------------------------------------------------------
/example/home.html:
--------------------------------------------------------------------------------
1 |
2 |
Documentation: angularjs.facebook.sdk
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/test/unit/angularjs-facebook-sdk/services/facebook_config_provider.js:
--------------------------------------------------------------------------------
1 | describe('FacebookConfigProvider', function () {
2 |
3 | var _facebookConfigProvider;
4 |
5 | beforeEach(function () {
6 | // Initialize the service provider by injecting it to a fake module's config block
7 | angular.module('testApp', [])
8 | .config(function (facebookConfigProvider) {
9 | _facebookConfigProvider = facebookConfigProvider;
10 | });
11 |
12 | // Initialize myApp injector
13 | module('angularjs-facebook-sdk', 'testApp');
14 |
15 | // Kickstart the injectors previously registered with calls to angular.mock.module
16 | inject(function () {});
17 | });
18 |
19 | describe('with custom configuration', function () {
20 | it('tests the providers internal function', inject(function ($injector) {
21 | // check sanity
22 | expect(_facebookConfigProvider).not.toBeUndefined();
23 |
24 | // configure the provider
25 | _facebookConfigProvider.setAppId('12345');
26 | _facebookConfigProvider.setSdkVersion('v2.2');
27 | _facebookConfigProvider.setDebug(true);
28 | _facebookConfigProvider.setLanguage('pt_BR');
29 |
30 | // Invoke the provider factory function
31 | var instance = $injector.invoke(_facebookConfigProvider.$get);
32 |
33 | // test an instance of the provider for
34 | // the custom configuration changes
35 | expect(instance.appId).toBe('12345');
36 | expect(instance.sdkVersion).toBe('v2.2');
37 | expect(instance.debug).toBe(true);
38 | expect(instance.lang).toBe('pt_BR');
39 | }));
40 |
41 | it('test setting of sdkVersion from user options', inject(function ($injector) {
42 | _facebookConfigProvider.setOptions({ version: 'v1.0' });
43 |
44 | // Invoke the provider factory function
45 | var instance = $injector.invoke(_facebookConfigProvider.$get);
46 |
47 | expect(instance.sdkVersion).toBe('v1.0');
48 | }));
49 |
50 | it('should initialize the SDK', inject(function ($injector) {
51 | _facebookConfigProvider.setAppId(1111);
52 | _facebookConfigProvider.setLanguage('pt_BR');
53 |
54 | // Invoke the provider factory function
55 | var instance = $injector.invoke(_facebookConfigProvider.$get);
56 |
57 | runs(function() {
58 | var promise = instance.init();
59 | expect(promise.then).toEqual(jasmine.any(Function));
60 | });
61 |
62 | waitsFor(function() {
63 | return window.FB != undefined
64 | }, "FB should be defined");
65 |
66 | runs(function() {
67 | expect(FB).not.toBe(undefined);
68 | expect(instance.lang).toBe('pt_BR');
69 | // expect(document.getElementsByTagName('script')[0].src).toContain('facebook');
70 | // expect(document.getElementsByTagName('script')[0].src).toBe('http://connect.facebook.net/pt_BR/all.js');
71 | });
72 | }));
73 | });
74 |
75 | });
76 |
--------------------------------------------------------------------------------
/example/app.js:
--------------------------------------------------------------------------------
1 | angular.module('app', ['angularjs-facebook-sdk', 'ngRoute'])
2 | .config(function facebookConfig(facebookConfigProvider, $routeProvider) {
3 | facebookConfigProvider.setAppId(394254447322921);
4 | facebookConfigProvider.setOptions({ status: false });
5 | $routeProvider.when('/', {
6 | templateUrl: 'home.html',
7 | controller: 'ComponentsController'
8 | })
9 | })
10 | .run(function (facebookConfig, facebookService) {
11 | facebookService.ready.then(function () {
12 | console.log('Facebook is ready!');
13 |
14 | var statusChangeHandler = function (response) {
15 | if (response.status === 'connected') {
16 | facebookService.api('/me').then(function (response) {
17 | console.log(response);
18 | });
19 | }
20 | };
21 |
22 | facebookService.Event.subscribe('auth.statusChange', statusChangeHandler);
23 | });
24 | })
25 | .filter('log', function() {
26 | return function () {
27 | console.log(arguments);
28 | }
29 | })
30 | .controller('ComponentsController', function ($scope, facebookService) {
31 | $scope.onEdgeCreated = function onEdgeCreated (url) {
32 | console.log('onEdgeCreated', arguments);
33 | }
34 |
35 | $scope.onEdgeRemoved = function onEdgeRemoved (url) {
36 | console.log('onEdgeRemoved', arguments);
37 | }
38 |
39 | $scope.onCommentCreated = function onCommentCreated (href, commentID, parentCommentID) {
40 | console.log('onCommentCreated', arguments);
41 | }
42 |
43 | $scope.onCommentRemoved = function onCommentRemoved (href, commentID, parentCommentID) {
44 | console.log('onCommentRemoved', arguments);
45 | }
46 |
47 | facebookService.ready.then(function(){
48 | FB.Event.subscribe('message.send', function messageSend (argument) {
49 | console.log(arguments);
50 | });
51 | })
52 |
53 | $scope.onMessageSend = function onMessageSend (url) {
54 | console.log('onMessageSend', arguments);
55 | }
56 | })
57 | .directive('component', function ($compile, $sce) {
58 | return {
59 | restrict: 'E',
60 | templateUrl: 'component.tpl',
61 | transclude: true,
62 | scope: {
63 | name: '@name'
64 | },
65 | compile: function compileFn (tElement, tAttrs, transcludeFn) {
66 | return function linkFn (scope, element) {
67 | scope.component = {};
68 |
69 | transcludeFn(scope, function (clonedElement, scope) {
70 | var componentDeclaration = clonedElement.find('component\\:declaration').html();
71 | var componentDocumentation = clonedElement.find('component\\:documentation');
72 |
73 | if (componentDocumentation.length > 0) {
74 | scope.documentation = componentDocumentation.attr('url');
75 | }
76 |
77 | // Result
78 | var result = $compile(componentDeclaration)(scope.$parent);
79 | element.find('.result').append(result);
80 |
81 | // Usage
82 | scope.component.usage = $sce.trustAsHtml(hljs.highlight('html', componentDeclaration.trim()).value);
83 | });
84 | }
85 | }
86 | };
87 | });
88 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt) {
2 |
3 | grunt.initConfig({
4 | pkg: grunt.file.readJSON('package.json'),
5 | library: grunt.file.readJSON('bower.json'),
6 | concat: {
7 | options: {
8 | separator: ''
9 | },
10 | library: {
11 | src: [
12 | 'src/<%= library.name %>/<%= library.name %>.prefix',
13 | 'src/<%= library.name %>/<%= library.name %>.js',
14 | 'src/<%= library.name %>/directives/**/*.js',
15 | 'src/<%= library.name %>/filters/**/*.js',
16 | 'src/<%= library.name %>/services/**/*.js',
17 | 'src/<%= library.name %>/<%= library.name %>.suffix'
18 | ],
19 | dest: 'dist/<%= library.name %>.js'
20 | }
21 | },
22 | uglify: {
23 | options: {
24 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
25 | },
26 | jid: {
27 | files: {
28 | 'dist/<%= library.name %>.min.js': ['<%= concat.library.dest %>']
29 | }
30 | }
31 | },
32 | jshint: {
33 | beforeConcat: {
34 | src: [
35 | 'gruntfile.js',
36 | 'src/<%= library.name %>/**/*.js',
37 | ]
38 | },
39 | afterConcat: {
40 | src: [
41 | '<%= concat.library.dest %>'
42 | ]
43 | },
44 | options: {
45 | // options here to override JSHint defaults
46 | globals: {
47 | jQuery: true,
48 | console: true,
49 | module: true,
50 | document: true,
51 | angular: true
52 | },
53 | globalstrict: false
54 | }
55 | },
56 | watch: {
57 | options: {
58 | livereload: true
59 | },
60 | files: [
61 | 'Gruntfile.js',
62 | 'src/**/*'
63 | ],
64 | tasks: ['default']
65 | },
66 | connect: {
67 | example: {
68 | options: {
69 | port: 9001,
70 | base: ['example', 'dist', 'bower_components', 'node_modules'],
71 | keepalive: true,
72 | middleware: function (connect, options) {
73 | var middlewares = [];
74 |
75 | if (!Array.isArray(options.base)) {
76 | options.base = [options.base];
77 | }
78 |
79 | var directory = options.directory || options.base[options.base.length - 1];
80 |
81 | options.base.forEach(function (base) {
82 | middlewares.push(connect.static(base));
83 | });
84 |
85 | // Make directory browse-able.
86 | middlewares.push(connect.directory(directory));
87 | return middlewares;
88 | },
89 | }
90 | }
91 | }
92 | });
93 |
94 | grunt.loadNpmTasks('grunt-contrib-uglify');
95 | grunt.loadNpmTasks('grunt-contrib-jshint');
96 | grunt.loadNpmTasks('grunt-contrib-concat');
97 | grunt.loadNpmTasks('grunt-contrib-watch');
98 | grunt.loadNpmTasks('grunt-contrib-connect');
99 |
100 | grunt.registerTask('default', ['jshint:beforeConcat', 'concat', 'jshint:afterConcat', 'uglify']);
101 | grunt.registerTask('livereload', ['watch']);
102 | grunt.registerTask('serve:examples', ['default', 'connect:example']);
103 |
104 | };
105 |
--------------------------------------------------------------------------------
/src/angularjs-facebook-sdk/services/facebook_config_provider.js:
--------------------------------------------------------------------------------
1 | angular.module('angularjs-facebook-sdk.services')
2 | .provider('facebookConfig', function () {
3 | var _appId = null;
4 | var _sdkVersion = 'v2.9';
5 | var _userOptions = {};
6 | var _langCode = 'en_US';
7 | var _debug = false;
8 | var _autoInit = true;
9 |
10 | /**
11 | * Set the Facebook SDK application ID.
12 | *
13 | * @param {Number} appId The application ID.
14 | */
15 | this.setAppId = function setAppId(appId) {
16 | _appId = appId;
17 | };
18 |
19 | /**
20 | * Set the Facebook SDK version.
21 | *
22 | * @param {String} sdkVersion The SDK version.
23 | */
24 | this.setSdkVersion = function setSdkVersion(sdkVersion) {
25 | _sdkVersion = sdkVersion;
26 | };
27 |
28 | /**
29 | * Set the language of the framework.
30 | * By default the en_US is used.
31 | *
32 | * @param {String} langCode The language code.
33 | */
34 | this.setLanguage = function setLanguage(langCode) {
35 | _langCode = langCode;
36 | };
37 |
38 | /**
39 | * Enable/Disable the debug for Facebook SDK.
40 | *
41 | * @param {Boolean} enableDebug Wheather to enable or disable the debug.
42 | */
43 | this.setDebug = function setDebug(enableDebug) {
44 | _debug = enableDebug;
45 | };
46 |
47 | /**
48 | * [setOptions description]
49 | *
50 | * @param {[type]} options [description]
51 | */
52 | this.setOptions = function setOptions(options) {
53 | _userOptions = options;
54 | };
55 |
56 |
57 | /**
58 | * Enable/Disable the automatic initialization.
59 | *
60 | * @param {Boolean} enableAutoInit Wheather to enable/disable the auto initialization.
61 | */
62 | this.autoInit = function autoInit(enableAutoInit) {
63 | _autoInit = enableAutoInit;
64 | };
65 |
66 | /**
67 | * [FacebookProviderFactoryFn description]
68 | */
69 | function FacebookProviderFactoryFn($rootScope, $window, $q) {
70 | var defaultOptions = {
71 | appId: _appId,
72 | version: _sdkVersion,
73 | status: true,
74 | xfbml: true
75 | };
76 |
77 | var initDefer = $q.defer();
78 | var initOpts = angular.extend(defaultOptions, _userOptions);
79 |
80 | if (initOpts.version != _sdkVersion) {
81 | _sdkVersion = initOpts.version;
82 | }
83 |
84 | /**
85 | * Hook up a method on the window object. This way we can be notified
86 | * when the Facebook SDK is ready to be used.
87 | *
88 | * The initDefer promise is resolved inside this method.
89 | *
90 | * @return {[type]} [description]
91 | */
92 | $window.fbAsyncInit = function fbAsyncInit() {
93 | FB.init(initOpts);
94 |
95 | $rootScope.$apply(function () {
96 | initDefer.resolve();
97 | });
98 | };
99 |
100 | // The public API
101 | return {
102 | appId: _appId,
103 | sdkVersion: _sdkVersion,
104 | lang: _langCode,
105 | debug: _debug,
106 | autoInit: _autoInit,
107 |
108 | // The initialization promise
109 | initialization: initDefer.promise,
110 |
111 | /**
112 | * Initialize the Facebook SDK for Javascript.
113 | * This will load the SDK using the configuration passed to the provider.
114 | *
115 | * @return {Promise} The initialize Promise instance.
116 | */
117 | init: function () {
118 | (function (d, s, id) {
119 | var js, fjs = d.getElementsByTagName(s)[0];
120 | if (d.getElementById(id)) {
121 | return;
122 | }
123 | js = d.createElement(s);
124 | js.id = id;
125 | js.src = "//connect.facebook.net/" + _langCode + (_debug ? "/all/debug.js" : (_sdkVersion.substring(0, 2) == 'v2' ? "/sdk.js" : "/all.js"));
126 | fjs.parentNode.insertBefore(js, fjs);
127 | }(document, 'script', 'facebook-jssdk'));
128 |
129 | return initDefer.promise;
130 | }
131 | };
132 | }
133 |
134 | FacebookProviderFactoryFn.$inject = ['$rootScope', '$window', '$q'];
135 |
136 | this.$get = FacebookProviderFactoryFn;
137 | });
138 |
--------------------------------------------------------------------------------
/dist/angularjs-facebook-sdk.min.js:
--------------------------------------------------------------------------------
1 | /*! angularjs-facebook-sdk 12-05-2017 */
2 | !function(a,b){function c(a){return{restrict:"E",replace:!0,template:"",scope:{href:"@href",colorschema:"@colorschema",numposts:"@numposts",commentCreated:"&onCommentCreated",commentRemoved:"&onCommentRemoved"},link:function(b,c){function d(a){a.href===b.href&&b.commentCreated(a)}function e(a){a.href===b.href&&b.commentRemoved(a)}a.ready.then(function(){FB.XFBML.parse(c[0]),a.Event.subscribe("comment.create",d),a.Event.subscribe("comment.remove",e)}),b.$on("$destroy",function(){a.Event.unsubscribe("comment.create",d),a.Event.unsubscribe("comment.remove",e)})}}}function d(a){return{restrict:"E",replace:!0,template:"",scope:{href:"@href",colorschema:"@colorschema",layout:"@layout",showFaces:"@showFaces"},link:function(b,c){a.ready.then(function(){FB.XFBML.parse(c[0])})}}}function e(a){return{restrict:"E",replace:!0,template:"",scope:{href:"@href",layout:"@layout",action:"@action",show_faces:"@showFaces",share:"@share",edgeCreated:"&onEdgeCreated",edgeRemoved:"&onEdgeRemoved"},link:function(b,c,d){function e(a,d){d===c[0]&&b.edgeCreated({url:a})}function f(a,d){d===c[0]&&b.edgeRemoved({url:a})}a.ready.then(function(){FB.XFBML.parse(c[0]),a.Event.subscribe("edge.create",e),a.Event.subscribe("edge.remove",f)}),b.$on("$destroy",function(){a.Event.unsubscribe("edge.create",e),a.Event.unsubscribe("edge.remove",f)})}}}function f(a){return{restrict:"E",replace:!0,template:'',scope:{label:"@label",scope:"@scope",enableProfileSelector:"@enableProfileSelector",profileSelectorIds:"@profileSelectorIds"},compile:function(b,c){var d={};return c.scope&&(d.scope=c.scope),c.enableProfileSelector&&(d.enable_profile_selector=!0),c.profileSelectorIds&&(d.profile_selector_ids=!0),function(b,c){b.dispatchLogin=function(){a.login(d)}}}}}function g(a){return{restrict:"E",replace:!0,template:'',scope:{label:"@label"},link:function(b,c){b.dispatchLogout=function(){a.logout()}}}}function h(a){return{restrict:"E",replace:!0,template:"
",scope:{uid:"@uid",type:"@type",width:"@width",height:"@height"},compile:function(b,c){return function(b,c){a.ready.then(function(){var d=b.uid?b.uid+"/picture":"/me/picture",e=a.api(d,{redirect:!1,type:b.type,width:b.width,height:b.height});e.then(function(a){a&&!a.error&&c.attr("src",a.data.url)})})}}}}function i(a){return{restrict:"E",replace:!0,template:"",scope:{href:"@href",colorschema:"@colorschema",width:"@width",height:"@height",messageSend:"@onMessageSend"},link:function(b,c){function d(a){a===b.href&&b.messageSend({url:a})}a.ready.then(function(){FB.XFBML.parse(c[0]),a.Event.subscribe("message.send",d)}),b.$on("$destroy",function(){a.Event.unsubscribe("message.send",d)})}}}function j(a){return{restrict:"E",replace:!0,template:"",scope:{href:"@href",type:"@type"},link:function(b,c){a.ready.then(function(){FB.XFBML.parse(c[0])})}}}function k(a,b,c){c.$new();return{ready:a.initialization,Event:{subscribe:function(a,b){var d=function(){var a=Array.prototype.slice.call(arguments,0);c.$apply(function(){b.apply(null,a)})};b.$$eventHandler=d,FB.Event.subscribe(a,d)},unsubscribe:function(a,b){FB.Event.unsubscribe(a,b.$$eventHandler)}},api:function(a,d,e){var f=Array.prototype.slice.call(arguments,0),g=b.defer();return this.ready.then(function(){f.push(function(a){c.$apply(function(){g.resolve(a)})}),FB.api.apply(null,f)}),g.promise},ui:function(a){var d=Array.prototype.slice.call(arguments,0),e=b.defer();return this.ready.then(function(){d.push(function(a){c.$apply(function(){e.resolve(a)})}),FB.ui.apply(null,d)}),e.promise},login:function(a){a=a||{};var d=b.defer();return this.ready.then(function(){FB.login(function(){var a=arguments;c.$apply(function(){d.resolve.apply(this,a)})},a)}),d.promise},logout:function(){var a=b.defer();return this.ready.then(function(){FB.logout(function(){a.resolve.apply(this,arguments)})}),a.promise},getLoginStatus:function(){var a=b.defer();return this.ready.then(function(){FB.getLoginStatus(function(){a.resolve.apply(this,arguments)})}),a.promise}}}angular.module("angularjs-facebook-sdk.config",[]).value("angularjs-facebook-sdk.config",{debug:!0}),angular.module("angularjs-facebook-sdk.directives",[]),angular.module("angularjs-facebook-sdk.services",[]),angular.module("angularjs-facebook-sdk",["angularjs-facebook-sdk.config","angularjs-facebook-sdk.directives","angularjs-facebook-sdk.services"]),angular.module("angularjs-facebook-sdk").run(["facebookConfig",function(a){a.autoInit&&a.init()}]),c.$inject=["facebookService"],angular.module("angularjs-facebook-sdk.directives").directive("afbComments",c),d.$inject=["facebookService"],angular.module("angularjs-facebook-sdk.directives").directive("afbFollow",d),e.$inject=["facebookService"],angular.module("angularjs-facebook-sdk.directives").directive("afbLike",e),f.$inject=["facebookService"],angular.module("angularjs-facebook-sdk.directives").directive("afbLogin",f),g.$inject=["facebookService"],angular.module("angularjs-facebook-sdk.directives").directive("afbLogout",g),h.$inject=["facebookService"],angular.module("angularjs-facebook-sdk.directives").directive("afbProfilePic",h),i.$inject=["facebookService"],angular.module("angularjs-facebook-sdk.directives").directive("afbSend",i),j.$inject=["facebookService"],angular.module("angularjs-facebook-sdk.directives").directive("afbShareButton",j),angular.module("angularjs-facebook-sdk.services").provider("facebookConfig",function(){function a(a,i,j){var k={appId:c,version:d,status:!0,xfbml:!0},l=j.defer(),m=angular.extend(k,e);return m.version!=d&&(d=m.version),i.fbAsyncInit=function(){FB.init(m),a.$apply(function(){l.resolve()})},{appId:c,sdkVersion:d,lang:f,debug:g,autoInit:h,initialization:l.promise,init:function(){return function(a,b,c){var e,h=a.getElementsByTagName(b)[0];a.getElementById(c)||(e=a.createElement(b),e.id=c,e.src="//connect.facebook.net/"+f+(g?"/all/debug.js":"v2"==d.substring(0,2)?"/sdk.js":"/all.js"),h.parentNode.insertBefore(e,h))}(b,"script","facebook-jssdk"),l.promise}}}var c=null,d="v2.9",e={},f="en_US",g=!1,h=!0;this.setAppId=function(a){c=a},this.setSdkVersion=function(a){d=a},this.setLanguage=function(a){f=a},this.setDebug=function(a){g=a},this.setOptions=function(a){e=a},this.autoInit=function(a){h=a},a.$inject=["$rootScope","$window","$q"],this.$get=a}),k.$inject=["facebookConfig","$q","$rootScope"],angular.module("angularjs-facebook-sdk.services").factory("facebookService",k)}(window,document);
--------------------------------------------------------------------------------
/src/angularjs-facebook-sdk/services/facebook_service.js:
--------------------------------------------------------------------------------
1 | function FacebookService(facebookConfig, $q, $rootScope) {
2 | var eventEmitter = $rootScope.$new();
3 |
4 | return {
5 | ready: facebookConfig.initialization,
6 |
7 | Event: {
8 | /**
9 | * FB.Event.subscribe allows you to define callbacks that will be called when
10 | * certain events take place on your site. These events include:
11 | *
12 | * - Logging in or logging out via Facebook Login
13 | * - Someone likes or unlikes a page via an embedded like button
14 | * - Rendering of social plugins
15 | * - Comments are added or removed
16 | * - Someone sending a message to your page or a friend via an embedded send button
17 | *
18 | * This method is a wrapper for the original event subscriber. We need to wrap the callback
19 | * call in a Scope.prototype.$apply method to let AngularJS know when it need to update bindings,
20 | * dispatch other promises among other things.
21 | *
22 | * @param {String} eventName The event name.
23 | * @return {Promise}
24 | */
25 | subscribe: function (eventName, callback) {
26 | var eventHandler = function () {
27 | var args = Array.prototype.slice.call(arguments, 0);
28 |
29 | $rootScope.$apply(function () {
30 | callback.apply(null, args);
31 | });
32 | };
33 |
34 | // Here we store a reference to the wrapped method so that we can unsubscribe the function correctly.
35 | callback.$$eventHandler = eventHandler;
36 |
37 | // Delegate the subscription to Facebook SDK
38 | FB.Event.subscribe(eventName, eventHandler);
39 | },
40 |
41 | /**
42 | * Removes handlers on events so that it no longer invokes your callback when the event fires.
43 | *
44 | * @return {[type]} [description]
45 | */
46 | unsubscribe: function (eventName, callback) {
47 | FB.Event.unsubscribe(eventName, callback.$$eventHandler);
48 | }
49 | },
50 |
51 | /**
52 | * This method lets you make calls to the Graph API.
53 | *
54 | * @param {string} path
55 | * This is the Graph API endpoint path that you want to call.
56 | * You can read the Graph API reference docs to see which endpoint you want to use.
57 | * This is a required parameter.
58 | *
59 | * @param {enum{get, post, delete}} method
60 | * This is the HTTP method that you want to use for the API request.
61 | * Consult the Graph API reference docs to see which method you need to use.
62 | * Default is get
63 | *
64 | * @param {object} params
65 | * This is an object consisting of any parameters that you want to pass into your Graph API call.
66 | * The parameters that can be used vary depending on the endpoint being called, so check the
67 | * Graph API reference docs for full lists of available parameters. One parameter of note is
68 | * access_token which you can use to make an API call with a Page access token.
69 | * App access tokens should never be used in this SDK as it is client-side, and your app secret would be exposed.
70 | *
71 | * @param {Function} callback
72 | * This is the function that is triggered whenever the API returns a response.
73 | * The response object available to this function contains the API result.
74 | *
75 | * @return {Promise}
76 | */
77 | api: function (path, method, params) {
78 | var args = Array.prototype.slice.call(arguments, 0);
79 | var defer = $q.defer();
80 |
81 | this.ready.then(function () {
82 | args.push(function apiCallback(response) {
83 | // We need to use $apply here because the FB.api callback
84 | // is outside the AngularJS kingdom. So we're telling it to
85 | // dispatch the deferred resolution ASAP.
86 | $rootScope.$apply(function () {
87 | defer.resolve(response);
88 | });
89 | });
90 |
91 | // Where we delegate the call to the FB.api method.
92 | FB.api.apply(null, args);
93 | });
94 |
95 | return defer.promise;
96 | },
97 |
98 | /**
99 | * This method is used to trigger different forms of Facebook created UI dialogs.
100 | *
101 | * @param {[type]} params
102 | * A collection of parameters that control which dialog is loaded, and relevant settings. Click for more info.
103 | *
104 | * @return {Promise}
105 | */
106 | ui: function (params) {
107 | var args = Array.prototype.slice.call(arguments, 0);
108 | var defer = $q.defer();
109 |
110 | this.ready.then(function () {
111 | args.push(function apiCallback(response) {
112 | // We need to use $apply here because the FB.api callback
113 | // is outside the AngularJS kingdom. So we're telling it to
114 | // dispatch the deferred resolution ASAP.
115 | $rootScope.$apply(function () {
116 | defer.resolve(response);
117 | });
118 | });
119 |
120 | // Where we delegate the call to the FB.api method.
121 | FB.ui.apply(null, args);
122 | });
123 |
124 | return defer.promise;
125 | },
126 |
127 | /**
128 | * Calling FB.login prompts the user to authenticate your application using the OAuth Dialog.
129 | *
130 | * Calling FB.login results in the JS SDK attempting to open a popup window. As such, this method should only
131 | * be called after a user click event, otherwise the popup window will be blocked by most browsers.
132 | *
133 | * On Canvas, if the user is 'unknown' (that is, when the login status == 'unknown'), do not use the JS SDK
134 | * to sign in the user, instead do a full redirect of the page to the oauth dialog so that we get a consistent state.
135 | *
136 | * @return {Promise}
137 | */
138 | login: function (opts) {
139 | opts = opts || {};
140 |
141 | var defer = $q.defer();
142 |
143 | this.ready.then(function () {
144 | FB.login(function () {
145 | var loginArgs = arguments;
146 | $rootScope.$apply(function () {
147 | defer.resolve.apply(this, loginArgs);
148 | });
149 | }, opts);
150 | });
151 |
152 | return defer.promise;
153 | },
154 |
155 | /**
156 | * Log the user out of your site and Facebook
157 | *
158 | * @return {Promise}
159 | */
160 | logout: function () {
161 | var defer = $q.defer();
162 |
163 | this.ready.then(function () {
164 | FB.logout(function () {
165 | defer.resolve.apply(this, arguments);
166 | });
167 | });
168 |
169 | return defer.promise;
170 | },
171 |
172 | /**
173 | * FB.getLoginStatus allows you to determine if a user is logged in to Facebook and has authenticated your app.
174 | *
175 | * There are three possible states for a user:
176 | * - the user is logged into Facebook and has authenticated your application (connected)
177 | * - the user is logged into Facebook but has not authenticated your application (not_authorized)
178 | * - the user is not logged into Facebook at this time and so we don't know if they've authenticated your
179 | * application or not (unknown)
180 | * - With social application, knowing which of the these three states the user is in is one of the
181 | * first things your application needs to know upon page load.
182 | *
183 | * Reponse example:
184 | * {
185 | * status: 'connected',
186 | * authResponse: {
187 | * accessToken: '...',
188 | * expiresIn:'...',
189 | * signedRequest:'...',
190 | * userID:'...'
191 | * }
192 | * }
193 | *
194 | * @return {Promise}
195 | */
196 | getLoginStatus: function () {
197 | var defer = $q.defer();
198 |
199 | this.ready.then(function () {
200 | FB.getLoginStatus(function () {
201 | defer.resolve.apply(this, arguments);
202 | });
203 | });
204 |
205 | return defer.promise;
206 | }
207 | };
208 | }
209 |
210 | FacebookService.$inject = ['facebookConfig', '$q', '$rootScope'];
211 |
212 | angular.module('angularjs-facebook-sdk.services')
213 | .factory('facebookService', FacebookService);
214 |
--------------------------------------------------------------------------------
/dist/angularjs-facebook-sdk.js:
--------------------------------------------------------------------------------
1 | (function(window, document) {
2 |
3 | // Create all modules and define dependencies to make sure they exist
4 | // and are loaded in the correct order to satisfy dependency injection
5 | // before all nested files are concatenated by Grunt
6 |
7 | // Config
8 | angular.module('angularjs-facebook-sdk.config', [])
9 | .value('angularjs-facebook-sdk.config', {
10 | debug: true
11 | });
12 |
13 | // Modules
14 | angular.module('angularjs-facebook-sdk.directives', []);
15 | angular.module('angularjs-facebook-sdk.services', []);
16 | angular.module('angularjs-facebook-sdk', [
17 | 'angularjs-facebook-sdk.config',
18 | 'angularjs-facebook-sdk.directives',
19 | 'angularjs-facebook-sdk.services'
20 | ]);
21 |
22 | angular.module('angularjs-facebook-sdk').run(['facebookConfig',
23 | function (facebookConfig) {
24 | if (facebookConfig.autoInit) {
25 | facebookConfig.init();
26 | }
27 | }
28 | ]);
29 | function FacebookCommentsDirective(facebookService) {
30 | return {
31 | restrict: 'E',
32 | replace: true,
33 | template: '',
34 | scope: {
35 | href: '@href',
36 | colorschema: '@colorschema',
37 | numposts: '@numposts',
38 | // Events
39 | commentCreated: '&onCommentCreated',
40 | commentRemoved: '&onCommentRemoved'
41 | },
42 | link: function (scope, element) {
43 | function commentCreatedHandler(data) {
44 | if (data.href === scope.href) {
45 | // Call the scope event if the htmlElement match
46 | scope.commentCreated(data);
47 | }
48 | }
49 |
50 | function commentRemovedHandler(data) {
51 | if (data.href === scope.href) {
52 | // Call the scope event if the htmlElement match
53 | scope.commentRemoved(data);
54 | }
55 | }
56 |
57 | facebookService.ready.then(function () {
58 | FB.XFBML.parse(element[0]);
59 |
60 | facebookService.Event.subscribe('comment.create', commentCreatedHandler);
61 | facebookService.Event.subscribe('comment.remove', commentRemovedHandler);
62 | });
63 |
64 | // Listen for scope removal and unsubscribe some previously added events.
65 | scope.$on('$destroy', function () {
66 | facebookService.Event.unsubscribe('comment.create', commentCreatedHandler);
67 | facebookService.Event.unsubscribe('comment.remove', commentRemovedHandler);
68 | });
69 | }
70 | };
71 | }
72 |
73 | FacebookCommentsDirective.$inject = ['facebookService'];
74 |
75 | angular.module('angularjs-facebook-sdk.directives')
76 | .directive('afbComments', FacebookCommentsDirective);
77 | function FacebookFollowDirective(facebookService) {
78 | return {
79 | restrict: 'E',
80 | replace: true,
81 | template: '',
82 | scope: {
83 | href: '@href',
84 | colorschema: '@colorschema',
85 | layout: '@layout',
86 | showFaces: '@showFaces'
87 | },
88 | link: function (scope, element) {
89 | facebookService.ready.then(function () {
90 | FB.XFBML.parse(element[0]);
91 | });
92 | }
93 | };
94 | }
95 |
96 | FacebookFollowDirective.$inject = ['facebookService'];
97 |
98 | angular.module('angularjs-facebook-sdk.directives')
99 | .directive('afbFollow', FacebookFollowDirective);
100 | function FacebookLikeDirective(facebookService) {
101 | return {
102 | restrict: 'E',
103 | replace: true,
104 | template: '',
105 | scope: {
106 | href: '@href',
107 | layout: '@layout',
108 | action: '@action',
109 | show_faces: '@showFaces',
110 | share: '@share',
111 | // Events
112 | edgeCreated: '&onEdgeCreated',
113 | edgeRemoved: '&onEdgeRemoved'
114 | },
115 | link: function (scope, element, attrs) {
116 | function edgeCreatedHandler(url, htmlElement) {
117 | if (htmlElement === element[0]) {
118 | // Call the scope event if the htmlElement match
119 | scope.edgeCreated({url: url});
120 | }
121 | }
122 |
123 | function edgeRemovedHandler(url, htmlElement) {
124 | if (htmlElement === element[0]) {
125 | // Call the scope event if the htmlElement match
126 | scope.edgeRemoved({url: url});
127 | }
128 | }
129 |
130 | facebookService.ready.then(function () {
131 | FB.XFBML.parse(element[0]);
132 | facebookService.Event.subscribe('edge.create', edgeCreatedHandler);
133 | facebookService.Event.subscribe('edge.remove', edgeRemovedHandler);
134 | });
135 |
136 | // Listen for scope removal and unsubscribe some previously added events.
137 | scope.$on('$destroy', function () {
138 | facebookService.Event.unsubscribe('edge.create', edgeCreatedHandler);
139 | facebookService.Event.unsubscribe('edge.remove', edgeRemovedHandler);
140 | });
141 | }
142 | };
143 | }
144 |
145 | FacebookLikeDirective.$inject = ['facebookService'];
146 |
147 | angular.module('angularjs-facebook-sdk.directives')
148 | .directive('afbLike', FacebookLikeDirective);
149 | function FacebookLoginDirective(facebookService) {
150 | return {
151 | restrict: 'E',
152 | replace: true,
153 | template: '',
154 | scope: {
155 | label: '@label',
156 | scope: '@scope',
157 | enableProfileSelector: '@enableProfileSelector',
158 | profileSelectorIds: '@profileSelectorIds'
159 | },
160 | compile: function (tElement, tAttrs) {
161 | var loginOpts = {};
162 |
163 | if (tAttrs.scope) {
164 | loginOpts.scope = tAttrs.scope;
165 | }
166 | if (tAttrs.enableProfileSelector) {
167 | loginOpts.enable_profile_selector = true;
168 | }
169 | if (tAttrs.profileSelectorIds) {
170 | loginOpts.profile_selector_ids = true;
171 | }
172 |
173 | return function linkFn(scope, element) {
174 | scope.dispatchLogin = function dispatchLogin() {
175 | facebookService.login(loginOpts);
176 | };
177 | };
178 | }
179 | };
180 | }
181 |
182 | FacebookLoginDirective.$inject = ['facebookService'];
183 |
184 | angular.module('angularjs-facebook-sdk.directives')
185 | .directive('afbLogin', FacebookLoginDirective);
186 | function FacebookLogoutDirective(facebookService) {
187 | return {
188 | restrict: 'E',
189 | replace: true,
190 | template: '',
191 | scope: {
192 | label: '@label'
193 | },
194 | link: function (scope, element) {
195 | scope.dispatchLogout = function dispatchLogin() {
196 | facebookService.logout();
197 | };
198 | }
199 | };
200 | }
201 |
202 | FacebookLogoutDirective.$inject = ['facebookService'];
203 |
204 | angular.module('angularjs-facebook-sdk.directives')
205 | .directive('afbLogout', FacebookLogoutDirective);
206 | function FacebookProfilePicDirective(facebookService) {
207 | return {
208 | restrict: 'E',
209 | replace: true,
210 | template: '
',
211 | scope: {
212 | uid: '@uid',
213 | type: '@type',
214 | width: '@width',
215 | height: '@height'
216 | },
217 | compile: function compileFn(tElement, tAttrs) {
218 | return function linkFn(scope, element) {
219 | facebookService.ready.then(function () {
220 | var pictureUrl = (scope.uid) ? scope.uid + "/picture" : "/me/picture";
221 |
222 | var apiCall = facebookService.api(pictureUrl, {
223 | redirect: false,
224 | type: scope.type,
225 | width: scope.width,
226 | height: scope.height
227 | });
228 |
229 | apiCall.then(function (response) {
230 | if (response && !response.error) {
231 | element.attr('src', response.data.url);
232 | }
233 | });
234 | });
235 | };
236 | }
237 | };
238 | }
239 |
240 | FacebookProfilePicDirective.$inject = ['facebookService'];
241 |
242 | angular.module('angularjs-facebook-sdk.directives')
243 | .directive('afbProfilePic', FacebookProfilePicDirective);
244 | function FacebookSendDirective(facebookService) {
245 | return {
246 | restrict: 'E',
247 | replace: true,
248 | template: '',
249 | scope: {
250 | href: '@href',
251 | colorschema: '@colorschema',
252 | width: '@width',
253 | height: '@height',
254 | // Events
255 | messageSend: '@onMessageSend'
256 | },
257 | link: function (scope, element) {
258 | function messageSendHandler(url) {
259 | if (url === scope.href) {
260 | // Call the scope event if the htmlElement match
261 | scope.messageSend({ url: url });
262 | }
263 | }
264 |
265 | facebookService.ready.then(function () {
266 | FB.XFBML.parse(element[0]);
267 | facebookService.Event.subscribe('message.send', messageSendHandler);
268 | });
269 |
270 | scope.$on('$destroy', function () {
271 | facebookService.Event.unsubscribe('message.send', messageSendHandler);
272 | });
273 | }
274 | };
275 | }
276 |
277 | FacebookSendDirective.$inject = ['facebookService'];
278 |
279 | angular.module('angularjs-facebook-sdk.directives')
280 | .directive('afbSend', FacebookSendDirective);
281 | function FacebookShareDirective(facebookService) {
282 | return {
283 | restrict: 'E',
284 | replace: true,
285 | template: '',
286 | scope: {
287 | href: '@href',
288 | type: '@type'
289 | },
290 | link: function (scope, element) {
291 | facebookService.ready.then(function () {
292 | FB.XFBML.parse(element[0]);
293 | });
294 | }
295 | };
296 | }
297 |
298 | FacebookShareDirective.$inject = ['facebookService'];
299 |
300 | angular.module('angularjs-facebook-sdk.directives')
301 | .directive('afbShareButton', FacebookShareDirective);
302 | angular.module('angularjs-facebook-sdk.services')
303 | .provider('facebookConfig', function () {
304 | var _appId = null;
305 | var _sdkVersion = 'v2.9';
306 | var _userOptions = {};
307 | var _langCode = 'en_US';
308 | var _debug = false;
309 | var _autoInit = true;
310 |
311 | /**
312 | * Set the Facebook SDK application ID.
313 | *
314 | * @param {Number} appId The application ID.
315 | */
316 | this.setAppId = function setAppId(appId) {
317 | _appId = appId;
318 | };
319 |
320 | /**
321 | * Set the Facebook SDK version.
322 | *
323 | * @param {String} sdkVersion The SDK version.
324 | */
325 | this.setSdkVersion = function setSdkVersion(sdkVersion) {
326 | _sdkVersion = sdkVersion;
327 | };
328 |
329 | /**
330 | * Set the language of the framework.
331 | * By default the en_US is used.
332 | *
333 | * @param {String} langCode The language code.
334 | */
335 | this.setLanguage = function setLanguage(langCode) {
336 | _langCode = langCode;
337 | };
338 |
339 | /**
340 | * Enable/Disable the debug for Facebook SDK.
341 | *
342 | * @param {Boolean} enableDebug Wheather to enable or disable the debug.
343 | */
344 | this.setDebug = function setDebug(enableDebug) {
345 | _debug = enableDebug;
346 | };
347 |
348 | /**
349 | * [setOptions description]
350 | *
351 | * @param {[type]} options [description]
352 | */
353 | this.setOptions = function setOptions(options) {
354 | _userOptions = options;
355 | };
356 |
357 |
358 | /**
359 | * Enable/Disable the automatic initialization.
360 | *
361 | * @param {Boolean} enableAutoInit Wheather to enable/disable the auto initialization.
362 | */
363 | this.autoInit = function autoInit(enableAutoInit) {
364 | _autoInit = enableAutoInit;
365 | };
366 |
367 | /**
368 | * [FacebookProviderFactoryFn description]
369 | */
370 | function FacebookProviderFactoryFn($rootScope, $window, $q) {
371 | var defaultOptions = {
372 | appId: _appId,
373 | version: _sdkVersion,
374 | status: true,
375 | xfbml: true
376 | };
377 |
378 | var initDefer = $q.defer();
379 | var initOpts = angular.extend(defaultOptions, _userOptions);
380 |
381 | if (initOpts.version != _sdkVersion) {
382 | _sdkVersion = initOpts.version;
383 | }
384 |
385 | /**
386 | * Hook up a method on the window object. This way we can be notified
387 | * when the Facebook SDK is ready to be used.
388 | *
389 | * The initDefer promise is resolved inside this method.
390 | *
391 | * @return {[type]} [description]
392 | */
393 | $window.fbAsyncInit = function fbAsyncInit() {
394 | FB.init(initOpts);
395 |
396 | $rootScope.$apply(function () {
397 | initDefer.resolve();
398 | });
399 | };
400 |
401 | // The public API
402 | return {
403 | appId: _appId,
404 | sdkVersion: _sdkVersion,
405 | lang: _langCode,
406 | debug: _debug,
407 | autoInit: _autoInit,
408 |
409 | // The initialization promise
410 | initialization: initDefer.promise,
411 |
412 | /**
413 | * Initialize the Facebook SDK for Javascript.
414 | * This will load the SDK using the configuration passed to the provider.
415 | *
416 | * @return {Promise} The initialize Promise instance.
417 | */
418 | init: function () {
419 | (function (d, s, id) {
420 | var js, fjs = d.getElementsByTagName(s)[0];
421 | if (d.getElementById(id)) {
422 | return;
423 | }
424 | js = d.createElement(s);
425 | js.id = id;
426 | js.src = "//connect.facebook.net/" + _langCode + (_debug ? "/all/debug.js" : (_sdkVersion.substring(0, 2) == 'v2' ? "/sdk.js" : "/all.js"));
427 | fjs.parentNode.insertBefore(js, fjs);
428 | }(document, 'script', 'facebook-jssdk'));
429 |
430 | return initDefer.promise;
431 | }
432 | };
433 | }
434 |
435 | FacebookProviderFactoryFn.$inject = ['$rootScope', '$window', '$q'];
436 |
437 | this.$get = FacebookProviderFactoryFn;
438 | });
439 | function FacebookService(facebookConfig, $q, $rootScope) {
440 | var eventEmitter = $rootScope.$new();
441 |
442 | return {
443 | ready: facebookConfig.initialization,
444 |
445 | Event: {
446 | /**
447 | * FB.Event.subscribe allows you to define callbacks that will be called when
448 | * certain events take place on your site. These events include:
449 | *
450 | * - Logging in or logging out via Facebook Login
451 | * - Someone likes or unlikes a page via an embedded like button
452 | * - Rendering of social plugins
453 | * - Comments are added or removed
454 | * - Someone sending a message to your page or a friend via an embedded send button
455 | *
456 | * This method is a wrapper for the original event subscriber. We need to wrap the callback
457 | * call in a Scope.prototype.$apply method to let AngularJS know when it need to update bindings,
458 | * dispatch other promises among other things.
459 | *
460 | * @param {String} eventName The event name.
461 | * @return {Promise}
462 | */
463 | subscribe: function (eventName, callback) {
464 | var eventHandler = function () {
465 | var args = Array.prototype.slice.call(arguments, 0);
466 |
467 | $rootScope.$apply(function () {
468 | callback.apply(null, args);
469 | });
470 | };
471 |
472 | // Here we store a reference to the wrapped method so that we can unsubscribe the function correctly.
473 | callback.$$eventHandler = eventHandler;
474 |
475 | // Delegate the subscription to Facebook SDK
476 | FB.Event.subscribe(eventName, eventHandler);
477 | },
478 |
479 | /**
480 | * Removes handlers on events so that it no longer invokes your callback when the event fires.
481 | *
482 | * @return {[type]} [description]
483 | */
484 | unsubscribe: function (eventName, callback) {
485 | FB.Event.unsubscribe(eventName, callback.$$eventHandler);
486 | }
487 | },
488 |
489 | /**
490 | * This method lets you make calls to the Graph API.
491 | *
492 | * @param {string} path
493 | * This is the Graph API endpoint path that you want to call.
494 | * You can read the Graph API reference docs to see which endpoint you want to use.
495 | * This is a required parameter.
496 | *
497 | * @param {enum{get, post, delete}} method
498 | * This is the HTTP method that you want to use for the API request.
499 | * Consult the Graph API reference docs to see which method you need to use.
500 | * Default is get
501 | *
502 | * @param {object} params
503 | * This is an object consisting of any parameters that you want to pass into your Graph API call.
504 | * The parameters that can be used vary depending on the endpoint being called, so check the
505 | * Graph API reference docs for full lists of available parameters. One parameter of note is
506 | * access_token which you can use to make an API call with a Page access token.
507 | * App access tokens should never be used in this SDK as it is client-side, and your app secret would be exposed.
508 | *
509 | * @param {Function} callback
510 | * This is the function that is triggered whenever the API returns a response.
511 | * The response object available to this function contains the API result.
512 | *
513 | * @return {Promise}
514 | */
515 | api: function (path, method, params) {
516 | var args = Array.prototype.slice.call(arguments, 0);
517 | var defer = $q.defer();
518 |
519 | this.ready.then(function () {
520 | args.push(function apiCallback(response) {
521 | // We need to use $apply here because the FB.api callback
522 | // is outside the AngularJS kingdom. So we're telling it to
523 | // dispatch the deferred resolution ASAP.
524 | $rootScope.$apply(function () {
525 | defer.resolve(response);
526 | });
527 | });
528 |
529 | // Where we delegate the call to the FB.api method.
530 | FB.api.apply(null, args);
531 | });
532 |
533 | return defer.promise;
534 | },
535 |
536 | /**
537 | * This method is used to trigger different forms of Facebook created UI dialogs.
538 | *
539 | * @param {[type]} params
540 | * A collection of parameters that control which dialog is loaded, and relevant settings. Click for more info.
541 | *
542 | * @return {Promise}
543 | */
544 | ui: function (params) {
545 | var args = Array.prototype.slice.call(arguments, 0);
546 | var defer = $q.defer();
547 |
548 | this.ready.then(function () {
549 | args.push(function apiCallback(response) {
550 | // We need to use $apply here because the FB.api callback
551 | // is outside the AngularJS kingdom. So we're telling it to
552 | // dispatch the deferred resolution ASAP.
553 | $rootScope.$apply(function () {
554 | defer.resolve(response);
555 | });
556 | });
557 |
558 | // Where we delegate the call to the FB.api method.
559 | FB.ui.apply(null, args);
560 | });
561 |
562 | return defer.promise;
563 | },
564 |
565 | /**
566 | * Calling FB.login prompts the user to authenticate your application using the OAuth Dialog.
567 | *
568 | * Calling FB.login results in the JS SDK attempting to open a popup window. As such, this method should only
569 | * be called after a user click event, otherwise the popup window will be blocked by most browsers.
570 | *
571 | * On Canvas, if the user is 'unknown' (that is, when the login status == 'unknown'), do not use the JS SDK
572 | * to sign in the user, instead do a full redirect of the page to the oauth dialog so that we get a consistent state.
573 | *
574 | * @return {Promise}
575 | */
576 | login: function (opts) {
577 | opts = opts || {};
578 |
579 | var defer = $q.defer();
580 |
581 | this.ready.then(function () {
582 | FB.login(function () {
583 | var loginArgs = arguments;
584 | $rootScope.$apply(function () {
585 | defer.resolve.apply(this, loginArgs);
586 | });
587 | }, opts);
588 | });
589 |
590 | return defer.promise;
591 | },
592 |
593 | /**
594 | * Log the user out of your site and Facebook
595 | *
596 | * @return {Promise}
597 | */
598 | logout: function () {
599 | var defer = $q.defer();
600 |
601 | this.ready.then(function () {
602 | FB.logout(function () {
603 | defer.resolve.apply(this, arguments);
604 | });
605 | });
606 |
607 | return defer.promise;
608 | },
609 |
610 | /**
611 | * FB.getLoginStatus allows you to determine if a user is logged in to Facebook and has authenticated your app.
612 | *
613 | * There are three possible states for a user:
614 | * - the user is logged into Facebook and has authenticated your application (connected)
615 | * - the user is logged into Facebook but has not authenticated your application (not_authorized)
616 | * - the user is not logged into Facebook at this time and so we don't know if they've authenticated your
617 | * application or not (unknown)
618 | * - With social application, knowing which of the these three states the user is in is one of the
619 | * first things your application needs to know upon page load.
620 | *
621 | * Reponse example:
622 | * {
623 | * status: 'connected',
624 | * authResponse: {
625 | * accessToken: '...',
626 | * expiresIn:'...',
627 | * signedRequest:'...',
628 | * userID:'...'
629 | * }
630 | * }
631 | *
632 | * @return {Promise}
633 | */
634 | getLoginStatus: function () {
635 | var defer = $q.defer();
636 |
637 | this.ready.then(function () {
638 | FB.getLoginStatus(function () {
639 | defer.resolve.apply(this, arguments);
640 | });
641 | });
642 |
643 | return defer.promise;
644 | }
645 | };
646 | }
647 |
648 | FacebookService.$inject = ['facebookConfig', '$q', '$rootScope'];
649 |
650 | angular.module('angularjs-facebook-sdk.services')
651 | .factory('facebookService', FacebookService);
652 | })(window, document);
653 |
--------------------------------------------------------------------------------