Skip to content

Commit

Permalink
Revert "initialisation and read me update"
Browse files Browse the repository at this point in the history
This reverts commit 4fe5d96.
  • Loading branch information
Pete Martin committed Sep 7, 2013
2 parents 4fe5d96 + 437dd6f commit 8983e35
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 189 deletions.
48 changes: 23 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ Facebook SDK wrapper for AngularJS Apps.

Currently under active development.

## Tooling
## Building

This project uses grunt for tooling. To build, navigate to the root directory and run `grunt build`. To run the tests run `grunt karma:jasmine`.
This project uses grunt for tooling. To build, navigate to the root directory and run `grunt build`. The built file is located at `build/angular-facebook.min.js`.

## Support

Expand All @@ -18,25 +18,35 @@ Currently supported features of the Facebook SDK:

## Usage

### Initialisation
You will need to initialise the facebook SDK externally before bootstrapping your angular app. This is the only way I could find to get around problems with the SDKs async loading routine. If you have any ideas to improve this **please comment, or even better submit a pull request!**

Include the module in your app and initialise it during the application config block in the same manner you would initialise the FB SDK:
```javascript
window.fbAsyncInit = function() {
FB.init({
appId : 'myApplicationId',
channelUrl : '//path/to/fbChannel.html'
status : true
cookie : true
xfbml : false
});

angular.bootstrap(document, ['my-angular-js-app']);
};
```
```html
<html xmlns:ng="my-angular-js-app"> // replaces simple ng-app autoloading
```

Include the module in your app and initialise it:
```javascript
angular
.module('my-angularjs-app', ['facebook'])
.config(['$facebookProvider', function($facebookProvider) {
$facebookProvider.init({
appId: 'myFbApplicationId',
channel: '//path/to/channel.html'
});
.run(['$facebook', function($facebook) {
$facebook.init();
}]);
```

### Methods

Use `$facebook` much as you would `FB`. Calls are the same as to the traditional `FB` object, except that they use promises instead of callbacks.

```javascript
angular
.module('my-angularjs-app')
Expand All @@ -58,19 +68,7 @@ angular

The one exception to this is `$facebook.getAuthResponse` which is synchronous.

### Events

If you want to consume events via `$scope.$on` you will have to call `subscribe` when your application is run...

```javascript
angular.module('my-angularjs-app')
.run(['$facebook', function($facebook) {
$facebook.subscribe();
}]);
```

Events from the facebook SDK are then broadcast through the $rootScope of the application. The naming convention is to use the same event name as the Facebook SDK, prepended with 'facebook.' - so 'auth.authResponseChange' is broadcast as 'facebook.auth.authResponseChange. Consume these events as you would any other angular event:

Events from the facebook SDK are broadcast through the $rootScope of the application. The naming convention is to use the same event name as the Facebook SDK, prepended with 'facebook.' - so 'auth.authResponseChange' is broadcast as 'facebook.auth.authResponseChange. Consume these events as you would any other angular event:
```javascript
angular
.module('my-angularjs-app')
Expand Down
177 changes: 70 additions & 107 deletions dev/src/unmin/facebook.js
Original file line number Diff line number Diff line change
@@ -1,124 +1,87 @@
angular.module('facebook', []).provider('$facebook', function() {

var initialised = false;
var queue = [];

return {
init: function (initParams) {
window.fbAsyncInit = function() {
FB.init(initParams || {status: true, xfbml: true});
initialised = true;
};

(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s);
js.id = id;
js.src = "//connect.facebook.net/en_US/all.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
},

$get: ['$rootScope', '$q',
function($rootScope, $q){

var events = {
auth: ['login', 'authResponseChange', 'statusChange', 'logout', 'prompt'],
xfbml: ['render'],
edge: ['create', 'remove'],
comment: ['create', 'remove'],
message: ['send']
};

function subscribe() {
angular.forEach(events, function(events, domain){
angular.forEach(events, function(event) {
subscribeEvent(domain, event);
});
});
}

function subscribeEvent(domain, event) {
angular.module('facebook', []).factory('$facebook',
['$rootScope', '$window', '$q',
function($rootScope, $window, $q){

var events = {
auth: ['login', 'authResponseChange', 'statusChange', 'logout', 'prompt'],
xfbml: ['render'],
edge: ['create', 'remove'],
comment: ['create', 'remove'],
message: ['send']
};

function init() {
angular.forEach(events, function(events, domain){
angular.forEach(events, function(event) {
FB.Event.subscribe(domain+'.'+event,
function(response) {
$rootScope.$broadcast('facebook.'+domain+'.'+event, response);
}
);
}
});
});
}

function defer(func, errorPredicate, deferred) {
func(function(response){
if(errorPredicate(response)) {
$rootScope.$apply(function(){
deferred.reject(response);
});
} else {
$rootScope.$apply(function(){
deferred.resolve(response);
});
}
function wrap(func, errorPredicate) {
errorPredicate = errorPredicate || function(response) { return response && response.error; };
var deferred = $q.defer();
func(function(response){
if(errorPredicate(response)) {
$rootScope.$apply(function(){
deferred.reject(response);
});
} else {
$rootScope.$apply(function(){
deferred.resolve(response);
});
}
});
return deferred.promise;
}

function wrap(func, errorPredicate) {
errorPredicate = errorPredicate || function(response) { return response && response.error; };
var deferred = $q.defer();
if(initialised) {
defer(func, errorPredicate, deferred);
} else {
queue.push(function() {
defer(func, errorPredicate, deferred);
});
}
return deferred.promise;
}

function wrapWithArgs(func, args, errorPredicate) {
return wrap(function(callback) {
func(args, callback);
}, errorPredicate);
}

function wrapNoArgs(func, errorPredicate) {
return wrap(func, errorPredicate);
}
function wrapWithArgs(func, args, errorPredicate) {
return wrap(function(callback) {
func(args, callback);
}, errorPredicate);
}

function api(args) {
return wrapWithArgs(FB.api, args);
}
function wrapNoArgs(func, errorPredicate) {
return wrap(func, errorPredicate);
}

function ui(args) {
return wrapWithArgs(FB.ui, args);
}
function api(args) {
return wrapWithArgs(FB.api, args);
}

function getAuthResponse() {
return FB.getAuthResponse();
}
function ui(args) {
return wrapWithArgs(FB.ui, args);
}

function getLogInStatus() {
return wrapNoArgs(FB.getLoginStatus);
}
function getAuthResponse() {
return FB.getAuthResponse();
}

function login() {
return wrapNoArgs(FB.login, function(response) {
return !response || !response.authResponse;
});
}
function getLogInStatus() {
return wrapNoArgs(FB.getLoginStatus);
}

function logout() {
return wrapNoArgs(FB.logout, function() {return false;})
}
function login() {
return wrapNoArgs(FB.login, function(response) {
return !response || !response.authResponse;
});
}

return {
getAuthResponse: getAuthResponse,
getLoginStatus: getLogInStatus,
login: login,
logout: logout,
subscribe: subscribe,
api: api,
ui: ui
};
}]
function logout() {
return wrapNoArgs(FB.logout, function() {return false;})
}
});

return {
getAuthResponse: getAuthResponse,
getLoginStatus: getLogInStatus,
login: login,
logout: logout,
init: init,
api: api,
ui: ui
};
}]);
8 changes: 0 additions & 8 deletions dev/test/js/globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,4 @@ var FB = {
getLoginStatus: function(callback) {},
login: function(callback) {},
logout: function(callback) {}
};

var document = {

};

var window = {

};
60 changes: 11 additions & 49 deletions dev/test/js/jasmine/facebook.js
Original file line number Diff line number Diff line change
@@ -1,56 +1,18 @@
describe('facebook', function() {
beforeEach(module('facebook'));

describe('-> $facebookProvider', function() {
var facebookProvider;

beforeEach(function() {
var fakeModule = angular.module('test.config', function() { });
fakeModule.config(function($facebookProvider) {
facebookProvider = $facebookProvider;
});
module('facebook', 'test.config');
inject(function() {});
});

describe('-> init', function() {
it('should be defined', function() {
expect(facebookProvider.init).toBeDefined();
});

it('should init the Facebook SDK once loaded', function() {
var expected = {
appId: 'myAppId',
channel: '//path/to/channel.html'
};
facebookProvider.init(expected);
spyOn(FB, 'init');
window.fbAsyncInit();
expect(FB.init).toHaveBeenCalledWith(expected);
});
});
});
var rootScope, window, facebook;

describe('-> $facebook', function() {
var rootScope, facebook, facebookProvider;
beforeEach(inject(function($rootScope, $window, $facebook) {
rootScope = $rootScope;
window = $window;
facebook = $facebook;
}));

beforeEach(function() {
var fakeModule = angular.module('test.config', function() { });
fakeModule.config(function($facebookProvider) {
facebookProvider = $facebookProvider;
});
module('facebook', 'test.config');
inject(function($rootScope, $facebook) {
facebookProvider.init();
rootScope = $rootScope;
facebook = $facebook;

window.fbAsyncInit();
})
});

describe('-> subscribe', function() {
describe('-> init', function() {
it('should be defined', function() {
expect(facebook.subscribe).toBeDefined();
expect(facebook.init).toBeDefined();
});

var events = {
Expand All @@ -70,7 +32,7 @@ describe('facebook', function() {
spyOn(FB.Event, 'subscribe').andCallFake(function(name) {
subscribedEvents.push(name);
});
facebook.subscribe();
facebook.init();
expect(subscribedEvents).toContain(eventName);
});

Expand All @@ -81,7 +43,7 @@ describe('facebook', function() {
spyOn(FB.Event, 'subscribe').andCallFake(function(name, handler) {
subscribedEvents[name] = handler;
});
facebook.subscribe();
facebook.init();
rootScope.$on('facebook.'+eventName, function(event, args) {
response = args;
});
Expand Down

0 comments on commit 8983e35

Please sign in to comment.