Creare il Login e il Custom Form in una Chrome Extension utilizzando AngularJS.
Questa guida, vi mostrerà come salvare i vostri dati nel database, usando la vostra Chrome Extension. Innanzitutto create la vostra estensione utilizzando Yeoman, ecco a voi una guida su come crearla:
http://dev.stasbranger.com/post/78122864622/crea-la-tua-prima-chromeapp-con-yeoman
Una volta creata la vostra Chrome Extension, come nell'esempio del link qui in alto, possiamo procedere. Quello che starete per fare, è una pagina di login, in cui una volta effettuato l'accesso, passerete alla pagina successiva cioè il customform, tutto ciò utilizzando "ng-view" di AngularJS. Iniziamo subito con il vostro file manifest.json:
{ "name": "AppExtension", "version": "0.0.1", "manifest_version": 2, "description": "AppExtension", "icons": { "16": "images/icon-16.png", "128": "images/icon-128.png" }, "default_locale": "en", "background": { "scripts": [ "scripts/controllers/chromereload.js", "scripts/controllers/background.js" ] }, "browser_action": { "default_icon": { "19": "images/icon-19.png", "38": "images/icon-38.png" }, "default_title": "AppExtension", "default_popup": "index.html" }, "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'", "options_page": "views/options.html", "omnibox": { "keyword": "AppExtension" }, "content_scripts": [ { "matches": [ "http://*/*", "https://*/*" ], "css": [ "styles/main.css" ], "js": [ "scripts/controllers/contentscript.js" ], "run_at": "document_end", "all_frames": false } ], "permissions": [ "contentSettings", "cookies", "storage", "tabs", "history", "management", "http://*/*", "https://*/*" ] }
Come potrete vedere, qui sono dichiarati tutti i permessi e le pagine principali, andate ad inserire alla voce "default_popup" la vostra pagina "Index.html" che avete creato installando il generatore ufficiale di Angularjs, tutto ciò vi servirà per l'utilizzo del ng-view.
Ora andate alla vostra pagina "Index.html", dove staranno inseriti tutti i percorsi delle vostre pagine javascript e delle librerie importate con bower.
<!doctype html> <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]--> <!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]--> <!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]--> <!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]--> <head> <meta charset="utf-8"> <title></title> <meta name="description" content=""> <meta name="viewport" content="width=device-width"> <link href="http://getbootstrap.com/2.3.2/assets/css/bootstrap.css" rel="stylesheet"> <link href="http://getbootstrap.com/2.3.2/assets/css/bootstrap-responsive.css" rel="stylesheet"> <link rel="stylesheet" href="bower_components/bootstrap-timepicker/css/bootstrap-timepicker.css" /> <link rel="stylesheet" href="bower_components/jquery-ui/themes/base/minified/jquery-ui.min.css"/> <link rel="stylesheet" href="styles/main.css"> </head> <body ng-app="ExtensionApp"> <!--[if lt IE 7]> <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p> <div class="container" ng-view=""></div> <script src="bower_components/jquery/jquery.js"></script> <script src="bower_components/angular/angular.js"></script> <script src="bower_components/angular-cookies/angular-cookies.js"></script> <script src="bower_components/angular-resource/angular-resource.js"></script> <script src="bower_components/angular-sanitize/angular-sanitize.js"></script> <script src="bower_components/angular-route/angular-route.js"></script> <script src="bower_components/angular-local-storage/angular-local-storage.js"></script> <script src="bower_components/momentjs/moment.js"></script> <script src="bower_components/momentjs/lang/it.js"></script> <script src="bower_components/jquery-ui/ui/jquery.ui.datepicker.js"></script> <script src="scripts/app.js"></script> <script src="scripts/controllers/main.js"></script> <script src="scripts/controllers/login.js"></script> <script src="scripts/services/login.js"></script> <script src="scripts/controllers/popup.js"></script> <script src="scripts/controllers/logout.js"></script> <script src="scripts/services/publishing.js"></script> </body> </html>
Nella vostra pagina Index.html dovrete inserire un div con all'interno ng-view, dovrete inserire i percorsi delle vostre librerie importate con bower e vi saranno i vostri file js.
<div class="container" ng-view=""></div>
Ecco come importare le librerie necessarie per lo sviluppo della vostra estensione tramite bower:
bower install jquery
bower install angular
bower install angular-cookies
bower install angular-resource
bower install angular-sanitize
bower install angular-route
bower install angular-local-storage
bower install momentjs
bower install jquery-ui
Tutte queste librerie dovrete importarle una alla volta, con il prompt dei comandi del vostro sistema operativo, una volta terminata l'importazione di tutte le librerie, dovrete inserire nel vostro file "Index.html" i rispettivi percorsi dei file da estrarre dalle librerie dove essi sono, ecco i percorsi dei file necessari:
<script src="bower_components/jquery/jquery.js"></script> <script src="bower_components/angular/angular.js"></script> <script src="bower_components/angular-cookies/angular-cookies.js"></script> <script src="bower_components/angular-resource/angular-resource.js"></script> <script src="bower_components/angular-sanitize/angular-sanitize.js"></script> <script src="bower_components/angular-route/angular-route.js"></script> <script src="bower_components/angular-local-storage/angular-local-storage.js"></script> <script src="bower_components/momentjs/moment.js"></script> <script src="bower_components/momentjs/lang/it.js"></script> <script src="bower_components/jquery-ui/ui/jquery.ui.datepicker.js"></script>
Inserite anche i file css di bootstrap nel tag head:
<link href="http://getbootstrap.com/2.3.2/assets/css/bootstrap.css" rel="stylesheet"> <link href="http://getbootstrap.com/2.3.2/assets/css/bootstrap-responsive.css" rel="stylesheet">
Ora creiamo le pagine necessarie per lo sviluppo. Andate nel prompt dei comandi e create i services e i controller necessari, ecco come fare:
yo angular:service login
yo angular:service publishing
yo angular:controller login
yo angular:controller main
yo angular:controller popup
yo angular:controller logout
Tutti questi file js saranno importati automaticamente nel vostro file "Index.html" .
Ora passiamo alla pagina "App.js" ecco cosa dovrete fare:
'use strict'; angular.module('ExtensionApp', [ 'ngCookies', 'ngResource', 'ngSanitize', 'ngRoute', 'LocalStorageModule' ]) .config([ '$routeProvider', '$locationProvider', '$httpProvider', function ($routeProvider, $locationProvider, $httpProvider) { $routeProvider .when('/', { templateUrl: 'views/main.html', controller: 'MainCtrl' }) .when('/login', { templateUrl: 'views/login.html', controller: 'LoginCtrl' }) .when('/popup', { templateUrl: 'views/popup.html', controller: 'PopupCtrl' }) .otherwise({ redirectTo: '/' }); $locationProvider.hashPrefix('!'); /* Intercept http errors */ var interceptor = function ($rootScope, $q, $location) { function success(response) { return response; } function error(response) { var status = response.status; var config = response.config; var method = config.method; var url = config.url; if (status == 401) { $location.path( "/login" ); } else { $rootScope.error = method + " on " + url + " failed with status " + status; } return $q.reject(response); } return function (promise) { return promise.then(success, error); }; }; $httpProvider.responseInterceptors.push(interceptor); } ] ).run(function($rootScope, $http, $location, $cookieStore) { $rootScope.logout = function() { delete $rootScope.user; delete $http.defaults.headers.common['X-Auth-Token']; $cookieStore.remove('user'); $location.path("/login"); }; /* Try getting valid user from cookie or go to login page */ var originalPath = $location.path(); $location.path("/login"); var user = $cookieStore.get('user'); if (user !== undefined) { $rootScope.user = user; $http.defaults.headers.common['X-Auth-Token'] = user.token; $location.path('/popup'); } });
In questo file andate a definire la sequenza della visualizzazione delle vostre view e i relativi controlli, se l'utente è registrato nel vostro database o meno e il logout dell'utente.
Ora passiamo alla pagina di login, essa viene visualizzata al lancio dell'estensione se l'utente non è registrato sul database o in caso contrario visualizzerà il castom form, essa conterrà due caselle di testo, una per lo username e l'altra per la password, una checkbox e un pulsante per l'invio dei dati, ecco il codice:
<div class="form-login" ng-controller="LoginCtrl"> <form name="loginForm" ng-submit="login()" novalidate> <div class="form-group" ng-class="{ 'has-error' : loginForm.username.$invalid && !loginForm.username.$pristine }"> <h2 class="form-login-heading">Please log in</h2> <input class="form-control" id="username" name="username" type="text" placeholder="Email address" required ng-model="username" ng-minlength="4"> <div ng-show="loginForm.username.$dirty && loginForm.username.$invalid">Invalid: <span ng-show="loginForm.username.$error.required">Tell us your email.</span> <span ng-show="loginForm.username.$error.email">This is not a valid email.</span> <span ng-show="loginForm.username.$error.minlength" class="help-block">Username is too short.</span> </div> </div> <div class="form-group" ng-class="{ 'has-error' : loginForm.password.$invalid && !loginForm.password.$pristine }"> <input class="form-control" id="password" name="password" placeholder="Your password" type="password" type="password" required ng-model="password" ng-minlength="4"> <div ng-show="loginForm.password.$dirty && loginForm.password.$invalid">Invalid: <span ng-show="loginForm.password.$error.minlength" class="help-block" >Password is too short.</span> </div> <div class="remember"> <label class="remember-me" for="remember-me"><input id="remember-me" type="checkbox">Remember me</label> </div> <input type="submit" class="btn-glow primary login" value="Log in"/> </div> <div class="alert alert-error" id="alert_alert-error" ng-show="error"> <a href="#" class="close" data-dismiss="alert">×</a> <strong>Error!</strong> The user is not registered! </div> </form> </div>
Come potete osservare, la pagina inizia con un tag div e non con un tag html, perché la view che stiamo chiamando, è già situata all'interno di un tag html nella pagina "Index.html".
Andate nella pagina "login.js", la quale sarà il controller del vostro login:
'use strict'; angular.module('ExtensionApp') .controller('LoginCtrl', function ($scope, $rootScope, $location, $http, $cookieStore, Login) { $scope.awesomeThings = [ 'HTML5 Boilerplate', 'AngularJS', 'Karma' ]; $scope.login = function() { Login.authenticate($.param({username: $('#username').val(), password: $('#password').val()}), function(user) { $rootScope.user = user; $http.defaults.headers.common['X-Auth-Token'] = user.token; $cookieStore.put('user', user); $location.path("/popup"); }); }; });
Questa pagina cattura i dati immessi nella pagina html di login e va a vedere se l'utente è registrato, se l'utente è registrato passa alla pagina html del custom form, però prima di fare tutto ciò ha bisogno di verificare che nel database l'utente esiste e per questo andiamo nella pagina "login.js" dove troverete il service del login:
'use strict'; angular.module('ExtensionApp') .service('Login', function Login($resource) { return $resource('URL del vostro database:action', {}, { authenticate: { method: 'POST', params: {'action' : 'authenticate'}, headers : {'Content-Type': 'application/x-www-form-urlencoded'} }, } ); });
Siamo a un buon punto, ora se l'utente è registrato all'interno del vostro database, apparirà la pagina del vostro custom form, all'interno di essa andremo a inserire una textarea, dove starà l'url della pagina dove state navigando e potrete digitare tutto quello che preferite e un pulsante per la conferma:
<form class="form-horizontal" role="form" name="composeForm" novalidate ng-init="init()"> <div class="modal-body"> <div class="form-group"> <label ng-click="logout()" >logout?</label> <textarea id="message" class="form-control" rows="3" ng-model="compose.message" name="message" ng-minlength=3 ng-maxlength=5000 required></textarea></br> <span ng-show="composeForm.message.$dirty && composeForm.message.$invalid">Seleziona il messaggio da scrivere.</span> </div> </div> <button type="button" class="btn btn-primary" ng-disabled="composeForm.$invalid" ng-click="getTts()">Save changes</button> </form>
Finita la pagina "popup.html" andiamo a creare il nostro controller della pagina popup, il quale avrà il compito di catturare l'URL della pagina che stiamo navigando e andrà a salvare nel database tutto ciò che noi scriveremo nella textarea:
'use strict'; angular.module('ExtensionApp') .config(['localStorageServiceProvider', function(localStorageServiceProvider){ localStorageServiceProvider.setPrefix('nome'); }]) .controller('PopupCtrl', function ($scope, $rootScope, localStorageService, $window, Publishing, $filter) { $scope.init = function(){ $rootScope.emptyCompose(); chrome.tabs.getSelected(null,function(tab) { var tablink = tab.url; $rootScope.compose.message=tablink; }); }; $scope.getTts = function(){ Publishing.save({ type:'S', message:$rootScope.compose.message, } } $rootScope.emptyCompose = function(){ $rootScope.compose = {}; console.log($rootScope.compose); } });
Per poter andare a scrivere all'interno del vostro database dovrete creare questo piccolo service, quindi entrate nella pagina che avete creato prima di nome "publishing.js":
'use strict'; angular.module('ExtensionApp') .service('Publishing', function ($resource) { return $resource('', { message:'@message', }); });
Ultimo passo è la vostra Chrome Extension è pronta, andate nella pagina "logout.js", è inserite queste poche righe di codice:
'use strict'; angular.module('ExtensionApp') .controller('LogoutCtrl', function ($scope, $rootScope) { $scope.awesomeThings = [ 'HTML5 Boilerplate', 'AngularJS', 'Karma' ]; $scope.init = function(){ $rootScope.logout(); }; });
Ecco a voi la vostra Chrome Extension è finita, spero di esservi stato utile.














