From 4d4eaf932b114967daed780072e7f4859077ce9b Mon Sep 17 00:00:00 2001 From: Tyler Romeo Date: Fri, 12 Aug 2016 17:12:02 -0400 Subject: [PATCH] fix($sniffer): don't use history.pushState for sandboxed Chrome apps Check in $sniffer if operating in a sandboxed Chrome app, which does not have access to chrome.app.runtime like other apps, but also does not have access to history.pushState. If inside a sandboxed Chrome app, do not try and use history.pushState, else an error will occur. See #11932 and #13945 for previous work. --- src/ng/sniffer.js | 9 +++++++-- test/ng/snifferSpec.js | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/ng/sniffer.js b/src/ng/sniffer.js index 8023bd8722ab..f65c45f57181 100644 --- a/src/ng/sniffer.js +++ b/src/ng/sniffer.js @@ -21,8 +21,13 @@ function $SnifferProvider() { this.$get = ['$window', '$document', function($window, $document) { var eventSupport = {}, // Chrome Packaged Apps are not allowed to access `history.pushState`. They can be detected by - // the presence of `chrome.app.runtime` (see https://developer.chrome.com/apps/api_index) - isChromePackagedApp = $window.chrome && $window.chrome.app && $window.chrome.app.runtime, + // the presence of `chrome.app.runtime` (see https://developer.chrome.com/apps/api_index). + // For sandboxed apps, check for an extension runtime ID, but no access to other Chrome + // runtime APIs. See https://developer.chrome.com/apps/manifest/sandbox + isChromePackagedApp = + $window.chrome && + ($window.chrome.app && $window.chrome.app.runtime || + !$window.chrome.app && $window.chrome.runtime && $window.chrome.runtime.id), hasHistoryPushState = !isChromePackagedApp && $window.history && $window.history.pushState, android = toInt((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]), diff --git a/test/ng/snifferSpec.js b/test/ng/snifferSpec.js index dd52de11ff29..46db283b06aa 100644 --- a/test/ng/snifferSpec.js +++ b/test/ng/snifferSpec.js @@ -90,6 +90,26 @@ describe('$sniffer', function() { expect(pushStateAccessCount).toBe(0); }); + + it('should not try to access `history.pushState` in sandbox Chrome Packaged Apps', function() { + var pushStateAccessCount = 0; + + var mockHistory = Object.create(Object.prototype, { + pushState: {get: function() { pushStateAccessCount++; return noop; }} + }); + var mockWindow = { + chrome: { + runtime: { + id: 'x' + } + }, + history: mockHistory + }; + + sniffer(mockWindow); + + expect(pushStateAccessCount).toBe(0); + }); });