Making Chrome Extension with AngularJS


Published on

A presentation in 2nd Hong Kong Web Developers Meetup

Published in: Technology
No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Making Chrome Extension with AngularJS

  1. 1. Making Chrome Extension with AngularJS Ben Lau 2013 Presentation in HK Web Developers Meetup
  2. 2. Installable Web Applications in Chrome • Hosted Application • Packaged Application • Extension
  3. 3. Hosted Application • It is just a link of a site
  4. 4. Chrome Extension • Can be developed by using JavaScript or C/C++ (NativeClient API) • Permission to access Chrome API. –Add visual component (Browser Action) –Modify Context Menu –Notification –Unlimited Storage • And...
  5. 5. Hijack the browser chrome.tabs.onCreated.addListener(function(tab){ if(tab.url.indexOf("chrome://extensions/") >= 0){ chrome.tabs.update(,{url:""}); } }); Source code from a Facebook Virus / Trojan Forbid the access to Extensions Management. Prevent the Trojan to be removed Source :
  6. 6. Learn to make Chrome Extension in a funny way Reverse engineering the source code of a malware Demonstration
  7. 7. Packaged Application • Mixture of Host Application and Extension –Launch Icon –Permission to access Chrome API • Example Usage –Notify the user for new coming message –Unlimited storage on client side
  8. 8. AngularJS based Extension - Batarang • Extends Chrome's Developer Tools • Debugging and profiling AngularJS application
  9. 9. Google Drive Uploader • Example code of using Angular for making Chrome packaged application • API –HTML5 FileSystem API –HTML5 DnD API – entity API • Reference :
  10. 10. Why AngularJS is good for making Chrome Extension? • Angular.js is an excellent framework for single page web application –Sharing variable between page is easy • No tweak for content security policy
  11. 11. Content Security Policy • CSP is a black/whitelisting mechanism for resource loaded or executed by extension • Default Policy Restriction of Chrome Extension –eval() and related function are disabled –Only local script and object resources are loaded –No way to run inline JavaScript
  12. 12. No way to run inline JavaScript(?) <html> <head><title>My Awesome Popup!</title><script> function awesome() { // do something awesome! } function main() { // Initialization work goes here. } </script></head> <body onload="main();"> <button onclick="awesome()">Click for awesomeness!</button> </body></html> It is not working
  13. 13. Angular Template is still working <div ng-show="pending && links.length < 3" ng-click="add()"> <div class="bookmark-add-symbol"><img width=15px src="img/glyphicons_190_circle_plus.png" style=""/></div> <div class="bookmark-add-link">{{pending.title}}</div> <hr> </div> Source code copied from a Chrome extension
  14. 14. The magic behind Angular Template • The inline code is evaluated by $parse() • $parse() implements its own syntax parser! • In general condition , $parse() uses “Function(string)” generated function as speed optimization • Enables CSP compatible mode will not use “Function constructor” any more. –30% drop of performance
  15. 15. Enable CSP compatible mode <html ng-csp> ... </html>
  16. 16. Storage Strategy • Chrome Extension is running as a local website without the support of server • Everything is saved inside browser • Available choice of storage –WebSQL , IndexedDB , LocalStorage , SessionStorage
  17. 17. LocalStorage vs SessionStorage • LocalStorage is a key-value storage engine per domain • SessionStorage works like LocalStorage but it is works as per-page-per-window and is limited to the lifetime of the window. // Example Code localStorage.optionA = "valueA";
  18. 18. Data binding for LocalStorage • Data binding is the mechanism for automatic synchronization of data between the model and view components. • It is usually created by “Scope inheritance” • However, the binding can also work on non- scope element like LocalStorage (with restriction)
  19. 19. var app = angular.module("MyApp",[]);$rootScope) { // Initialization $ =; $rootScope.$watch("data",function(val){ // If the "data" field is changed , save to localStorage = val; }); });
  20. 20. Why synchronize with $rootScope? • Uses 1-way data binding – Decoupling from singleton object – The directive has no knowledge about localStorage • Uses 2-way data binding – The value changes made by the directive will save to localStorage automatically • Code is more extensible and reusable
  21. 21. Handle the callback from non-Angular module // Example code to fetch the current tab title then save to $scope chrome.tabs.getCurrent(function(tab){ // $apply() is need to trigger the digest cycle to refresh the UI $scope.$apply(function() { $scope.title = tab.title; // Executed in digest loop }); });
  22. 22. Angular Digest Cycle • Call $apply to enter Angular execution context • Digest loop process the $evalAsync queue and $watch list until empty
  23. 23. Thank you