~abreu-alexandre/unity-chromium-extension/fix-1138473

« back to all changes in this revision

Viewing changes to chromium-patches/stable-23.0.1271.64/5-desktop-integration-settings.patch

  • Committer: Alexandre Abreu
  • Date: 2012-11-09 20:49:25 UTC
  • Revision ID: alexandre.abreu@canonical.com-20121109204925-3xy5tje8i0ouqkau
Add support for chromium new stable release v23

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Index: src/chrome/chrome_browser_ui.gypi
 
2
===================================================================
 
3
--- src/chrome/chrome_browser_ui.gypi   (revision 165188)
 
4
+++ src/chrome/chrome_browser_ui.gypi   (working copy)
 
5
@@ -1888,6 +1888,8 @@
 
6
         'browser/ui/webui/options/cookies_view_handler.h',
 
7
         'browser/ui/webui/options/core_options_handler.cc',
 
8
         'browser/ui/webui/options/core_options_handler.h',
 
9
+        'browser/ui/webui/options/desktop_integration_settings_handler.cc',
 
10
+        'browser/ui/webui/options/desktop_integration_settings_handler.h',
 
11
         'browser/ui/webui/options/font_settings_handler.cc',
 
12
         'browser/ui/webui/options/font_settings_handler.h',
 
13
         'browser/ui/webui/options/font_settings_utils.h',
 
14
Index: src/chrome/browser/resources/options/options.html
 
15
===================================================================
 
16
--- src/chrome/browser/resources/options/options.html   (revision 165188)
 
17
+++ src/chrome/browser/resources/options/options.html   (working copy)
 
18
@@ -18,6 +18,7 @@
 
19
 <link rel="stylesheet" href="clear_browser_data_overlay.css">
 
20
 <link rel="stylesheet" href="content_settings.css">
 
21
 <link rel="stylesheet" href="cookies_view.css">
 
22
+<link rel="stylesheet" href="desktop_integration_overlay.css">
 
23
 <link rel="stylesheet" href="do_not_track_confirm_overlay.css">
 
24
 <link rel="stylesheet" href="font_settings.css">
 
25
 <link rel="stylesheet" href="handler_options.css">
 
26
@@ -86,6 +87,7 @@
 
27
   <include src="font_settings.html">
 
28
   <include src="home_page_overlay.html">
 
29
   <include src="import_data_overlay.html">
 
30
+  <include src="desktop_integration_overlay.html">
 
31
   <include src="instant_confirm_overlay.html">
 
32
   <include src="language_options.html">
 
33
   <include src="manage_profile_overlay.html">
 
34
@@ -118,6 +120,7 @@
 
35
   <include src="content_settings_exceptions_area.html">
 
36
   <include src="cookies_view.html">
 
37
   <include src="cookies_view_app.html">
 
38
+  <include src="desktop_integration_add_website_overlay.html">
 
39
   <include src="handler_options.html">
 
40
   <include src="language_add_language_overlay.html">
 
41
   <include src="media_galleries_manager_overlay.html">
 
42
Index: src/chrome/browser/resources/options/options_bundle.js
 
43
===================================================================
 
44
--- src/chrome/browser/resources/options/options_bundle.js      (revision 165188)
 
45
+++ src/chrome/browser/resources/options/options_bundle.js      (working copy)
 
46
@@ -73,6 +73,8 @@
 
47
 <include src="cookies_list.js"></include>
 
48
 <include src="cookies_view.js"></include>
 
49
 <include src="cookies_view_app.js"></include>
 
50
+<include src="desktop_integration_add_website_overlay.js"></include>
 
51
+<include src="desktop_integration_overlay.js"></include>
 
52
 <include src="do_not_track_confirm_overlay.js"></include>
 
53
 <include src="factory_reset_overlay.js"></include>
 
54
 <include src="font_settings.js"></include>
 
55
Index: src/chrome/browser/resources/options/desktop_integration_overlay.html
 
56
===================================================================
 
57
--- src/chrome/browser/resources/options/desktop_integration_overlay.html       (revision 0)
 
58
+++ src/chrome/browser/resources/options/desktop_integration_overlay.html       (working copy)
 
59
@@ -0,0 +1,26 @@
 
60
+<div id="desktop-integration-area" class="page" hidden>
 
61
+
 
62
+  <div class="close-button"></div>
 
63
+  <h1 i18n-content="desktopIntegrationPage"></h1>
 
64
+  
 
65
+  <span i18n-content="desktopIntegrationInfoText"></span>
 
66
 
67
+  <div class="content-area">
 
68
+    <list id="domains-list"></list>
 
69
+
 
70
+    <div class="desktop-integration-lower-left">
 
71
+      <button id="desktop-integration-add-button"
 
72
+              i18n-content="add_button"></button>
 
73
+    </div>
 
74
+  </div>
 
75
+
 
76
+  <div class="action-area">
 
77
+    <div class="button-strip">
 
78
+      <button id="desktop-integrations-overlay-confirm"
 
79
+          i18n-content="ok">
 
80
+      </button>
 
81
+    </div>
 
82
+  </div>
 
83
+
 
84
+</div>
 
85
+
 
86
Index: src/chrome/browser/resources/options/desktop_integration_add_website_overlay.js
 
87
===================================================================
 
88
--- src/chrome/browser/resources/options/desktop_integration_add_website_overlay.js     (revision 0)
 
89
+++ src/chrome/browser/resources/options/desktop_integration_add_website_overlay.js     (working copy)
 
90
@@ -0,0 +1,47 @@
 
91
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
 
92
+// Use of this source code is governed by a BSD-style license that can be
 
93
+// found in the LICENSE file.
 
94
+
 
95
+///////////////////////////////////////////////////////////////////////////////
 
96
+// AddDesktopIntegrationWebsiteOverlay class:
 
97
+
 
98
+cr.define('options', function() {
 
99
+  /** @const */ var OptionsPage = options.OptionsPage;
 
100
+
 
101
+  /**
 
102
+   * @constructor
 
103
+   */
 
104
+  function AddDesktopIntegrationWebsiteOverlay() {
 
105
+    OptionsPage.call(this, 'addDesktopIntegrationWebsite',
 
106
+                     loadTimeData.getString('add_button'),
 
107
+                     'add-desktop-integration-website-overlay-page');
 
108
+  }
 
109
+
 
110
+  cr.addSingletonGetter(AddDesktopIntegrationWebsiteOverlay);
 
111
+
 
112
+  AddDesktopIntegrationWebsiteOverlay.prototype = {
 
113
+    // Inherit AddDesktopIntegrationWebsiteOverlay from OptionsPage.
 
114
+    __proto__: OptionsPage.prototype,
 
115
+
 
116
+    /**
 
117
+     * Initializes AddDesktopIntegrationWebsiteOverlay page.
 
118
+     * Calls base class implementation to starts preference initialization.
 
119
+     */
 
120
+    initializePage: function() {
 
121
+      // Call base class implementation to starts preference initialization.
 
122
+      OptionsPage.prototype.initializePage.call(this);
 
123
+      
 
124
+      // Cleanup any previously entered text.
 
125
+      $('integration-domain-url-field').value = '';
 
126
+
 
127
+      // Set up the cancel button.
 
128
+      $('add-integration-website-overlay-cancel-button').onclick = function(e) {
 
129
+        OptionsPage.closeOverlay();
 
130
+      };
 
131
+    },
 
132
+  };
 
133
+
 
134
+  return {
 
135
+    AddDesktopIntegrationWebsiteOverlay: AddDesktopIntegrationWebsiteOverlay
 
136
+  };
 
137
+});
 
138
Index: src/chrome/browser/resources/options/desktop_integration_overlay.js
 
139
===================================================================
 
140
--- src/chrome/browser/resources/options/desktop_integration_overlay.js (revision 0)
 
141
+++ src/chrome/browser/resources/options/desktop_integration_overlay.js (working copy)
 
142
@@ -0,0 +1,203 @@
 
143
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
 
144
+// Use of this source code is governed by a BSD-style license that can be
 
145
+// found in the LICENSE file.
 
146
+
 
147
+cr.define('options', function() {
 
148
+  /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
 
149
+  /** @const */ var DeletableItemList = options.DeletableItemList;
 
150
+  /** @const */ var DeletableItem = options.DeletableItem;
 
151
+
 
152
+  /**
 
153
+   * Creates a new exceptions list item.
 
154
+   * @constructor
 
155
+   * @extends {options.DeletableItem}
 
156
+   */
 
157
+  function IntegratedWebsitesListItem(domain) {
 
158
+    var el = cr.doc.createElement('div');
 
159
+    el.__proto__ = IntegratedWebsitesListItem.prototype;
 
160
+    el.domain = domain;
 
161
+    el.decorate();
 
162
+    return el;
 
163
+  }
 
164
+
 
165
+  IntegratedWebsitesListItem.prototype = {
 
166
+    __proto__: DeletableItem.prototype,
 
167
+
 
168
+    /**
 
169
+     * Called when an element is decorated as a list item.
 
170
+     */
 
171
+    decorate: function() {
 
172
+      DeletableItem.prototype.decorate.call(this);
 
173
+
 
174
+      // The stored label.
 
175
+      var label = this.ownerDocument.createElement('div');
 
176
+      label.className = 'domain-name';
 
177
+      label.textContent = this.domain;
 
178
+      this.contentElement.appendChild(label);
 
179
+
 
180
+      this.deletable = true;
 
181
+    },
 
182
+  };
 
183
+
 
184
+  /**
 
185
+   * Creates a integrated websites list.
 
186
+   * @constructor
 
187
+   * @extends {cr.ui.List}
 
188
+   */
 
189
+  var IntegratedWebsitesList = cr.ui.define('list');
 
190
+
 
191
+  IntegratedWebsitesList.prototype = {
 
192
+    __proto__: DeletableItemList.prototype,
 
193
+
 
194
+    /**
 
195
+     * Called when an element is decorated as a list.
 
196
+     */
 
197
+    decorate: function() {
 
198
+      DeletableItemList.prototype.decorate.call(this);
 
199
+      this.reset();
 
200
+    },
 
201
+
 
202
+    /** @inheritDoc */
 
203
+    createItem: function(domain) {
 
204
+      return new IntegratedWebsitesListItem(domain);
 
205
+    },
 
206
+
 
207
+    /*
 
208
+     * Adds a website domain name to the list of allowed integrated websites.
 
209
+     * @param {string} domain domain name of the website to add.
 
210
+     */
 
211
+    addWebsite: function(domain) {
 
212
+      if (!domain || this.dataModel.indexOf(domain) >= 0) {
 
213
+        return;
 
214
+      }
 
215
+      this.dataModel.push(domain);
 
216
+      this.redraw();
 
217
+      chrome.send('addIntegrationSite', [domain]);
 
218
+    },
 
219
+
 
220
+    /**
 
221
+     * Forces a revailidation of the list content. Content added while the list
 
222
+     * is hidden is not properly rendered when the list becomes visible. In
 
223
+     * addition, deleting a single item from the list results in a stale cache
 
224
+     * requiring an invalidation.
 
225
+     */
 
226
+    refresh: function() {
 
227
+      // TODO(kevers): Investigate if the root source of the problems can be
 
228
+      // fixed in cr.ui.list.
 
229
+      this.invalidate();
 
230
+      this.redraw();
 
231
+    },
 
232
+
 
233
+    /**
 
234
+     * Sets the integrated websites in the js model.
 
235
+     * @param {Object} entries A list of dictionaries of values, each dictionary
 
236
+     *     represents an exception.
 
237
+     */
 
238
+    setIntegratedWebsites: function(entries) {
 
239
+      var integratedWebsites = null;
 
240
+      try {
 
241
+        integratedWebsites = JSON.parse(entries);
 
242
+      } catch(e) {
 
243
+        console.log("Error while parsing integrated websites json: " + entries);
 
244
+        return;
 
245
+      }
 
246
+      // TODO hightlight domains differently based on permission
 
247
+      var domains = [];
 
248
+      domains = domains.concat(integratedWebsites['allowed']);
 
249
+      domains = domains.concat(integratedWebsites['dontask']);
 
250
+      this.dataModel = new ArrayDataModel(domains);
 
251
+      this.refresh();
 
252
+    },
 
253
+
 
254
+    /**
 
255
+     * Removes all integration scripts from the js model.
 
256
+     */
 
257
+    reset: function() {
 
258
+      this.dataModel = new ArrayDataModel([]);
 
259
+    },
 
260
+
 
261
+    /** @inheritDoc */
 
262
+    deleteItemAtIndex: function(index) {
 
263
+      if (index >= 0) {
 
264
+        var args = [this.dataModel.item(index)];
 
265
+        chrome.send('removeIntegrationSite', args);
 
266
+        this.dataModel.splice(index, 1);
 
267
+      }
 
268
+    },
 
269
+
 
270
+    /**
 
271
+     * The length of the list.
 
272
+     */
 
273
+    get length() {
 
274
+      return null != this.dataModel ? this.dataModel.length : 0;
 
275
+    },
 
276
+  };
 
277
+
 
278
+  var OptionsPage = options.OptionsPage;
 
279
+
 
280
+  /**
 
281
+   * DesktopIntegrationOverlay class
 
282
+   * Encapsulated handling of the 'Desktop integration' page.
 
283
+   * @class
 
284
+   */
 
285
+  function DesktopIntegrationOverlay() {
 
286
+    OptionsPage.call(this, 'desktopIntegrationOverlay',
 
287
+                     loadTimeData.getString('desktopIntegrationPage'),
 
288
+                     'desktop-integration-area');
 
289
+  }
 
290
+
 
291
+  cr.addSingletonGetter(DesktopIntegrationOverlay);
 
292
+
 
293
+  DesktopIntegrationOverlay.prototype = {
 
294
+    __proto__: OptionsPage.prototype,
 
295
+
 
296
+    /**
 
297
+     * Initialize the page.
 
298
+     */
 
299
+    initializePage: function() {
 
300
+      OptionsPage.prototype.initializePage.call(this);
 
301
+
 
302
+      var integrationList = $('domains-list');
 
303
+      IntegratedWebsitesList.decorate(integrationList);
 
304
+      $('desktop-integrations-overlay-confirm').onclick =
 
305
+          OptionsPage.closeOverlay.bind(OptionsPage);
 
306
+
 
307
+      // Set up add button.
 
308
+      $('desktop-integration-add-button').onclick = function(e) {
 
309
+        OptionsPage.navigateToPage('addDesktopIntegrationWebsite');
 
310
+      };
 
311
+
 
312
+      // Listen to add website dialog ok button.
 
313
+      var addWebsiteOkButton = $('add-integration-website-overlay-ok-button');
 
314
+      addWebsiteOkButton.addEventListener('click',
 
315
+          this.handleAddWebsiteOkButtonClick_.bind(this));
 
316
+    },
 
317
+
 
318
+    handleAddWebsiteOkButtonClick_: function () {
 
319
+      var website = $('integration-domain-url-field').value;
 
320
+      var integratedDomain = website.replace(/\s*/g, '')
 
321
+      console.log (integratedDomain);
 
322
+      $('domains-list').addWebsite(integratedDomain);
 
323
+      OptionsPage.closeOverlay();
 
324
+    },
 
325
+
 
326
+    /**
 
327
+     * Called by the options page when this page has been shown.
 
328
+     */
 
329
+    didShowPage: function() {
 
330
+      chrome.send('updateIntegratedWebsitesList');
 
331
+    },
 
332
+  };
 
333
+
 
334
+  DesktopIntegrationOverlay.setIntegratedWebsites = function(entries) {
 
335
+    $('domains-list').setIntegratedWebsites(entries);
 
336
+  };
 
337
+
 
338
+  // Export
 
339
+  return {
 
340
+    IntegratedWebsitesListItem: IntegratedWebsitesListItem,
 
341
+    IntegratedWebsitesList: IntegratedWebsitesList,
 
342
+    DesktopIntegrationOverlay: DesktopIntegrationOverlay
 
343
+  };
 
344
+});
 
345
+
 
346
Index: src/chrome/browser/resources/options/desktop_integration_overlay.css
 
347
===================================================================
 
348
--- src/chrome/browser/resources/options/desktop_integration_overlay.css        (revision 0)
 
349
+++ src/chrome/browser/resources/options/desktop_integration_overlay.css        (working copy)
 
350
@@ -0,0 +1,71 @@
 
351
+/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
 
352
+ * Use of this source code is governed by a BSD-style license that can be
 
353
+ * found in the LICENSE file. */
 
354
+
 
355
+#desktop-integration-options {
 
356
+  min-width: 550px;
 
357
+}
 
358
+
 
359
+#desktop-integration-options list {
 
360
+  min-height: 172px;
 
361
+}
 
362
+
 
363
+.desktop-integration-list-item {
 
364
+  -webkit-box-flex: 1;
 
365
+  -webkit-padding-start: 8px;
 
366
+  overflow: hidden;
 
367
+  text-overflow: ellipsis;
 
368
+}
 
369
+
 
370
+.desktop-integration-lower-left button {
 
371
+  min-width: 70px;
 
372
+}
 
373
+
 
374
+.desktop-integration-lower-left {
 
375
+  -webkit-box-flex: 0;
 
376
+  -webkit-padding-start: 12px;
 
377
+  padding-bottom: 10px;
 
378
+}
 
379
+
 
380
+#desktop-integration-column-headers {
 
381
+  -webkit-margin-start: 17px;
 
382
+  display: -webkit-box;
 
383
+  margin-top: 17px;
 
384
+}
 
385
+
 
386
+#desktop-integration-column-headers > div {
 
387
+  font-weight: bold;
 
388
+}
 
389
+
 
390
+#desktop-integration-pattern-column {
 
391
+  -webkit-box-flex: 1;
 
392
+}
 
393
+
 
394
+#desktop-integration-behavior-column {
 
395
+  width: 145px;
 
396
+}
 
397
+
 
398
+#desktop-integration-area list {
 
399
+  margin-bottom: 10px;
 
400
+  margin-top: 4px;
 
401
+}
 
402
+
 
403
+#domains-list {
 
404
+  -webkit-box-flex: 1;
 
405
+  outline: none;
 
406
+  padding: 1px 0 0;
 
407
+  width: 100%;
 
408
+}
 
409
+
 
410
+#domains-list .domain-name {
 
411
+  -webkit-box-flex: 1;
 
412
+  overflow: hidden;
 
413
+  text-overflow: ellipsis;
 
414
+  white-space: nowrap;
 
415
+}
 
416
+
 
417
+#domains-list li {
 
418
+  -webkit-padding-start: 12px;
 
419
+  padding-bottom: 2px;
 
420
+  padding-top: 2px;
 
421
+}
 
422
Index: src/chrome/browser/resources/options/desktop_integration_add_website_overlay.html
 
423
===================================================================
 
424
--- src/chrome/browser/resources/options/desktop_integration_add_website_overlay.html   (revision 0)
 
425
+++ src/chrome/browser/resources/options/desktop_integration_add_website_overlay.html   (working copy)
 
426
@@ -0,0 +1,16 @@
 
427
+<div id="add-desktop-integration-website-overlay-page" class="page" hidden>
 
428
+  <div class="close-button"></div>
 
429
+  <h1 i18n-content="add_desktop_website_title"></h1>
 
430
+
 
431
+  <div class="content-area">
 
432
+    <span i18n-content="add_desktop_website_input_label"></span>
 
433
+    <input id="integration-domain-url-field" type="url" data-type="url"
 
434
+           class="weakrtl favicon-cell hbox stretch">
 
435
+  </div>
 
436
+
 
437
+  <div class="action-area button-strip">
 
438
+    <button id="add-integration-website-overlay-cancel-button" i18n-content="cancel">
 
439
+    </button>
 
440
+    <button id="add-integration-website-overlay-ok-button" i18n-content="ok"></button>
 
441
+  </div>
 
442
+</div>
 
443
Index: src/chrome/browser/resources/options/browser_options.html
 
444
===================================================================
 
445
--- src/chrome/browser/resources/options/browser_options.html   (revision 158531)
 
446
+++ src/chrome/browser/resources/options/browser_options.html   (working copy)
 
447
@@ -377,6 +377,22 @@
 
448
 </if>
 
449
     </div>
 
450
   </section>
 
451
+
 
452
+<if expr="is_linux and not pp_ifdef('chromeos')">
 
453
+  <section id="desktop-integration-section">
 
454
+    <h3 i18n-content="advancedSectionTitleIntegration"></h3>
 
455
+    <div class="checkbox">
 
456
+      <label>
 
457
+        <input id="promptIntegrationForAnyWebsite" pref="desktop_integration_prompt.enabled"
 
458
+            metric="Options_PromptIntegration" type="checkbox">
 
459
+        <span i18n-content="promptIntegrationEnableIntegration"></span>
 
460
+      </label>
 
461
+    </div>
 
462
+    <button id="desktop-integration-button"
 
463
+        i18n-content="desktopIntegrationExceptionsSettingsButton"></button>
 
464
+  </section>
 
465
+</if>
 
466
+
 
467
 <if expr="not pp_ifdef('chromeos')">
 
468
   <section>
 
469
     <h3 i18n-content="advancedSectionTitleNetwork"></h3>
 
470
Index: src/chrome/browser/resources/options/browser_options.js
 
471
===================================================================
 
472
--- src/chrome/browser/resources/options/browser_options.js     (revision 165188)
 
473
+++ src/chrome/browser/resources/options/browser_options.js     (working copy)
 
474
@@ -367,6 +367,23 @@
 
475
             [String(event.target.options[event.target.selectedIndex].value)]);
 
476
       };
 
477
 
 
478
+      // Desktop integration section
 
479
+      if (cr.isLinux && !cr.isChromeOS) {
 
480
+        var updateButtonState = function () {
 
481
+          $('desktop-integration-button').disabled =
 
482
+            ! $('promptIntegrationForAnyWebsite').checked;
 
483
+        };
 
484
+        $('promptIntegrationForAnyWebsite').onchange = function () {
 
485
+          updateButtonState();
 
486
+          chrome.send('setDesktopIntegrationAllowed',
 
487
+                      [$('promptIntegrationForAnyWebsite').checked]);
 
488
+        };
 
489
+        updateButtonState();
 
490
+        $('desktop-integration-button').onclick = function(event) {
 
491
+          OptionsPage.navigateToPage('desktopIntegrationOverlay');
 
492
+        };
 
493
+      }
 
494
+
 
495
       // Languages section.
 
496
       $('language-button').onclick = function(event) {
 
497
         OptionsPage.navigateToPage('languages');
 
498
@@ -1008,7 +1025,25 @@
 
499
       $('factory-reset-section').hidden = false;
 
500
     },
 
501
 
 
502
+     /**
 
503
+     * Disable the desktop integration settings if needed.
 
504
+     * @private
 
505
+     */
 
506
+    disableDesktopIntegration_: function() {
 
507
+      $('desktop-integration-section').style.display = 'none';
 
508
+    },
 
509
+
 
510
     /**
 
511
+     * Disable the desktop integration settings if needed.
 
512
+     * @private
 
513
+     */
 
514
+    setDesktopIntegrationIsAllowed_: function(enabled) {
 
515
+      $('promptIntegrationForAnyWebsite').checked = enabled;
 
516
+      $('desktop-integration-button').disabled =
 
517
+        ! $('promptIntegrationForAnyWebsite').checked;
 
518
+    },
 
519
+
 
520
+    /**
 
521
      * Set the checked state of the metrics reporting checkbox.
 
522
      * @private
 
523
      */
 
524
@@ -1326,6 +1361,7 @@
 
525
   //Forward public APIs to private implementations.
 
526
   [
 
527
     'addBluetoothDevice',
 
528
+    'disableDesktopIntegration',
 
529
     'enableFactoryResetSection',
 
530
     'getCurrentProfile',
 
531
     'getStartStopSyncButton',
 
532
@@ -1339,6 +1375,7 @@
 
533
     'setFontSize',
 
534
     'setGtkThemeButtonEnabled',
 
535
     'setHighContrastCheckboxState',
 
536
+    'setDesktopIntegrationIsAllowed',
 
537
     'setMetricsReportingCheckboxState',
 
538
     'setMetricsReportingSettingVisibility',
 
539
     'setPasswordGenerationSettingVisibility',
 
540
Index: src/chrome/browser/resources/options/options.js
 
541
===================================================================
 
542
--- src/chrome/browser/resources/options/options.js     (revision 165188)
 
543
+++ src/chrome/browser/resources/options/options.js     (working copy)
 
544
@@ -14,6 +14,8 @@
 
545
     options.contentSettings.ContentSettingsExceptionsArea;
 
546
 var CookiesView = options.CookiesView;
 
547
 var CookiesViewApp = options.CookiesViewApp;
 
548
+var DesktopIntegrationOverlay = options.DesktopIntegrationOverlay;
 
549
+var AddDesktopIntegrationWebsiteOverlay = options.AddDesktopIntegrationWebsiteOverlay;
 
550
 var DoNotTrackConfirmOverlay = options.DoNotTrackConfirmOverlay;
 
551
 var FactoryResetOverlay = options.FactoryResetOverlay;
 
552
 var FontSettings = options.FontSettings;
 
553
@@ -90,6 +92,13 @@
 
554
   OptionsPage.registerOverlay(FontSettings.getInstance(),
 
555
                               BrowserOptions.getInstance(),
 
556
                               [$('fontSettingsCustomizeFontsButton')]);
 
557
+  if (cr.isLinux && !cr.isChromeos) {
 
558
+    OptionsPage.registerOverlay(AddDesktopIntegrationWebsiteOverlay.getInstance(),
 
559
+                                DesktopIntegrationOverlay.getInstance());
 
560
+    OptionsPage.registerOverlay(DesktopIntegrationOverlay.getInstance(),
 
561
+                                BrowserOptions.getInstance(),
 
562
+                                [$('desktop-integration-button')]);
 
563
+  }
 
564
   if (HandlerOptions && $('manage-handlers-button')) {
 
565
     OptionsPage.registerOverlay(HandlerOptions.getInstance(),
 
566
                                 ContentSettings.getInstance(),
 
567
Index: src/chrome/browser/ui/webui/options/desktop_integration_settings_handler.cc
 
568
===================================================================
 
569
--- src/chrome/browser/ui/webui/options/desktop_integration_settings_handler.cc (revision 0)
 
570
+++ src/chrome/browser/ui/webui/options/desktop_integration_settings_handler.cc (working copy)
 
571
@@ -0,0 +1,262 @@
 
572
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
 
573
+// Use of this source code is governed by a BSD-style license that can be
 
574
+// found in the LICENSE file.
 
575
+
 
576
+#include "chrome/browser/ui/webui/options/desktop_integration_settings_handler.h"
 
577
+
 
578
+#include <glib.h>
 
579
+#include <dlfcn.h>
 
580
+#include <vector>
 
581
+
 
582
+#include "base/bind.h"
 
583
+#include "base/bind_helpers.h"
 
584
+#include "base/logging.h"
 
585
+#include "base/string16.h"
 
586
+#include "base/string_number_conversions.h"
 
587
+#include "base/utf_string_conversions.h"
 
588
+#include "base/values.h"
 
589
+#include "chrome/browser/ui/webui/web_ui_util.h"
 
590
+#include "chrome/common/url_constants.h"
 
591
+#include "content/public/browser/web_ui.h"
 
592
+#include "grit/generated_resources.h"
 
593
+#include "grit/webkit_resources.h"
 
594
+#include "ui/base/l10n/l10n_util.h"
 
595
+
 
596
+// Not a constant but preprocessor definition for easy concatenation.
 
597
+#define kLibunityWebappsEntryPointLibName "libunity-webapps.so.0"
 
598
+
 
599
+namespace options {
 
600
+
 
601
+// TODO: -> extract to function
 
602
+DesktopIntegrationSettingsHandler::DesktopIntegrationSettingsHandler()
 
603
+    : lib_unity_webapps_handle_(NULL),
 
604
+      get_all_func_handle_(NULL),
 
605
+      remove_from_permissions_func_handle_(NULL),
 
606
+      add_allowed_domain_func_handle_(NULL),
 
607
+      is_integration_allowed_func_handle_(NULL),
 
608
+      set_integration_allowed_func_handle_(NULL) {
 
609
+}
 
610
+
 
611
+DesktopIntegrationSettingsHandler::~DesktopIntegrationSettingsHandler() {
 
612
+  if (lib_unity_webapps_handle_) {
 
613
+    dlclose (lib_unity_webapps_handle_);
 
614
+    lib_unity_webapps_handle_ = NULL;
 
615
+
 
616
+    remove_from_permissions_func_handle_ = NULL;
 
617
+    get_all_func_handle_ = NULL;
 
618
+    add_allowed_domain_func_handle_ = NULL;
 
619
+    is_integration_allowed_func_handle_ = NULL;
 
620
+    set_integration_allowed_func_handle_ = NULL;
 
621
+  }
 
622
+}
 
623
+
 
624
+/////////////////////////////////////////////////////////////////////////////
 
625
+// OptionsPageUIHandler implementation:
 
626
+void DesktopIntegrationSettingsHandler::GetLocalizedValues(
 
627
+    DictionaryValue* localized_strings) {
 
628
+  DCHECK(localized_strings);
 
629
+
 
630
+  static OptionsStringResource resources[] = {
 
631
+    { "desktopIntegrationInfoText",
 
632
+      IDS_DESKTOP_INTEGRATION_SETTINGS_OVERLAY_DESCRIPTION }
 
633
+  };
 
634
+
 
635
+  localized_strings->SetString("add_button",
 
636
+      l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_INTEGRATION_WEBSITE_ADD_BUTTON));
 
637
+  localized_strings->SetString("add_desktop_website_input_label",
 
638
+      l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_INTEGRATION_WEBSITE_ADD_TEXT));
 
639
+  localized_strings->SetString("add_desktop_website_title",
 
640
+      l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_INTEGRATION_WEBSITE_ADD_TITLE));
 
641
+
 
642
+  RegisterStrings(localized_strings, resources, arraysize(resources));
 
643
+  RegisterTitle(localized_strings, "desktopIntegrationPage",
 
644
+                IDS_DESKTOP_INTEGRATION_SETTINGS_OVERLAY_TITLE);
 
645
+}
 
646
+
 
647
+void DesktopIntegrationSettingsHandler::InitializeHandler() {
 
648
+  if (!IsUnityWebappsInitialized()) {
 
649
+    LoadUnityWebappsEntryPoint();
 
650
+  }
 
651
+}
 
652
+
 
653
+void DesktopIntegrationSettingsHandler::InitializePage() {
 
654
+  DCHECK(IsUnityWebappsInitialized());
 
655
+  LoadIntegratedWebsitesData();
 
656
+}
 
657
+
 
658
+void DesktopIntegrationSettingsHandler::RegisterMessages() {
 
659
+  web_ui()->RegisterMessageCallback(
 
660
+      std::string("addIntegrationSite"),
 
661
+      base::Bind(&DesktopIntegrationSettingsHandler::AddIntegrationSite,
 
662
+                 base::Unretained(this)));
 
663
+  web_ui()->RegisterMessageCallback(
 
664
+      std::string("setDesktopIntegrationAllowed"),
 
665
+      base::Bind(&DesktopIntegrationSettingsHandler::SetDesktopIntegrationAllowed,
 
666
+                 base::Unretained(this)));
 
667
+  web_ui()->RegisterMessageCallback(
 
668
+      std::string("removeIntegrationSite"),
 
669
+      base::Bind(&DesktopIntegrationSettingsHandler::RemoveIntegrationSite,
 
670
+                 base::Unretained(this)));
 
671
+  web_ui()->RegisterMessageCallback(
 
672
+      std::string("updateIntegratedWebsitesList"),
 
673
+      base::Bind(&DesktopIntegrationSettingsHandler::UpdateIntegratedWebsitesList,
 
674
+                 base::Unretained(this)));
 
675
+}
 
676
+
 
677
+void DesktopIntegrationSettingsHandler::LoadUnityWebappsEntryPoint() {
 
678
+  DCHECK(!IsUnityWebappsInitialized());
 
679
+
 
680
+  // TODO run on FILE thread
 
681
+  static const char* const search_paths[] = {
 
682
+    kLibunityWebappsEntryPointLibName,
 
683
+    "/usr/local/lib/" kLibunityWebappsEntryPointLibName
 
684
+    , "/usr/lib/" kLibunityWebappsEntryPointLibName
 
685
+  };
 
686
+
 
687
+  void * handle = NULL;
 
688
+  for (size_t i = 0; i < sizeof(search_paths)/sizeof(search_paths[0]); ++i) {
 
689
+    DCHECK(handle == NULL);
 
690
+    // TODO validate path?
 
691
+    handle = dlopen (search_paths[i], RTLD_LAZY|RTLD_GLOBAL);
 
692
+    if (handle) {
 
693
+      LOG(INFO) << "Found libunitywebapps entry point:" << search_paths[i];
 
694
+      break;
 
695
+    }
 
696
+  }
 
697
+  if (!handle) {
 
698
+    LOG(INFO) << "Could not load Unity Webapps entry point library";
 
699
+    return;
 
700
+  }
 
701
+
 
702
+  void * get_all_handle =
 
703
+    dlsym (handle, "unity_webapps_permissions_get_all_domains");
 
704
+  void * remove_from_permissions_handle =
 
705
+    dlsym (handle, "unity_webapps_permissions_remove_domain_from_permissions");
 
706
+  void * add_allowed_domain_handle =
 
707
+    dlsym (handle, "unity_webapps_permissions_allow_domain");
 
708
+  void * is_integration_allowed_handle =
 
709
+    dlsym (handle, "unity_webapps_permissions_is_integration_allowed");
 
710
+  void * set_integration_allowed_handle =
 
711
+    dlsym (handle, "unity_webapps_permissions_set_integration_allowed");
 
712
+
 
713
+  if (!get_all_handle ||
 
714
+      !remove_from_permissions_handle ||
 
715
+      !add_allowed_domain_handle ||
 
716
+      !is_integration_allowed_handle ||
 
717
+      !set_integration_allowed_handle) {
 
718
+    LOG(WARNING) << "Could not load Unity Webapps entry point functions";
 
719
+    dlclose(handle);
 
720
+    return;
 
721
+  }
 
722
+
 
723
+  // TODO(FIXME): cleanup that mess
 
724
+  lib_unity_webapps_handle_ = handle;
 
725
+  get_all_func_handle_ = get_all_handle;
 
726
+  remove_from_permissions_func_handle_ = remove_from_permissions_handle;
 
727
+  add_allowed_domain_func_handle_ = add_allowed_domain_handle;
 
728
+  is_integration_allowed_func_handle_ = is_integration_allowed_handle;
 
729
+  set_integration_allowed_func_handle_ = set_integration_allowed_handle;
 
730
+}
 
731
+
 
732
+bool DesktopIntegrationSettingsHandler::IsUnityWebappsInitialized() const {
 
733
+  return NULL != lib_unity_webapps_handle_
 
734
+    && NULL != get_all_func_handle_
 
735
+    && NULL != remove_from_permissions_func_handle_
 
736
+    && NULL != add_allowed_domain_func_handle_
 
737
+    && NULL != is_integration_allowed_func_handle_
 
738
+    && NULL != set_integration_allowed_func_handle_;
 
739
+}
 
740
+
 
741
+void DesktopIntegrationSettingsHandler::LoadIntegratedWebsitesData() {
 
742
+  if (!IsUnityWebappsInitialized()) {
 
743
+    web_ui()->CallJavascriptFunction(
 
744
+        "BrowserOptions.disableDesktopIntegration");
 
745
+    LOG(INFO) << "Disabling Desktop Integration options";
 
746
+    return;
 
747
+  }
 
748
+
 
749
+  typedef gboolean (* IsIntegrationAllowedFunc) (void);
 
750
+  gboolean isallowed =
 
751
+    ((IsIntegrationAllowedFunc) is_integration_allowed_func_handle_) ();
 
752
+  web_ui()->CallJavascriptFunction(
 
753
+       "BrowserOptions.setDesktopIntegrationIsAllowed",
 
754
+       base::FundamentalValue(isallowed));
 
755
+}
 
756
+
 
757
+void DesktopIntegrationSettingsHandler::UpdateIntegratedWebsitesList(
 
758
+    const base::ListValue* args) {
 
759
+  DCHECK(IsUnityWebappsInitialized());
 
760
+
 
761
+  // TODO move elsewhere
 
762
+  typedef gchar* (* GetAllDomainsFunc) (void);
 
763
+
 
764
+  gchar* all_domains = ((GetAllDomainsFunc) get_all_func_handle_) ();
 
765
+  if (all_domains) { 
 
766
+    web_ui()->CallJavascriptFunction(
 
767
+        "DesktopIntegrationOverlay.setIntegratedWebsites",
 
768
+        StringValue(all_domains));
 
769
+  }
 
770
+}
 
771
+
 
772
+void DesktopIntegrationSettingsHandler::SetDesktopIntegrationAllowed(
 
773
+    const base::ListValue* args) {
 
774
+  DCHECK(IsUnityWebappsInitialized());
 
775
+
 
776
+  // TODO move elsewhere
 
777
+  typedef void (* SetDesktopIntegrationAllowedFunc) (gboolean);
 
778
+
 
779
+  bool is_allowed;
 
780
+  if (!args->GetBoolean(0, &is_allowed)) {
 
781
+    NOTREACHED();
 
782
+    return;
 
783
+  }
 
784
+
 
785
+  LOG(INFO) << "Setting desktop integration:" << is_allowed;
 
786
+
 
787
+  ((SetDesktopIntegrationAllowedFunc) set_integration_allowed_func_handle_) (
 
788
+      is_allowed ? TRUE : FALSE);
 
789
+}
 
790
+
 
791
+void DesktopIntegrationSettingsHandler::AddIntegrationSite(
 
792
+    const base::ListValue* args) {
 
793
+  DCHECK(IsUnityWebappsInitialized());
 
794
+
 
795
+  // TODO move elsewhere
 
796
+  typedef void (* AddDomainFromPermissionsFunc) (gchar *);
 
797
+
 
798
+  std::string domain;
 
799
+  if (!args->GetString(0, &domain)) {
 
800
+    NOTREACHED();
 
801
+    return;
 
802
+  }
 
803
+
 
804
+  LOG(INFO) << "Adding domain:" << domain << " to the list of websites allowed";
 
805
+
 
806
+  ((AddDomainFromPermissionsFunc) add_allowed_domain_func_handle_) (
 
807
+      const_cast<gchar *>(domain.c_str()));
 
808
+
 
809
+  LoadIntegratedWebsitesData ();
 
810
+}
 
811
+
 
812
+void DesktopIntegrationSettingsHandler::RemoveIntegrationSite(
 
813
+    const base::ListValue* args) {
 
814
+  DCHECK(IsUnityWebappsInitialized());
 
815
+
 
816
+  // TODO move elsewhere
 
817
+  typedef void (* RemoveDomainFromPermissionsFunc) (gchar *);
 
818
+
 
819
+  std::string domain;
 
820
+  if (!args->GetString(0, &domain)) {
 
821
+    NOTREACHED();
 
822
+    return;
 
823
+  }
 
824
+
 
825
+  LOG(INFO) << "Removing domain:" << domain << " from the list of websites not prompting integration";
 
826
+
 
827
+  ((RemoveDomainFromPermissionsFunc) remove_from_permissions_func_handle_) (
 
828
+      const_cast<gchar *>(domain.c_str()));
 
829
+
 
830
+  LoadIntegratedWebsitesData ();
 
831
+}
 
832
+
 
833
+}  // namespace options
 
834
Index: src/chrome/browser/ui/webui/options/desktop_integration_settings_handler.h
 
835
===================================================================
 
836
--- src/chrome/browser/ui/webui/options/desktop_integration_settings_handler.h  (revision 0)
 
837
+++ src/chrome/browser/ui/webui/options/desktop_integration_settings_handler.h  (working copy)
 
838
@@ -0,0 +1,76 @@
 
839
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
 
840
+// Use of this source code is governed by a BSD-style license that can be
 
841
+// found in the LICENSE file.
 
842
+
 
843
+#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_DESKTOP_INTEGRATION_SETTINGS_HANDLER2_H_
 
844
+#define CHROME_BROWSER_UI_WEBUI_OPTIONS_DESKTOP_INTEGRATION_SETTINGS_HANDLER2_H_
 
845
+
 
846
+#include <string>
 
847
+
 
848
+#include "base/compiler_specific.h"
 
849
+#include "chrome/browser/ui/webui/options/options_ui.h"
 
850
+
 
851
+namespace base {
 
852
+class DictionaryValue;
 
853
+class ListValue;
 
854
+}
 
855
+
 
856
+namespace options {
 
857
+
 
858
+class DesktopIntegrationSettingsHandler : public OptionsPageUIHandler {
 
859
+ public:
 
860
+  DesktopIntegrationSettingsHandler();
 
861
+  virtual ~DesktopIntegrationSettingsHandler();
 
862
+
 
863
+  // OptionsPageUIHandler implementation.
 
864
+  virtual void GetLocalizedValues(
 
865
+      base::DictionaryValue* localized_strings) OVERRIDE;
 
866
+  virtual void InitializeHandler() OVERRIDE;
 
867
+  virtual void InitializePage() OVERRIDE;
 
868
+  virtual void RegisterMessages() OVERRIDE;
 
869
+
 
870
+ private:
 
871
+
 
872
+  // Loads the data associated with the currently integrated websites.
 
873
+  void LoadIntegratedWebsitesData();
 
874
+
 
875
+  // Initializes the list of website domain names that are currently
 
876
+  // either allowed or 'dontask' and send it to the overlay.
 
877
+  void LoadUnityWebappsEntryPoint();
 
878
+
 
879
+  // Removes an website from the list of integrated websites that won't prompt
 
880
+  // from integration.
 
881
+  // |args| - A string, the domain name of the website to remove.
 
882
+  void RemoveIntegrationSite(const base::ListValue* args);
 
883
+
 
884
+  // Adds an website from the list of integrated websites that won't prompt
 
885
+  // from integration. The website is being added to the list of 'allowed' sites.
 
886
+  // |args| - A string, the domain name of the website to add.
 
887
+  void AddIntegrationSite(const base::ListValue* args);
 
888
+
 
889
+  // Updates the integration allowed flag.
 
890
+  // |args| - A boolean flag indicating if integration should be allowed
 
891
+  void SetDesktopIntegrationAllowed(const base::ListValue* args);
 
892
+
 
893
+  // Updates the list of integrated websites.
 
894
+  void UpdateIntegratedWebsitesList(const base::ListValue* args);
 
895
+
 
896
+  // Predicate informing if we have been able to initialize the connection
 
897
+  // with the unity-webapps library (entry point for website integration
 
898
+  // permissions).
 
899
+  bool IsUnityWebappsInitialized() const;
 
900
+
 
901
+  // 
 
902
+  void * lib_unity_webapps_handle_;
 
903
+  void * get_all_func_handle_;
 
904
+  void * remove_from_permissions_func_handle_;
 
905
+  void * add_allowed_domain_func_handle_;
 
906
+  void * is_integration_allowed_func_handle_;
 
907
+  void * set_integration_allowed_func_handle_;
 
908
+
 
909
+  DISALLOW_COPY_AND_ASSIGN(DesktopIntegrationSettingsHandler);
 
910
+};
 
911
+
 
912
+}  // namespace options
 
913
+
 
914
+#endif  // CHROME_BROWSER_UI_WEBUI_OPTIONS_DESKTOP_INTEGRATION_SETTINGS_HANDLER2_H_
 
915
Index: src/chrome/browser/ui/webui/options/options_ui.cc
 
916
===================================================================
 
917
--- src/chrome/browser/ui/webui/options/options_ui.cc   (revision 158531)
 
918
+++ src/chrome/browser/ui/webui/options/options_ui.cc   (working copy)
 
919
@@ -89,6 +89,10 @@
 
920
 #include "chrome/browser/ui/webui/options/certificate_manager_handler.h"
 
921
 #endif
 
922
 
 
923
+#if defined(OS_LINUX)
 
924
+#include "chrome/browser/ui/webui/options/desktop_integration_settings_handler.h"
 
925
+#endif
 
926
+
 
927
 using content::RenderViewHost;
 
928
 
 
929
 namespace {
 
930
@@ -233,6 +237,10 @@
 
931
   AddOptionsPageUIHandler(localized_strings, new ClearBrowserDataHandler());
 
932
   AddOptionsPageUIHandler(localized_strings, new ContentSettingsHandler());
 
933
   AddOptionsPageUIHandler(localized_strings, new CookiesViewHandler());
 
934
+#if defined(OS_LINUX)
 
935
+  AddOptionsPageUIHandler(localized_strings,
 
936
+                          new DesktopIntegrationSettingsHandler());
 
937
+#endif
 
938
   AddOptionsPageUIHandler(localized_strings, new FontSettingsHandler());
 
939
   AddOptionsPageUIHandler(localized_strings, new HomePageOverlayHandler());
 
940
   AddOptionsPageUIHandler(localized_strings, new MediaGalleriesHandler());
 
941
Index: src/chrome/browser/ui/webui/options/browser_options_handler.cc
 
942
===================================================================
 
943
--- src/chrome/browser/ui/webui/options/browser_options_handler.cc      (revision 158531)
 
944
+++ src/chrome/browser/ui/webui/options/browser_options_handler.cc      (working copy)
 
945
@@ -155,6 +155,8 @@
 
946
     { "currentUserOnly", IDS_OPTIONS_CURRENT_USER_ONLY },
 
947
     { "advancedSectionTitleContent",
 
948
       IDS_OPTIONS_ADVANCED_SECTION_TITLE_CONTENT },
 
949
+    { "advancedSectionTitleIntegration",
 
950
+      IDS_OPTIONS_ADVANCED_SECTION_TITLE_INTEGRATION },
 
951
     { "advancedSectionTitleLanguages",
 
952
       IDS_OPTIONS_ADVANCED_SECTION_TITLE_LANGUAGES },
 
953
     { "advancedSectionTitleNetwork",
 
954
@@ -174,6 +176,10 @@
 
955
     { "defaultFontSizeLabel", IDS_OPTIONS_DEFAULT_FONT_SIZE_LABEL },
 
956
     { "defaultSearchManageEngines", IDS_OPTIONS_DEFAULTSEARCH_MANAGE_ENGINES },
 
957
     { "defaultZoomFactorLabel", IDS_OPTIONS_DEFAULT_ZOOM_LEVEL_LABEL },
 
958
+    { "desktopIntegrationExceptionsSettingsButton",
 
959
+      IDS_DESKTOP_INTEGRATION_SETTINGS_EXCEPTIONS_BUTTON_LABEL },
 
960
+    { "desktopIntegrationNoteSettingsContent",
 
961
+      IDS_DESKTOP_INTEGRATION_NOTE_DESCRIPTION },
 
962
 #if defined(OS_CHROMEOS)
 
963
     { "disableGData", IDS_OPTIONS_DISABLE_GDATA },
 
964
 #endif
 
965
@@ -234,6 +240,8 @@
 
966
     { "profilesDeleteSingle", IDS_PROFILES_DELETE_SINGLE_BUTTON_LABEL },
 
967
     { "profilesListItemCurrent", IDS_PROFILES_LIST_ITEM_CURRENT },
 
968
     { "profilesManage", IDS_PROFILES_MANAGE_BUTTON_LABEL },
 
969
+    { "promptIntegrationEnableIntegration",
 
970
+      IDS_PROMPT_INTEGRATION_ENABLE_BUTTON_LABEL },
 
971
     { "proxiesLabel", IDS_OPTIONS_PROXIES_LABEL },
 
972
     { "safeBrowsingEnableProtection",
 
973
       IDS_OPTIONS_SAFEBROWSING_ENABLEPROTECTION },
 
974
Index: src/chrome/app/generated_resources.grd
 
975
===================================================================
 
976
--- src/chrome/app/generated_resources.grd      (revision 158531)
 
977
+++ src/chrome/app/generated_resources.grd      (working copy)
 
978
@@ -10981,6 +10981,9 @@
 
979
       <message name="IDS_OPTIONS_ADVANCED_SECTION_TITLE_CONTENT">
 
980
         Web content
 
981
       </message>
 
982
+      <message name="IDS_OPTIONS_ADVANCED_SECTION_TITLE_INTEGRATION">
 
983
+        Installed Websites
 
984
+      </message>
 
985
       <message name="IDS_OPTIONS_ADVANCED_SECTION_TITLE_SECURITY">
 
986
         HTTPS/SSL
 
987
       </message>
 
988
@@ -17077,6 +17080,35 @@
 
989
       </message>
 
990
     </if>
 
991
 
 
992
+    <!-- Desktop integration -->
 
993
+    <message name="IDS_PROMPT_INTEGRATION_ENABLE_BUTTON_LABEL" desc="The text to be displayed on the checkbox that enables desktop integration.">
 
994
+      Notify me when the website I am visiting can run as an application
 
995
+    </message>
 
996
+    <message name="IDS_DESKTOP_INTEGRATION_NOTE_DESCRIPTION" desc="The text to be displayed below the Exceptions button in the Integrated Websites section.">
 
997
+      Websites which have been installed can be removed, like any other application, using Ubuntu Software Center.
 
998
+    </message>
 
999
+    <message name="IDS_DESKTOP_INTEGRATION_SETTINGS_EXCEPTIONS_BUTTON_LABEL" desc="The text to be displayed on the button that drives integration exceptions.">
 
1000
+      Exceptions...
 
1001
+    </message>
 
1002
+    <message name="IDS_DESKTOP_INTEGRATION_SETTINGS_OVERLAY_TITLE" desc="Title for the desktop integration overlay.">
 
1003
+      Integration prompt exceptions
 
1004
+    </message>
 
1005
+    <message name="IDS_DESKTOP_INTEGRATION_SETTINGS_OVERLAY_DESCRIPTION" desc="Description for the desktop integration overlay.">
 
1006
+      These websites won't prompt to be installed:
 
1007
+    </message>
 
1008
+    <message name="IDS_OPTIONS_SETTINGS_INTEGRATION_WEBSITE_ADD_BUTTON"
 
1009
+             desc="The label for the add button for adding a integration websites">
 
1010
+      Add
 
1011
+    </message>
 
1012
+    <message name="IDS_OPTIONS_SETTINGS_INTEGRATION_WEBSITE_ADD_TEXT"
 
1013
+             desc="The description text for the add overlay for adding a integration websites">
 
1014
+      Website domain name (e.g. www.html5rocks.com)
 
1015
+    </message>
 
1016
+    <message name="IDS_OPTIONS_SETTINGS_INTEGRATION_WEBSITE_ADD_TITLE"
 
1017
+             desc="Title for add overlay for adding a integration websites">
 
1018
+      Add Integrated Website
 
1019
+    </message>
 
1020
+
 
1021
     <!-- Manage Profile Dialog -->
 
1022
     <message name="IDS_PROFILES_MANAGE_TITLE" desc="Title of the manage profile dialog">
 
1023
       Edit user