1 // Copyright (c) 2013 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 var g_next_async_call_id = 0;
6 var g_async_calls = [];
9 // Preserve first element for "oncontactschange" way event listener.
11 // Compared with addEventListener, the main difference is there is only one
12 // oncontactschange callback will be invoked. While addEventListener can
13 // add multiple callbacks when event "contactschanged" arrives.
15 // This listener can be set as "oncontactschange = function(){...};"
16 // and can be unset as "oncontactschange = null;"
17 g_listeners[0] = null;
18 var g_next_listener_id = 1;
20 function AsyncCall(resolve, reject) {
21 this.resolve = resolve;
25 function createPromise(msg) {
26 var promise = new Promise(function(resolve, reject) {
27 g_async_calls[g_next_async_call_id] = new AsyncCall(resolve, reject);
29 msg.asyncCallId = g_next_async_call_id;
30 extension.postMessage(JSON.stringify(msg));
31 ++g_next_async_call_id;
35 function _addConstProperty(obj, propertyKey, propertyValue) {
36 Object.defineProperty(obj, propertyKey, {
43 function _createConstClone(obj) {
45 for (var key in obj) {
46 _addConstProperty(const_obj, key, obj[key]);
51 extension.setMessageListener(function(json) {
52 var msg = JSON.parse(json);
54 if (msg.reply == 'contactschange') {
55 for (var id in g_listeners) {
56 if (typeof g_listeners[id] === 'function') {
57 g_listeners[id](_createConstClone(msg.data));
64 if (!msg.data.hasOwnProperty("error") || !msg.data.error) {
65 g_async_calls[msg.asyncCallId].resolve(msg.data);
67 g_async_calls[msg.asyncCallId].reject(msg.data);
70 console.log("WARNING: Message from backend doesn't have data.")
71 g_async_calls[msg.asyncCallId].resolve();
74 delete g_async_calls[msg.asyncCallId];
77 exports.save = function(contact) {
80 msg['contact'] = contact;
81 return createPromise(msg);
84 exports.find = function(options) {
87 msg['options'] = options;
88 return createPromise(msg);
91 exports.remove = function(contactId) {
93 msg['cmd'] = 'remove';
94 msg['contactId'] = contactId;
95 return createPromise(msg);
98 exports.clear = function() {
100 msg['cmd'] = 'clear';
101 return createPromise(msg);
104 function _addListener(isOnChange, callback) {
105 // Check validation of callback for addEventListener way.
106 if (!isOnChange && (typeof callback !== 'function')) {
107 console.log('Invalid parameters of callback!');
111 // Check validation of callback for oncontactschanged way, it can be null or a function.
112 if (isOnChange && (callback !== null) && (typeof callback !== 'function')) {
113 console.log('Invalid parameters of callback!');
118 if (isOnChange) { // Set callback to oncontactschange()
119 g_listeners[0] = callback;
121 } else { // Set callback by addEventListner()
122 listener_id = g_next_listener_id;
123 ++g_next_listener_id;
124 g_listeners[listener_id] = callback;
127 // Notify native code there is valid listener.
128 if (g_listeners[0] != null || g_listeners.length > 1) {
129 var msg = { 'cmd': 'addEventListener' };
130 extension.postMessage(JSON.stringify(msg));
136 exports.addEventListener = function(eventName, callback) {
137 if (eventName !== 'contactschange') {
138 console.log("Invalid parameters of eventName: "+eventName);
141 return _addListener(false, callback);
144 Object.defineProperty(exports, 'oncontactschange', {
145 set: function(callback) {
146 _addListener(true, callback);
150 window.ContactField = function(init) {
151 this.types = init.types;
152 this.preferred = init.preferred;
153 this.value = init.value;
156 window.ContactTelField = function(init) {
157 this.carrier = init.carrier;
158 this.types = init.types;
159 this.preferred = init.preferred;
160 this.value = init.value;
163 window.ContactAddress = function(init) {
164 this.types = init.types;
165 this.preferred = init.preferred;
166 this.streetAddress = init.streetAddress;
167 this.locality = init.locality;
168 this.region = init.region;
169 this.postalCode = init.postalCode;
170 this.countryName = init.countryName;
173 window.ContactName = function(init) {
174 this.displayName = init.displayName;
175 this.honorificPrefixes = init.honorificPrefixes;
176 this.givenNames = init.givenNames;
177 this.additionalNames = init.additionalNames;
178 this.familyNames = init.familyNames;
179 this.honorificSuffixes = init.honorificSuffixes;
180 this.nicknames = init.nicknames;
183 window.Contact = function(init) {
185 this.lastUpdated = new Date();
186 this.name = init.name;
187 this.emails = init.emails;
188 this.photos = init.photos;
189 this.urls = init.urls;
190 this.categories = init.categories;
191 this.addresses = init.addresses;
192 this.phoneNumbers = init.phoneNumbers;
193 this.organizations = init.organizations;
194 this.jobTitles = init.jobTitles;
195 this.birthday = init.birthday;
196 this.notes = init.notes;
197 this.impp = init.impp;
198 this.anniversary = init.anniversary;
199 this.gender = init.gender;
202 window.ContactsChangeEvent = function(init) {
203 this.added = init.added;
204 this.modified = init.modified;
205 this.removed = init.removed;