~ps-jenkins/unity-chromium-extension/trusty-proposed

« back to all changes in this revision

Viewing changes to chromium-extension/unity-api.js

  • Committer: Tarmac
  • Author(s): Alexandre Abreu
  • Date: 2013-09-16 15:40:39 UTC
  • mfrom: (227.1.5 latest)
  • Revision ID: tarmac-20130916154039-oj5t4j3stjrog9sz
Release version 3.0
Remove tab integration
Keep webapps installation scheme
Keep website api injection but only handle the init() w/ a default desktop file generated to launch the webbrowser-app in chromeless mode
.

Approved by PS Jenkins bot, Robert Bruce Park.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
2
 
Components.utils.import("resource://unity/unity-misc-utils.js");
3
 
 
4
 
var EXPORTED_SYMBOLS = [ "makeAPI" ];
5
 
 
6
 
function makeAPI(setTimeout, contextAddApplicationActions, init, toDataURL, log, get_uwa, unity, CallbackManager, acceptDataCb) {
7
 
    var api;
8
 
    function checkString(str, allowUndef) {
9
 
        if (allowUndef && str == undefined) {
10
 
            return;
11
 
        }
12
 
        if (!str || typeof(str) !== 'string') {
13
 
            throw new TypeError("incorrect argument");
14
 
        }
15
 
   }
16
 
   function findName(func, prefix, obj) {
17
 
        if (!prefix) {
18
 
            return findName(func, 'Unity.', api);
19
 
        }
20
 
        var keys = Object.keys(obj);
21
 
        for (var i = 0; i < keys.length; i++) {
22
 
            if (typeof(keys[i]) !== 'string') {
23
 
                continue;
24
 
            }
25
 
            var descr = Object.getOwnPropertyDescriptor(obj, keys[i]);
26
 
            if (descr.value === func) {
27
 
                return prefix + keys[i];
28
 
            }
29
 
            if (descr.value instanceof Object) {
30
 
                var res = findName(func, prefix + keys[i] + '.', obj[keys[i]]);
31
 
                if (res)
32
 
                    return res;
33
 
            }
34
 
            if (obj.__lookupGetter__(keys[i]) === func) {
35
 
                return prefix + keys[i];
36
 
            }
37
 
            if (obj.__lookupSetter__(keys[i]) === func) {
38
 
                return prefix + keys[i];
39
 
            }
40
 
        }
41
 
        return null;
42
 
    }
43
 
    function stringify(obj) {
44
 
        if (obj === undefined)
45
 
            return obj;
46
 
        if (obj === null)
47
 
            return obj;
48
 
        if (typeof(obj) == 'string')
49
 
            return obj;
50
 
        if (typeof(obj) == 'number')
51
 
            return obj;
52
 
        if (typeof(obj) == 'function')
53
 
            return String(obj);
54
 
        var dump = {};
55
 
        for (var i in obj) {
56
 
            if (obj.hasOwnProperty(i))
57
 
                dump[i] = stringify(obj[i]);
58
 
        }
59
 
        return dump;
60
 
    }
61
 
    function stringifyArgs(obj) {
62
 
        var args = [];
63
 
        for (var i = 0; i < obj.length; i++) {
64
 
            args.push(stringify(obj[i]));
65
 
        }
66
 
        var res = JSON.stringify(args);
67
 
        return res.substr(1, res.length - 2);
68
 
    }
69
 
    function createArgumentsSanitaizer(func, argsDesc, callback) {
70
 
        return function () {
71
 
            var uwa = get_uwa();
72
 
 
73
 
            var realArgs = arguments;
74
 
 
75
 
            var name = findName(arguments.callee);
76
 
            log(String(name) + '(' + stringifyArgs(arguments) + ')');
77
 
 
78
 
            if (unity.context == null || unity.contextReady == false) {return;}
79
 
            var k = 0;
80
 
            function argumentSanitaizer(desc, arg) {
81
 
                if (!desc) {
82
 
                    throw new InternalError("argument description is null");
83
 
                }
84
 
                if (desc.dummy) {
85
 
                    k--;
86
 
                    return null;
87
 
                }
88
 
                if (desc.array) {
89
 
                    if (!(desc.array instanceof Object) || !(desc.array.element instanceof Object)) {
90
 
                        throw new InternalError("invalid argument description");
91
 
                    }
92
 
 
93
 
                    try {
94
 
                        for (var j = 0; j < arg.length; j++) {
95
 
                            argumentSanitaizer(desc.array.element, arg[j]);
96
 
                        }
97
 
                    } catch (x) {
98
 
                        throw new TypeError("incorrect argument");
99
 
                    }
100
 
                    return arg;
101
 
                }
102
 
                if (desc.obj) {
103
 
                    if (!(desc.obj instanceof Object)) {
104
 
                        throw new InternalError("invalid argument description");
105
 
                    }
106
 
                    var res = [], i;
107
 
                    for (i in desc.obj) {
108
 
                        if (desc.obj.hasOwnProperty(i)) {
109
 
                            res.push(null);
110
 
                        }
111
 
                    }
112
 
                    for (i in desc.obj) {
113
 
                        if (desc.obj.hasOwnProperty(i)) {
114
 
                            res[desc.obj[i].place] = argumentSanitaizer(desc.obj[i], arg[i]);
115
 
                        }
116
 
                    }
117
 
                    return res;
118
 
                }
119
 
                if (desc.str) {
120
 
                    if (desc.allowNull && !arg) {
121
 
                        return null;
122
 
                    }
123
 
                    checkString(arg, false);
124
 
                    return arg;
125
 
                }
126
 
                if (desc.number) {
127
 
                    if (typeof(arg) !== 'number' && typeof(arg) !== 'boolean')
128
 
                        throw new TypeError("incorrect argument");
129
 
                    return arg;
130
 
                }
131
 
                if (!desc.type) {
132
 
                    throw new InternalError("argument description miss required parameter");
133
 
                }
134
 
                if ((arg instanceof desc.type) || (desc.type === Function && ((typeof arg) === 'function'))
135
 
                    || (arg === null && desc.allowNull)) {
136
 
                    if (desc.type === Function) {
137
 
                        if (!arg) {
138
 
                            return null;
139
 
                        }
140
 
 
141
 
                        var id;
142
 
                        if (desc.argAsCallbackId !== undefined) {
143
 
                            id = realArgs[desc.argAsCallbackId];
144
 
                        }
145
 
                        if (desc.js)
146
 
                            return arg;
147
 
                        return CallbackManager.makeCallback(uwa.ContextActionCallbackType,
148
 
                                                            function (context, user_data) {
149
 
                                                                arg();
150
 
                                                            }, name, id);
151
 
                    }
152
 
                    return arg;
153
 
                } else {
154
 
                    throw new TypeError("incorrect argument");
155
 
                }
156
 
                throw new InternalError("unreacheable");
157
 
            }
158
 
            var args = [unity.context], i;
159
 
            for (i = 0; i < argsDesc.length; i++) {
160
 
                if (k >= realArgs.length && k > 0 && !argsDesc[i].dummy) {
161
 
                    throw new Error("not enough arguments");
162
 
                }
163
 
 
164
 
                var value = argumentSanitaizer(argsDesc[i], realArgs[k]);
165
 
                k++;
166
 
                if (argsDesc[i].obj) {
167
 
                    args = args.concat(value);
168
 
                } else {
169
 
                    args.push(value);
170
 
                }
171
 
            }
172
 
 
173
 
            if (k < realArgs.length) {
174
 
                throw new Error("too much arguments");
175
 
            }
176
 
 
177
 
            if (callback)
178
 
                callback.apply(uwa, args);
179
 
            if (func)
180
 
                return Function.apply.apply(func, [uwa, args]);
181
 
        };
182
 
    }
183
 
 
184
 
    var uwa = get_uwa();
185
 
 
186
 
    var actions = [];
187
 
    var timeoutId = null;
188
 
    function fireContextAddApplicationActions() {
189
 
        timeoutId = null;
190
 
        if (unity.context == null || unity.contextReady == false) {return;}
191
 
        contextAddApplicationActions(actions);
192
 
    }
193
 
    var firstAddStaticAction = true;
194
 
    api = {
195
 
        init: function(props) {
196
 
            var sx, sy, sw, sh;
197
 
            checkString(props.name, false);
198
 
            checkString(props.iconUrl, true);
199
 
            checkString(props.domain, true);
200
 
            checkString(props.login, true);
201
 
            checkString(props.mimeTypes, true);
202
 
            checkString(props.homepage, true);
203
 
            if (props.homepage && !/^(http|https|file):\/\//.test(props.homepage)) {
204
 
                throw new TypeError("incorrect argument");
205
 
            }
206
 
 
207
 
            try {
208
 
                sx = props.crop.sx;
209
 
                sy = props.crop.sy;
210
 
                sw = props.crop.sw;
211
 
                sh = props.crop.sh;
212
 
            } catch (e) {}
213
 
 
214
 
            if (props.crop) {
215
 
                toDataURL(props.iconUrl, function (aResult, uri) {
216
 
                    var tmp = {};
217
 
                    for (var i in props) {
218
 
                        if (props.hasOwnProperty(i)) {
219
 
                            tmp[i] = props[i];
220
 
                        }
221
 
                    }
222
 
                    tmp.iconUrl = uri;
223
 
                    init(tmp);
224
 
                }, sx, sy, sw, sh);
225
 
            } else {
226
 
                init(props);
227
 
            }
228
 
        },
229
 
        acceptData: createArgumentsSanitaizer(null, [{ array: { element: { str: true } } },
230
 
                                                   { type: Function, js: true }],
231
 
                                              acceptDataCb)
232
 
        ,
233
 
        addAction: createArgumentsSanitaizer(null, [{ str: true },
234
 
                                                    { type: Function, argAsCallbackId: 0 }],
235
 
                                                    function (context, name, callback) {
236
 
            actions.push({ name: name, callback: callback });
237
 
            if (timeoutId == null) {
238
 
                timeoutId = setTimeout(fireContextAddApplicationActions, 100);
239
 
            }
240
 
        }),
241
 
        clearAction: createArgumentsSanitaizer(uwa.context_remove_application_action,
242
 
                                               [{ str: true }], fireContextAddApplicationActions),
243
 
        clearActions: createArgumentsSanitaizer(uwa.context_remove_application_actions,
244
 
                                                [],
245
 
                                                function () {
246
 
            fireContextAddApplicationActions();
247
 
            CallbackManager.releaseCallback('Unity.addAction');
248
 
        }),
249
 
 
250
 
        MediaPlayer: {
251
 
            init: createArgumentsSanitaizer(uwa.music_player_init, [{ str: true }]),
252
 
 
253
 
            onPlayPause: createArgumentsSanitaizer(uwa.music_player_on_play_pause_callback,
254
 
                                                   [{ type: Function, allowNull: true }, { dummy: true }]),
255
 
 
256
 
            onPrevious: createArgumentsSanitaizer(uwa.music_player_on_previous_callback,
257
 
                                                  [{ type: Function, allowNull: true }, { dummy: true }]),
258
 
 
259
 
            onNext: createArgumentsSanitaizer(uwa.music_player_on_next_callback,
260
 
                                              [{ type: Function, allowNull: true }, { dummy: true }]),
261
 
 
262
 
            setTrack: createArgumentsSanitaizer(uwa.music_player_set_track,
263
 
                                                [{ obj: { artist: { str: true, place: 0, allowNull: true },
264
 
                                                          album: { str: true, place: 1, allowNull: true },
265
 
                                                          title: { str: true, place: 2 },
266
 
                                                          artLocation: { str: true, place: 3, allowNull: true } } }]),
267
 
 
268
 
            setCanGoNext: createArgumentsSanitaizer(uwa.music_player_set_can_go_next, [{ number: true }]),
269
 
 
270
 
            setCanGoPrevious: createArgumentsSanitaizer(uwa.music_player_set_can_go_previous, [{ number: true }]),
271
 
 
272
 
            setCanPlay: createArgumentsSanitaizer(uwa.music_player_set_can_play, [{ number: true }]),
273
 
 
274
 
            setCanPause: createArgumentsSanitaizer(uwa.music_player_set_can_pause, [{ number: true }]),
275
 
 
276
 
            setPlaybackState: createArgumentsSanitaizer(uwa.music_player_set_playback_state, [{ number: true }]),
277
 
 
278
 
            getPlaybackState: createArgumentsSanitaizer(null
279
 
                                                        , [{ type: Function }]
280
 
                                                        , function (callback) {
281
 
                                                          var uwa = get_uwa();
282
 
                                                          callback (uwa.music_player_get_playback_state(unity.context));
283
 
                                                        }),
284
 
 
285
 
            PlaybackState: {PLAYING: 0, PAUSED:1}
286
 
        },
287
 
 
288
 
        Notification: {
289
 
            showNotification: createArgumentsSanitaizer(uwa.notification_show_notification,
290
 
                                                        [{ str: true }, { str: true }, { str: true, allowNull: true }])
291
 
        },
292
 
 
293
 
        Launcher: {
294
 
            setCount: createArgumentsSanitaizer(uwa.launcher_set_count,
295
 
                                                [{ number: true }]),
296
 
            clearCount: createArgumentsSanitaizer(uwa.launcher_clear_count,
297
 
                                                  []),
298
 
            setProgress: createArgumentsSanitaizer(uwa.launcher_set_progress,
299
 
                                                   [{ number: true }]),
300
 
            clearProgress: createArgumentsSanitaizer(uwa.launcher_clear_progress,
301
 
                                                     []),
302
 
            setUrgent: createArgumentsSanitaizer(uwa.launcher_set_urgent,
303
 
                                                 []),
304
 
            _addAction: createArgumentsSanitaizer(uwa.launcher_add_action,
305
 
                                                  [{ str: true }, { type: Function, argAsCallbackId: 0 }, { dummy: true }]),
306
 
            _addStaticAction: createArgumentsSanitaizer(uwa.launcher_add_static_action,
307
 
                                                        [{ str: true }, { str: true }]),
308
 
            addAction: function (arg1, arg2) {
309
 
                if (typeof(arg2) === 'string') {
310
 
                    if (firstAddStaticAction)
311
 
                        uwa.launcher_remove_static_actions(unity.context);
312
 
                    firstAddStaticAction = false;
313
 
                    this._addStaticAction(arg1, arg2);
314
 
                } else {
315
 
                    this._addAction(arg1, arg2);
316
 
                }
317
 
            },
318
 
            removeAction: createArgumentsSanitaizer(uwa.launcher_remove_action,
319
 
                                                 [{ str: true }]),
320
 
            removeActions: createArgumentsSanitaizer(uwa.launcher_remove_actions,
321
 
                                                 [], function () {CallbackManager.releaseCallback('Unity.Launcher.addAction');})
322
 
        },
323
 
 
324
 
        MessagingIndicator: {
325
 
            addAction: createArgumentsSanitaizer(uwa.indicator_add_action,
326
 
                                                 [{ str: true }, { type: Function, argAsCallbackId: 0 }, { dummy: true }]),
327
 
            showIndicator: function(name, properties) {
328
 
                log('Unity.MessagingIndicator.showIndicator(' + stringifyArgs(arguments) + ')');
329
 
 
330
 
                if (unity.context == null) {return};
331
 
 
332
 
                checkString(name, false);
333
 
 
334
 
                var uwa = get_uwa();
335
 
                uwa.indicator_show_indicator(unity.context, String(name));
336
 
                for (i in properties) {
337
 
                    if (i == "time") {
338
 
                        uwa.indicator_set_property(unity.context, String(name), i, UnityMiscUtils.toISODate(properties[i]));
339
 
                    }
340
 
                    else if (i == "icon") {
341
 
                        uwa.indicator_set_property_icon(unity.context, String(name), i, String(properties[i]));
342
 
                    }
343
 
                    else if (i == "callback") {
344
 
                        var callback = CallbackManager.makeCallback(uwa.IndicatorCallbackType,
345
 
                                                                    (function (propidx) {
346
 
                                                                       return function (context, user_data) {
347
 
                                                                         (properties[propidx])();
348
 
                                                                       };
349
 
                                                                     })(i),
350
 
                                                                    'Unity.MessagingIndicator.showIndicator', name);
351
 
 
352
 
                        uwa.indicator_set_callback(unity.context, String(name), callback, null);
353
 
                    }
354
 
                    else if (i == "count") {
355
 
                        uwa.indicator_set_property(unity.context, String(name), i, String(Number(properties[i])));
356
 
                    }
357
 
                    else {
358
 
                        uwa.indicator_set_property(unity.context, String(name), i, String(properties[i]));
359
 
                    }
360
 
                }
361
 
            },
362
 
            clearIndicator: createArgumentsSanitaizer(uwa.indicator_clear_indicator, [{ str: true }]),
363
 
            clearIndicators: createArgumentsSanitaizer(uwa.indicator_clear_indicators, [], function () {CallbackManager.releaseCallback('Unity.MessagingIndicator.showIndicator');})
364
 
        }
365
 
    };
366
 
 
367
 
    return api;
368
 
}