Persist context menus for event pages to preferences.

Refactor a whole bunch of URLPatternSet parsing so it doesn't happen in so many places.

BUG=123366
TEST=Check that event pages that add  context menus at runtime.onInstalled still have them after browser restart.

Review URL: https://chromiumcodereview.appspot.com/10450028

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@139557 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/extension_menu_manager.h b/chrome/browser/extensions/extension_menu_manager.h
index d55ebca4..1197c274 100644
--- a/chrome/browser/extensions/extension_menu_manager.h
+++ b/chrome/browser/extensions/extension_menu_manager.h
@@ -16,6 +16,7 @@
 #include "base/gtest_prod_util.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/string16.h"
+#include "base/values.h"
 #include "chrome/browser/extensions/extension_icon_manager.h"
 #include "chrome/common/extensions/url_pattern_set.h"
 #include "content/public/browser/notification_observer.h"
@@ -108,6 +109,18 @@
       value_ |= context;
     }
 
+    scoped_ptr<Value> ToValue() const {
+      return scoped_ptr<Value>(Value::CreateIntegerValue(value_));
+    }
+
+    bool Populate(const Value& value) {
+      int int_value;
+      if (!value.GetAsInteger(&int_value) || int_value < 0)
+        return false;
+      value_ = int_value;
+      return true;
+    }
+
    private:
     uint32 value_;  // A bitmask of Context values.
   };
@@ -156,9 +169,24 @@
   string16 TitleWithReplacement(const string16& selection,
                                 size_t max_length) const;
 
-  // Set the checked state to |checked|. Returns true if successful.
+  // Sets the checked state to |checked|. Returns true if successful.
   bool SetChecked(bool checked);
 
+  // Converts to Value for serialization to preferences.
+  scoped_ptr<base::DictionaryValue> ToValue() const;
+
+  // Returns a new ExtensionMenuItem created from |value|, or NULL if there is
+  // an error. The caller takes ownership of the ExtensionMenuItem.
+  static ExtensionMenuItem* Populate(const std::string& extension_id,
+                                     const DictionaryValue& value,
+                                     std::string* error);
+
+  // Sets any document and target URL patterns from |properties|.
+  bool PopulateURLPatterns(const base::DictionaryValue& properties,
+                           const char* document_url_patterns_key,
+                           const char* target_url_patterns_key,
+                           std::string* error);
+
  protected:
   friend class ExtensionMenuManager;
 
@@ -169,6 +197,10 @@
   // then owns the pointer.
   ExtensionMenuItem* ReleaseChild(const Id& child_id, bool recursive);
 
+  // Recursively appends all descendant items (children, grandchildren, etc.)
+  // to the output |list|.
+  void GetFlattenedSubtree(ExtensionMenuItem::List* list);
+
   // Recursively removes all descendant items (children, grandchildren, etc.),
   // returning the ids of the removed items.
   std::set<Id> RemoveAllDescendants();
@@ -275,6 +307,13 @@
   virtual void Observe(int type, const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE;
 
+  // Stores the menu items for the extension in the preferences.
+  void WriteToPrefs(const extensions::Extension* extension);
+
+  // Reads menu items for the extension from the preferences. Any invalid
+  // items are ignored.
+  void ReadFromPrefs(const extensions::Extension* extension);
+
  private:
   FRIEND_TEST_ALL_PREFIXES(ExtensionMenuManagerTest, DeleteParent);
   FRIEND_TEST_ALL_PREFIXES(ExtensionMenuManagerTest, RemoveOneByOne);
@@ -306,6 +345,8 @@
 
   ExtensionIconManager icon_manager_;
 
+  Profile* profile_;
+
   DISALLOW_COPY_AND_ASSIGN(ExtensionMenuManager);
 };