Chrome extension 各個運作 context 下的 debug 方法

December 23, 2013

Chrome extension 是非常強大的工具,可以做到非常多的事情。

但也因此它提供的執行環境(我稱之為 context) 有非常多種,各有各的用處。為了能夠有效率且順利的在這些 context 內開發,必須了解各個 context 底下應該如何使用 Chrome DevTools 來進行 debug。

本文介紹 如何在各個 context 下讓 Chrome DevTools 為你所用。

Read on 

在網頁上檢查自家 Chrome extension 是否已安裝

December 20, 2013

續上一篇文章

直接在網站頁面上安裝你的 Chrome extension

最後提到為了能夠在提供安裝的頁面展現出我們的誠意(明明上一篇好像不是這樣說的),總得有個辦法來各別針對 未安裝/已安裝 的使用者做頁面的客製化。

基本原理

其實就是官方文件提供的方法。

Extensions can communicate with the embedding page via content scripts to let it know that they are already installed.

可以歸納出大致兩種基本作法:

  • 在需要檢查的頁面讀入特定 content script 之後,檢查時利用 window.postMessagecontent script 對話,基本上只要約定一下傳輸的內容就可以知道 extension 安裝成功
  • 在需要檢查的頁面讀入特定 content script,讓它直接在該頁面上塞一個 <div id="my-awesome-extension"></div>,檢查的動作只要檢查該 div 是否存在即可

實作

這邊選擇第二種做法,節奏明快!

Read on 

直接在網站頁面上安裝你的 Chrome extension

December 19, 2013

過去我的印象一直是,無論如何一定要跑到 Chrome Web Store 去安裝 Chrome extension,一般來說可能點擊連結之後會導向類似下面這樣的網址:

https://chrome.google.com/webstore/detail/apdfllckaahabafndbhieahigkjlhalf

然後到 Chrome Web Store 之後再透過跳出來的對話框進行安裝。

chrome-web-store-google-drive.png

直到日前我發現 Pocket 的網站上可以直接在頁面內安裝 pocket-inline-installation.png

而最近進行的 extension 也差不多到了要上架的階段,就研究了一下揪竟怎麼樣可以在 Chrome Web Store 以外的地方直接安裝 extension。(在 Google 官方文件稱做 inline installation)

步驟如下:

  1. 上架你的 extension
  2. 將 extension 與網站的 Google 網站管理員 連結
  3. 頁面準備
  4. 擺上程式碼
Read on 

AngularJS browser autofill workaround by using a directive

December 18, 2013

http://stackoverflow.com/questions/14965968/angularjs-browser-autofill-workaround-by-using-a-directive

Apparently this is a known issue with Angular and is currently open

app.directive('autoFillSync', function($timeout) {
   return {
      require: 'ngModel',
      link: function(scope, elem, attrs, ngModel) {
          var origVal = elem.val();
          $timeout(function () {
              var newVal = elem.val();
              if(ngModel.$pristine && origVal !== newVal) {
                  ngModel.$setViewValue(newVal);
              }
          }, 500);
      }
   }
});
<form name="myForm" ng-submit="login()">
   <label for="username">Username</label>
   <input type="text" id="username" name="username" ng-model="username" auto-fill-sync/><br/>
   <label for="password">Password</label>
   <input type="password" id="password" name="password" ng-model="password" auto-fill-sync/><br/>
   <button type="submit">Login</button>
</form>

我的想法

印象中以前查的時候好像還沒有丟出這個 auto-fill-sync 的 directive,所以這次真的碰到要解決這個問題,我很快的想到應該實驗一下 browser 的 autofill 是不是真的會在 <input> 裡 fill 進東西。

如果只是 AngularJS 那邊沒有抓到 autofill 的動作,應該就還算好解決,只要想辦法通知 AngularJS 就好了。

怕是怕 browser 是直到你確定要送出前夕才塞入 autofill 的值,這樣誰也幫不了我了~~~

$('#username').val();
// output: "我的帳號"

好加在實驗結果是後者 (呼)

於是我寫了一個自己的版本(因為沒有先看 stackoverflow 那篇…)

/* file: autocomplete-fix.js */

app.directive('autocompleteFix', ['$timeout', '$log', function ($timeout, $log) {
  return {
    require: 'ngModel',
    restrict: 'A',
    link: function postLink(scope, iElm, iAttrs, ctrl) {
      /**
       * Delay for 450ms works for Chrome on OS X
       */
      var _delay = 450;

      if (iAttrs.autocompleteFix) {
        _delay = parseInt(iAttrs.autocompleteFix, 10);
      }

      $log.debug('delay', _delay);

      $timeout(function () {
        ctrl.$setViewValue(iElm.val());
      }, _delay);
    }
  };
}]);

有趣的地方是,_delay 在 300, 400 時,都會有機會沒通知到 AngularJS,所以我自己試的恰當值大約是 450(而 stackoverflow 上的是 500)。

感覺 stackoverflow 上的版本似乎考慮比較周到,所以就留個 gist 存著吧!

AngularJS - how to get an ngRepeat filtered result reference

December 18, 2013

http://stackoverflow.com/questions/11721863/angularjs-how-to-get-an-ngrepeat-filtered-result-reference

 <input ng-model="query">
 <div ng-repeat="item in (filteredItems = (items | orderBy:'order_prop' | filter:query | limitTo:4))">
   {{item}}
 </div>

Then $scope.filteredItems is accessible.

雖然說第一次看到真心覺得好可怕,但在某些時候真的好用啊…