summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authormattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-24 01:11:41 +0000
committermattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-24 01:11:41 +0000
commit214b81d70ec2a3eb09e381f7f306c651affd918b (patch)
treebdd252488d5e16af779121d70876376e67e9abbd /chrome/browser
parent083bac6bb70ed7d18c25d40112c0ae0431575a35 (diff)
downloadchromium_src-214b81d70ec2a3eb09e381f7f306c651affd918b.zip
chromium_src-214b81d70ec2a3eb09e381f7f306c651affd918b.tar.gz
chromium_src-214b81d70ec2a3eb09e381f7f306c651affd918b.tar.bz2
Revert 97955 - First pass on intents options UI.
Copies the cookies view handler for intents. Add pass-throughs to grit for flag. Optionalize intents options page JS/CSS. Fix up data model to read title. Working test. R=jhawkins@chromium.org BUG=None TEST=*Intents* Review URL: http://codereview.chromium.org/7624012 TBR=gbillock@chromium.org Review URL: http://codereview.chromium.org/7717016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@97966 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/intents/web_intents_registry.h1
-rw-r--r--chrome/browser/intents/web_intents_registry_factory.h2
-rw-r--r--chrome/browser/resources/options/content_settings.html50
-rw-r--r--chrome/browser/resources/options/content_settings.js12
-rw-r--r--chrome/browser/resources/options/intents_list.js715
-rw-r--r--chrome/browser/resources/options/intents_view.css181
-rw-r--r--chrome/browser/resources/options/intents_view.html12
-rw-r--r--chrome/browser/resources/options/intents_view.js83
-rw-r--r--chrome/browser/resources/options/options.html6
-rw-r--r--chrome/browser/resources/options/options.js6
-rw-r--r--chrome/browser/resources/options/options_bundle.js4
-rw-r--r--chrome/browser/ui/intents/intents_model.cc152
-rw-r--r--chrome/browser/ui/intents/intents_model.h133
-rw-r--r--chrome/browser/ui/intents/intents_model_unittest.cc185
-rw-r--r--chrome/browser/ui/webui/options/intents_settings_handler.cc159
-rw-r--r--chrome/browser/ui/webui/options/intents_settings_handler.h78
-rw-r--r--chrome/browser/ui/webui/options/options_ui.cc2
17 files changed, 27 insertions, 1754 deletions
diff --git a/chrome/browser/intents/web_intents_registry.h b/chrome/browser/intents/web_intents_registry.h
index 4b0f646..f5d724a 100644
--- a/chrome/browser/intents/web_intents_registry.h
+++ b/chrome/browser/intents/web_intents_registry.h
@@ -55,7 +55,6 @@ class WebIntentsRegistry
// WebIntentsRegistry.
friend class WebIntentsRegistryFactory;
friend class WebIntentsRegistryTest;
- friend class IntentsModelTest;
WebIntentsRegistry();
virtual ~WebIntentsRegistry();
diff --git a/chrome/browser/intents/web_intents_registry_factory.h b/chrome/browser/intents/web_intents_registry_factory.h
index 05ea36b8..4827097 100644
--- a/chrome/browser/intents/web_intents_registry_factory.h
+++ b/chrome/browser/intents/web_intents_registry_factory.h
@@ -18,7 +18,7 @@ class WebIntentsRegistry;
class WebIntentsRegistryFactory : public ProfileKeyedServiceFactory {
public:
// Returns the WebIntentsRegistry that provides intent registration for
- // |profile|. Ownership stays with this factory object.
+ // |profile|.
static WebIntentsRegistry* GetForProfile(Profile* profile);
// Returns the singleton instance of the WebIntentsRegistryFactory.
diff --git a/chrome/browser/resources/options/content_settings.html b/chrome/browser/resources/options/content_settings.html
index 9579633..ea1fb11 100644
--- a/chrome/browser/resources/options/content_settings.html
+++ b/chrome/browser/resources/options/content_settings.html
@@ -212,34 +212,30 @@
</div>
</section>
<!-- Intent registration filter tab contents -->
- <if expr="pp_ifdef('enable_web_intents')">
- <section id="intents-section">
+ <section id="intent-filter">
<h3 i18n-content="intentsTabLabel" class="content-settings-header"></h3>
- <div>
- <div class="radio">
- <label>
- <input type="radio" name="intents" value="allow">
- <span i18n-content="intentsAllow"></span>
- </label>
- </div>
- <div class="radio">
- <label>
- <input type="radio" name="intents" value="ask">
- <span i18n-content="intentsAsk"></span>
- </label>
- </div>
- <div class="radio">
- <label>
- <input type="radio" name="intents" value="block">
- <span i18n-content="intentsBlock"></span>
- </label>
- </div>
- <button class="exceptions-list-button" contentType="intents"
- i18n-content="manage_exceptions"></button>
- <button id="manage-intents-button" contentType="intents"
- i18n-content="manageIntents"></button>
+ <div>
+ <div class="radio">
+ <label>
+ <input type="radio" name="intents" value="allow">
+ <span i18n-content="intentsAllow"></span>
+ </label>
</div>
- </section>
- </if>
+ <div class="radio">
+ <label>
+ <input type="radio" name="intents" value="ask">
+ <span i18n-content="intentsAsk"></span>
+ </label>
+ </div>
+ <div class="radio">
+ <label>
+ <input type="radio" name="intents" value="block">
+ <span i18n-content="intentsBlock"></span>
+ </label>
+ </div>
+ <button class="exceptions-list-button" contentType="intents"
+ i18n-content="manage_exceptions"></button>
+ </div>
+ </section>
</div>
</div>
diff --git a/chrome/browser/resources/options/content_settings.js b/chrome/browser/resources/options/content_settings.js
index e8f5e52..08c6015 100644
--- a/chrome/browser/resources/options/content_settings.js
+++ b/chrome/browser/resources/options/content_settings.js
@@ -45,20 +45,14 @@ cr.define('options', function() {
};
}
- var manageHandlersButton = $('manage-handlers-button');
+ var manageHandlersButton =
+ this.pageDiv.querySelector('#manage-handlers-button');
if (manageHandlersButton) {
manageHandlersButton.onclick = function(event) {
OptionsPage.navigateToPage('handlers');
};
}
- var manageIntentsButton = $('manage-intents-button');
- if (manageIntentsButton) {
- manageIntentsButton.onclick = function(event) {
- OptionsPage.navigateToPage('intents');
- };
- }
-
// Cookies filter page ---------------------------------------------------
$('show-cookies-button').onclick = function(event) {
chrome.send('coreOptionsUserMetricsAction', ['Options_ShowCookies']);
@@ -69,7 +63,7 @@ cr.define('options', function() {
$('click_to_play').hidden = true;
if (!templateData.enable_web_intents)
- $('intent-section').hidden = true;
+ $('intent-filter').hidden = true;
},
};
diff --git a/chrome/browser/resources/options/intents_list.js b/chrome/browser/resources/options/intents_list.js
deleted file mode 100644
index d4f3fdd..0000000
--- a/chrome/browser/resources/options/intents_list.js
+++ /dev/null
@@ -1,715 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// TODO(gbillock): refactor this together with CookiesList once we have
-// a better sense from UX design what it'll look like and so what'll be shared.
-cr.define('options', function() {
- const DeletableItemList = options.DeletableItemList;
- const DeletableItem = options.DeletableItem;
- const ArrayDataModel = cr.ui.ArrayDataModel;
- const ListSingleSelectionModel = cr.ui.ListSingleSelectionModel;
- const localStrings = new LocalStrings();
-
- /**
- * Returns the item's height, like offsetHeight but such that it works better
- * when the page is zoomed. See the similar calculation in @{code cr.ui.List}.
- * This version also accounts for the animation done in this file.
- * @param {Element} item The item to get the height of.
- * @return {number} The height of the item, calculated with zooming in mind.
- */
- function getItemHeight(item) {
- var height = item.style.height;
- // Use the fixed animation target height if set, in case the element is
- // currently being animated and we'd get an intermediate height below.
- if (height && height.substr(-2) == 'px')
- return parseInt(height.substr(0, height.length - 2));
- return item.getBoundingClientRect().height;
- }
-
- // Map of parent pathIDs to node objects.
- var parentLookup = {};
-
- // Pending requests for child information.
- var lookupRequests = {};
-
- /**
- * Creates a new list item for intent service data. Note that these are
- * created and destroyed lazily as they scroll into and out of view,
- * so they must be stateless. We cache the expanded item in
- * @{code IntentsList} though, so it can keep state.
- * (Mostly just which item is selected.)
- *
- * @param {Object} origin Data used to create an intents list item.
- * @param {IntentsList} list The list that will contain this item.
- * @constructor
- * @extends {DeletableItem}
- */
- function IntentsListItem(origin, list) {
- var listItem = new DeletableItem(null);
- listItem.__proto__ = IntentsListItem.prototype;
-
- listItem.origin = origin;
- listItem.list = list;
- listItem.decorate();
-
- // This hooks up updateOrigin() to the list item, makes the top-level
- // tree nodes (i.e., origins) register their IDs in parentLookup, and
- // causes them to request their children if they have none. Note that we
- // have special logic in the setter for the parent property to make sure
- // that we can still garbage collect list items when they scroll out of
- // view, even though it appears that we keep a direct reference.
- if (origin) {
- origin.parent = listItem;
- origin.updateOrigin();
- }
-
- return listItem;
- }
-
- IntentsListItem.prototype = {
- __proto__: DeletableItem.prototype,
-
- /** @inheritDoc */
- decorate: function() {
- this.siteChild = this.ownerDocument.createElement('div');
- this.siteChild.className = 'intents-site';
- this.dataChild = this.ownerDocument.createElement('div');
- this.dataChild.className = 'intents-data';
- this.itemsChild = this.ownerDocument.createElement('div');
- this.itemsChild.className = 'intents-items';
- this.infoChild = this.ownerDocument.createElement('div');
- this.infoChild.className = 'intents-details';
- this.infoChild.hidden = true;
- var remove = this.ownerDocument.createElement('button');
- remove.textContent = localStrings.getString('removeIntent');
- remove.onclick = this.removeIntent_.bind(this);
- this.infoChild.appendChild(remove);
- var content = this.contentElement;
- content.appendChild(this.siteChild);
- content.appendChild(this.dataChild);
- content.appendChild(this.itemsChild);
- this.itemsChild.appendChild(this.infoChild);
- if (this.origin && this.origin.data) {
- this.siteChild.textContent = this.origin.data.site;
- this.siteChild.setAttribute('title', this.origin.data.site);
- }
- this.itemList_ = [];
- },
-
- /** @type {boolean} */
- get expanded() {
- return this.expanded_;
- },
- set expanded(expanded) {
- if (this.expanded_ == expanded)
- return;
- this.expanded_ = expanded;
- if (expanded) {
- var oldExpanded = this.list.expandedItem;
- this.list.expandedItem = this;
- this.updateItems_();
- if (oldExpanded)
- oldExpanded.expanded = false;
- this.classList.add('show-items');
- this.dataChild.hidden = true;
- } else {
- if (this.list.expandedItem == this) {
- this.list.leadItemHeight = 0;
- this.list.expandedItem = null;
- }
- this.style.height = '';
- this.itemsChild.style.height = '';
- this.classList.remove('show-items');
- this.dataChild.hidden = false;
- }
- },
-
- /**
- * The callback for the "remove" button shown when an item is selected.
- * Requests that the currently selected intent service be removed.
- * @private
- */
- removeIntent_: function() {
- if (this.selectedIndex_ >= 0) {
- var item = this.itemList_[this.selectedIndex_];
- if (item && item.node)
- chrome.send('removeIntent', [item.node.pathId]);
- }
- },
-
- /**
- * Disable animation within this intents list item, in preparation for
- * making changes that will need to be animated. Makes it possible to
- * measure the contents without displaying them, to set animation targets.
- * @private
- */
- disableAnimation_: function() {
- this.itemsHeight_ = getItemHeight(this.itemsChild);
- this.classList.add('measure-items');
- },
-
- /**
- * Enable animation after changing the contents of this intents list item.
- * See @{code disableAnimation_}.
- * @private
- */
- enableAnimation_: function() {
- if (!this.classList.contains('measure-items'))
- this.disableAnimation_();
- this.itemsChild.style.height = '';
- // This will force relayout in order to calculate the new heights.
- var itemsHeight = getItemHeight(this.itemsChild);
- var fixedHeight = getItemHeight(this) + itemsHeight - this.itemsHeight_;
- this.itemsChild.style.height = this.itemsHeight_ + 'px';
- // Force relayout before enabling animation, so that if we have
- // changed things since the last layout, they will not be animated
- // during subsequent layouts.
- this.itemsChild.offsetHeight;
- this.classList.remove('measure-items');
- this.itemsChild.style.height = itemsHeight + 'px';
- this.style.height = fixedHeight + 'px';
- if (this.expanded)
- this.list.leadItemHeight = fixedHeight;
- },
-
- /**
- * Updates the origin summary to reflect changes in its items.
- * Both IntentsListItem and IntentsTreeNode implement this API.
- * This implementation scans the descendants to update the text.
- */
- updateOrigin: function() {
- console.log('IntentsListItem.updateOrigin');
- var text = '';
- for (var i = 0; i < this.origin.children.length; ++i) {
- if (text.length > 0)
- text += ', ' + this.origin.children[i].data.action;
- else
- text = this.origin.children[i].data.action;
- }
- this.dataChild.textContent = text;
-
- if (this.expanded)
- this.updateItems_();
- },
-
- /**
- * Updates the items section to reflect changes, animating to the new state.
- * Removes existing contents and calls @{code IntentsTreeNode.createItems}.
- * @private
- */
- updateItems_: function() {
- this.disableAnimation_();
- this.itemsChild.textContent = '';
- this.infoChild.hidden = true;
- this.selectedIndex_ = -1;
- this.itemList_ = [];
- if (this.origin)
- this.origin.createItems(this);
- this.itemsChild.appendChild(this.infoChild);
- this.enableAnimation_();
- },
-
- /**
- * Append a new intents node "bubble" to this list item.
- * @param {IntentsTreeNode} node The intents node to add a bubble for.
- * @param {Element} div The DOM element for the bubble itself.
- * @return {number} The index the bubble was added at.
- */
- appendItem: function(node, div) {
- this.itemList_.push({node: node, div: div});
- this.itemsChild.appendChild(div);
- return this.itemList_.length - 1;
- },
-
- /**
- * The currently selected intents node ("intents bubble") index.
- * @type {number}
- * @private
- */
- selectedIndex_: -1,
-
- /**
- * Get the currently selected intents node ("intents bubble") index.
- * @type {number}
- */
- get selectedIndex() {
- return this.selectedIndex_;
- },
-
- /**
- * Set the currently selected intents node ("intents bubble") index to
- * @{code itemIndex}, unselecting any previously selected node first.
- * @param {number} itemIndex The index to set as the selected index.
- * TODO: KILL THIS
- */
- set selectedIndex(itemIndex) {
- // Get the list index up front before we change anything.
- var index = this.list.getIndexOfListItem(this);
- // Unselect any previously selected item.
- if (this.selectedIndex_ >= 0) {
- var item = this.itemList_[this.selectedIndex_];
- if (item && item.div)
- item.div.removeAttribute('selected');
- }
- // Special case: decrementing -1 wraps around to the end of the list.
- if (itemIndex == -2)
- itemIndex = this.itemList_.length - 1;
- // Check if we're going out of bounds and hide the item details.
- if (itemIndex < 0 || itemIndex >= this.itemList_.length) {
- this.selectedIndex_ = -1;
- this.disableAnimation_();
- this.infoChild.hidden = true;
- this.enableAnimation_();
- return;
- }
- // Set the new selected item and show the item details for it.
- this.selectedIndex_ = itemIndex;
- this.itemList_[itemIndex].div.setAttribute('selected', '');
- this.disableAnimation_();
- this.infoChild.hidden = false;
- this.enableAnimation_();
- // If we're near the bottom of the list this may cause the list item to go
- // beyond the end of the visible area. Fix it after the animation is done.
- var list = this.list;
- window.setTimeout(function() { list.scrollIndexIntoView(index); }, 150);
- },
- };
-
- /**
- * {@code IntentsTreeNode}s mirror the structure of the intents tree lazily,
- * and contain all the actual data used to generate the
- * {@code IntentsListItem}s.
- * @param {Object} data The data object for this node.
- * @constructor
- */
- function IntentsTreeNode(data) {
- this.data = data;
- this.children = [];
- }
-
- IntentsTreeNode.prototype = {
- /**
- * Insert an intents tree node at the given index.
- * Both IntentsList and IntentsTreeNode implement this API.
- * @param {Object} data The data object for the node to add.
- * @param {number} index The index at which to insert the node.
- */
- insertAt: function(data, index) {
- console.log('IntentsTreeNode.insertAt adding ' +
- JSON.stringify(data) + ' at ' + index);
- var child = new IntentsTreeNode(data);
- this.children.splice(index, 0, child);
- child.parent = this;
- this.updateOrigin();
- },
-
- /**
- * Remove an intents tree node from the given index.
- * Both IntentsList and IntentsTreeNode implement this API.
- * @param {number} index The index of the tree node to remove.
- */
- remove: function(index) {
- if (index < this.children.length) {
- this.children.splice(index, 1);
- this.updateOrigin();
- }
- },
-
- /**
- * Clears all children.
- * Both IntentsList and IntentsTreeNode implement this API.
- * It is used by IntentsList.loadChildren().
- */
- clear: function() {
- // We might leave some garbage in parentLookup for removed children.
- // But that should be OK because parentLookup is cleared when we
- // reload the tree.
- this.children = [];
- this.updateOrigin();
- },
-
- /**
- * The counter used by startBatchUpdates() and endBatchUpdates().
- * @type {number}
- */
- batchCount_: 0,
-
- /**
- * See cr.ui.List.startBatchUpdates().
- * Both IntentsList (via List) and IntentsTreeNode implement this API.
- */
- startBatchUpdates: function() {
- this.batchCount_++;
- },
-
- /**
- * See cr.ui.List.endBatchUpdates().
- * Both IntentsList (via List) and IntentsTreeNode implement this API.
- */
- endBatchUpdates: function() {
- if (!--this.batchCount_)
- this.updateOrigin();
- },
-
- /**
- * Requests updating the origin summary to reflect changes in this item.
- * Both IntentsListItem and IntentsTreeNode implement this API.
- */
- updateOrigin: function() {
- if (!this.batchCount_ && this.parent)
- this.parent.updateOrigin();
- },
-
- /**
- * Create the intents services rows for this node.
- * Append the rows to @{code item}.
- * @param {IntentsListItem} item The intents list item to create items in.
- */
- createItems: function(item) {
- if (this.children.length > 0) {
- for (var i = 0; i < this.children.length; ++i)
- this.children[i].createItems(item);
- } else if (this.data && !this.data.hasChildren) {
- var div = item.ownerDocument.createElement('div');
- div.className = 'intents-item';
- // Help out screen readers and such: this is a clickable thing.
- div.setAttribute('role', 'button');
-
- var divAction = item.ownerDocument.createElement('div');
- divAction.className = 'intents-item-action';
- divAction.textContent = this.data.action;
- div.appendChild(divAction);
-
- var divTypes = item.ownerDocument.createElement('div');
- divTypes.className = 'intents-item-types';
- var text = "";
- for (var i = 0; i < this.data.types.length; ++i) {
- if (text != "")
- text += ", ";
- text += this.data.types[i];
- }
- divTypes.textContent = text;
- div.appendChild(divTypes);
-
- var divUrl = item.ownerDocument.createElement('div');
- divUrl.className = 'intents-item-url';
- divUrl.textContent = this.data.url;
- div.appendChild(divUrl);
-
- var index = item.appendItem(this, div);
- div.onclick = function() {
- if (item.selectedIndex == index)
- item.selectedIndex = -1;
- else
- item.selectedIndex = index;
- };
- }
- },
-
- /**
- * The parent of this intents tree node.
- * @type {?IntentsTreeNode|IntentsListItem}
- */
- get parent(parent) {
- // See below for an explanation of this special case.
- if (typeof this.parent_ == 'number')
- return this.list_.getListItemByIndex(this.parent_);
- return this.parent_;
- },
- set parent(parent) {
- if (parent == this.parent)
- return;
-
- if (parent instanceof IntentsListItem) {
- // If the parent is to be a IntentsListItem, then we keep the reference
- // to it by its containing list and list index, rather than directly.
- // This allows the list items to be garbage collected when they scroll
- // out of view (except the expanded item, which we cache). This is
- // transparent except in the setter and getter, where we handle it.
- this.parent_ = parent.listIndex;
- this.list_ = parent.list;
- parent.addEventListener('listIndexChange',
- this.parentIndexChanged_.bind(this));
- } else {
- this.parent_ = parent;
- }
-
-
- if (parent)
- parentLookup[this.pathId] = this;
- else
- delete parentLookup[this.pathId];
-
- if (this.data && this.data.hasChildren &&
- !this.children.length && !lookupRequests[this.pathId]) {
- console.log('SENDING loadIntents');
- lookupRequests[this.pathId] = true;
- chrome.send('loadIntents', [this.pathId]);
- }
- },
-
- /**
- * Called when the parent is a IntentsListItem whose index has changed.
- * See the code above that avoids keeping a direct reference to
- * IntentsListItem parents, to allow them to be garbage collected.
- * @private
- */
- parentIndexChanged_: function(event) {
- if (typeof this.parent_ == 'number') {
- this.parent_ = event.newValue;
- // We set a timeout to update the origin, rather than doing it right
- // away, because this callback may occur while the list items are
- // being repopulated following a scroll event. Calling updateOrigin()
- // immediately could trigger relayout that would reset the scroll
- // position within the list, among other things.
- window.setTimeout(this.updateOrigin.bind(this), 0);
- }
- },
-
- /**
- * The intents tree path id.
- * @type {string}
- */
- get pathId() {
- var parent = this.parent;
- if (parent && parent instanceof IntentsTreeNode)
- return parent.pathId + ',' + this.data.action;
- return this.data.site;
- },
- };
-
- /**
- * Creates a new intents list.
- * @param {Object=} opt_propertyBag Optional properties.
- * @constructor
- * @extends {DeletableItemList}
- */
- var IntentsList = cr.ui.define('list');
-
- IntentsList.prototype = {
- __proto__: DeletableItemList.prototype,
-
- /** @inheritDoc */
- decorate: function() {
- DeletableItemList.prototype.decorate.call(this);
- this.classList.add('intents-list');
- this.data_ = [];
- this.dataModel = new ArrayDataModel(this.data_);
- this.addEventListener('keydown', this.handleKeyLeftRight_.bind(this));
- var sm = new ListSingleSelectionModel();
- sm.addEventListener('change', this.cookieSelectionChange_.bind(this));
- sm.addEventListener('leadIndexChange', this.cookieLeadChange_.bind(this));
- this.selectionModel = sm;
- },
-
- /**
- * Handles key down events and looks for left and right arrows, then
- * dispatches to the currently expanded item, if any.
- * @param {Event} e The keydown event.
- * @private
- */
- handleKeyLeftRight_: function(e) {
- var id = e.keyIdentifier;
- if ((id == 'Left' || id == 'Right') && this.expandedItem) {
- var cs = this.ownerDocument.defaultView.getComputedStyle(this);
- var rtl = cs.direction == 'rtl';
- if ((!rtl && id == 'Left') || (rtl && id == 'Right'))
- this.expandedItem.selectedIndex--;
- else
- this.expandedItem.selectedIndex++;
- this.scrollIndexIntoView(this.expandedItem.listIndex);
- // Prevent the page itself from scrolling.
- e.preventDefault();
- }
- },
-
- /**
- * Called on selection model selection changes.
- * @param {Event} ce The selection change event.
- * @private
- */
- cookieSelectionChange_: function(ce) {
- ce.changes.forEach(function(change) {
- var listItem = this.getListItemByIndex(change.index);
- if (listItem) {
- if (!change.selected) {
- // We set a timeout here, rather than setting the item unexpanded
- // immediately, so that if another item gets set expanded right
- // away, it will be expanded before this item is unexpanded. It
- // will notice that, and unexpand this item in sync with its own
- // expansion. Later, this callback will end up having no effect.
- window.setTimeout(function() {
- if (!listItem.selected || !listItem.lead)
- listItem.expanded = false;
- }, 0);
- } else if (listItem.lead) {
- listItem.expanded = true;
- }
- }
- }, this);
- },
-
- /**
- * Called on selection model lead changes.
- * @param {Event} pe The lead change event.
- * @private
- */
- cookieLeadChange_: function(pe) {
- if (pe.oldValue != -1) {
- var listItem = this.getListItemByIndex(pe.oldValue);
- if (listItem) {
- // See cookieSelectionChange_ above for why we use a timeout here.
- window.setTimeout(function() {
- if (!listItem.lead || !listItem.selected)
- listItem.expanded = false;
- }, 0);
- }
- }
- if (pe.newValue != -1) {
- var listItem = this.getListItemByIndex(pe.newValue);
- if (listItem && listItem.selected)
- listItem.expanded = true;
- }
- },
-
- /**
- * The currently expanded item. Used by IntentsListItem above.
- * @type {?IntentsListItem}
- */
- expandedItem: null,
-
- // from cr.ui.List
- /** @inheritDoc */
- createItem: function(data) {
- // We use the cached expanded item in order to allow it to maintain some
- // state (like its fixed height, and which bubble is selected).
- if (this.expandedItem && this.expandedItem.origin == data)
- return this.expandedItem;
- return new IntentsListItem(data, this);
- },
-
- // from options.DeletableItemList
- /** @inheritDoc */
- deleteItemAtIndex: function(index) {
- var item = this.data_[index];
- if (item) {
- var pathId = item.pathId;
- if (pathId)
- chrome.send('removeIntent', [pathId]);
- }
- },
-
- /**
- * Insert an intents tree node at the given index.
- * Both IntentsList and IntentsTreeNode implement this API.
- * @param {Object} data The data object for the node to add.
- * @param {number} index The index at which to insert the node.
- */
- insertAt: function(data, index) {
- this.dataModel.splice(index, 0, new IntentsTreeNode(data));
- },
-
- /**
- * Remove an intents tree node from the given index.
- * Both IntentsList and IntentsTreeNode implement this API.
- * @param {number} index The index of the tree node to remove.
- */
- remove: function(index) {
- if (index < this.data_.length)
- this.dataModel.splice(index, 1);
- },
-
- /**
- * Clears the list.
- * Both IntentsList and IntentsTreeNode implement this API.
- * It is used by IntentsList.loadChildren().
- */
- clear: function() {
- parentLookup = {};
- this.data_ = [];
- this.dataModel = new ArrayDataModel(this.data_);
- this.redraw();
- },
-
- /**
- * Add tree nodes by given parent.
- * Note: this method will be O(n^2) in the general case. Use it only to
- * populate an empty parent or to insert single nodes to avoid this.
- * @param {Object} parent The parent node.
- * @param {number} start Start index of where to insert nodes.
- * @param {Array} nodesData Nodes data array.
- * @private
- */
- addByParent_: function(parent, start, nodesData) {
- if (!parent)
- return;
-
- parent.startBatchUpdates();
- for (var i = 0; i < nodesData.length; ++i)
- parent.insertAt(nodesData[i], start + i);
- parent.endBatchUpdates();
-
- cr.dispatchSimpleEvent(this, 'change');
- },
-
- /**
- * Add tree nodes by parent id.
- * This is used by intents_view.js.
- * Note: this method will be O(n^2) in the general case. Use it only to
- * populate an empty parent or to insert single nodes to avoid this.
- * @param {string} parentId Id of the parent node.
- * @param {number} start Start index of where to insert nodes.
- * @param {Array} nodesData Nodes data array.
- */
- addByParentId: function(parentId, start, nodesData) {
- var parent = parentId ? parentLookup[parentId] : this;
- this.addByParent_(parent, start, nodesData);
- },
-
- /**
- * Removes tree nodes by parent id.
- * This is used by intents_view.js.
- * @param {string} parentId Id of the parent node.
- * @param {number} start Start index of nodes to remove.
- * @param {number} count Number of nodes to remove.
- */
- removeByParentId: function(parentId, start, count) {
- var parent = parentId ? parentLookup[parentId] : this;
- if (!parent)
- return;
-
- parent.startBatchUpdates();
- while (count-- > 0)
- parent.remove(start);
- parent.endBatchUpdates();
-
- cr.dispatchSimpleEvent(this, 'change');
- },
-
- /**
- * Loads the immediate children of given parent node.
- * This is used by intents_view.js.
- * @param {string} parentId Id of the parent node.
- * @param {Array} children The immediate children of parent node.
- */
- loadChildren: function(parentId, children) {
- console.log('Loading intents view: ' +
- parentId + ' ' + JSON.stringify(children));
- if (parentId)
- delete lookupRequests[parentId];
- var parent = parentId ? parentLookup[parentId] : this;
- if (!parent)
- return;
-
- parent.startBatchUpdates();
- parent.clear();
- this.addByParent_(parent, 0, children);
- parent.endBatchUpdates();
- },
- };
-
- return {
- IntentsList: IntentsList
- };
-});
diff --git a/chrome/browser/resources/options/intents_view.css b/chrome/browser/resources/options/intents_view.css
deleted file mode 100644
index 84c274d..0000000
--- a/chrome/browser/resources/options/intents_view.css
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
-Copyright (c) 2011 The Chromium Authors. All rights reserved.
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
-*/
-
-/* Styles for the intents list elements in intents_view.html. */
-
-#intents-column-headers {
- position: relative;
- width: 100%;
-}
-
-#intents-column-headers h3 {
- font-size: 105%;
- font-weight: bold;
- margin: 10px 0;
-}
-
-/* Notice the width and padding for these columns match up with those below. */
-#intents-site-column {
- display: inline-block;
- font-weight: bold;
- width: 11em;
-}
-
-#intents-data-column {
- -webkit-padding-start: 7px;
- display: inline-block;
- font-weight: bold;
-}
-
-#intents-list {
- border: 1px solid #d9d9d9;
- margin: 0;
-}
-
-/* Enable animating the height of items. */
-list.intents-list .deletable-item {
- -webkit-transition: height .15s ease-in-out;
-}
-
-/* Disable webkit-box display. */
-list.intents-list .deletable-item > :first-child {
- display: block;
-}
-
-/* Force the X for deleting an origin to stay at the top. */
-list.intents-list > .deletable-item > .close-button {
- position: absolute;
- right: 2px;
- top: 8px;
-}
-
-html[dir=rtl] list.intents-list > .deletable-item > .close-button {
- left: 2px;
- right: auto;
-}
-
-/* Styles for the site (aka origin) and its summary. */
-
-.intents-site {
- /* Notice that the width, margin, and padding match up with those above. */
- -webkit-margin-end: 2px;
- -webkit-padding-start: 5px;
- display: inline-block;
- overflow: hidden;
- text-overflow: ellipsis;
- width: 11em;
-}
-
-list.intents-list > .deletable-item[selected] .intents-site {
- -webkit-user-select: text;
-}
-
-.intents-data {
- display: inline-block;
-}
-
-list.intents-list > .deletable-item[selected] .intents-data {
- -webkit-user-select: text;
-}
-
-.intents-items {
- /* Notice that the margin and padding match up with those above. */
- -webkit-margin-start: 11em;
- -webkit-padding-start: 7px;
- -webkit-transition: .15s ease-in-out;
- display: table;
- height: 0;
- opacity: 0;
- /* Make the intents items wrap correctly. */
- white-space: normal;
-}
-
-.measure-items .intents-items {
- -webkit-transition: none;
- height: auto;
- visibility: hidden;
-}
-
-.show-items .intents-items {
- opacity: 1;
-}
-
-.intents-items .intents-item {
- -webkit-box-orient: horizontal;
- -webkit-box-pack: start;
- background: #e0e9f5;
- border: 1px solid #8392ae;
- display: table-row;
- font-size: 85%;
- height: auto;
- margin: 2px 4px 2px 0;
- overflow: hidden;
- padding: 0 3px;
- text-align: center;
- text-overflow: ellipsis;
-}
-
-.intents-item .intents-item-action {
- display: table-cell;
- padding: 2px 5px;
-}
-
-.intents-item .intents-item-types {
- display: table-cell;
- padding: 2px 5px;
- overflow: hidden;
-}
-
-.intents-item .intents-item-url {
- display: table-cell;
- padding: 2px 5px;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.intents-items .intents-item:hover {
- background: #eef3f9;
- border-color: #647187;
-}
-
-.intents-items .intents-item[selected] {
- background: #f5f8f8;
- border-color: #b2b2b2;
-}
-
-.intents-items .intents-item[selected]:hover {
- background: #f5f8f8;
- border-color: #647187;
-}
-
-/* Styles for the intents details box. */
-
-.intents-details {
- background: #f5f8f8;
- border-radius: 5px;
- border: 1px solid #b2b2b2;
- margin-top: 2px;
- padding: 5px;
-}
-
-list.intents-list > .deletable-item[selected] .intents-details {
- -webkit-user-select: text;
-}
-
-.intents-details-table {
- table-layout: fixed;
- width: 100%;
-}
-
-.intents-details-label {
- vertical-align: top;
- white-space: pre;
- width: 10em;
-}
-
-.intents-details-value {
- word-wrap: break-word;
-}
diff --git a/chrome/browser/resources/options/intents_view.html b/chrome/browser/resources/options/intents_view.html
deleted file mode 100644
index 6803c23..0000000
--- a/chrome/browser/resources/options/intents_view.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<div id="intents-view-page" class="page" hidden>
- <h1 i18n-content="intentsViewPage"></h1>
- <div id="intents-column-headers">
- <div id="intents-site-column">
- <h3 i18n-content="intentsDomain"></h3>
- </div>
- <div id="intents-data-column">
- <h3 i18n-content="intentsServiceData"></h3>
- </div>
- </div>
- <list id="intents-list"></list>
-</div>
diff --git a/chrome/browser/resources/options/intents_view.js b/chrome/browser/resources/options/intents_view.js
deleted file mode 100644
index afc7d68..0000000
--- a/chrome/browser/resources/options/intents_view.js
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-cr.define('options', function() {
- var OptionsPage = options.OptionsPage;
-
- /////////////////////////////////////////////////////////////////////////////
- // IntentsView class:
-
- /**
- * Encapsulated handling of the Intents data page.
- * @constructor
- */
- function IntentsView(model) {
- OptionsPage.call(this, 'intents',
- templateData.intentsViewPageTabTitle,
- 'intents-view-page');
- }
-
- cr.addSingletonGetter(IntentsView);
-
- IntentsView.prototype = {
- __proto__: OptionsPage.prototype,
-
- initializePage: function() {
- OptionsPage.prototype.initializePage.call(this);
-
- var intentsList = $('intents-list');
- options.IntentsList.decorate(intentsList);
- window.addEventListener('resize', this.handleResize_.bind(this));
-
- this.addEventListener('visibleChange', this.handleVisibleChange_);
- },
-
- initialized_: false,
-
- /**
- * Handler for OptionsPage's visible property change event.
- * @param {Event} e Property change event.
- * @private
- */
- handleVisibleChange_: function(e) {
- if (!this.visible)
- return;
-
- // Resize the intents list whenever the options page becomes visible.
- this.handleResize_(null);
- if (!this.initialized_) {
- this.initialized_ = true;
- chrome.send('loadIntents');
- } else {
- $('intents-list').redraw();
- }
- },
-
- /**
- * Handler for when the window changes size. Resizes the intents list to
- * match the window height.
- * @param {?Event} e Window resize event, or null if called directly.
- * @private
- */
- handleResize_: function(e) {
- if (!this.visible)
- return;
- var intentsList = $('intents-list');
- // 25 pixels from the window bottom seems like a visually pleasing amount.
- var height = window.innerHeight - intentsList.offsetTop - 25;
- intentsList.style.height = height + 'px';
- },
- };
-
- // IntentsViewHandler callbacks.
- IntentsView.loadChildren = function(args) {
- $('intents-list').loadChildren(args[0], args[1]);
- };
-
- // Export
- return {
- IntentsView: IntentsView
- };
-
-});
diff --git a/chrome/browser/resources/options/options.html b/chrome/browser/resources/options/options.html
index de3754c..3fb7c74 100644
--- a/chrome/browser/resources/options/options.html
+++ b/chrome/browser/resources/options/options.html
@@ -29,9 +29,6 @@
<link rel="stylesheet" href="handler_options.css">
</if>
<link rel="stylesheet" href="import_data_overlay.css">
-<if expr="pp_ifdef('enable_web_intents')">
- <link rel="stylesheet" href="intents_view.css">
-</if>
<link rel="stylesheet" href="language_options.css">
<link rel="stylesheet" href="manage_profile_overlay.css">
<link rel="stylesheet" href="password_manager.css">
@@ -167,9 +164,6 @@
<if expr="pp_ifdef('enable_register_protocol_handler')">
<include src="handler_options.html">
</if>
- <if expr="pp_ifdef('enable_web_intents')">
- <include src="intents_view.html">
- </if>
<include src="content_settings_exceptions_area.html">
</div>
</div>
diff --git a/chrome/browser/resources/options/options.js b/chrome/browser/resources/options/options.js
index 3e5c41b..de55f64 100644
--- a/chrome/browser/resources/options/options.js
+++ b/chrome/browser/resources/options/options.js
@@ -17,7 +17,6 @@ var CookiesView = options.CookiesView;
var FontSettings = options.FontSettings;
var HandlerOptions = options.HandlerOptions;
var ImportDataOverlay = options.ImportDataOverlay;
-var IntentsView = options.IntentsView;
var InstantConfirmOverlay = options.InstantConfirmOverlay;
var LanguageOptions = options.LanguageOptions;
var OptionsPage = options.OptionsPage;
@@ -121,11 +120,6 @@ function load() {
ContentSettings.getInstance(),
[$('manage-handlers-button')]);
}
- if (IntentsView && $('manage-intents-button')) {
- OptionsPage.registerSubPage(IntentsView.getInstance(),
- ContentSettings.getInstance(),
- [$('manage-intents-button')]);
- }
OptionsPage.registerSubPage(FontSettings.getInstance(),
AdvancedOptions.getInstance(),
[$('fontSettingsCustomizeFontsButton')]);
diff --git a/chrome/browser/resources/options/options_bundle.js b/chrome/browser/resources/options/options_bundle.js
index 0b58a74..a181de9 100644
--- a/chrome/browser/resources/options/options_bundle.js
+++ b/chrome/browser/resources/options/options_bundle.js
@@ -68,10 +68,6 @@
</if>
<include src="import_data_overlay.js"></include>
<include src="instant_confirm_overlay.js"></include>
-<if expr="pp_ifdef('enable_web_intents')">
- <include src="intents_list.js"></include>
- <include src="intents_view.js"></include>
-</if>
<include src="language_add_language_overlay.js"></include>
<include src="language_list.js"></include>
<include src="language_options.js"></include>
diff --git a/chrome/browser/ui/intents/intents_model.cc b/chrome/browser/ui/intents/intents_model.cc
deleted file mode 100644
index 8114724..0000000
--- a/chrome/browser/ui/intents/intents_model.cc
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/intents/intents_model.h"
-#include "base/string_split.h"
-#include "base/string_util.h"
-#include "base/stringprintf.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/intents/web_intents_registry.h"
-
-ServiceTreeNode::ServiceTreeNode(const string16& title)
- : IntentsTreeNode(title, IntentsTreeNode::TYPE_SERVICE),
- blocked_(false),
- disabled_(false) {}
-
-ServiceTreeNode::~ServiceTreeNode() {}
-
-IntentsModel::IntentsModel(WebIntentsRegistry* intents_registry)
- : ui::TreeNodeModel<IntentsTreeNode>(new IntentsTreeNode()),
- intents_registry_(intents_registry),
- batch_update_(0) {
- LoadModel();
-}
-
-IntentsModel::~IntentsModel() {}
-
-void IntentsModel::AddIntentsTreeObserver(Observer* observer) {
- intents_observer_list_.AddObserver(observer);
- // Call super so that TreeNodeModel can notify, too.
- ui::TreeNodeModel<IntentsTreeNode>::AddObserver(observer);
-}
-
-void IntentsModel::RemoveIntentsTreeObserver(Observer* observer) {
- intents_observer_list_.RemoveObserver(observer);
- // Call super so that TreeNodeModel doesn't have dead pointers.
- ui::TreeNodeModel<IntentsTreeNode>::RemoveObserver(observer);
-}
-
-string16 IntentsModel::GetTreeNodeId(IntentsTreeNode* node) {
- if (node->Type() == IntentsTreeNode::TYPE_ORIGIN)
- return node->GetTitle();
-
- // TODO(gbillock): handle TYPE_SERVICE when/if we ever want to do
- // specific managing of them.
-
- return string16();
-}
-
-IntentsTreeNode* IntentsModel::GetTreeNode(std::string path_id) {
- if (path_id.empty())
- return GetRoot();
-
- std::vector<std::string> node_ids;
- base::SplitString(path_id, ',', &node_ids);
-
- for (int i = 0; i < GetRoot()->child_count(); ++i) {
- IntentsTreeNode* node = GetRoot()->GetChild(i);
- if (UTF16ToUTF8(node->GetTitle()) == node_ids[0]) {
- if (node_ids.size() == 1)
- return node;
- }
- }
-
- // TODO: support service nodes?
- return NULL;
-}
-
-void IntentsModel::GetChildNodeList(IntentsTreeNode* parent,
- int start, int count,
- base::ListValue* nodes) {
- for (int i = 0; i < count; ++i) {
- base::DictionaryValue* dict = new base::DictionaryValue;
- IntentsTreeNode* child = parent->GetChild(start + i);
- GetIntentsTreeNodeDictionary(*child, dict);
- nodes->Append(dict);
- }
-}
-
-void IntentsModel::GetIntentsTreeNodeDictionary(const IntentsTreeNode& node,
- base::DictionaryValue* dict) {
- if (node.Type() == IntentsTreeNode::TYPE_ROOT) {
- return;
- }
-
- if (node.Type() == IntentsTreeNode::TYPE_ORIGIN) {
- dict->SetString("site", node.GetTitle());
- dict->SetBoolean("hasChildren", node.child_count() > 0);
- return;
- }
-
- if (node.Type() == IntentsTreeNode::TYPE_SERVICE) {
- const ServiceTreeNode* snode = static_cast<const ServiceTreeNode*>(&node);
- dict->SetString("site", snode->GetTitle());
- dict->SetString("name", snode->ServiceName());
- dict->SetString("url", snode->ServiceUrl());
- dict->SetString("icon", snode->IconUrl());
- dict->SetString("action", snode->Action());
- dict->Set("types", snode->Types().DeepCopy());
- dict->SetBoolean("blocked", snode->IsBlocked());
- dict->SetBoolean("disabled", snode->IsDisabled());
- return;
- }
-}
-
-void IntentsModel::LoadModel() {
- NotifyObserverBeginBatch();
- intents_registry_->GetAllIntentProviders(this);
-}
-
-void IntentsModel::OnIntentsQueryDone(
- WebIntentsRegistry::QueryID query_id,
- const std::vector<WebIntentData>& intents) {
- for (size_t i = 0; i < intents.size(); ++i) {
- // Eventually do some awesome sorting, grouping, clustering stuff here.
- // For now, just stick it in the model flat.
- IntentsTreeNode* n = new IntentsTreeNode(ASCIIToUTF16(
- intents[i].service_url.host()));
- ServiceTreeNode* ns = new ServiceTreeNode(ASCIIToUTF16(
- intents[i].service_url.host()));
- ns->SetServiceName(intents[i].title);
- ns->SetServiceUrl(ASCIIToUTF16(intents[i].service_url.spec()));
- GURL icon_url = intents[i].service_url.GetOrigin().Resolve("/favicon.ico");
- ns->SetIconUrl(ASCIIToUTF16(icon_url.spec()));
- ns->SetAction(intents[i].action);
- ns->AddType(intents[i].type);
- // Won't generate a notification. OK for now as the next line will.
- n->Add(ns, 0);
- Add(GetRoot(), n, GetRoot()->child_count());
- }
-
- NotifyObserverEndBatch();
-}
-
-void IntentsModel::NotifyObserverBeginBatch() {
- // Only notify the model once if we're batching in a nested manner.
- if (batch_update_++ == 0) {
- FOR_EACH_OBSERVER(Observer,
- intents_observer_list_,
- TreeModelBeginBatch(this));
- }
-}
-
-void IntentsModel::NotifyObserverEndBatch() {
- // Only notify the observers if this is the outermost call to EndBatch() if
- // called in a nested manner.
- if (--batch_update_ == 0) {
- FOR_EACH_OBSERVER(Observer,
- intents_observer_list_,
- TreeModelEndBatch(this));
- }
-}
diff --git a/chrome/browser/ui/intents/intents_model.h b/chrome/browser/ui/intents/intents_model.h
deleted file mode 100644
index 0221b7d..0000000
--- a/chrome/browser/ui/intents/intents_model.h
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_INTENTS_INTENTS_MODEL_H_
-#define CHROME_BROWSER_UI_INTENTS_INTENTS_MODEL_H_
-#pragma once
-
-#include "base/values.h"
-#include "chrome/browser/intents/web_intents_registry.h"
-#include "ui/base/models/tree_node_model.h"
-
-class WebIntentsRegistry;
-
-// The tree structure is a TYPE_ROOT node with title="",
-// children are TYPE_ORIGIN nodes with title=origin, whose
-// children are TYPE_SERVICE nodes with title=origin, and
-// will be of type ServiceTreeNode with data on individual
-// services.
-class IntentsTreeNode : public ui::TreeNode<IntentsTreeNode> {
- public:
- IntentsTreeNode()
- : ui::TreeNode<IntentsTreeNode>(string16()),
- type_(TYPE_ROOT) {}
-
- explicit IntentsTreeNode(const string16& title)
- : ui::TreeNode<IntentsTreeNode>(title),
- type_(TYPE_ORIGIN) {}
-
- virtual ~IntentsTreeNode() {}
-
- enum NodeType {
- TYPE_ROOT,
- TYPE_ORIGIN,
- TYPE_SERVICE,
- };
-
- NodeType Type() const { return type_; }
-
- protected:
- IntentsTreeNode(const string16& title, NodeType type)
- : ui::TreeNode<IntentsTreeNode>(title),
- type_(type) {}
-
- private:
- NodeType type_;
-};
-
-// Tree node representing particular services presented by an origin.
-class ServiceTreeNode : public IntentsTreeNode {
- public:
- explicit ServiceTreeNode(const string16& title);
- virtual ~ServiceTreeNode();
-
- const string16& ServiceName() const { return service_name_; }
- const string16& ServiceUrl() const { return service_url_; }
- const string16& IconUrl() const { return icon_url_; }
- const string16& Action() const { return action_; }
- const base::ListValue& Types() const { return types_; }
- bool IsBlocked() const { return blocked_; }
- bool IsDisabled() const { return disabled_; }
-
- void SetServiceName(string16 name) { service_name_ = name; }
- void SetServiceUrl(string16 url) { service_url_ = url; }
- void SetIconUrl(string16 url) { icon_url_ = url; }
- void SetAction(string16 action) { action_ = action; }
- void AddType(string16 type) { types_.Append(Value::CreateStringValue(type)); }
- void SetBlocked(bool blocked) { blocked_ = blocked; }
- void SetDisabled(bool disabled) { disabled_ = disabled; }
-
- private:
- string16 service_name_;
- string16 icon_url_;
- string16 service_url_;
- string16 action_;
- base::ListValue types_;
-
- // TODO(gbillock): these are kind of a placeholder for exceptions data.
- bool blocked_;
- bool disabled_;
-};
-
-// UI-backing tree model of the data in the WebIntentsRegistry.
-class IntentsModel : public ui::TreeNodeModel<IntentsTreeNode>,
- public WebIntentsRegistry::Consumer {
- public:
- // Because nodes are fetched in a background thread, they are not
- // present at the time the Model is created. The Model then notifies its
- // observers for every item added.
- class Observer : public ui::TreeModelObserver {
- public:
- virtual void TreeModelBeginBatch(IntentsModel* model) {}
- virtual void TreeModelEndBatch(IntentsModel* model) {}
- };
-
- explicit IntentsModel(WebIntentsRegistry* intents_registry);
- virtual ~IntentsModel();
-
- void AddIntentsTreeObserver(Observer* observer);
- void RemoveIntentsTreeObserver(Observer* observer);
-
- string16 GetTreeNodeId(IntentsTreeNode* node);
- IntentsTreeNode* GetTreeNode(std::string path_id);
- void GetChildNodeList(IntentsTreeNode* parent, int start, int count,
- base::ListValue* nodes);
- void GetIntentsTreeNodeDictionary(const IntentsTreeNode& node,
- base::DictionaryValue* dict);
-
- virtual void OnIntentsQueryDone(
- WebIntentsRegistry::QueryID query_id,
- const std::vector<WebIntentData>& intents) OVERRIDE;
-
- private:
- // Loads the data model from the WebIntentsRegistry.
- // TODO(gbillock): need an observer on that to absorb async updates?
- void LoadModel();
-
- // Do batch-specific notifies for updates coming from the LoadModel.
- void NotifyObserverBeginBatch();
- void NotifyObserverEndBatch();
-
- // The backing registry. Weak pointer.
- WebIntentsRegistry* intents_registry_;
-
- // Separate list of observers that'll get batch updates.
- ObserverList<Observer> intents_observer_list_;
-
- // Batch update nesting level. Incremented to indicate that we're in
- // the middle of a batch update.
- int batch_update_;
-};
-
-#endif // CHROME_BROWSER_UI_INTENTS_INTENTS_MODEL_H_
diff --git a/chrome/browser/ui/intents/intents_model_unittest.cc b/chrome/browser/ui/intents/intents_model_unittest.cc
deleted file mode 100644
index 175e546..0000000
--- a/chrome/browser/ui/intents/intents_model_unittest.cc
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/file_util.h"
-#include "base/scoped_temp_dir.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/values.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/intents/web_intents_registry.h"
-#include "chrome/browser/webdata/web_data_service.h"
-#include "chrome/test/base/testing_browser_process_test.h"
-#include "chrome/browser/ui/intents/intents_model.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/base/models/tree_node_model.h"
-
-class IntentsModelTest : public TestingBrowserProcessTest {
- public:
- IntentsModelTest()
- : ui_thread_(BrowserThread::UI, &message_loop_),
- db_thread_(BrowserThread::DB) {}
-
- protected:
- virtual void SetUp() {
- db_thread_.Start();
- wds_ = new WebDataService();
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- wds_->Init(temp_dir_.path());
-
- registry_.Initialize(wds_);
- }
-
- virtual void TearDown() {
- if (wds_.get())
- wds_->Shutdown();
-
- db_thread_.Stop();
- MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask);
- MessageLoop::current()->Run();
- }
-
- void LoadRegistry() {
- {
- WebIntentData provider;
- provider.service_url = GURL("http://www.google.com/share");
- provider.action = ASCIIToUTF16("SHARE");
- provider.type = ASCIIToUTF16("text/url");
- provider.title = ASCIIToUTF16("Google");
- registry_.RegisterIntentProvider(provider);
- }
- {
- WebIntentData provider;
- provider.service_url = GURL("http://picasaweb.google.com/share");
- provider.action = ASCIIToUTF16("EDIT");
- provider.type = ASCIIToUTF16("image/*");
- provider.title = ASCIIToUTF16("Picasa");
- registry_.RegisterIntentProvider(provider);
- }
- {
- WebIntentData provider;
- provider.service_url = GURL("http://www.digg.com/share");
- provider.action = ASCIIToUTF16("SHARE");
- provider.type = ASCIIToUTF16("text/url");
- provider.title = ASCIIToUTF16("Digg");
- registry_.RegisterIntentProvider(provider);
- }
- }
-
- MessageLoopForUI message_loop_;
- BrowserThread ui_thread_;
- BrowserThread db_thread_;
- scoped_refptr<WebDataService> wds_;
- WebIntentsRegistry registry_;
- ScopedTempDir temp_dir_;
-};
-
-class WaitingIntentsObserver : public IntentsModel::Observer {
- public:
- WaitingIntentsObserver() : event_(true, false), added_(0) {}
-
- virtual void TreeModelBeginBatch(IntentsModel* model) {}
-
- virtual void TreeModelEndBatch(IntentsModel* model) {
- event_.Signal();
- MessageLoop::current()->Quit();
- }
-
- virtual void TreeNodesAdded(ui::TreeModel* model,
- ui::TreeModelNode* parent,
- int start,
- int count) {
- added_++;
- }
-
- virtual void TreeNodesRemoved(ui::TreeModel* model,
- ui::TreeModelNode* node,
- int start,
- int count) {
- }
-
- virtual void TreeNodeChanged(ui::TreeModel* model, ui::TreeModelNode* node) {
- }
-
- void Wait() {
- MessageLoop::current()->Run();
- event_.Wait();
- LOG(INFO) << "DONE!";
- }
-
- base::WaitableEvent event_;
- int added_;
-};
-
-TEST_F(IntentsModelTest, NodeIDs) {
- LoadRegistry();
- WaitingIntentsObserver obs;
- IntentsModel intents_model(&registry_);
- intents_model.AddIntentsTreeObserver(&obs);
- obs.Wait();
-
- IntentsTreeNode* n1 = new IntentsTreeNode(ASCIIToUTF16("origin"));
- intents_model.Add(intents_model.GetRoot(), n1,
- intents_model.GetRoot()->child_count());
- EXPECT_EQ(ASCIIToUTF16("origin"), intents_model.GetTreeNodeId(n1));
-
- IntentsTreeNode* ncheck = intents_model.GetTreeNode("origin");
- EXPECT_EQ(ncheck, n1);
-
- base::ListValue nodes;
- intents_model.GetChildNodeList(
- intents_model.GetTreeNode("www.google.com"), 0, 1, &nodes);
- EXPECT_EQ(static_cast<size_t>(1), nodes.GetSize());
- base::DictionaryValue* dict;
- EXPECT_TRUE(nodes.GetDictionary(0, &dict));
-
- std::string val;
- EXPECT_TRUE(dict->GetString("site", &val));
- EXPECT_EQ("www.google.com", val);
- EXPECT_TRUE(dict->GetString("name", &val));
- EXPECT_EQ("Google", val);
- EXPECT_TRUE(dict->GetString("url", &val));
- EXPECT_EQ("http://www.google.com/share", val);
- EXPECT_TRUE(dict->GetString("icon", &val));
- EXPECT_EQ("http://www.google.com/favicon.ico", val);
- base::ListValue* types_list;
- EXPECT_TRUE(dict->GetList("types", &types_list));
- EXPECT_EQ(static_cast<size_t>(1), types_list->GetSize());
- EXPECT_TRUE(types_list->GetString(0, &val));
- EXPECT_EQ("text/url", val);
- bool bval;
- EXPECT_TRUE(dict->GetBoolean("blocked", &bval));
- EXPECT_FALSE(bval);
- EXPECT_TRUE(dict->GetBoolean("disabled", &bval));
- EXPECT_FALSE(bval);
-}
-
-TEST_F(IntentsModelTest, LoadFromWebData) {
- LoadRegistry();
- WaitingIntentsObserver obs;
- IntentsModel intents_model(&registry_);
- intents_model.AddIntentsTreeObserver(&obs);
- obs.Wait();
- EXPECT_EQ(3, obs.added_);
-
- IntentsTreeNode* node = intents_model.GetTreeNode("www.google.com");
- ASSERT_NE(static_cast<IntentsTreeNode*>(NULL), node);
- EXPECT_EQ(IntentsTreeNode::TYPE_ORIGIN, node->Type());
- EXPECT_EQ(ASCIIToUTF16("www.google.com"), node->GetTitle());
- EXPECT_EQ(1, node->child_count());
- node = node->GetChild(0);
- ASSERT_EQ(IntentsTreeNode::TYPE_SERVICE, node->Type());
- ServiceTreeNode* snode = static_cast<ServiceTreeNode*>(node);
- EXPECT_EQ(ASCIIToUTF16("Google"), snode->ServiceName());
- EXPECT_EQ(ASCIIToUTF16("SHARE"), snode->Action());
- EXPECT_EQ(ASCIIToUTF16("http://www.google.com/share"), snode->ServiceUrl());
- EXPECT_EQ(static_cast<size_t>(1), snode->Types().GetSize());
- string16 stype;
- ASSERT_TRUE(snode->Types().GetString(0, &stype));
- EXPECT_EQ(ASCIIToUTF16("text/url"), stype);
-
- node = intents_model.GetTreeNode("www.digg.com");
- ASSERT_NE(static_cast<IntentsTreeNode*>(NULL), node);
- EXPECT_EQ(IntentsTreeNode::TYPE_ORIGIN, node->Type());
- EXPECT_EQ(ASCIIToUTF16("www.digg.com"), node->GetTitle());
-}
diff --git a/chrome/browser/ui/webui/options/intents_settings_handler.cc b/chrome/browser/ui/webui/options/intents_settings_handler.cc
deleted file mode 100644
index 42f4868..0000000
--- a/chrome/browser/ui/webui/options/intents_settings_handler.cc
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/webui/options/intents_settings_handler.h"
-
-#include "base/utf_string_conversions.h"
-#include "base/values.h"
-#include "chrome/browser/browsing_data_appcache_helper.h"
-#include "chrome/browser/browsing_data_database_helper.h"
-#include "chrome/browser/browsing_data_file_system_helper.h"
-#include "chrome/browser/browsing_data_indexed_db_helper.h"
-#include "chrome/browser/browsing_data_local_storage_helper.h"
-#include "chrome/browser/intents/web_intents_registry.h"
-#include "chrome/browser/intents/web_intents_registry_factory.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/webdata/web_data_service.h"
-#include "content/browser/webui/web_ui.h"
-#include "grit/generated_resources.h"
-#include "net/url_request/url_request_context_getter.h"
-#include "ui/base/l10n/l10n_util.h"
-
-IntentsSettingsHandler::IntentsSettingsHandler() : batch_update_(false) {
-}
-
-IntentsSettingsHandler::~IntentsSettingsHandler() {
-}
-
-void IntentsSettingsHandler::GetLocalizedValues(
- DictionaryValue* localized_strings) {
- DCHECK(localized_strings);
-
- static OptionsStringResource resources[] = {
- { "intentsDomain", IDS_INTENTS_DOMAIN_COLUMN_HEADER },
- { "intentsServiceData", IDS_INTENTS_SERVICE_DATA_COLUMN_HEADER },
- { "manageIntents", IDS_INTENTS_MANAGE_BUTTON },
- { "removeIntent", IDS_INTENTS_REMOVE_INTENT_BUTTON },
- };
-
- RegisterStrings(localized_strings, resources, arraysize(resources));
- RegisterTitle(localized_strings, "intentsViewPage",
- IDS_INTENTS_MANAGER_WINDOW_TITLE);
-}
-
-void IntentsSettingsHandler::RegisterMessages() {
- web_ui_->RegisterMessageCallback("removeIntent",
- NewCallback(this, &IntentsSettingsHandler::RemoveIntent));
- web_ui_->RegisterMessageCallback("loadIntents",
- NewCallback(this, &IntentsSettingsHandler::LoadChildren));
-}
-
-void IntentsSettingsHandler::TreeNodesAdded(ui::TreeModel* model,
- ui::TreeModelNode* parent,
- int start,
- int count) {
- SendChildren(intents_tree_model_->GetRoot());
-}
-
-void IntentsSettingsHandler::TreeNodesRemoved(ui::TreeModel* model,
- ui::TreeModelNode* parent,
- int start,
- int count) {
- SendChildren(intents_tree_model_->GetRoot());
-}
-
-void IntentsSettingsHandler::TreeModelBeginBatch(IntentsModel* model) {
- batch_update_ = true;
-}
-
-void IntentsSettingsHandler::TreeModelEndBatch(IntentsModel* model) {
- batch_update_ = false;
-
- SendChildren(intents_tree_model_->GetRoot());
-}
-
-void IntentsSettingsHandler::EnsureIntentsModelCreated() {
- if (intents_tree_model_.get()) return;
-
- Profile* profile = Profile::FromWebUI(web_ui_);
- web_data_service_ = profile->GetWebDataService(Profile::EXPLICIT_ACCESS);
- web_intents_registry_ = WebIntentsRegistryFactory::GetForProfile(profile);
- web_intents_registry_->Initialize(web_data_service_.get());
- intents_tree_model_.reset(new IntentsModel(web_intents_registry_));
- intents_tree_model_->AddIntentsTreeObserver(this);
-}
-
-void IntentsSettingsHandler::RemoveIntent(const base::ListValue* args) {
- std::string node_path;
- if (!args->GetString(0, &node_path)) {
- return;
- }
-
- EnsureIntentsModelCreated();
-
- IntentsTreeNode* node = intents_tree_model_->GetTreeNode(node_path);
- if (node->Type() == IntentsTreeNode::TYPE_ORIGIN) {
- RemoveOrigin(node);
- } else if (node->Type() == IntentsTreeNode::TYPE_SERVICE) {
- ServiceTreeNode* snode = static_cast<ServiceTreeNode*>(node);
- RemoveService(snode);
- }
-}
-
-void IntentsSettingsHandler::RemoveOrigin(IntentsTreeNode* node) {
- // TODO(gbillock): This is a known batch update. Worth optimizing?
- while (node->child_count() > 0) {
- IntentsTreeNode* cnode = node->GetChild(0);
- CHECK(cnode->Type() == IntentsTreeNode::TYPE_SERVICE);
- ServiceTreeNode* snode = static_cast<ServiceTreeNode*>(cnode);
- RemoveService(snode);
- }
- delete intents_tree_model_->Remove(node->parent(), node);
-}
-
-void IntentsSettingsHandler::RemoveService(ServiceTreeNode* snode) {
- WebIntentData provider;
- provider.service_url = GURL(snode->ServiceUrl());
- provider.action = snode->Action();
- string16 stype;
- if (snode->Types().GetString(0, &stype)) {
- provider.type = stype; // Really need to iterate here.
- }
- provider.title = snode->ServiceName();
- LOG(INFO) << "Removing service " << snode->ServiceName()
- << " " << snode->ServiceUrl();
- web_intents_registry_->UnregisterIntentProvider(provider);
- delete intents_tree_model_->Remove(snode->parent(), snode);
-}
-
-void IntentsSettingsHandler::LoadChildren(const base::ListValue* args) {
- EnsureIntentsModelCreated();
-
- std::string node_path;
- if (!args->GetString(0, &node_path)) {
- SendChildren(intents_tree_model_->GetRoot());
- return;
- }
-
- IntentsTreeNode* node = intents_tree_model_->GetTreeNode(node_path);
- SendChildren(node);
-}
-
-void IntentsSettingsHandler::SendChildren(IntentsTreeNode* parent) {
- // Early bailout during batch updates. We'll get one after the batch concludes
- // with batch_update_ set false.
- if (batch_update_) return;
-
- ListValue* children = new ListValue;
- intents_tree_model_->GetChildNodeList(parent, 0, parent->child_count(),
- children);
-
- ListValue args;
- args.Append(parent == intents_tree_model_->GetRoot() ?
- Value::CreateNullValue() :
- Value::CreateStringValue(intents_tree_model_->GetTreeNodeId(parent)));
- args.Append(children);
-
- web_ui_->CallJavascriptFunction("IntentsView.loadChildren", args);
-}
diff --git a/chrome/browser/ui/webui/options/intents_settings_handler.h b/chrome/browser/ui/webui/options/intents_settings_handler.h
deleted file mode 100644
index 957284c..0000000
--- a/chrome/browser/ui/webui/options/intents_settings_handler.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_WEBUI_OPTIONS_INTENTS_SETTINGS_HANDLER_H_
-#define CHROME_BROWSER_UI_WEBUI_OPTIONS_INTENTS_SETTINGS_HANDLER_H_
-#pragma once
-
-#include "base/compiler_specific.h"
-#include "base/memory/scoped_ptr.h"
-#include "chrome/browser/ui/intents/intents_model.h"
-#include "chrome/browser/ui/webui/options/options_ui.h"
-
-class WebDataService;
-class WebIntentsRegistry;
-
-// Manage setting up the backing data for the web intents options page.
-class IntentsSettingsHandler : public OptionsPageUIHandler,
- public IntentsModel::Observer {
- public:
- IntentsSettingsHandler();
- virtual ~IntentsSettingsHandler();
-
- // OptionsPageUIHandler implementation.
- virtual void GetLocalizedValues(base::DictionaryValue* localized_strings);
- virtual void RegisterMessages();
-
- // IntentsModel::Observer implementation.
- virtual void TreeNodesAdded(ui::TreeModel* model,
- ui::TreeModelNode* parent,
- int start,
- int count) OVERRIDE;
- virtual void TreeNodesRemoved(ui::TreeModel* model,
- ui::TreeModelNode* parent,
- int start,
- int count) OVERRIDE;
- virtual void TreeNodeChanged(ui::TreeModel* model,
- ui::TreeModelNode* node) OVERRIDE {}
- virtual void TreeModelBeginBatch(IntentsModel* model) OVERRIDE;
- virtual void TreeModelEndBatch(IntentsModel* model) OVERRIDE;
-
- private:
- // Creates the IntentsModel if neccessary.
- void EnsureIntentsModelCreated();
-
- // Updates search filter for cookies tree model.
- void UpdateSearchResults(const base::ListValue* args);
-
- // Remove all sites data.
- void RemoveAll(const base::ListValue* args);
-
- // Remove selected sites data.
- void RemoveIntent(const base::ListValue* args);
-
- // Helper functions for removals.
- void RemoveOrigin(IntentsTreeNode* node);
- void RemoveService(ServiceTreeNode* snode);
-
- // Trigger for SendChildren to load the JS model.
- void LoadChildren(const base::ListValue* args);
-
- // Get children nodes data and pass it to 'IntentsView.loadChildren' to
- // update the WebUI.
- void SendChildren(IntentsTreeNode* parent);
-
- scoped_refptr<WebDataService> web_data_service_;
- WebIntentsRegistry* web_intents_registry_; // Weak pointer.
-
- // Backing data model for the intents list.
- scoped_ptr<IntentsModel> intents_tree_model_;
-
- // Flag to indicate whether there is a batch update in progress.
- bool batch_update_;
-
- DISALLOW_COPY_AND_ASSIGN(IntentsSettingsHandler);
-};
-
-#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_INTENTS_SETTINGS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/options_ui.cc b/chrome/browser/ui/webui/options/options_ui.cc
index 98e7d8b..0847472 100644
--- a/chrome/browser/ui/webui/options/options_ui.cc
+++ b/chrome/browser/ui/webui/options/options_ui.cc
@@ -28,7 +28,6 @@
#include "chrome/browser/ui/webui/options/core_options_handler.h"
#include "chrome/browser/ui/webui/options/font_settings_handler.h"
#include "chrome/browser/ui/webui/options/import_data_handler.h"
-#include "chrome/browser/ui/webui/options/intents_settings_handler.h"
#include "chrome/browser/ui/webui/options/language_options_handler.h"
#include "chrome/browser/ui/webui/options/manage_profile_handler.h"
#include "chrome/browser/ui/webui/options/options_sync_setup_handler.h"
@@ -211,7 +210,6 @@ OptionsUI::OptionsUI(TabContents* contents)
AddOptionsPageUIHandler(localized_strings, new ContentSettingsHandler());
AddOptionsPageUIHandler(localized_strings, new CookiesViewHandler());
AddOptionsPageUIHandler(localized_strings, new FontSettingsHandler());
- AddOptionsPageUIHandler(localized_strings, new IntentsSettingsHandler());
#if defined(OS_CHROMEOS)
AddOptionsPageUIHandler(localized_strings,
new chromeos::CrosLanguageOptionsHandler());