summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-26 20:43:14 +0000
committerthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-26 20:43:14 +0000
commit71bc0d0d454034744c1657e24edae9d31b569d66 (patch)
treef42797f2e03ddb134af264c865041b932f1b8226
parentce236a17f258746c1fcfd0203bc94f192ca37f13 (diff)
downloadchromium_src-71bc0d0d454034744c1657e24edae9d31b569d66.zip
chromium_src-71bc0d0d454034744c1657e24edae9d31b569d66.tar.gz
chromium_src-71bc0d0d454034744c1657e24edae9d31b569d66.tar.bz2
Mac: Content Settings Exceptions dialog.
xib changes: ContentSettings.xib: Connect the various "Exceptions" buttons to their handlers and enable them. ContentBlocked*.xib: Now that exceptions can be edited, enable the radio buttons. ContentExceptionsWindow.xib: Add a xib with an exceptions window. Screenshot: http://imgur.com/fLwKA Screenshot on windows: http://imgur.com/UltQp Adding and editing exceptions doesn't work yet. I'll probably do this inline like in the bookmarks manager instead of with a sheet. BUG=34894 TEST=prefs->content settings->exceptions. if you set e.g. the cookie setting to "ask" and then say "remember" in the cookie dialog, these exceptions should show up in the cookie exceptions list. Likewise, if you use the radio group in the popup blocker bubble to override the blocking setting, that should show up there too. Also test this: 1.) Set cookie settings for www.tagesschau.de to "ask", leave window open 2.) Go to tagesschau.de 3.) In dialog, say "remember" and "block" 4.) in exceptions window, the setting should now say "block". Check that all buttons work as expected. Return should enter renaming mode for the current line, esc should stop editing, delete should delete the current line. Review URL: http://codereview.chromium.org/660150 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40156 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/nibs/ContentBlockedImages.xib26
-rw-r--r--chrome/app/nibs/ContentBlockedJavaScript.xib9
-rw-r--r--chrome/app/nibs/ContentBlockedPlugins.xib7
-rw-r--r--chrome/app/nibs/ContentBlockedPopups.xib9
-rw-r--r--chrome/app/nibs/ContentExceptionsWindow.xib843
-rw-r--r--chrome/app/nibs/ContentSettings.xib81
-rw-r--r--chrome/browser/cocoa/content_blocked_bubble_controller.mm3
-rw-r--r--chrome/browser/cocoa/content_exceptions_window_controller.h54
-rw-r--r--chrome/browser/cocoa/content_exceptions_window_controller.mm428
-rw-r--r--chrome/browser/cocoa/content_exceptions_window_controller_unittest.mm41
-rw-r--r--chrome/browser/cocoa/content_settings_dialog_controller.h6
-rw-r--r--chrome/browser/cocoa/content_settings_dialog_controller.mm33
-rw-r--r--chrome/browser/cocoa/cookies_window_controller.h2
-rw-r--r--chrome/browser/content_exceptions_table_model.cc3
-rw-r--r--chrome/browser/host_content_settings_map.cc38
-rwxr-xr-xchrome/chrome_browser.gypi3
-rw-r--r--chrome/chrome_dll.gypi1
-rw-r--r--chrome/chrome_tests.gypi1
18 files changed, 1542 insertions, 46 deletions
diff --git a/chrome/app/nibs/ContentBlockedImages.xib b/chrome/app/nibs/ContentBlockedImages.xib
index bc84d6f..7c6bca0 100644
--- a/chrome/app/nibs/ContentBlockedImages.xib
+++ b/chrome/app/nibs/ContentBlockedImages.xib
@@ -8,7 +8,7 @@
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
- <integer value="28"/>
+ <integer value="4"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -94,12 +94,13 @@
<int key="NSvFlags">292</int>
<string key="NSFrame">{{20, 54}, {276, 38}}</string>
<reference key="NSSuperview" ref="301729179"/>
+ <bool key="NSEnabled">YES</bool>
<int key="NSNumRows">2</int>
<int key="NSNumCols">1</int>
<object class="NSMutableArray" key="NSCells">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSButtonCell" id="193088222">
- <int key="NSCellFlags">604110336</int>
+ <int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">^IDS_BLOCKED_IMAGES_UNBLOCK</string>
<reference key="NSSupport" ref="26"/>
@@ -116,7 +117,7 @@
<int key="NSPeriodicInterval">25</int>
</object>
<object class="NSButtonCell" id="619648789">
- <int key="NSCellFlags">-1543373312</int>
+ <int key="NSCellFlags">-2080244224</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">^IDS_BLOCKED_IMAGES_NO_ACTION</string>
<reference key="NSSupport" ref="26"/>
@@ -230,7 +231,7 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA</bytes>
<int key="NSMatrixFlags">1151868928</int>
<string key="NSCellClass">NSActionCell</string>
<object class="NSButtonCell" key="NSProtoCell" id="789299084">
- <int key="NSCellFlags">604110336</int>
+ <int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">Radio</string>
<reference key="NSSupport" ref="26"/>
@@ -729,6 +730,14 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
+ <string key="className">ChromeEventProcessingWindow</string>
+ <string key="superclassName">NSWindow</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">browser/cocoa/chrome_event_processing_window.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
<string key="className">ChromeUILocalizer</string>
<string key="superclassName">GTMUILocalizer</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
@@ -850,7 +859,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
<object class="IBPartialClassDescription">
<string key="className">InfoBubbleWindow</string>
- <string key="superclassName">NSWindow</string>
+ <string key="superclassName">ChromeEventProcessingWindow</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">browser/cocoa/info_bubble_window.h</string>
@@ -870,6 +879,13 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string key="minorKey">browser/cocoa/tab_strip_model_observer_bridge.h</string>
</object>
</object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSWindow</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">browser/cocoa/themed_window.h</string>
+ </object>
+ </object>
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
diff --git a/chrome/app/nibs/ContentBlockedJavaScript.xib b/chrome/app/nibs/ContentBlockedJavaScript.xib
index 63b9098..88cdfd1 100644
--- a/chrome/app/nibs/ContentBlockedJavaScript.xib
+++ b/chrome/app/nibs/ContentBlockedJavaScript.xib
@@ -8,7 +8,7 @@
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
- <integer value="28"/>
+ <integer value="4"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -94,12 +94,13 @@
<int key="NSvFlags">292</int>
<string key="NSFrame">{{20, 54}, {276, 38}}</string>
<reference key="NSSuperview" ref="301729179"/>
+ <bool key="NSEnabled">YES</bool>
<int key="NSNumRows">2</int>
<int key="NSNumCols">1</int>
<object class="NSMutableArray" key="NSCells">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSButtonCell" id="193088222">
- <int key="NSCellFlags">604110336</int>
+ <int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">^IDS_BLOCKED_JAVASCRIPT_UNBLOCK</string>
<reference key="NSSupport" ref="26"/>
@@ -116,7 +117,7 @@
<int key="NSPeriodicInterval">25</int>
</object>
<object class="NSButtonCell" id="619648789">
- <int key="NSCellFlags">-1543373312</int>
+ <int key="NSCellFlags">-2080244224</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">^IDS_BLOCKED_JAVASCRIPT_NO_ACTION</string>
<reference key="NSSupport" ref="26"/>
@@ -230,7 +231,7 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA</bytes>
<int key="NSMatrixFlags">1151868928</int>
<string key="NSCellClass">NSActionCell</string>
<object class="NSButtonCell" key="NSProtoCell" id="789299084">
- <int key="NSCellFlags">604110336</int>
+ <int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">Radio</string>
<reference key="NSSupport" ref="26"/>
diff --git a/chrome/app/nibs/ContentBlockedPlugins.xib b/chrome/app/nibs/ContentBlockedPlugins.xib
index f3f4116..946bf97 100644
--- a/chrome/app/nibs/ContentBlockedPlugins.xib
+++ b/chrome/app/nibs/ContentBlockedPlugins.xib
@@ -94,12 +94,13 @@
<int key="NSvFlags">292</int>
<string key="NSFrame">{{20, 54}, {276, 38}}</string>
<reference key="NSSuperview" ref="301729179"/>
+ <bool key="NSEnabled">YES</bool>
<int key="NSNumRows">2</int>
<int key="NSNumCols">1</int>
<object class="NSMutableArray" key="NSCells">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSButtonCell" id="193088222">
- <int key="NSCellFlags">604110336</int>
+ <int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">^IDS_BLOCKED_PLUGINS_UNBLOCK</string>
<reference key="NSSupport" ref="26"/>
@@ -116,7 +117,7 @@
<int key="NSPeriodicInterval">25</int>
</object>
<object class="NSButtonCell" id="619648789">
- <int key="NSCellFlags">-1543373312</int>
+ <int key="NSCellFlags">-2080244224</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">^IDS_BLOCKED_PLUGINS_NO_ACTION</string>
<reference key="NSSupport" ref="26"/>
@@ -230,7 +231,7 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA</bytes>
<int key="NSMatrixFlags">1151868928</int>
<string key="NSCellClass">NSActionCell</string>
<object class="NSButtonCell" key="NSProtoCell" id="789299084">
- <int key="NSCellFlags">604110336</int>
+ <int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">Radio</string>
<reference key="NSSupport" ref="26"/>
diff --git a/chrome/app/nibs/ContentBlockedPopups.xib b/chrome/app/nibs/ContentBlockedPopups.xib
index 38a66b1..f5d9959 100644
--- a/chrome/app/nibs/ContentBlockedPopups.xib
+++ b/chrome/app/nibs/ContentBlockedPopups.xib
@@ -8,7 +8,7 @@
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
- <integer value="1"/>
+ <integer value="4"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -94,12 +94,13 @@
<int key="NSvFlags">292</int>
<string key="NSFrame">{{20, 54}, {276, 38}}</string>
<reference key="NSSuperview" ref="301729179"/>
+ <bool key="NSEnabled">YES</bool>
<int key="NSNumRows">2</int>
<int key="NSNumCols">1</int>
<object class="NSMutableArray" key="NSCells">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSButtonCell" id="193088222">
- <int key="NSCellFlags">604110336</int>
+ <int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">^IDS_BLOCKED_POPUPS_UNBLOCK</string>
<reference key="NSSupport" ref="26"/>
@@ -116,7 +117,7 @@
<int key="NSPeriodicInterval">25</int>
</object>
<object class="NSButtonCell" id="619648789">
- <int key="NSCellFlags">-1543373312</int>
+ <int key="NSCellFlags">-2080244224</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">^IDS_BLOCKED_POPUPS_NO_ACTION</string>
<reference key="NSSupport" ref="26"/>
@@ -230,7 +231,7 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA</bytes>
<int key="NSMatrixFlags">1151868928</int>
<string key="NSCellClass">NSActionCell</string>
<object class="NSButtonCell" key="NSProtoCell" id="789299084">
- <int key="NSCellFlags">604110336</int>
+ <int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">Radio</string>
<reference key="NSSupport" ref="26"/>
diff --git a/chrome/app/nibs/ContentExceptionsWindow.xib b/chrome/app/nibs/ContentExceptionsWindow.xib
new file mode 100644
index 0000000..4fb260f
--- /dev/null
+++ b/chrome/app/nibs/ContentExceptionsWindow.xib
@@ -0,0 +1,843 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.03">
+ <data>
+ <int key="IBDocument.SystemTarget">1050</int>
+ <string key="IBDocument.SystemVersion">9L31a</string>
+ <string key="IBDocument.InterfaceBuilderVersion">677</string>
+ <string key="IBDocument.AppKitVersion">949.54</string>
+ <string key="IBDocument.HIToolboxVersion">353.00</string>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="8"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSCustomObject" id="1001">
+ <string key="NSClassName">ContentExceptionsWindowController</string>
+ </object>
+ <object class="NSCustomObject" id="1003">
+ <string key="NSClassName">FirstResponder</string>
+ </object>
+ <object class="NSCustomObject" id="1004">
+ <string key="NSClassName">NSApplication</string>
+ </object>
+ <object class="NSWindowTemplate" id="1005">
+ <int key="NSWindowStyleMask">15</int>
+ <int key="NSWindowBacking">2</int>
+ <string key="NSWindowRect">{{477, 316}, {480, 270}}</string>
+ <int key="NSWTFlags">536870912</int>
+ <string key="NSWindowTitle">Title set by controller</string>
+ <string key="NSWindowClass">NSWindow</string>
+ <nil key="NSViewClass"/>
+ <string key="NSWindowContentMaxSize">{3.40282e+38, 3.40282e+38}</string>
+ <string key="NSWindowContentMinSize">{200, 100}</string>
+ <object class="NSView" key="NSWindowView" id="1006">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSScrollView" id="832680793">
+ <reference key="NSNextResponder" ref="1006"/>
+ <int key="NSvFlags">274</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSClipView" id="854753160">
+ <reference key="NSNextResponder" ref="832680793"/>
+ <int key="NSvFlags">2304</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSTableView" id="178750169">
+ <reference key="NSNextResponder" ref="854753160"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrameSize">{480, 233}</string>
+ <reference key="NSSuperview" ref="854753160"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTableHeaderView" key="NSHeaderView" id="1052514209">
+ <reference key="NSNextResponder" ref="522115304"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrameSize">{480, 17}</string>
+ <reference key="NSSuperview" ref="522115304"/>
+ <reference key="NSTableView" ref="178750169"/>
+ </object>
+ <object class="_NSCornerView" key="NSCornerView" id="274818157">
+ <reference key="NSNextResponder" ref="832680793"/>
+ <int key="NSvFlags">-2147483392</int>
+ <string key="NSFrame">{{466, 0}, {16, 17}}</string>
+ <reference key="NSSuperview" ref="832680793"/>
+ </object>
+ <object class="NSMutableArray" key="NSTableColumns">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSTableColumn" id="20203331">
+ <string key="NSIdentifier">hostname</string>
+ <double key="NSWidth">2.180000e+02</double>
+ <double key="NSMinWidth">4.000000e+01</double>
+ <double key="NSMaxWidth">1.000000e+03</double>
+ <object class="NSTableHeaderCell" key="NSHeaderCell">
+ <int key="NSCellFlags">75628032</int>
+ <int key="NSCellFlags2">0</int>
+ <string key="NSContents">^IDS_EXCEPTIONS_HOSTNAME_HEADER</string>
+ <object class="NSFont" key="NSSupport" id="26">
+ <string key="NSName">LucidaGrande</string>
+ <double key="NSSize">1.100000e+01</double>
+ <int key="NSfFlags">3100</int>
+ </object>
+ <object class="NSColor" key="NSBackgroundColor" id="531830935">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC4zMzMzMzI5OQA</bytes>
+ </object>
+ <object class="NSColor" key="NSTextColor" id="1021472174">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">headerTextColor</string>
+ <object class="NSColor" key="NSColor" id="688302513">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MAA</bytes>
+ </object>
+ </object>
+ </object>
+ <object class="NSTextFieldCell" key="NSDataCell" id="988046756">
+ <int key="NSCellFlags">337772096</int>
+ <int key="NSCellFlags2">2048</int>
+ <string key="NSContents">Text Cell</string>
+ <object class="NSFont" key="NSSupport">
+ <string key="NSName">LucidaGrande</string>
+ <double key="NSSize">1.300000e+01</double>
+ <int key="NSfFlags">1044</int>
+ </object>
+ <reference key="NSControlView" ref="178750169"/>
+ <object class="NSColor" key="NSBackgroundColor" id="241443011">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">controlBackgroundColor</string>
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC42NjY2NjY2OQA</bytes>
+ </object>
+ </object>
+ <object class="NSColor" key="NSTextColor">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">controlTextColor</string>
+ <reference key="NSColor" ref="688302513"/>
+ </object>
+ </object>
+ <int key="NSResizingMask">3</int>
+ <bool key="NSIsResizeable">YES</bool>
+ <bool key="NSIsEditable">YES</bool>
+ <reference key="NSTableView" ref="178750169"/>
+ </object>
+ <object class="NSTableColumn" id="332085935">
+ <string key="NSIdentifier">action</string>
+ <double key="NSWidth">2.560000e+02</double>
+ <double key="NSMinWidth">4.000000e+01</double>
+ <double key="NSMaxWidth">1.000000e+03</double>
+ <object class="NSTableHeaderCell" key="NSHeaderCell">
+ <int key="NSCellFlags">75628032</int>
+ <int key="NSCellFlags2">0</int>
+ <string key="NSContents">^IDS_EXCEPTIONS_ACTION_HEADER</string>
+ <reference key="NSSupport" ref="26"/>
+ <reference key="NSBackgroundColor" ref="531830935"/>
+ <reference key="NSTextColor" ref="1021472174"/>
+ </object>
+ <object class="NSPopUpButtonCell" key="NSDataCell" id="515496406">
+ <int key="NSCellFlags">-2076049856</int>
+ <int key="NSCellFlags2">133120</int>
+ <reference key="NSSupport" ref="26"/>
+ <reference key="NSControlView" ref="178750169"/>
+ <int key="NSButtonFlags">100679935</int>
+ <int key="NSButtonFlags2">129</int>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">400</int>
+ <int key="NSPeriodicInterval">75</int>
+ <object class="NSMenuItem" key="NSMenuItem" id="954294582">
+ <reference key="NSMenu" ref="1034662954"/>
+ <string key="NSTitle">Pop Up</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <int key="NSState">1</int>
+ <object class="NSCustomResource" key="NSOnImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSMenuCheckmark</string>
+ </object>
+ <object class="NSCustomResource" key="NSMixedImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSMenuMixedState</string>
+ </object>
+ <string key="NSAction">_popUpItemAction:</string>
+ <reference key="NSTarget" ref="515496406"/>
+ </object>
+ <bool key="NSMenuItemRespectAlignment">YES</bool>
+ <object class="NSMenu" key="NSMenu" id="1034662954">
+ <string key="NSTitle">OtherViews</string>
+ <object class="NSMutableArray" key="NSMenuItems">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="954294582"/>
+ </object>
+ </object>
+ <int key="NSPreferredEdge">3</int>
+ <bool key="NSUsesItemFromMenu">YES</bool>
+ <bool key="NSAltersState">YES</bool>
+ <int key="NSArrowPosition">1</int>
+ </object>
+ <int key="NSResizingMask">3</int>
+ <bool key="NSIsResizeable">YES</bool>
+ <bool key="NSIsEditable">YES</bool>
+ <reference key="NSTableView" ref="178750169"/>
+ </object>
+ </object>
+ <double key="NSIntercellSpacingWidth">3.000000e+00</double>
+ <double key="NSIntercellSpacingHeight">2.000000e+00</double>
+ <object class="NSColor" key="NSBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <object class="NSColor" key="NSGridColor">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">gridColor</string>
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC41AA</bytes>
+ </object>
+ </object>
+ <double key="NSRowHeight">1.700000e+01</double>
+ <int key="NSTvFlags">1379958784</int>
+ <int key="NSColumnAutoresizingStyle">1</int>
+ <int key="NSDraggingSourceMaskForLocal">15</int>
+ <int key="NSDraggingSourceMaskForNonLocal">0</int>
+ <bool key="NSAllowsTypeSelect">YES</bool>
+ </object>
+ </object>
+ <string key="NSFrame">{{1, 17}, {480, 233}}</string>
+ <reference key="NSSuperview" ref="832680793"/>
+ <reference key="NSNextKeyView" ref="178750169"/>
+ <reference key="NSDocView" ref="178750169"/>
+ <reference key="NSBGColor" ref="241443011"/>
+ <int key="NScvFlags">4</int>
+ </object>
+ <object class="NSScroller" id="984908608">
+ <reference key="NSNextResponder" ref="832680793"/>
+ <int key="NSvFlags">-2147483392</int>
+ <string key="NSFrame">{{466, 17}, {15, 218}}</string>
+ <reference key="NSSuperview" ref="832680793"/>
+ <reference key="NSTarget" ref="832680793"/>
+ <string key="NSAction">_doScroller:</string>
+ <double key="NSCurValue">3.700000e+01</double>
+ <double key="NSPercent">1.947368e-01</double>
+ </object>
+ <object class="NSScroller" id="689783017">
+ <reference key="NSNextResponder" ref="832680793"/>
+ <int key="NSvFlags">-2147483392</int>
+ <string key="NSFrame">{{1, 235}, {465, 15}}</string>
+ <reference key="NSSuperview" ref="832680793"/>
+ <int key="NSsFlags">1</int>
+ <reference key="NSTarget" ref="832680793"/>
+ <string key="NSAction">_doScroller:</string>
+ <double key="NSPercent">8.040201e-01</double>
+ </object>
+ <object class="NSClipView" id="522115304">
+ <reference key="NSNextResponder" ref="832680793"/>
+ <int key="NSvFlags">2304</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="1052514209"/>
+ </object>
+ <string key="NSFrame">{{1, 0}, {480, 17}}</string>
+ <reference key="NSSuperview" ref="832680793"/>
+ <reference key="NSNextKeyView" ref="1052514209"/>
+ <reference key="NSDocView" ref="1052514209"/>
+ <reference key="NSBGColor" ref="241443011"/>
+ <int key="NScvFlags">4</int>
+ </object>
+ <reference ref="274818157"/>
+ </object>
+ <string key="NSFrame">{{-1, 20}, {482, 251}}</string>
+ <reference key="NSSuperview" ref="1006"/>
+ <reference key="NSNextKeyView" ref="854753160"/>
+ <int key="NSsFlags">562</int>
+ <reference key="NSVScroller" ref="984908608"/>
+ <reference key="NSHScroller" ref="689783017"/>
+ <reference key="NSContentView" ref="854753160"/>
+ <reference key="NSHeaderClipView" ref="522115304"/>
+ <reference key="NSCornerView" ref="274818157"/>
+ <bytes key="NSScrollAmts">QSAAAEEgAABBmAAAQZgAAA</bytes>
+ </object>
+ <object class="NSButton" id="232729973">
+ <reference key="NSNextResponder" ref="1006"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{0, -1}, {25, 23}}</string>
+ <reference key="NSSuperview" ref="1006"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="723955339">
+ <int key="NSCellFlags">-2080244224</int>
+ <int key="NSCellFlags2">134348800</int>
+ <string key="NSContents"/>
+ <reference key="NSSupport" ref="26"/>
+ <reference key="NSControlView" ref="232729973"/>
+ <int key="NSButtonFlags">-2033434369</int>
+ <int key="NSButtonFlags2">162</int>
+ <object class="NSCustomResource" key="NSNormalImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSAddTemplate</string>
+ </object>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">400</int>
+ <int key="NSPeriodicInterval">75</int>
+ </object>
+ </object>
+ <object class="NSButton" id="297568762">
+ <reference key="NSNextResponder" ref="1006"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{23, -1}, {25, 23}}</string>
+ <reference key="NSSuperview" ref="1006"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="655968889">
+ <int key="NSCellFlags">-2080244224</int>
+ <int key="NSCellFlags2">134348800</int>
+ <string key="NSContents"/>
+ <reference key="NSSupport" ref="26"/>
+ <reference key="NSControlView" ref="297568762"/>
+ <int key="NSButtonFlags">-2033434369</int>
+ <int key="NSButtonFlags2">162</int>
+ <object class="NSCustomResource" key="NSNormalImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSRemoveTemplate</string>
+ </object>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">400</int>
+ <int key="NSPeriodicInterval">75</int>
+ </object>
+ </object>
+ <object class="NSButton" id="882966747">
+ <reference key="NSNextResponder" ref="1006"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{46, -1}, {96, 23}}</string>
+ <reference key="NSSuperview" ref="1006"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="1032008525">
+ <int key="NSCellFlags">-2080244224</int>
+ <int key="NSCellFlags2">134348800</int>
+ <string key="NSContents">^IDS_EXCEPTIONS_PAGE_VIEW_REMOVE_ALL_BUTTON</string>
+ <reference key="NSSupport" ref="26"/>
+ <reference key="NSControlView" ref="882966747"/>
+ <int key="NSButtonFlags">-2033434369</int>
+ <int key="NSButtonFlags2">162</int>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">400</int>
+ <int key="NSPeriodicInterval">75</int>
+ </object>
+ </object>
+ </object>
+ <string key="NSFrameSize">{480, 270}</string>
+ <reference key="NSSuperview"/>
+ </object>
+ <string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
+ <string key="NSMinSize">{200, 122}</string>
+ <string key="NSMaxSize">{3.40282e+38, 3.40282e+38}</string>
+ </object>
+ <object class="NSCustomObject" id="792052397">
+ <string key="NSClassName">ChromeUILocalizer</string>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">window</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="1005"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="1005"/>
+ <reference key="destination" ref="1001"/>
+ </object>
+ <int key="connectionID">4</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">owner_</string>
+ <reference key="source" ref="792052397"/>
+ <reference key="destination" ref="1001"/>
+ </object>
+ <int key="connectionID">21</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">addButton_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="232729973"/>
+ </object>
+ <int key="connectionID">22</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">removeButton_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="297568762"/>
+ </object>
+ <int key="connectionID">23</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">removeAllButton_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="882966747"/>
+ </object>
+ <int key="connectionID">24</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">tableView_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="178750169"/>
+ </object>
+ <int key="connectionID">25</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">dataSource</string>
+ <reference key="source" ref="178750169"/>
+ <reference key="destination" ref="1001"/>
+ </object>
+ <int key="connectionID">26</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="178750169"/>
+ <reference key="destination" ref="1001"/>
+ </object>
+ <int key="connectionID">27</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">addException:</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="232729973"/>
+ </object>
+ <int key="connectionID">28</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">removeException:</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="297568762"/>
+ </object>
+ <int key="connectionID">29</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">removeAllExceptions:</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="882966747"/>
+ </object>
+ <int key="connectionID">30</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <object class="NSArray" key="object" id="1002">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="1001"/>
+ <reference key="parent" ref="1002"/>
+ <string type="base64-UTF8" key="objectName">RmlsZSdzIE93bmVyA</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="1003"/>
+ <reference key="parent" ref="1002"/>
+ <string key="objectName">First Responder</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-3</int>
+ <reference key="object" ref="1004"/>
+ <reference key="parent" ref="1002"/>
+ <string key="objectName">Application</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1</int>
+ <reference key="object" ref="1005"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="1006"/>
+ </object>
+ <reference key="parent" ref="1002"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">2</int>
+ <reference key="object" ref="1006"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="832680793"/>
+ <reference ref="232729973"/>
+ <reference ref="297568762"/>
+ <reference ref="882966747"/>
+ </object>
+ <reference key="parent" ref="1005"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">5</int>
+ <reference key="object" ref="832680793"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="984908608"/>
+ <reference ref="689783017"/>
+ <reference ref="178750169"/>
+ <reference ref="1052514209"/>
+ </object>
+ <reference key="parent" ref="1006"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">6</int>
+ <reference key="object" ref="984908608"/>
+ <reference key="parent" ref="832680793"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">7</int>
+ <reference key="object" ref="689783017"/>
+ <reference key="parent" ref="832680793"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">8</int>
+ <reference key="object" ref="178750169"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="20203331"/>
+ <reference ref="332085935"/>
+ </object>
+ <reference key="parent" ref="832680793"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">9</int>
+ <reference key="object" ref="1052514209"/>
+ <reference key="parent" ref="832680793"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">10</int>
+ <reference key="object" ref="20203331"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="988046756"/>
+ </object>
+ <reference key="parent" ref="178750169"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">11</int>
+ <reference key="object" ref="332085935"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="515496406"/>
+ </object>
+ <reference key="parent" ref="178750169"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">13</int>
+ <reference key="object" ref="988046756"/>
+ <reference key="parent" ref="20203331"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">14</int>
+ <reference key="object" ref="232729973"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="723955339"/>
+ </object>
+ <reference key="parent" ref="1006"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">15</int>
+ <reference key="object" ref="723955339"/>
+ <reference key="parent" ref="232729973"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">16</int>
+ <reference key="object" ref="297568762"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="655968889"/>
+ </object>
+ <reference key="parent" ref="1006"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">17</int>
+ <reference key="object" ref="655968889"/>
+ <reference key="parent" ref="297568762"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">18</int>
+ <reference key="object" ref="882966747"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="1032008525"/>
+ </object>
+ <reference key="parent" ref="1006"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">19</int>
+ <reference key="object" ref="1032008525"/>
+ <reference key="parent" ref="882966747"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">20</int>
+ <reference key="object" ref="792052397"/>
+ <reference key="parent" ref="1002"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">31</int>
+ <reference key="object" ref="515496406"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="1034662954"/>
+ </object>
+ <reference key="parent" ref="332085935"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">32</int>
+ <reference key="object" ref="1034662954"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="954294582"/>
+ </object>
+ <reference key="parent" ref="515496406"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">33</int>
+ <reference key="object" ref="954294582"/>
+ <reference key="parent" ref="1034662954"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.IBPluginDependency</string>
+ <string>-2.IBPluginDependency</string>
+ <string>-3.IBPluginDependency</string>
+ <string>1.IBEditorWindowLastContentRect</string>
+ <string>1.IBPluginDependency</string>
+ <string>1.IBWindowTemplateEditedContentRect</string>
+ <string>1.NSWindowTemplate.visibleAtLaunch</string>
+ <string>1.WindowOrigin</string>
+ <string>1.editorWindowContentRectSynchronizationRect</string>
+ <string>1.windowTemplate.hasMinSize</string>
+ <string>1.windowTemplate.minSize</string>
+ <string>10.IBPluginDependency</string>
+ <string>11.IBPluginDependency</string>
+ <string>13.IBPluginDependency</string>
+ <string>14.IBPluginDependency</string>
+ <string>15.IBPluginDependency</string>
+ <string>16.IBPluginDependency</string>
+ <string>17.IBPluginDependency</string>
+ <string>18.IBPluginDependency</string>
+ <string>19.IBPluginDependency</string>
+ <string>2.IBPluginDependency</string>
+ <string>20.IBPluginDependency</string>
+ <string>31.IBPluginDependency</string>
+ <string>32.IBEditorWindowLastContentRect</string>
+ <string>32.IBPluginDependency</string>
+ <string>33.IBPluginDependency</string>
+ <string>5.IBPluginDependency</string>
+ <string>6.IBPluginDependency</string>
+ <string>7.IBPluginDependency</string>
+ <string>8.IBPluginDependency</string>
+ <string>9.IBPluginDependency</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>{{24, 257}, {480, 270}}</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>{{24, 257}, {480, 270}}</string>
+ <integer value="1"/>
+ <string>{196, 240}</string>
+ <string>{{357, 418}, {480, 270}}</string>
+ <boolean value="YES"/>
+ <string>{200, 100}</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>{{13, 491}, {480, 20}}</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">33</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">ChromeUILocalizer</string>
+ <string key="superclassName">GTMUILocalizer</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">browser/cocoa/ui_localizer.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">ContentExceptionsWindowController</string>
+ <string key="superclassName">NSWindowController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>addException:</string>
+ <string>removeAllExceptions:</string>
+ <string>removeException:</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>addButton_</string>
+ <string>removeAllButton_</string>
+ <string>removeButton_</string>
+ <string>tableView_</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>NSButton</string>
+ <string>NSButton</string>
+ <string>NSButton</string>
+ <string>NSTableView</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">browser/cocoa/content_exceptions_window_controller.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">GTMUILocalizer</string>
+ <string key="superclassName">NSObject</string>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>otherObjectToLocalize_</string>
+ <string>owner_</string>
+ <string>yetAnotherObjectToLocalize_</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">../third_party/GTM/AppKit/GTMUILocalizer.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSMenuItem</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">browser/cocoa/nsmenuitem_additions.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">browser/cocoa/status_bubble_mac.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">browser/cocoa/tab_strip_model_observer_bridge.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSWindow</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">browser/cocoa/themed_window.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.LastKnownRelativeProjectPath">../../chrome.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ </data>
+</archive>
diff --git a/chrome/app/nibs/ContentSettings.xib b/chrome/app/nibs/ContentSettings.xib
index eb83234..2cf8c57 100644
--- a/chrome/app/nibs/ContentSettings.xib
+++ b/chrome/app/nibs/ContentSettings.xib
@@ -8,7 +8,7 @@
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
- <integer value="40"/>
+ <integer value="68"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -58,7 +58,7 @@
<object class="NSTabViewItem" id="284642839">
<string key="NSIdentifier">1</string>
<object class="NSView" key="NSView" id="701201796">
- <reference key="NSNextResponder" ref="604468971"/>
+ <nil key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -436,7 +436,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<reference key="NSSuperview" ref="959667781"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="973058887">
- <int key="NSCellFlags">604110336</int>
+ <int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">134217728</int>
<string key="NSContents">^IDS_COOKIES_EXCEPTIONS_BUTTON</string>
<reference key="NSSupport" ref="793851927"/>
@@ -545,7 +545,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
</object>
<string key="NSFrame">{{10, 33}, {524, 282}}</string>
- <reference key="NSSuperview" ref="604468971"/>
</object>
<string key="NSLabel">^IDS_COOKIES_TAB_LABEL</string>
<reference key="NSColor" ref="542606114"/>
@@ -778,7 +777,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<reference key="NSSuperview" ref="364725860"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="483672048">
- <int key="NSCellFlags">604110336</int>
+ <int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">134217728</int>
<string key="NSContents">^IDS_COOKIES_EXCEPTIONS_BUTTON</string>
<reference key="NSSupport" ref="793851927"/>
@@ -1030,7 +1029,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<reference key="NSSuperview" ref="144997107"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="938126330">
- <int key="NSCellFlags">604110336</int>
+ <int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">134217728</int>
<string key="NSContents">^IDS_COOKIES_EXCEPTIONS_BUTTON</string>
<reference key="NSSupport" ref="793851927"/>
@@ -1282,7 +1281,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<reference key="NSSuperview" ref="427448830"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="970371058">
- <int key="NSCellFlags">604110336</int>
+ <int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">134217728</int>
<string key="NSContents">^IDS_COOKIES_EXCEPTIONS_BUTTON</string>
<reference key="NSSupport" ref="793851927"/>
@@ -1310,7 +1309,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<object class="NSTabViewItem" id="904332317">
<string key="NSIdentifier">5</string>
<object class="NSView" key="NSView" id="776928083">
- <nil key="NSNextResponder"/>
+ <reference key="NSNextResponder" ref="604468971"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -1534,7 +1533,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<reference key="NSSuperview" ref="1010772578"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="87777598">
- <int key="NSCellFlags">604110336</int>
+ <int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">134217728</int>
<string key="NSContents">^IDS_COOKIES_EXCEPTIONS_BUTTON</string>
<reference key="NSSupport" ref="793851927"/>
@@ -1554,20 +1553,21 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
</object>
<string key="NSFrame">{{10, 33}, {524, 282}}</string>
+ <reference key="NSSuperview" ref="604468971"/>
</object>
<string key="NSLabel">^IDS_POPUP_TAB_LABEL</string>
<reference key="NSColor" ref="542606114"/>
<reference key="NSTabView" ref="604468971"/>
</object>
</object>
- <reference key="NSSelectedTabViewItem" ref="284642839"/>
+ <reference key="NSSelectedTabViewItem" ref="904332317"/>
<reference key="NSFont" ref="793851927"/>
<int key="NSTvFlags">0</int>
<bool key="NSAllowTruncatedLabels">YES</bool>
<bool key="NSDrawsBackground">YES</bool>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
- <reference ref="701201796"/>
+ <reference ref="776928083"/>
</object>
</object>
</object>
@@ -1778,6 +1778,46 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
<int key="connectionID">107</int>
</object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">showCookieExceptions:</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="375419183"/>
+ </object>
+ <int key="connectionID">108</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">showImagesExceptions:</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="555400207"/>
+ </object>
+ <int key="connectionID">109</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">showJavaScriptExceptions:</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="226545616"/>
+ </object>
+ <int key="connectionID">110</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">showPluginsExceptions:</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="681719912"/>
+ </object>
+ <int key="connectionID">111</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">showPopupsExceptions:</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="676037782"/>
+ </object>
+ <int key="connectionID">112</int>
+ </object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -2515,7 +2555,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
</object>
</object>
<nil key="sourceID"/>
- <int key="maxID">107</int>
+ <int key="maxID">112</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -2536,12 +2576,22 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>openFlashPlayerSettings:</string>
+ <string>showCookieExceptions:</string>
<string>showCookies:</string>
+ <string>showImagesExceptions:</string>
+ <string>showJavaScriptExceptions:</string>
+ <string>showPluginsExceptions:</string>
+ <string>showPopupsExceptions:</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>id</string>
<string>id</string>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
@@ -2637,6 +2687,13 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA</bytes>
<string key="minorKey">browser/cocoa/tab_strip_model_observer_bridge.h</string>
</object>
</object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSWindow</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">browser/cocoa/themed_window.h</string>
+ </object>
+ </object>
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
diff --git a/chrome/browser/cocoa/content_blocked_bubble_controller.mm b/chrome/browser/cocoa/content_blocked_bubble_controller.mm
index ef16fd5..7191d29 100644
--- a/chrome/browser/cocoa/content_blocked_bubble_controller.mm
+++ b/chrome/browser/cocoa/content_blocked_bubble_controller.mm
@@ -284,6 +284,9 @@ static NSString* ReplaceNSStringPlaceholders(NSString* formatString,
}
- (void)awakeFromNib {
+ DCHECK([self window]);
+ DCHECK_EQ(self, [[self window] delegate]);
+
[bubble_ setBubbleType:kWhiteInfoBubble];
[bubble_ setArrowLocation:kTopRight];
diff --git a/chrome/browser/cocoa/content_exceptions_window_controller.h b/chrome/browser/cocoa/content_exceptions_window_controller.h
new file mode 100644
index 0000000..e7eab5e
--- /dev/null
+++ b/chrome/browser/cocoa/content_exceptions_window_controller.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2010 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.
+
+#import <Cocoa/Cocoa.h>
+
+#include <string>
+
+#include "base/cocoa_protocols_mac.h"
+#include "base/scoped_ptr.h"
+#include "chrome/browser/host_content_settings_map.h"
+#include "chrome/common/content_settings_types.h"
+
+class ContentExceptionsTableModel;
+class UpdatingContentSettingsObserver;
+
+// Controller for the content exception dialogs.
+@interface ContentExceptionsWindowController : NSWindowController
+ <NSWindowDelegate,
+ NSTableViewDataSource,
+ NSTableViewDelegate> {
+ @private
+ IBOutlet NSTableView* tableView_;
+ IBOutlet NSButton* addButton_;
+ IBOutlet NSButton* removeButton_;
+ IBOutlet NSButton* removeAllButton_;
+
+ ContentSettingsType settingsType_;
+ HostContentSettingsMap* settingsMap_; // weak
+ scoped_ptr<ContentExceptionsTableModel> model_;
+
+ // Set if "Ask" should be a valid option in the "action" popup.
+ BOOL showAsk_;
+
+ // Listens for changes to the content settings and reloads the data when they
+ // change. See comment in |modelDidChange| in the mm file for details.
+ scoped_ptr<UpdatingContentSettingsObserver> tableObserver_;
+
+ // If this is set to NO, notifications by |tableObserver_| are ignored. This
+ // is used to suppress updates at bad times.
+ BOOL updatesEnabled_;
+
+ // This is non-NULL only while a new element is being added.
+ scoped_ptr<HostContentSettingsMap::HostSettingPair> newException_;
+}
+
++ (id)showForType:(ContentSettingsType)settingsType
+ settingsMap:(HostContentSettingsMap*)settingsMap;
+
+- (IBAction)addException:(id)sender;
+- (IBAction)removeException:(id)sender;
+- (IBAction)removeAllExceptions:(id)sender;
+
+@end
diff --git a/chrome/browser/cocoa/content_exceptions_window_controller.mm b/chrome/browser/cocoa/content_exceptions_window_controller.mm
new file mode 100644
index 0000000..1140074
--- /dev/null
+++ b/chrome/browser/cocoa/content_exceptions_window_controller.mm
@@ -0,0 +1,428 @@
+// Copyright (c) 2010 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.
+
+#import "chrome/browser/cocoa/content_exceptions_window_controller.h"
+
+#include "app/l10n_util_mac.h"
+#include "app/table_model_observer.h"
+#import "base/mac_util.h"
+#import "base/scoped_nsobject.h"
+#include "base/sys_string_conversions.h"
+#include "chrome/browser/content_exceptions_table_model.h"
+#include "chrome/common/notification_registrar.h"
+#include "chrome/common/notification_service.h"
+#include "grit/generated_resources.h"
+#include "net/base/net_util.h"
+#include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
+
+@interface ContentExceptionsWindowController(Private)
+- (id)initWithType:(ContentSettingsType)settingsType
+ settingsMap:(HostContentSettingsMap*)settingsMap;
+- (void)adjustEditingButtons;
+- (void)modelDidChange;
+- (size_t)menuItemCount;
+- (NSString*)titleForIndex:(size_t)index;
+- (ContentSetting)settingForIndex:(size_t)index;
+- (size_t)indexForSetting:(ContentSetting)setting;
+@end
+
+////////////////////////////////////////////////////////////////////////////////
+// UrlFormatter
+
+// A simple formatter that only accepts text that vaguely looks like a hostname.
+@interface UrlFormatter : NSFormatter
+@end
+
+@implementation UrlFormatter
+- (NSString*)stringForObjectValue:(id)object {
+ if (![object isKindOfClass:[NSString class]])
+ return nil;
+ return object;
+}
+
+- (BOOL)getObjectValue:(id*)object
+ forString:(NSString*)string
+ errorDescription:(NSString**)error {
+ if ([string length]) {
+ url_canon::CanonHostInfo hostInfo;
+ if (!net::CanonicalizeHost(
+ base::SysNSStringToUTF8(string), &hostInfo).empty()) {
+ *object = string;
+ return YES;
+ }
+ }
+ if (error)
+ *error = @"Invalid hostname";
+ return NO;
+}
+
+- (NSAttributedString*)attributedStringForObjectValue:(id)object
+ withDefaultAttributes:(NSDictionary*)attribs {
+ return nil;
+}
+@end
+
+////////////////////////////////////////////////////////////////////////////////
+// UpdatingContentSettingsObserver
+
+// A UpdatingContentSettingsObserver that tells a window controller to update
+// its data on every notification.
+class UpdatingContentSettingsObserver : public NotificationObserver {
+ public:
+ UpdatingContentSettingsObserver(ContentExceptionsWindowController* controller)
+ : controller_(controller) {
+ // One would think one could register a TableModelObserver to be notified of
+ // changes to ContentExceptionsTableModel. One would be wrong: The table
+ // model only sends out changes that are made through the model, not for
+ // changes made directly to its backing HostContentSettings object (that
+ // happens e.g. if the user uses the cookie confirmation dialog). Hence,
+ // observe the CONTENT_SETTINGS_CHANGED notification directly.
+ registrar_.Add(this, NotificationType::CONTENT_SETTINGS_CHANGED,
+ NotificationService::AllSources());
+ }
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+ private:
+ NotificationRegistrar registrar_;
+ ContentExceptionsWindowController* controller_;
+};
+
+void UpdatingContentSettingsObserver::Observe(
+ NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ [controller_ modelDidChange];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Static functions
+
+namespace {
+
+NSString* GetWindowTitle(ContentSettingsType settingsType) {
+ switch (settingsType) {
+ case CONTENT_SETTINGS_TYPE_COOKIES:
+ return l10n_util::GetNSStringWithFixup(IDS_COOKIE_EXCEPTION_TITLE);
+ case CONTENT_SETTINGS_TYPE_IMAGES:
+ return l10n_util::GetNSStringWithFixup(IDS_IMAGES_EXCEPTION_TITLE);
+ case CONTENT_SETTINGS_TYPE_JAVASCRIPT:
+ return l10n_util::GetNSStringWithFixup(IDS_JS_EXCEPTION_TITLE);
+ case CONTENT_SETTINGS_TYPE_PLUGINS:
+ return l10n_util::GetNSStringWithFixup(IDS_PLUGINS_EXCEPTION_TITLE);
+ case CONTENT_SETTINGS_TYPE_POPUPS:
+ return l10n_util::GetNSStringWithFixup(IDS_POPUP_EXCEPTION_TITLE);
+ default:
+ NOTREACHED();
+ }
+ return @"";
+}
+
+// The settings shown in the combobox if showAsk_ is false;
+const ContentSetting kNoAskSettings[] = { CONTENT_SETTING_ALLOW,
+ CONTENT_SETTING_BLOCK };
+
+// The settings shown in the combobox if showAsk_ is true;
+const ContentSetting kAskSettings[] = { CONTENT_SETTING_ALLOW,
+ CONTENT_SETTING_ASK,
+ CONTENT_SETTING_BLOCK };
+
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+// ContentExceptionsWindowController implementation
+
+static ContentExceptionsWindowController*
+ g_exceptionWindows[CONTENT_SETTINGS_NUM_TYPES] = { nil };
+
+@implementation ContentExceptionsWindowController
+
++ (id)showForType:(ContentSettingsType)settingsType
+ settingsMap:(HostContentSettingsMap*)settingsMap {
+ if (!g_exceptionWindows[settingsType]) {
+ g_exceptionWindows[settingsType] =
+ [[ContentExceptionsWindowController alloc] initWithType:settingsType
+ settingsMap:settingsMap];
+ }
+ [g_exceptionWindows[settingsType] showWindow:nil];
+ return g_exceptionWindows[settingsType];
+}
+
+- (id)initWithType:(ContentSettingsType)settingsType
+ settingsMap:(HostContentSettingsMap*)settingsMap {
+ NSString* nibpath =
+ [mac_util::MainAppBundle() pathForResource:@"ContentExceptionsWindow"
+ ofType:@"nib"];
+ if ((self = [super initWithWindowNibPath:nibpath owner:self])) {
+ settingsType_ = settingsType;
+ settingsMap_ = settingsMap;
+ model_.reset(new ContentExceptionsTableModel(settingsMap_, settingsType_));
+ showAsk_ = settingsType_ == CONTENT_SETTINGS_TYPE_COOKIES;
+ tableObserver_.reset(new UpdatingContentSettingsObserver(self));
+
+ // TODO(thakis): autoremember window rect.
+ // TODO(thakis): sorting support.
+ }
+ return self;
+}
+
+- (void)awakeFromNib {
+ DCHECK([self window]);
+ DCHECK_EQ(self, [[self window] delegate]);
+ DCHECK(tableView_);
+ DCHECK_EQ(self, [tableView_ dataSource]);
+ DCHECK_EQ(self, [tableView_ delegate]);
+
+ [[self window] setTitle:GetWindowTitle(settingsType_)];
+
+ // Make sure the button fits its label, but keep it the same height as the
+ // other two buttons.
+ [GTMUILocalizerAndLayoutTweaker sizeToFitView:removeAllButton_];
+ NSSize size = [removeAllButton_ frame].size;
+ size.height = NSHeight([addButton_ frame]);
+ [removeAllButton_ setFrameSize:size];
+
+ [self adjustEditingButtons];
+
+ // Initialize menu for the data cell in the "action" column.
+ scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@"exceptionMenu"]);
+ for (size_t i = 0; i < [self menuItemCount]; ++i) {
+ scoped_nsobject<NSMenuItem> allowItem([[NSMenuItem alloc]
+ initWithTitle:[self titleForIndex:i] action:NULL keyEquivalent:@""]);
+ [allowItem.get() setTag:[self settingForIndex:i]];
+ [menu.get() addItem:allowItem.get()];
+ }
+ NSCell* menuCell =
+ [[tableView_ tableColumnWithIdentifier:@"action"] dataCell];
+ [menuCell setMenu:menu.get()];
+
+ NSCell* hostCell =
+ [[tableView_ tableColumnWithIdentifier:@"hostname"] dataCell];
+ [hostCell setFormatter:[[[UrlFormatter alloc] init] autorelease]];
+}
+
+- (void)windowWillClose:(NSNotification*)notification {
+ g_exceptionWindows[settingsType_] = nil;
+ [self autorelease];
+}
+
+// Let esc close the window.
+- (void)cancel:(id)sender {
+ if ([tableView_ currentEditor] != nil) {
+ [tableView_ abortEditing];
+ [[self window] makeFirstResponder:tableView_]; // Re-gain focus.
+
+ if ([tableView_ selectedRow] == model_->RowCount()) {
+ // Cancel addition of new row.
+ [self removeException:self];
+ }
+ } else {
+ [self close];
+ }
+}
+
+- (void)keyDown:(NSEvent*)event {
+ NSString* chars = [event charactersIgnoringModifiers];
+ if ([chars length] == 1) {
+ switch ([chars characterAtIndex:0]) {
+ case NSDeleteCharacter:
+ case NSDeleteFunctionKey:
+ // Delete deletes.
+ if ([[tableView_ selectedRowIndexes] count] > 0)
+ [self removeException:self];
+ return;
+ case NSCarriageReturnCharacter:
+ case NSEnterCharacter:
+ // Return enters rename mode.
+ if ([[tableView_ selectedRowIndexes] count] == 1) {
+ [tableView_ editColumn:0
+ row:[[tableView_ selectedRowIndexes] lastIndex]
+ withEvent:nil
+ select:YES];
+ }
+ return;
+ }
+ }
+ [super keyDown:event];
+}
+
+- (IBAction)addException:(id)sender {
+ newException_.reset(new HostContentSettingsMap::HostSettingPair);
+ newException_->first = "example.com";
+ newException_->second = CONTENT_SETTING_BLOCK;
+ [tableView_ reloadData];
+ [self adjustEditingButtons];
+
+ int index = model_->RowCount();
+ [tableView_ selectRowIndexes:[NSIndexSet indexSetWithIndex:index]
+ byExtendingSelection:NO];
+ [tableView_ editColumn:0 row:index withEvent:nil select:YES];
+}
+
+- (IBAction)removeException:(id)sender {
+ updatesEnabled_ = NO;
+ NSIndexSet* selection = [tableView_ selectedRowIndexes];
+ DCHECK_GT([selection count], 0U);
+ NSUInteger index = [selection lastIndex];
+ while (index != NSNotFound) {
+ if (index == static_cast<NSUInteger>(model_->RowCount()))
+ newException_.reset();
+ else
+ model_->RemoveException(index);
+ index = [selection indexLessThanIndex:index];
+ }
+ updatesEnabled_ = YES;
+ [self modelDidChange];
+}
+
+- (IBAction)removeAllExceptions:(id)sender {
+ updatesEnabled_ = NO;
+ newException_.reset();
+ model_->RemoveAll();
+ updatesEnabled_ = YES;
+ [self modelDidChange];
+}
+
+// Table View Data Source -----------------------------------------------------
+
+- (NSInteger)numberOfRowsInTableView:(NSTableView*)table {
+ return model_->RowCount() + (newException_.get() ? 1 : 0);
+}
+
+- (id)tableView:(NSTableView*)tv
+ objectValueForTableColumn:(NSTableColumn*)tableColumn
+ row:(NSInteger)row {
+ const HostContentSettingsMap::HostSettingPair* entry;
+ if (newException_.get() && row >= model_->RowCount())
+ entry = newException_.get();
+ else
+ entry = &model_->entry_at(row);
+
+ NSObject* result = nil;
+ NSString* identifier = [tableColumn identifier];
+ if ([identifier isEqualToString:@"hostname"]) {
+ result = base::SysUTF8ToNSString(entry->first);
+ } else if ([identifier isEqualToString:@"action"]) {
+ result = [NSNumber numberWithInt:[self indexForSetting:entry->second]];
+ } else {
+ NOTREACHED();
+ }
+ return result;
+}
+
+- (void) tableView:(NSTableView*)tv
+ setObjectValue:(id)object
+ forTableColumn:(NSTableColumn*)tableColumn
+ row:(NSInteger)row {
+ // Get model object.
+ bool isNewRow = newException_.get() && row >= model_->RowCount();
+ const HostContentSettingsMap::HostSettingPair* originalEntry =
+ isNewRow ? newException_.get() : &model_->entry_at(row);
+ HostContentSettingsMap::HostSettingPair entry = *originalEntry;
+
+ // Modify it.
+ NSString* identifier = [tableColumn identifier];
+ if ([identifier isEqualToString:@"hostname"]) {
+ entry.first = base::SysNSStringToUTF8(object);
+ }
+ if ([identifier isEqualToString:@"action"]) {
+ int index = [object intValue];
+ entry.second = [self settingForIndex:index];
+ }
+
+ // Commit modification, if any.
+ // TODO(thakis): This apparently moves an edited row to the back of the list.
+ // It's what windows and linux do, but it's kinda sucky. Fix.
+ // http://crbug.com/36904
+ if (entry != *originalEntry) {
+ updatesEnabled_ = NO;
+ if (!isNewRow) {
+ model_->RemoveException(row);
+ } else {
+ newException_.reset();
+ if (![identifier isEqualToString:@"hostname"]) {
+ [tableView_ reloadData];
+ [self adjustEditingButtons];
+ return; // Commit new rows only when the hostname has been set.
+ }
+ }
+
+ model_->AddException(entry.first, entry.second);
+ updatesEnabled_ = YES;
+ [self modelDidChange];
+
+ // For now, at least re-select the edited element.
+ int newIndex = model_->IndexOfExceptionByHost(entry.first);
+ DCHECK(newIndex != -1);
+ [tableView_ selectRowIndexes:[NSIndexSet indexSetWithIndex:newIndex]
+ byExtendingSelection:NO];
+ }
+}
+
+
+// Table View Delegate --------------------------------------------------------
+
+// When the selection in the table view changes, we need to adjust buttons.
+- (void)tableViewSelectionDidChange:(NSNotification*)notification {
+ [self adjustEditingButtons];
+}
+
+// Private --------------------------------------------------------------------
+
+// This method appropriately sets the enabled states on the table's editing
+// buttons.
+- (void)adjustEditingButtons {
+ NSIndexSet* selection = [tableView_ selectedRowIndexes];
+ [removeButton_ setEnabled:([selection count] > 0)];
+ [removeAllButton_ setEnabled:([tableView_ numberOfRows] > 0)];
+}
+
+- (void)modelDidChange {
+ // Some calls on model_, e.g. RemoveException(), change something on the
+ // backing content settings map object (which sends a notification) and then
+ // change more stuff in model_. If model_ is deleted when the notification is
+ // sent, this second access causes a segmentation violation. Hence, disable
+ // resetting model_ while updates can be in progress.
+ if (!updatesEnabled_)
+ return;
+
+ // Tthe model caches its data, meaning we need to recreate it on every change.
+ model_.reset(new ContentExceptionsTableModel(settingsMap_, settingsType_));
+
+ [tableView_ reloadData];
+ [self adjustEditingButtons];
+}
+
+- (size_t)menuItemCount {
+ return showAsk_ ? arraysize(kAskSettings) : arraysize(kNoAskSettings);
+}
+
+- (NSString*)titleForIndex:(size_t)index {
+ switch ([self settingForIndex:index]) {
+ case CONTENT_SETTING_ALLOW:
+ return l10n_util::GetNSStringWithFixup(IDS_EXCEPTIONS_ALLOW_BUTTON);
+ case CONTENT_SETTING_BLOCK:
+ return l10n_util::GetNSStringWithFixup(IDS_EXCEPTIONS_BLOCK_BUTTON);
+ case CONTENT_SETTING_ASK:
+ return l10n_util::GetNSStringWithFixup(IDS_EXCEPTIONS_ASK_BUTTON);
+ default:
+ NOTREACHED();
+ }
+ return @"";
+}
+
+- (ContentSetting)settingForIndex:(size_t)index {
+ return showAsk_ ? kAskSettings[index] : kNoAskSettings[index];
+}
+
+- (size_t)indexForSetting:(ContentSetting)setting {
+ for (size_t i = 0; i < [self menuItemCount]; ++i) {
+ if ([self settingForIndex:i] == setting)
+ return i;
+ }
+ NOTREACHED();
+ return 0;
+}
+
+@end
diff --git a/chrome/browser/cocoa/content_exceptions_window_controller_unittest.mm b/chrome/browser/cocoa/content_exceptions_window_controller_unittest.mm
new file mode 100644
index 0000000..d321dc2
--- /dev/null
+++ b/chrome/browser/cocoa/content_exceptions_window_controller_unittest.mm
@@ -0,0 +1,41 @@
+// Copyright (c) 2010 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.
+
+#import "chrome/browser/cocoa/content_exceptions_window_controller.h"
+
+#import <Cocoa/Cocoa.h>
+
+#import "base/scoped_nsobject.h"
+#include "base/ref_counted.h"
+#include "chrome/browser/cocoa/browser_test_helper.h"
+#include "chrome/browser/cocoa/cocoa_test_helper.h"
+#include "googleurl/src/gurl.h"
+#include "net/url_request/url_request_context.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
+
+namespace {
+
+class ContentExceptionsWindowControllerTest : public CocoaTest {
+ public:
+ virtual void SetUp() {
+ CocoaTest::SetUp();
+ TestingProfile* profile = browser_helper_.profile();
+ settingsMap_ = new HostContentSettingsMap(profile);
+ }
+
+ protected:
+ BrowserTestHelper browser_helper_;
+ scoped_refptr<HostContentSettingsMap> settingsMap_;
+};
+
+TEST_F(ContentExceptionsWindowControllerTest, Construction) {
+ ContentExceptionsWindowController* controller =
+ [ContentExceptionsWindowController
+ showForType:CONTENT_SETTINGS_TYPE_PLUGINS
+ settingsMap:settingsMap_.get()];
+ [controller close]; // Should autorelease.
+}
+
+} // namespace
diff --git a/chrome/browser/cocoa/content_settings_dialog_controller.h b/chrome/browser/cocoa/content_settings_dialog_controller.h
index ff2ef523..7a4bc8c 100644
--- a/chrome/browser/cocoa/content_settings_dialog_controller.h
+++ b/chrome/browser/cocoa/content_settings_dialog_controller.h
@@ -30,4 +30,10 @@ class Profile;
- (IBAction)showCookies:(id)sender;
- (IBAction)openFlashPlayerSettings:(id)sender;
+- (IBAction)showCookieExceptions:(id)sender;
+- (IBAction)showImagesExceptions:(id)sender;
+- (IBAction)showJavaScriptExceptions:(id)sender;
+- (IBAction)showPluginsExceptions:(id)sender;
+- (IBAction)showPopupsExceptions:(id)sender;
+
@end
diff --git a/chrome/browser/cocoa/content_settings_dialog_controller.mm b/chrome/browser/cocoa/content_settings_dialog_controller.mm
index df27d2c..0b59c50 100644
--- a/chrome/browser/cocoa/content_settings_dialog_controller.mm
+++ b/chrome/browser/cocoa/content_settings_dialog_controller.mm
@@ -10,6 +10,7 @@
#include "base/mac_util.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
+#import "chrome/browser/cocoa/content_exceptions_window_controller.h"
#import "chrome/browser/cocoa/cookies_window_controller.h"
#import "chrome/browser/host_content_settings_map.h"
#include "chrome/browser/profile.h"
@@ -37,6 +38,7 @@ ContentSettingsDialogController* g_instance = nil;
@interface ContentSettingsDialogController(Private)
- (id)initWithProfile:(Profile*)profile;
+- (void)showExceptionsForType:(ContentSettingsType)settingsType;
// Properties that the radio groups and checkboxes are bound to.
@property(assign, nonatomic) NSInteger cookieSettingIndex;
@@ -97,6 +99,11 @@ ContentSettingsDialogController* g_instance = nil;
return self;
}
+- (void)awakeFromNib {
+ DCHECK([self window]);
+ DCHECK_EQ(self, [[self window] delegate]);
+}
+
- (void)windowWillClose:(NSNotification*)notification {
[self autorelease];
g_instance = nil;
@@ -173,6 +180,32 @@ ContentSettingsDialogController* g_instance = nil;
browser->window()->Show();
}
+- (IBAction)showCookieExceptions:(id)sender {
+ [self showExceptionsForType:CONTENT_SETTINGS_TYPE_COOKIES];
+}
+
+- (IBAction)showImagesExceptions:(id)sender {
+ [self showExceptionsForType:CONTENT_SETTINGS_TYPE_IMAGES];
+}
+
+- (IBAction)showJavaScriptExceptions:(id)sender {
+ [self showExceptionsForType:CONTENT_SETTINGS_TYPE_JAVASCRIPT];
+}
+
+- (IBAction)showPluginsExceptions:(id)sender {
+ [self showExceptionsForType:CONTENT_SETTINGS_TYPE_PLUGINS];
+}
+
+- (IBAction)showPopupsExceptions:(id)sender {
+ [self showExceptionsForType:CONTENT_SETTINGS_TYPE_POPUPS];
+}
+
+- (void)showExceptionsForType:(ContentSettingsType)settingsType {
+ HostContentSettingsMap* settingsMap = profile_->GetHostContentSettingsMap();
+ [ContentExceptionsWindowController showForType:settingsType
+ settingsMap:settingsMap];
+}
+
- (void)setImagesEnabledIndex:(NSInteger)value {
ContentSetting setting = value == kEnabledIndex ?
CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
diff --git a/chrome/browser/cocoa/cookies_window_controller.h b/chrome/browser/cocoa/cookies_window_controller.h
index b03653c..e0d31f3 100644
--- a/chrome/browser/cocoa/cookies_window_controller.h
+++ b/chrome/browser/cocoa/cookies_window_controller.h
@@ -52,7 +52,7 @@ class CookiesTreeModelObserverBridge : public TreeModelObserver {
private:
friend class ::CookiesWindowControllerTest;
- // Creates an CocoaCookieTreeNodefrom a platform-independent one.
+ // Creates a CocoaCookieTreeNode from a platform-independent one.
// Return value is autoreleased. This creates child nodes recusively.
CocoaCookieTreeNode* CocoaNodeFromTreeNode(TreeModelNode* node);
diff --git a/chrome/browser/content_exceptions_table_model.cc b/chrome/browser/content_exceptions_table_model.cc
index 530fc10..7c7cb68 100644
--- a/chrome/browser/content_exceptions_table_model.cc
+++ b/chrome/browser/content_exceptions_table_model.cc
@@ -39,7 +39,8 @@ void ContentExceptionsTableModel::RemoveAll() {
int old_row_count = RowCount();
entries_.clear();
map_->ClearSettingsForOneType(content_type_);
- observer_->OnItemsRemoved(0, old_row_count);
+ if (observer_)
+ observer_->OnItemsRemoved(0, old_row_count);
}
int ContentExceptionsTableModel::IndexOfExceptionByHost(
diff --git a/chrome/browser/host_content_settings_map.cc b/chrome/browser/host_content_settings_map.cc
index 096566d..56ac5353 100644
--- a/chrome/browser/host_content_settings_map.cc
+++ b/chrome/browser/host_content_settings_map.cc
@@ -213,6 +213,7 @@ void HostContentSettingsMap::SetContentSetting(const std::string& host,
ContentSetting setting) {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ bool early_exit = false;
std::wstring wide_host(UTF8ToWide(host));
DictionaryValue* all_settings_dictionary =
profile_->GetPrefs()->GetMutableDictionary(
@@ -227,25 +228,30 @@ void HostContentSettingsMap::SetContentSetting(const std::string& host,
if (AllDefault(settings)) {
host_content_settings_.erase(i);
all_settings_dictionary->RemoveWithoutPathExpansion(wide_host, NULL);
- return;
+
+ // We can't just return because |NotifyObservers()| needs to be called,
+ // without |lock_| being held.
+ early_exit = true;
}
}
- DictionaryValue* host_settings_dictionary;
- bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion(
- wide_host, &host_settings_dictionary);
- if (!found) {
- host_settings_dictionary = new DictionaryValue;
- all_settings_dictionary->SetWithoutPathExpansion(
- wide_host, host_settings_dictionary);
- DCHECK_NE(setting, CONTENT_SETTING_DEFAULT);
- }
- std::wstring dictionary_path(kTypeNames[content_type]);
- if (setting == CONTENT_SETTING_DEFAULT) {
- host_settings_dictionary->RemoveWithoutPathExpansion(dictionary_path, NULL);
- } else {
- host_settings_dictionary->SetWithoutPathExpansion(
- dictionary_path, Value::CreateIntegerValue(setting));
+ if (!early_exit) {
+ DictionaryValue* host_settings_dictionary;
+ bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion(
+ wide_host, &host_settings_dictionary);
+ if (!found) {
+ host_settings_dictionary = new DictionaryValue;
+ all_settings_dictionary->SetWithoutPathExpansion(
+ wide_host, host_settings_dictionary);
+ DCHECK_NE(setting, CONTENT_SETTING_DEFAULT);
+ }
+ std::wstring dictionary_path(kTypeNames[content_type]);
+ if (setting == CONTENT_SETTING_DEFAULT) {
+ host_settings_dictionary->RemoveWithoutPathExpansion(dictionary_path, NULL);
+ } else {
+ host_settings_dictionary->SetWithoutPathExpansion(
+ dictionary_path, Value::CreateIntegerValue(setting));
+ }
}
NotifyObservers(host);
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 461fa04..626d415 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -499,6 +499,8 @@
'browser/cocoa/constrained_window_mac.mm',
'browser/cocoa/content_blocked_bubble_controller.h',
'browser/cocoa/content_blocked_bubble_controller.mm',
+ 'browser/cocoa/content_exceptions_window_controller.h',
+ 'browser/cocoa/content_exceptions_window_controller.mm',
'browser/cocoa/content_settings_dialog_controller.h',
'browser/cocoa/content_settings_dialog_controller.mm',
'browser/cocoa/cookie_tree_node.h',
@@ -2385,6 +2387,7 @@
'app/nibs/ContentBlockedJavaScript.xib',
'app/nibs/ContentBlockedPlugins.xib',
'app/nibs/ContentBlockedPopups.xib',
+ 'app/nibs/ContentExceptionsWindow.xib',
'app/nibs/ContentSettings.xib',
'app/nibs/DownloadItem.xib',
'app/nibs/DownloadShelf.xib',
diff --git a/chrome/chrome_dll.gypi b/chrome/chrome_dll.gypi
index 47beb7a..7bd2163 100644
--- a/chrome/chrome_dll.gypi
+++ b/chrome/chrome_dll.gypi
@@ -200,6 +200,7 @@
'app/nibs/ContentBlockedJavaScript.xib',
'app/nibs/ContentBlockedPlugins.xib',
'app/nibs/ContentBlockedPopups.xib',
+ 'app/nibs/ContentExceptionsWindow.xib',
'app/nibs/ContentSettings.xib',
'app/nibs/DownloadItem.xib',
'app/nibs/DownloadShelf.xib',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 6685622..d58a8d6 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -613,6 +613,7 @@
'browser/cocoa/cocoa_test_helper.mm',
'browser/cocoa/command_observer_bridge_unittest.mm',
'browser/cocoa/content_blocked_bubble_controller_unittest.mm',
+ 'browser/cocoa/content_exceptions_window_controller_unittest.mm',
'browser/cocoa/content_settings_dialog_controller_unittest.mm',
'browser/cocoa/cookies_window_controller_unittest.mm',
'browser/cocoa/custom_home_pages_model_unittest.mm',