~justinmcp/unity-chromium-extension/13.10

« back to all changes in this revision

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

  • Committer: Alexandre Abreu
  • Date: 2012-03-23 02:31:15 UTC
  • Revision ID: alexandre.abreu@canonical.com-20120323023115-zi0jnr824x3wcjnu
Fixes to build; expand npapi; add sanitizer; fixes to js

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// copy from lp:unity-firefox-extension/unity-firefox-extension/content/unity-api.js
 
2
// It should be sync with it.
 
3
 
 
4
// var EXPORTED_SYMBOLS = [ "makeAPI" ];
 
5
 
 
6
console.log ("unity-api.js");
 
7
 
 
8
function makeAPI (init, toDataURL, log, uwa, unity, CallbackManager) {
 
9
    var api;
 
10
    
 
11
    console.log ("makeAPI: ");
 
12
    
 
13
    function findName(func, prefix, obj) {
 
14
      
 
15
        if (!prefix) {
 
16
            return findName(func, 'Unity.', api);
 
17
        }
 
18
        var keys = Object.keys(obj);
 
19
        for (var i = 0; i < keys.length; i++) {
 
20
          log ("findName: " + func + ", " + keys[i]);
 
21
            if (typeof(keys[i]) !== 'string') {
 
22
                continue;
 
23
            }
 
24
            var descr = Object.getOwnPropertyDescriptor(obj, keys[i]);
 
25
            if (descr.value === func) {
 
26
                return prefix + keys[i];
 
27
            }
 
28
            if (descr.value instanceof Object) {
 
29
                var res = findName(func, prefix + keys[i] + '.', obj[keys[i]]);
 
30
                if (res)
 
31
                    return res;
 
32
            }
 
33
            if (obj.__lookupGetter__(keys[i]) === func) {
 
34
                return prefix + keys[i];
 
35
            }
 
36
            if (obj.__lookupSetter__(keys[i]) === func) {
 
37
                return prefix + keys[i];
 
38
            }
 
39
        }
 
40
        return null;
 
41
    };
 
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
 
 
62
    function stringifyArgs(obj) {
 
63
        var args = [];
 
64
        for (var i = 0; i < obj.length; i++) {
 
65
            args.push(stringify(obj[i]));
 
66
        }
 
67
        var res = JSON.stringify(args);
 
68
        return res.substr(1, res.length - 2);
 
69
    };
 
70
 
 
71
    function createArgumentsSanitaizer(func, argsDesc) {
 
72
        
 
73
        log('createArgumentsSanitaizer: ' + String(func) + '(' + stringifyArgs(arguments) + ')');
 
74
            
 
75
        return function () {
 
76
            var realArgs = arguments;
 
77
 
 
78
            log(String(arguments.callee) + '(' + stringifyArgs(arguments) + ')');
 
79
            
 
80
            var name = findName(arguments.callee);
 
81
            log(String(name) + '(' + stringifyArgs(arguments) + ')');
 
82
 
 
83
            if (unity.context == null) {return;}
 
84
            var k = 0;
 
85
            function argumentSanitaizer(desc, arg) {
 
86
                if (!desc) {
 
87
                    throw new InternalError("argument description is null");
 
88
                }
 
89
                if (desc.dummy) {
 
90
                    k--;
 
91
                    return null;
 
92
                }
 
93
                if (desc.obj) {
 
94
                    if (!(desc.obj instanceof Object)) {
 
95
                        throw new InternalError("invalid argument description");
 
96
                    }
 
97
                    var res = [], i;
 
98
                    for (i in desc.obj) {
 
99
                        if (desc.obj.hasOwnProperty(i)) {
 
100
                            res.push(null);
 
101
                        }
 
102
                    }
 
103
                    for (i in desc.obj) {
 
104
                        if (desc.obj.hasOwnProperty(i)) {
 
105
                            res[desc.obj[i].place] = argumentSanitaizer(desc.obj[i], arg[i]);
 
106
                        }
 
107
                    }
 
108
                    return res;
 
109
                }
 
110
                if (desc.str) {
 
111
                    if (desc.allowNull && !arg) {
 
112
                        return null;
 
113
                    }
 
114
                    if (typeof(arg) !== 'string')
 
115
                        throw new TypeError("incorrect argument");
 
116
                    return arg;
 
117
                }
 
118
                if (desc.number) {
 
119
                    if (typeof(arg) !== 'number')
 
120
                        throw new TypeError("incorrect argument");
 
121
                    return arg;
 
122
                }
 
123
                if (!desc.type) {
 
124
                    throw new InternalError("argument description miss required parameter");
 
125
                }
 
126
                if ((arg instanceof desc.type) || (desc.type === Function && ((typeof arg) === 'function'))
 
127
                    || (arg === null && desc.allowNull)) {
 
128
                    if (desc.type === Function) {
 
129
                        if (!arg) {
 
130
                            return null;
 
131
                        }
 
132
                        return CallbackManager.makeCallback(null,
 
133
                                                            function (context, user_data) {
 
134
                                                                arg();
 
135
                                                            });
 
136
                    }
 
137
                    return arg;
 
138
                } else {
 
139
                    throw new TypeError("incorrect argument");
 
140
                }
 
141
                throw new InternalError("unreacheable");
 
142
            }
 
143
            var args = [unity.context], i;
 
144
            for (i = 0; i < argsDesc.length; i++) {
 
145
                if (k >= realArgs.length && k > 0 && !argsDesc[i].dummy) {
 
146
                    throw new Error("not enough arguments");
 
147
                }
 
148
 
 
149
                var value = argumentSanitaizer(argsDesc[i], realArgs[k]);
 
150
                k++;
 
151
                if (value instanceof Array) {
 
152
                    args = args.concat(value);
 
153
                } else {
 
154
                    args.push(value);
 
155
                }
 
156
            }
 
157
 
 
158
            if (k < realArgs.length) {
 
159
                throw new Error("too much arguments");
 
160
            }
 
161
 
 
162
            return Function.apply.apply(func, [uwa, args]);
 
163
        };
 
164
    };
 
165
 
 
166
    api = {
 
167
        init: function(props) {
 
168
            console.log ('init called from api');
 
169
            init(props);
 
170
            console.log ('init call done');
 
171
        },
 
172
 
 
173
        addAction: createArgumentsSanitaizer(uwa.context_add_application_action, [{ str: true },
 
174
                                                                                  { type: Function }, { dummy: true }]),
 
175
        clearAction: createArgumentsSanitaizer(uwa.context_remove_application_action,
 
176
                                               [{ str: true }]),
 
177
 
 
178
        MusicPlayer: {
 
179
            init: createArgumentsSanitaizer(uwa.music_player_init, [{ str: true }]),
 
180
 
 
181
            onPlayPause: createArgumentsSanitaizer(uwa.music_player_on_play_pause_callback,
 
182
                                                   [{ type: Function, allowNull: true }, { dummy: true }]),
 
183
 
 
184
            onPrevious: createArgumentsSanitaizer(uwa.music_player_on_previous_callback,
 
185
                                                  [{ type: Function, allowNull: true }, { dummy: true }]),
 
186
 
 
187
            onNext: createArgumentsSanitaizer(uwa.music_player_on_next_callback,
 
188
                                              [{ type: Function, allowNull: true }, { dummy: true }]),
 
189
 
 
190
            setTrack: createArgumentsSanitaizer(uwa.music_player_set_track,
 
191
                                                [{ obj: { artist: { str: true, place: 0, allowNull: true },
 
192
                                                          album: { str: true, place: 1, allowNull: true },
 
193
                                                          title: { str: true, place: 2 },
 
194
                                                          artLocation: { str: true, place: 3, allowNull: true } } }]),
 
195
            PlaybackState: {PLAYING: 0, PAUSED:1}
 
196
        },
 
197
 
 
198
        Notification: {
 
199
            showNotification: createArgumentsSanitaizer(uwa.notification_show_notification,
 
200
                                                        [{ str: true }, { str: true }, { str: true, allowNull: true }])
 
201
        },
 
202
 
 
203
        Launcher: {
 
204
            setCount: createArgumentsSanitaizer(uwa.launcher_set_count,
 
205
                                                [{ number: true }]),
 
206
            clearCount: createArgumentsSanitaizer(uwa.launcher_clear_count,
 
207
                                                  []),
 
208
            setProgress: createArgumentsSanitaizer(uwa.launcher_set_progress,
 
209
                                                   [{ number: true }]),
 
210
            clearProgress: createArgumentsSanitaizer(uwa.launcher_clear_progress,
 
211
                                                     []),
 
212
            setUrgent: createArgumentsSanitaizer(uwa.launcher_set_urgent,
 
213
                                                 []),
 
214
            addAction: createArgumentsSanitaizer(uwa.launcher_add_action,
 
215
                                                 [{ str: true }, { type: Function }, { dummy: true }])
 
216
        },
 
217
 
 
218
        MessagingIndicator: {
 
219
            addAction: createArgumentsSanitaizer(uwa.indicator_add_action,
 
220
                                                 [{ str: true }, { type: Function }, { dummy: true }]),
 
221
            showIndicator: function(name, properties) {
 
222
                log('Unity.MessagingIndicator.showIndicator(' + stringifyArgs(arguments) + ')');
 
223
 
 
224
                if (unity.context == null) {return};
 
225
 
 
226
                if (name == null) {
 
227
                    throw new TypeError("name is null");
 
228
                }
 
229
 
 
230
                uwa.indicator_show_indicator(unity.context, String(name));
 
231
                for (i in properties) {
 
232
                    if (i == "time") {
 
233
                        uwa.indicator_set_property(unity.context, String(name), i, UnityMiscUtils.toISODate(String(properties[i])));
 
234
                    }
 
235
                    else if (i == "icon") {
 
236
                        uwa.indicator_set_property_icon(unity.context, String(name), i, String(properties[i]));
 
237
                    }
 
238
                    else if (i == "callback") {
 
239
                        var callback = CallbackManager.makeCallback (null,
 
240
                                                                     function (context, user_data) {(properties[i])()});
 
241
 
 
242
                        uwa.indicator_set_callback(unity.context, String(name), callback, null);
 
243
                    }
 
244
                    else {
 
245
                        uwa.indicator_set_property(unity.context, String(name), i, String(properties[i]));
 
246
                    }
 
247
                }
 
248
            },
 
249
            clearIndicator: createArgumentsSanitaizer(uwa.indicator_clear_indicator, [{ str: true }]),
 
250
            clearIndicators: createArgumentsSanitaizer(uwa.indicator_clear_indicators, [])
 
251
        },
 
252
 
 
253
        toDataURL: function (uri, callback, sx, sy, sw, sh) { console.log ("toDataURL");
 
254
                         // TODO resolve this
 
255
        // skip for nowx
 
256
        callback (true, null);
 
257
        return;
 
258
            toDataURL(uri, callback, sx, sy, sw, sh);
 
259
        }
 
260
    };
 
261
 
 
262
    api.MusicPlayer.__defineGetter__("canGoNext",
 
263
                                     createArgumentsSanitaizer(uwa.music_player_get_can_go_next, []));
 
264
    api.MusicPlayer.__defineGetter__("canGoPrevious",
 
265
                                     createArgumentsSanitaizer(uwa.music_player_get_can_go_previous, []));
 
266
    api.MusicPlayer.__defineGetter__("canPlay",
 
267
                                     createArgumentsSanitaizer(uwa.music_player_get_can_play, []));
 
268
    api.MusicPlayer.__defineGetter__("canPause",
 
269
                                     createArgumentsSanitaizer(uwa.music_player_get_can_pause, []));
 
270
    api.MusicPlayer.__defineGetter__("playbackState",
 
271
                                     createArgumentsSanitaizer(uwa.music_player_get_playback_state, []));
 
272
 
 
273
    api.MusicPlayer.__defineSetter__("canGoNext",
 
274
                                     createArgumentsSanitaizer(uwa.music_player_set_can_go_next, [{ number: true }]));
 
275
    api.MusicPlayer.__defineSetter__("canGoPrevious",
 
276
                                     createArgumentsSanitaizer(uwa.music_player_set_can_go_previous, [{ number: true }]));
 
277
    api.MusicPlayer.__defineSetter__("canPlay",
 
278
                                     createArgumentsSanitaizer(uwa.music_player_set_can_play, [{ number: true }]));
 
279
    api.MusicPlayer.__defineSetter__("canPause",
 
280
                                     createArgumentsSanitaizer(uwa.music_player_set_can_pause, [{ number: true }]));
 
281
    api.MusicPlayer.__defineSetter__("playbackState",
 
282
                                     createArgumentsSanitaizer(uwa.music_player_set_playback_state, [{ number: true }]));
 
283
 
 
284
    return api;
 
285
};