Index: polymer_1.0.4/bower_components/google-sheets/google-sheets.html |
diff --git a/polymer_1.0.4/bower_components/google-sheets/google-sheets.html b/polymer_1.0.4/bower_components/google-sheets/google-sheets.html |
new file mode 100755 |
index 0000000000000000000000000000000000000000..de2a5e8a39acadee9361540f97aab8b3fec67448 |
--- /dev/null |
+++ b/polymer_1.0.4/bower_components/google-sheets/google-sheets.html |
@@ -0,0 +1,412 @@ |
+<link rel="import" href="../polymer/polymer.html"> |
+<link rel="import" href="../iron-ajax/iron-ajax.html"> |
+<link rel="import" href="../google-signin/google-signin-aware.html"> |
+ |
+<!-- |
+Element for interacting with Google Sheets. |
+ |
+`<google-sheets>` pulls cell data from the Google Sheet specified by `key`. |
+A spreadsheet's key can be found in the URL when viewing it in google docs (e.g. `docs.google.com/spreadsheet/ccc?key=<KEY>#gid=12345`). |
+ |
+Optionally, pass the `tab-id` attribute to specify a particular worksheet tab in the spreadsheet. For example, the first tab would be `tab-id="1"`. If `tab` is updated at a later time, the underlying data is also updated. **API calls are cached** as to not make extraneous calls. |
+ |
+See [developers.google.com/google-apps/spreadsheets](https://developers.google.com/google-apps/spreadsheets) for full Spreadsheets API documentation. |
+ |
+#### Example |
+ |
+ <google-sheets key="..." tab-id="1" client-id="..."></google-sheets> |
+ |
+ <script> |
+ var sheet = document.querySelector('google-sheets'); |
+ |
+ sheet.addEventListener('google-sheet-data', function(e) { |
+ // this.spreadsheets - list of the user's spreadsheets |
+ // this.tab - information on the tab that was fetched |
+ // this.rows - cell row information for the tab that was fetched |
+ }); |
+ |
+ sheet.addEventListener('error', function(e) { |
+ // e.detail.response |
+ }); |
+ </script> |
+ |
+<b>Example</b> - `published` is a perf optimization and hints that the spreadsheet has been published (public): |
+ |
+ <google-sheets key="0Anye-JMjUkZZdDBkMVluMEhZMmFGeHpYdDJJV1FBRWc" published></google-sheets> |
+ |
+<b>Example</b> - leaving off the `key` returns as list of the user's spreadsheets. |
+ |
+ <google-sheets client-id="..."></google-sheets> |
+ |
+<b>Example</b> - show a list of Map markers, using data-binding features inside Polymer: |
+ |
+ <google-sheets |
+ key="0Anye-JMjUkZZdDBkMVluMEhZMmFGeHpYdDJJV1FBRWc" tab-id="1" rows="{{rows}}" |
+ client-id="..."> |
+ </google-sheets> |
+ <google-map> |
+ <template is="dom-bind"> |
+ <google-map-marker latitude="{{gsx$lat.$t}}" longitude="{{gsx$lng.$t}}"> |
+ </template> |
+ </google-map> |
+ |
+@demo |
+--> |
+ |
+ |
+<dom-module id="google-sheets"> |
+ <template> |
+ <template if="{{!published}}"> |
+ <google-signin-aware client-id="{{clientId}}" |
+ scopes="https://spreadsheets.google.com/feeds" |
+ on-google-signin-aware-success="_onSignInSuccess" |
+ on-google-signin-aware-signed-out="_onSignInFail"></google-signin-aware> |
+ </template> |
+ |
+ <iron-ajax id="publicajax" params='{"alt": "json"}' handle-as="json" |
+ on-response="_onCellRows"></iron-ajax> |
+ <iron-ajax id="listsheetsajax" params='{"alt": "json"}' handle-as="json" |
+ on-response="_onSpreadsheetList"></iron-ajax> |
+ <iron-ajax id="worksheetajax" params='{"alt": "json"}' handle-as="json" |
+ on-response="_onWorksheet"></iron-ajax> |
+ <iron-ajax id="cellrowsajax" params='{"alt": "json"}' handle-as="json" |
+ on-response="_onCellRows"></iron-ajax> |
+ |
+ </template> |
+</dom-module> |
+ |
+<script> |
+(function() { |
+ var SCOPE_ = 'https://spreadsheets.google.com/feeds'; |
+ |
+ // Minimal cache for worksheet row data. Shared across instances so subsequent |
+ // accesses are fast and API calls only happen once. |
+ var rowDataCache_ = {}; |
+ |
+ function generateCacheKey_() { |
+ return this.worksheetId_ + '_'+ this.tabId; |
+ } |
+ |
+ function getLink_(rel, links) { |
+ for (var i = 0, link; link = links[i]; ++i) { |
+ if (link.rel === rel) { |
+ return link; |
+ } |
+ } |
+ return null; |
+ } |
+ |
+ // Conversion of Worksheet Ids to GIDs and vice versa |
+ // od4 > 2 |
+ function wid_to_gid_(wid) { |
+ return parseInt(String(wid), 36) ^ 31578; |
+ } |
+ // 2 > 0d4 |
+ function gid_to_wid_(gid) { |
+ // (gid xor 31578) encoded in base 36 |
+ return parseInt((gid ^ 31578)).toString(36); |
+ } |
+ |
+ window.GoogleSheets = Polymer({ |
+ |
+ is: 'google-sheets', |
+ |
+/** |
+Fired when the spreadsheet's cell information is available. |
+ |
+@event google-sheet-data |
+@param {Object} detail |
+@param {Object} detail.data The data returned by the Spreadsheet API. |
+@param {string} detail.type The type of data that was fetched. One of 'spreadsheets', 'tab', 'rows' to correspond to the feed type. |
+*/ |
+ properties: { |
+ /** |
+ * A Google Developers client ID. Obtain from [console.developers.google.com](https://console.developers.google.com). Required for accessing a private spreadsheet. Optional if accessing a public spreadsheet. |
+ */ |
+ clientId: { |
+ type: String, |
+ value: '', |
+ observer: '_configUpdate' |
+ }, |
+ |
+ /** |
+ * The key of the spreadsheet. This can be found in the URL when viewing |
+ * the document is Google Docs (e.g. `docs.google.com/spreadsheet/ccc?key=<KEY>`). |
+ * |
+ * Leaving off this attribute still returns a list of the users spreadsheets in the `spreadsheets` property. |
+ */ |
+ key: { |
+ type: String, |
+ value: '', |
+ observer: '_keyChanged' |
+ }, |
+ |
+ /** |
+ * Tab within a spreadsheet. For example, the first tab in a spreadsheet |
+ * would be `tab-id="1"`. |
+ */ |
+ tabId: { |
+ type: Number, |
+ value: 1, |
+ observer: '_configUpdate' |
+ }, |
+ |
+ /** |
+ * A hint that the spreadsheet is published publicly in Google Docs. Used as a performance optimization. |
+ * Make sure the sheet is also publicly viewable by anyone in the Share settings. |
+ * |
+ * @attribute published |
+ * @type boolean |
+ * @default false |
+ */ |
+ published: { |
+ type: Boolean, |
+ value: false, |
+ observer: '_configUpdate' |
+ }, |
+ |
+ _worksheetId: { |
+ type: String, |
+ value: null, |
+ readOnly: true |
+ }, |
+ |
+ /** |
+ * The fetched sheet corresponding to the `key` attribute. |
+ */ |
+ sheet: { |
+ type: Object, |
+ value: function() { return {}; }, |
+ readOnly: true, |
+ notify: true, |
+ observer: '_sheetChanged' |
+ }, |
+ |
+ /** |
+ * Meta data about the particular tab that was retrieved for the spreadsheet. |
+ */ |
+ tab: { |
+ type: Object, |
+ value: function() { return {}; }, |
+ readOnly: true, |
+ notify: true, |
+ observer: '_tabChanged' |
+ }, |
+ |
+ /** |
+ * If a spreadsheet `key` is specified, returns a list of cell row data. |
+ */ |
+ rows: { |
+ type: Array, |
+ value: function() { return []; }, |
+ readOnly: true, |
+ notify: true |
+ }, |
+ |
+ /** |
+ * List of the user's spreadsheets. Shared across instances. |
+ */ |
+ spreadsheets: { |
+ type: Array, |
+ readOnly: true, |
+ value: function() { return []; } |
+ }, |
+ |
+ /** |
+ * The URL to open this spreadsheet in Google Sheets. |
+ */ |
+ openInGoogleDocsUrl: { |
+ type: String, |
+ computed: '_computeGoogleDocsUrl(key)', |
+ notify: true |
+ } |
+ }, |
+ |
+ _computeGoogleDocsUrl: function(key) { |
+ var url = 'https://docs.google.com/spreadsheet/'; |
+ if (key) { |
+ url += 'ccc?key=' + key; |
+ } |
+ return url; |
+ }, |
+ |
+ _configUpdate: function(key, published, tabId, clientId) { |
+ this._tabIdChanged(); |
+ }, |
+ |
+ _keyChanged: function(newValue, oldValue) { |
+ // TODO(ericbidelman): need to better handle updates to the key attribute. |
+ // Below doesn't account for private feeds. |
+ if (this.published) { |
+ var url = SCOPE_ + '/list/' + this.key + '/' + |
+ this.tabId + '/public/values'; |
+ this.$.publicajax.url = url; |
+ this.$.publicajax.generateRequest(); |
+ } |
+ }, |
+ |
+ _tabIdChanged: function(newValue, oldValue) { |
+ if (this.worksheetId_) { |
+ this._getCellRows(); |
+ } else if (this.published) { |
+ this._keyChanged(); |
+ } |
+ }, |
+ |
+ _sheetChanged: function(newValue, oldValue) { |
+ if (!this.sheet.title) { |
+ return; |
+ } |
+ |
+ // Make metadata easily accessible on sheet object. |
+ var authors = this.sheet.author && this.sheet.author.map(function(a) { |
+ return {email: a.email.$t, name: a.name.$t}; |
+ }); |
+ |
+ this.set('sheet.title', this.sheet.title.$t); |
+ this.set('sheet.updated', new Date(this.sheet.updated.$t)); |
+ this.set('sheet.authors', authors); |
+ |
+ //this.worksheetId_ = this.sheet.id.$t.split('/').slice(-1)[0]; |
+ this._setWorksheetId_(this.sheet.id.$t.split('/').slice(-1)[0]); |
+ this._getWorksheet(); |
+ }, |
+ |
+ _tabChanged: function(newValue, oldValue) { |
+ if (!this.tab.title) { |
+ return; |
+ } |
+ |
+ var authors = this.tab.authors = this.tab.author && this.tab.author.map(function(a) { |
+ return {email: a.email.$t, name: a.name.$t}; |
+ }); |
+ |
+ this.set('tab.title', this.tab.title.$t); |
+ this.set('tab.updated', new Date(this.tab.updated.$t)); |
+ this.set('tab.authors', authors); |
+ |
+ this.fire('google-sheet-data', { |
+ type: 'tab', |
+ data: this.tab |
+ }); |
+ }, |
+ |
+ _onSignInSuccess: function(e, detail) { |
+ var oauthToken = gapi.auth.getToken(); |
+ |
+ var headers = { |
+ 'Authorization': 'Bearer ' + oauthToken.access_token |
+ }; |
+ |
+ this.$.listsheetsajax.headers = headers; |
+ this.$.worksheetajax.headers = headers; |
+ this.$.cellrowsajax.headers = headers; |
+ |
+ // TODO(ericbidelman): don't make this call if this.spreadsheets is |
+ // already populated from another instance. |
+ this._listSpreadsheets(); |
+ }, |
+ |
+ _onSignInFail: function(e, detail) { |
+ // TODO(ericbidelman): handle this in some way. |
+ console.log(e, e.type); |
+ }, |
+ |
+ _listSpreadsheets: function() { |
+ var url = SCOPE_ + '/spreadsheets/private/full'; |
+ this.$.listsheetsajax.url = url; |
+ this.$.listsheetsajax.generateRequest(); |
+ }, |
+ |
+ _onSpreadsheetList: function(e) { |
+ e.stopPropagation(); |
+ |
+ var feed = e.target.lastResponse.feed; |
+ |
+ this.spreadsheets = feed.entry; |
+ |
+ this.fire('google-sheet-data', { |
+ type: 'spreadsheets', |
+ data: this.spreadsheets |
+ }); |
+ |
+ // Fetch worksheet feed if key was given and worksheet exists. |
+ if (this.key) { |
+ for (var i = 0, entry; entry = feed.entry[i]; ++i) { |
+ var altLink = getLink_('alternate', entry.link); |
+ if (altLink && altLink.href.indexOf(this.key) != -1) { |
+ this.sheet = entry; |
+ break; |
+ } |
+ } |
+ } |
+ }, |
+ |
+ _getWorksheet: function() { |
+ if (!this.worksheetId_) { |
+ throw new Error('workesheetId was not given.'); |
+ } |
+ |
+ var url = SCOPE_ + '/worksheets/' + this.worksheetId_ + |
+ '/private/full/' + this.tabId; |
+ this.$.worksheetajax.url = url; |
+ this.$.worksheetajax.generateRequest(); |
+ }, |
+ |
+ _onWorksheet: function(e) { |
+ e.stopPropagation(); |
+ |
+ // this.tab = e.target.lastResponse.entry; |
+ this._setTab(e.target.lastResponse.entry); |
+ this._getCellRows(); |
+ }, |
+ |
+ _getCellRows: function() { |
+ // Use cached data if available. |
+ var key = generateCacheKey_.call(this); |
+ if (key in rowDataCache_) { |
+ this._onCellRows(null, null, rowDataCache_[key]); |
+ |
+ return; |
+ } |
+ |
+ var url = SCOPE_ + '/list/' + |
+ this.worksheetId_ + '/' + this.tabId + |
+ '/private/full'; |
+ this.$.cellrowsajax.url = url; |
+ this.$.cellrowsajax.generateRequest(); |
+ }, |
+ |
+ _onCellRows: function(e) { |
+ e.stopPropagation(); |
+ |
+ var feed = e.target.lastResponse.feed; |
+ |
+ // Cache data if key doesn't exist. |
+ var key = generateCacheKey_.call(this); |
+ if (!(key in rowDataCache_)) { |
+ rowDataCache_[key] = {response: {feed: feed}}; |
+ } |
+ |
+ // this.rows = feed.entry; |
+ this._setRows(feed.entry); |
+ var authors = feed.author && feed.author.map(function(a) { |
+ return {email: a.email.$t, name: a.name.$t}; |
+ }); |
+ this.set('rows.authors', authors); |
+ |
+ if (this.published) { |
+ // this.tab = feed; |
+ this._setTab(feed); |
+ } |
+ |
+ this.fire('google-sheet-data', { |
+ type: 'rows', |
+ data: this.rows |
+ }); |
+ } |
+ |
+ }); |
+ |
+})(); |
+</script> |