Răsfoiți Sursa

HUE-27. Convert collection of JFrameFilters to Behaviors
* Implementing SplitView behaviors
* Implementing SizeTo behaviors
* Implementing Tabs
* Implementing Tips
* Fixing SubmitOnChange backwards compat
* Adding new Behavior content to JFrame dependencies
* JFrame Gallery demo for SubmitOnChange
* data-sort-value > data-sort-number
* JFrame's error handler uses dbug.warn
* fixing depenedencies and file references
* latest -more and -widgets
* removing HtmlTableKeys; these are now in HtmlTable.Select in -more
* passing the invokeLinker method from JFrame to filters
* moving all our deprecated JFrame filters into a single file
* Element.Data is now in the Widget repo
* making the JFrame.Deprecated stuff work; some copy-paste issues.
* data-sort-number > data-sort-numeric
* adding configureRequest method to the passed methods for jframe's behavior
* JFrame Form.Request filter updates to match the behavior in art-widgets

Marcus McLaughlin 15 ani în urmă
părinte
comite
34dbc651b1
93 a modificat fișierele cu 1022 adăugiri și 1204 ștergeri
  1. 1 1
      apps/beeswax/src/beeswax/templates/beeswax_components.mako
  2. 1 1
      apps/beeswax/src/beeswax/templates/choose_file.mako
  3. 1 1
      apps/beeswax/src/beeswax/templates/configuration.mako
  4. 2 2
      apps/beeswax/src/beeswax/templates/create_table_manually.mako
  5. 7 7
      apps/beeswax/src/beeswax/templates/describe_table.mako
  6. 10 10
      apps/beeswax/src/beeswax/templates/execute.mako
  7. 1 1
      apps/beeswax/src/beeswax/templates/explain.mako
  8. 9 9
      apps/beeswax/src/beeswax/templates/header_footer.mako
  9. 2 2
      apps/beeswax/src/beeswax/templates/list_designs.mako
  10. 7 7
      apps/beeswax/src/beeswax/templates/list_history.mako
  11. 1 1
      apps/beeswax/src/beeswax/templates/load_table.mako
  12. 5 5
      apps/beeswax/src/beeswax/templates/my_queries.mako
  13. 5 5
      apps/beeswax/src/beeswax/templates/show_tables.mako
  14. 4 4
      apps/beeswax/src/beeswax/templates/watch_results.mako
  15. 1 1
      apps/beeswax/src/beeswax/templates/watch_wait.mako
  16. 4 4
      apps/beeswax/static/css/beeswax.css
  17. 2 2
      apps/beeswax/static/js/Source/Beeswax/CCS.Beeswax.js
  18. 1 1
      apps/filebrowser/src/filebrowser/static/css/fb.css
  19. 4 4
      apps/filebrowser/src/filebrowser/static/js/Source/FileBrowser/CCS.FileBrowser.js
  20. 2 1
      apps/filebrowser/src/filebrowser/static/js/Source/FileBrowser/CCS.FileEditor.js
  21. 3 3
      apps/filebrowser/src/filebrowser/templates/chooser.mako
  22. 13 13
      apps/filebrowser/src/filebrowser/templates/display.mako
  23. 2 2
      apps/filebrowser/src/filebrowser/templates/edit.mako
  24. 4 4
      apps/filebrowser/src/filebrowser/templates/fb_components.mako
  25. 3 3
      apps/filebrowser/src/filebrowser/templates/listdir_components.mako
  26. 25 25
      apps/help/src/help/static/css/dv.css
  27. 1 1
      apps/help/src/help/templates/display.mako
  28. 1 1
      apps/jframegallery/src/jframegallery/templates/chooser.linker.html
  29. 2 2
      apps/jframegallery/src/jframegallery/templates/context-menu.html
  30. 2 2
      apps/jframegallery/src/jframegallery/templates/filter.input.html
  31. 1 1
      apps/jframegallery/src/jframegallery/templates/fit.text.(table).html
  32. 1 1
      apps/jframegallery/src/jframegallery/templates/html-table.html
  33. 8 8
      apps/jframegallery/src/jframegallery/templates/jframe.sizeTo.html
  34. 1 1
      apps/jframegallery/src/jframegallery/templates/partial_refresh.mako
  35. 1 1
      apps/jframegallery/src/jframegallery/templates/show.and.hide.history.html
  36. 1 1
      apps/jframegallery/src/jframegallery/templates/split-view-with-header.html
  37. 14 14
      apps/jframegallery/src/jframegallery/templates/splitview.(vertical).html
  38. 1 1
      apps/jframegallery/src/jframegallery/templates/splitview.html
  39. 4 4
      apps/jframegallery/src/jframegallery/templates/stand-alone.nav.buttons.html
  40. 47 0
      apps/jframegallery/src/jframegallery/templates/submit.form.on.change.html
  41. 6 6
      apps/jframegallery/src/jframegallery/templates/tips.html
  42. 2 2
      apps/jframegallery/src/jframegallery/windmilltests.py
  43. 2 2
      apps/jobbrowser/src/jobbrowser/templates/attempt.mako
  44. 2 2
      apps/jobbrowser/src/jobbrowser/templates/job.mako
  45. 2 2
      apps/jobbrowser/src/jobbrowser/templates/jobbrowser_components.mako
  46. 2 2
      apps/jobbrowser/src/jobbrowser/templates/jobs.mako
  47. 2 2
      apps/jobbrowser/src/jobbrowser/templates/task.mako
  48. 2 2
      apps/jobbrowser/src/jobbrowser/templates/tasks.mako
  49. 2 2
      apps/jobbrowser/src/jobbrowser/templates/tasktrackers.mako
  50. 2 2
      apps/jobbrowser/static/css/jobbrowser.css
  51. 1 1
      apps/jobsub/src/jobsub/templates/edit.html
  52. 3 3
      apps/jobsub/src/jobsub/templates/list.html
  53. 1 1
      apps/jobsub/src/jobsub/templates/watch.html
  54. 1 1
      apps/jobsub/static/css/jobsub.css
  55. 1 1
      apps/useradmin/src/useradmin/templates/list_users.mako
  56. 21 18
      desktop/core/static/css/shared.css
  57. 13 34
      desktop/core/static/js/Source/BehaviorFilters/Behavior.ContextMenu.js
  58. 99 0
      desktop/core/static/js/Source/BehaviorFilters/Behavior.FilterInput.js
  59. 47 0
      desktop/core/static/js/Source/BehaviorFilters/Behavior.FormRequest.js
  60. 33 0
      desktop/core/static/js/Source/BehaviorFilters/Behavior.FormValidatorScroller.js
  61. 24 25
      desktop/core/static/js/Source/BehaviorFilters/Behavior.SizeTo.js
  62. 34 0
      desktop/core/static/js/Source/BehaviorFilters/Behavior.SplitViewPostFold.js
  63. 61 0
      desktop/core/static/js/Source/BehaviorFilters/Behavior.SubmitOnChange.js
  64. 29 0
      desktop/core/static/js/Source/BehaviorFilters/Behavior.Tabs.js
  65. 70 0
      desktop/core/static/js/Source/BehaviorFilters/Behavior.Tips.js
  66. 1 1
      desktop/core/static/js/Source/CCS/CCS.ContextMenu.js
  67. 1 1
      desktop/core/static/js/Source/CCS/CCS.Desktop.Keys.js
  68. 47 9
      desktop/core/static/js/Source/CCS/CCS.JFrame.js
  69. 1 1
      desktop/core/static/js/Source/CCS/CCS.User.js
  70. 0 47
      desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.ArtButtons.js
  71. 1 1
      desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.DataGroupToggle.js
  72. 195 0
      desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.Deprecated.js
  73. 1 1
      desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.DoubleClickDelegate.js
  74. 0 95
      desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.FilterInput.js
  75. 0 54
      desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.FitText.js
  76. 16 16
      desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.FormRequest.js
  77. 0 58
      desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.FormValidator.js
  78. 0 101
      desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.HtmlTable.js
  79. 0 42
      desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.Input.js
  80. 0 36
      desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.OverText.js
  81. 0 188
      desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.SplitView.js
  82. 0 45
      desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.SubmitOnChange.js
  83. 0 47
      desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.Tabs.js
  84. 0 86
      desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.Tips.js
  85. 69 0
      desktop/core/static/js/Source/JFrameLinkers/CCS.JFrame.SplitViewLinkers.js
  86. 3 3
      desktop/core/static/js/Source/JFrameRenderers/CCS.JFrame.Alert.js
  87. 1 1
      desktop/core/static/js/Source/JFrameRenderers/CCS.JFrame.PartialRefresh.js
  88. 4 4
      desktop/core/static/js/Source/JFrameRenderers/CCS.JFrame.Prompt.js
  89. 2 84
      desktop/core/static/js/Source/Native/Element.Data.js
  90. 3 3
      desktop/core/static/js/Source/UI/ART.SideBySideSelect.js
  91. 8 13
      desktop/core/static/js/package.yml
  92. 1 1
      ext/thirdparty/js/art-widgets.hash
  93. 1 1
      ext/thirdparty/js/mootools-more.hash

+ 1 - 1
apps/beeswax/src/beeswax/templates/beeswax_components.mako

@@ -89,7 +89,7 @@
         % endif
       % endif
       % if help:
-        <p class="ccs-help_text" ${make_attr_str(help_attrs) | n}>${help}</p>
+        <p class="ccs-inline" data-filters="HelpTip" ${make_attr_str(help_attrs) | n}>${help}</p>
       % endif
     </dd>
     % if len(field.errors):

+ 1 - 1
apps/beeswax/src/beeswax/templates/choose_file.mako

@@ -55,7 +55,7 @@ ${wrappers.head('Choose a File')}
                     alt="/user/user_name/data_dir",
                   ),
                   help="The HDFS path to the file that you would like to base this new table definition on.  It can be compressed (gzip) or not.")}
-                <a class="ccs-art_button ccs-choose_file" data-icon-styles="{'width': 16, 'height' : 16, 'top' : 3, 'left' : 6 }" data-chooseFor="path">Choose File</a>
+                <a class="ccs-choose_file" data-filters="ArtButton" data-icon-styles="{'width': 16, 'height' : 16, 'top' : 3, 'left' : 6 }" data-chooseFor="path">Choose File</a>
                 <div class="bw-import_data">
                   ${comps.field(file_form["do_import"],
                     render_default=True,

+ 1 - 1
apps/beeswax/src/beeswax/templates/configuration.mako

@@ -17,7 +17,7 @@
 <%namespace name="util" file="util.mako" />
 ${wrappers.head('Hive Configuration Variables', section='hive configuration')}
 <h1 class="ccs-hidden">Hive Configuration Variables</h1>
-<table class="ccs-data_table sortable" cellpadding="0" cellspacing="0">
+<table class="sortable" data-filters="HtmlTable" cellpadding="0" cellspacing="0">
   <thead>
     <tr>
       <th>Key</th>

+ 2 - 2
apps/beeswax/src/beeswax/templates/create_table_manually.mako

@@ -197,7 +197,7 @@ ${wrappers.head('Create a Table', toolbar=has_tables, section='new table')}
                   data_filters="OverText",
                   alt='/user/user_name/data_dir'
                 )
-              )}<a class="ccs-choose_file ccs-art_button" data-icon-styles="{'width': 16, 'height': 16, 'top': 3, 'left': 6 }" data-chooseFor="table-external_location">Choose File</a>
+              )}<a class="ccs-choose_file" data-filters="ArtButton" data-icon-styles="{'width': 16, 'height': 16, 'top': 3, 'left': 6 }" data-chooseFor="table-external_location">Choose File</a>
             </div>
           </dl>
           <a href="#step6" class="ccs-multipart-next">Final Step: Configure Table Columns &raquo;</a>
@@ -213,7 +213,7 @@ ${wrappers.head('Create a Table', toolbar=has_tables, section='new table')}
               <div class="bw-column">
                 <dt class="bw-column_header bw-inactive">
                   <input name="${form["column_name"].html_name | n}" value="${form["column_name"].data or ''}" class="required bw-column_name" alt="Column Name" data-filters="OverText"/>
-                  <p class="ccs-help_text" data-help-direction="1">
+                  <p class="ccs-inline" data-filters="HelpTip" data-help-direction="1">
                     Column name must be single words that start
                     with a letter or a digit.
                   </p>

+ 7 - 7
apps/beeswax/src/beeswax/templates/describe_table.mako

@@ -19,7 +19,7 @@ ${wrappers.head("Beeswax Table Metadata: " + table.tableName, section='tables')}
 <div id="describe_table" class="view">
   <%def name="column_table(cols)">
     <div class="bw-col_table_wrapper">
-      <table class="ccs-data_table sortable" cellpadding="0" cellspacing="0">
+      <table class="sortable" data-filters="HtmlTable" cellpadding="0" cellspacing="0">
         <thead>
           <tr>
             <th>Name</th>
@@ -40,7 +40,7 @@ ${wrappers.head("Beeswax Table Metadata: " + table.tableName, section='tables')}
     </div>
   </%def>
 
-  <div class="splitview resizable">
+  <div class="resizable" data-filters="SplitView">
     <div class="left_col">
       <h2>${table.tableName}</h2>
       <div class="jframe_padded">
@@ -66,10 +66,10 @@ ${wrappers.head("Beeswax Table Metadata: " + table.tableName, section='tables')}
                           klass='bw-loadPath',
                           data_filters="OverText",
                           alt='/user/data'))}
-                        <div class="ccs-button_bar clearfix">
-                          <a class="ccs-choose_file ccs-art_button" 
+                        <div class="clearfix" data-filters="ArtButtonBar">
+                          <a class="ccs-choose_file" data-filters="ArtButton" 
                             data-icon-styles="{'width': 16, 'height': 16, 'top': 1, 'left': 4 }" data-chooseFor="path">Choose File</a>
-                          <input type="submit" class="ccs-art_button bw-loadSubmit" value="Submit"/>
+                          <input type="submit" class="bw-loadSubmit" data-filters="ArtButton" value="Submit"/>
                         </div>
                         
                         % for pf in load_form.partition_columns:
@@ -84,7 +84,7 @@ ${wrappers.head("Beeswax Table Metadata: " + table.tableName, section='tables')}
               </li>
               <li class="ccs-clear"><a href="${ url("beeswax.views.read_table", table=table_name) }" class="bw-browse_data">Browse Data</a></li>
               <li class="ccs-clear"><a href="${ url("beeswax.views.drop_table", table=table_name) }" class="bw-drop_table">Drop Table</a></li>
-              <li class="ccs-clear"><a href="${hdfs_link}" target="FileBrowser" class="ccs-pointy_tip bw-location_link" data-tip-direction="11" rel="${ table.sd.location }">View File Location</a></li>
+              <li class="ccs-clear"><a href="${hdfs_link}" target="FileBrowser" class="tip bw-location_link" data-filters="PointyTip" data-tip-direction="11" rel="${ table.sd.location }">View File Location</a></li>
             </ul>
           </dd>
         </dl>
@@ -104,7 +104,7 @@ ${wrappers.head("Beeswax Table Metadata: " + table.tableName, section='tables')}
         <ul class="ccs-tab_sections ccs-clear">
           % if top_rows is not None:
             <li class="bw-table_sample">
-              <table class="ccs-data_table" cellpadding="0" cellspacing="0">
+              <table data-filters="HtmlTable" cellpadding="0" cellspacing="0">
                 <thead>
                   <tr>
                     % for col in table.sd.cols:

+ 10 - 10
apps/beeswax/src/beeswax/templates/execute.mako

@@ -28,28 +28,28 @@
         <label>
           ${design.name}
           % if design.desc:
-            <p class="ccs-info_text" data-help-direction="6">${design.desc}</p>
+            <p class="ccs-inline" data-filters="InfoTip" data-help-direction="6">${design.desc}</p>
           % endif
         </label>
       % else:
         <label>New Query</label>
       % endif
       <ul class="query_edit_actions clearfix">
-        <li class="ccs-button_bar bw-query_save_buttons">
+        <li class="bw-query_save_buttons" data-filters="ArtButtonBar">
           <a href="${ url('beeswax.views.execute_query') }"
-            class="ccs-art_button bw-query_new"
+            class="bw-query_new" data-filters="ArtButton"
             data-icon-styles="{'width': 16, 'height': 16, 'top': 4, 'left': 5}">New</a>
 
           % if design and not design.is_auto and design.name:
-            <input type="submit" name="saveform-save" value="Save" class="ccs-art_button bw-query_save"
+            <input type="submit" name="saveform-save" value="Save" class="bw-query_save" data-filters="ArtButton"
               data-icon-styles="{'width':16,'height':16, 'left':7}"/>
           % endif
-          <input type="submit" name="saveform-saveas" value="Save As..." class="ccs-art_button bw-query_save_as"
+          <input type="submit" name="saveform-saveas" value="Save As..." class="bw-query_save_as" data-filters="ArtButton"
             data-icon-styles="{'width':16,'height':16, 'left':7}"/>
-          <a href="#settings" class="ccs-art_button bw-query_settings_toggle" data-icon-styles="{'width':16, 'height': 16}">Advanced</a>
-          <input type="submit" name="button-explain" value="Explain" class="ccs-art_button bw-query_explain"
+          <a href="#settings" class="bw-query_settings_toggle" data-filters="ArtButton" data-icon-styles="{'width':16, 'height': 16}">Advanced</a>
+          <input type="submit" name="button-explain" value="Explain" class="bw-query_explain" data-filters="ArtButton"
            data-icon-styles="{'width':16,'height':16, left: 7}"/>
-          <input type="submit" name="button-submit" value="Execute" class="ccs-art_button bw-query_execute"
+          <input type="submit" name="button-submit" value="Execute" class="bw-query_execute" data-filters="ArtButton"
            data-icon-styles="{'width':16,'height':16, 'left':52, 'top':3}"/>
         </li>
       </ul>
@@ -93,7 +93,7 @@ ${wrappers.head('Hive Query', section='query')}
 
 <div class="view" id="execute">
   <form action="${action}" method="POST" class="form-validator">
-    <div class="splitview resizable">
+    <div class="resizable" data-filters="SplitView">
       <%
         if form.settings.forms or form.file_resources.forms or form.functions.forms:
           width = 230
@@ -154,7 +154,7 @@ ${wrappers.head('Hive Query', section='query')}
                   data_filters="OverText",
                 ))}
                 <div class="ccs-button_subbar_below clearfix">
-                  <a class="ccs-art_button ccs-choose_file" data-chooseFor="${f['path'].html_name | n}" data-icon-styles="{'width':16, 'height':16, 'top':2}">Choose a File</a>
+                  <a class="ccs-choose_file" data-filters="ArtButton" data-chooseFor="${f['path'].html_name | n}" data-icon-styles="{'width':16, 'height':16, 'top':2}">Choose a File</a>
                 </div>
                 ${comps.field(f['_exists'], hidden=True)}
               % endfor

+ 1 - 1
apps/beeswax/src/beeswax/templates/explain.mako

@@ -18,7 +18,7 @@
 <%namespace name="util" file="util.mako" />
 ${wrappers.head('Query Explanation', section='saved queries')}
 <div class="view" id="watch_wait">
-  <div class="splitview resizable">
+  <div class="resizable" data-filters="SplitView">
     <div class="left_col">
       ${util.render_query_context(query_context)}
     </div>

+ 9 - 9
apps/beeswax/src/beeswax/templates/header_footer.mako

@@ -34,28 +34,28 @@ def is_selected(section, matcher):
   <div class="toolbar">
     <a href="${ url('beeswax.views.index') }"><img src="/beeswax/static/art/beeswax-logo.png" width="55" height="55" alt="Beeswax" class="beeswax_logo"></a>
     % if toolbar:
-    <ul class="bw-nav ccs-button_bar">
+    <ul class="bw-nav" data-filters="ArtButtonBar">
       <li><a href="${ url('beeswax.views.execute_query') }" 
-        class="ccs-art_button bw-nav_icon bw-query_nav ${is_selected(section, 'query')}" 
+        class="bw-nav_icon bw-query_nav ${is_selected(section, 'query')}" data-filters="ArtButton"
         data-icon-styles="{'width': 16, 'height': 16, 'top': 4, 'left': 5}">Query Editor</a></li>
       <li><a href="${ url('beeswax.views.my_queries') }"
-        class="ccs-art_button bw-nav_icon bw-my_queries_nav ${is_selected(section, 'my queries')}"
+        class="bw-nav_icon bw-my_queries_nav ${is_selected(section, 'my queries')}" data-filters="ArtButton"
         data-icon-styles="{'width': 16, 'height': 16, 'top': 4, 'left': 5}">My Queries</a></li>
       <li><a href="${ url('beeswax.views.list_designs') }" 
-        class="ccs-art_button bw-nav_icon bw-queries_nav ${is_selected(section, 'saved queries')}" 
+        class="bw-nav_icon bw-queries_nav ${is_selected(section, 'saved queries')}" data-filters="ArtButton"
         data-icon-styles="{'width': 16, 'height': 16, 'top': 4, 'left': 5}">Saved Queries</a></li>
-    ## <li><a href="${ url('beeswax.views.edit_report') }" class="ccs-art_button bw-nav_icon bw-new_report_gen_nav ${is_selected(section, 'report generator')}" data-icon-styles="{'width': 16, 'height': 16, 'top': 4, 'left': 5}">Report Generator</a></li>
+    ## <li><a href="${ url('beeswax.views.edit_report') }" class="bw-nav_icon bw-new_report_gen_nav ${is_selected(section, 'report generator')}" data-filters="ArtButton" data-icon-styles="{'width': 16, 'height': 16, 'top': 4, 'left': 5}">Report Generator</a></li>
       <li><a href="${ url('beeswax.views.list_query_history') }" 
-        class="ccs-art_button bw-nav_icon bw-history_nav ${is_selected(section, 'history')}" 
+        class="bw-nav_icon bw-history_nav ${is_selected(section, 'history')}" data-filters="ArtButton"
         data-icon-styles="{'width': 16, 'height': 16, 'top': 4, 'left': 5}">History</a></li>
       <li><a href="${ url('beeswax.views.show_tables') }" 
-        class="ccs-art_button bw-nav_icon bw-tables_nav ${is_selected(section, 'tables')}" 
+        class="bw-nav_icon bw-tables_nav ${is_selected(section, 'tables')}" data-filters="ArtButton"
         data-icon-styles="{'width': 16, 'height': 16, 'top': 4, 'left': 5}">Tables</a></li>
       <li><a href="${ url('beeswax.views.configuration') }" 
-        class="ccs-art_button bw-nav_icon bw-config_nav ${is_selected(section, 'hive configuration')}" 
+        class="bw-nav_icon bw-config_nav ${is_selected(section, 'hive configuration')}" data-filters="ArtButton"
         data-icon-styles="{'width': 16, 'height': 16, 'top': 4, 'left': 5}">Settings</a>
       </li>
-      <li><a class="ccs-art_button ccs-refresh large">Refresh</a></li>
+      <li><a class="ccs-refresh large" data-filters="ArtButton">Refresh</a></li>
     </ul>
     % endif
   </div>

+ 2 - 2
apps/beeswax/src/beeswax/templates/list_designs.mako

@@ -23,7 +23,7 @@ ${wrappers.head("Beeswax: Queries", section='saved queries')}
 <div id="list_designs" class="view">
   ${comps.pagination(page)}
   <h2 class="ccs-hidden">Saved Queries:</h2>
-  <table class="ccs-data_table selectable" cellpadding="0" cellspacing="0">
+  <table data-filters="HtmlTable" class="selectable" cellpadding="0" cellspacing="0">
     <thead>
       <tr>
         <th colspan="2">Name</th>
@@ -69,7 +69,7 @@ ${wrappers.head("Beeswax: Queries", section='saved queries')}
         </td>
         <td>
           % if design.desc:
-           <p class="ccs-info_text">${design.desc}</p>
+           <p class="ccs-inline" data-filters="InfoTip">${design.desc}</p>
           % endif
         </td>
         <td>${design.owner.username}</td>

+ 7 - 7
apps/beeswax/src/beeswax/templates/list_history.mako

@@ -52,13 +52,13 @@ ${wrappers.head("Beeswax: Query History", section='history')}
         my_querydict = filter_params.copy()
         my_querydict['user'] = request.user.username
       %>
-      <a href="?${my_querydict.urlencode()}" class="ccs-art_button bw-show_group_mine">mine</a>
+      <a href="?${my_querydict.urlencode()}" class="bw-show_group_mine" data-filters="ArtButton">mine</a>
     % else:
       <%
         my_querydict = filter_params.copy()
         my_querydict['user'] = '_all'
       %>
-      <a href="?${my_querydict.urlencode()}" class="ccs-art_button bw-show_group_all">everyone's</a>
+      <a href="?${my_querydict.urlencode()}" class="bw-show_group_all" data-filters="ArtButton">everyone's</a>
     % endif
 
     % if filter_params.get('auto_query', None):
@@ -66,18 +66,18 @@ ${wrappers.head("Beeswax: Query History", section='history')}
         my_querydict = filter_params.copy()
         my_querydict['auto_query'] = ''
       %>
-      <a href="?${my_querydict.urlencode()}" class="ccs-art_button bw-show_group_noauto">user queries</a>
+      <a href="?${my_querydict.urlencode()}" class="bw-show_group_noauto" data-filters="ArtButton">user queries</a>
     % else:
       <%
         my_querydict = filter_params.copy()
         my_querydict['auto_query'] = 'on'
       %>
-      <a href="?${my_querydict.urlencode()}" class="ccs-art_button bw-show_group_auto">auto actions</a>
+      <a href="?${my_querydict.urlencode()}" class="bw-show_group_auto" data-filters="ArtButton">auto actions</a>
     % endif
   </div>
 
   <h3 class="ccs-hidden">Query History:</h3>
-  <table class="ccs-data_table selectable" cellpadding="0" cellspacing="0">
+  <table data-filters="HtmlTable" class="selectable" cellpadding="0" cellspacing="0">
     <thead>
       <tr>
         <th>Time</th>
@@ -103,7 +103,7 @@ ${wrappers.head("Beeswax: Query History", section='history')}
         <td>${query.submission_date.strftime("%x %X")}</td>
         <td>${show_saved_query(design, query)}</td>
         <td>
-          <p class="ccs-info_text">
+          <p class="ccs-inline" data-filters="InfoTip">
             % if len(query.query) > 100:
               <code>${collapse_whitespace(query.query[:100])}...</code>
             % else:
@@ -115,7 +115,7 @@ ${wrappers.head("Beeswax: Query History", section='history')}
         <td>${models.QueryHistory.STATE[query.last_state]}</td>
         <td class="bw-query_result">
           % if query.last_state != models.QueryHistory.STATE.expired.index:
-            <a href="${ url('beeswax.views.watch_query', id=query.id) }?context=${qcontext|u}" class="bw-view_result ccs-art_button" data-icon-styles="{'width': 16, 'height': 16, 'top': 2}">Results</a>
+            <a href="${ url('beeswax.views.watch_query', id=query.id) }?context=${qcontext|u}" class="bw-view_result" data-filters="ArtButton" data-icon-styles="{'width': 16, 'height': 16, 'top': 2}">Results</a>
           % else:
             ~
           % endif

+ 1 - 1
apps/beeswax/src/beeswax/templates/load_table.mako

@@ -21,7 +21,7 @@ ${wrappers.head("Beeswax: Load Data into " + table)}
     <form action="${action}" method="POST">
       <dl>
         ${util.render_field(form["path"])}
-        <a class="ccs-chooseFile ccs-art_button" data-icon-styles="{'width': 16, 'height': 16, 'top': 6, 'left': 6 }" data-chooseFor="path">Open File Chooser </a>
+        <a class="ccs-chooseFile" data-filters="ArtButton" data-icon-styles="{'width': 16, 'height': 16, 'top': 6, 'left': 6 }" data-chooseFor="path">Open File Chooser </a>
         ## Path (on HDFS) of files to load.
         ${util.render_field(form["overwrite"])}
         ## Any existing data will be erased!

+ 5 - 5
apps/beeswax/src/beeswax/templates/my_queries.mako

@@ -33,7 +33,7 @@ ${wrappers.head("Beeswax: My Queries", section='my queries')}
 
     <ul class="ccs-tab_sections ccs-clear">
       <li>
-        <table class="ccs-data_table selectable" cellpadding="0" cellspacing="0">
+        <table data-filters="HtmlTable" class="selectable" cellpadding="0" cellspacing="0">
           <thead>
             <tr>
               <th colspan="2">Name</th>
@@ -68,7 +68,7 @@ ${wrappers.head("Beeswax: My Queries", section='my queries')}
               </td>
               <td>
                 % if design.desc:
-                 <p class="ccs-info_text">${design.desc}</p>
+                 <p class="ccs-inline" data-filters="InfoTip">${design.desc}</p>
                 % endif
               </td>
               <td>
@@ -96,7 +96,7 @@ ${wrappers.head("Beeswax: My Queries", section='my queries')}
         ##
         ## ----------------- My history -------------------
         ##
-        <table class="ccs-data_table selectable" cellpadding="0" cellspacing="0">
+        <table data-filters="HtmlTable" class="selectable" cellpadding="0" cellspacing="0">
           <thead>
             <tr>
               <th>Time</th>
@@ -120,7 +120,7 @@ ${wrappers.head("Beeswax: My Queries", section='my queries')}
               ## TODO (bc): Only showing HQL (not REPORT)
               <td><a href="${ url('beeswax.views.execute_query', design_id=design.id) }" class="bw-view_query">${design.name}</a></td>
               <td>
-                <p class="ccs-info_text">
+                <p class="ccs-inline" data-filters="InfoTip">
                   % if len(query.query) > 100:
                     <code>${collapse_whitespace(query.query[:100])}...</code>
                   % else:
@@ -131,7 +131,7 @@ ${wrappers.head("Beeswax: My Queries", section='my queries')}
               <td>${models.QueryHistory.STATE[query.last_state]}</td>
               <td class="bw-query_result">
                 % if query.last_state != models.QueryHistory.STATE.expired.index:
-                  <a href="${ url('beeswax.views.watch_query', id=query.id) }?context=${qcontext|u}" class="bw-view_result ccs-art_button" data-icon-styles="{'width': 16, 'height': 16, 'top': 2}">View</a>
+                  <a href="${ url('beeswax.views.watch_query', id=query.id) }?context=${qcontext|u}" class="bw-view_result" data-filters="ArtButton" data-icon-styles="{'width': 16, 'height': 16, 'top': 2}">View</a>
                 % else:
                   ~
                 % endif

+ 5 - 5
apps/beeswax/src/beeswax/templates/show_tables.mako

@@ -16,18 +16,18 @@
 <%namespace name="wrappers" file="header_footer.mako" />
 ${wrappers.head("Beeswax: Table List", section='tables')}
   <div class="toolbar">
-    <div class="bw-show_tables_subnav ccs-button_bar">
+    <div class="bw-show_tables_subnav" data-filters="ArtButtonBar">
       % if not examples_installed:
-        <a href="${ url('beeswax.views.install_examples') }" class="ccs-art_button bw-install_samples" data-icon-styles="{'width': 16, 'height': 16, 'top': 1}">install samples</a>
+        <a href="${ url('beeswax.views.install_examples') }" data-filters="ArtButton" class="bw-install_samples" data-icon-styles="{'width': 16, 'height': 16, 'top': 1}">install samples</a>
       % endif
-      <a href="${ url('beeswax.create_table.index') }" class="ccs-art_button bw-new_table" data-icon-styles="{'width': 16, 'height': 16, 'top': 1}">new table</a>
+      <a href="${ url('beeswax.create_table.index') }" data-filters="ArtButton" class="bw-new_table" data-icon-styles="{'width': 16, 'height': 16, 'top': 1}">new table</a>
     </div>
   </div>
 
 <div id="show_tables" class="view">
   <h2 class="ccs-hidden">Tables</h2>
 
-  <table class="ccs-data_table sortable" cellpadding="0" cellspacing="0">
+  <table data-filters="HtmlTable" class="sortable" cellpadding="0" cellspacing="0">
     <thead>
       <tr>
         <th>Table Name</th>
@@ -39,7 +39,7 @@ ${wrappers.head("Beeswax: Table List", section='tables')}
         <tr data-dblclick-delegate="{'dblclick_loads':'.bw-tables_table a'}" class="ccs-no_select">
           <td class="bw-tables_table ccs-no_select">
             <a href="${ url("beeswax.views.describe_table", table=table) }">${ table }</a>
-            <!-- <p class="ccs-help_text">TODO</p> -->
+            <!-- <p class="ccs-inline" data-filters="HelpTip">TODO</p> -->
           </td>
           <td class="bw-tables_browse"><a href="${ url("beeswax.views.read_table", table=table) }">Browse Data</a></td>
         </tr>

+ 4 - 4
apps/beeswax/src/beeswax/templates/watch_results.mako

@@ -19,7 +19,7 @@
 ${wrappers.head("Beeswax: Query Results", section='query')}
 
 <div class="view" id="watch_results">
-  <div class="splitview resizable">
+  <div class="resizable" data-filters="SplitView">
     <div class="left_col">
       ${util.render_query_context(query_context)}
         <dl class="jframe_padded">
@@ -51,9 +51,9 @@ ${wrappers.head("Beeswax: Query Results", section='query')}
                         data_filters="OverText",
                         alt="/user/dir"
                         ))}
-                        <a class="ccs-art_button ccs-choose_file" data-icon-styles="{'width': 16, 'height': 16, 'top': 1, 'left': 4 }" data-chooseFor="target_dir">Choose File</a>
+                        <a data-filters="ArtButton" class="ccs-choose_file" data-icon-styles="{'width': 16, 'height': 16, 'top': 1, 'left': 4 }" data-chooseFor="target_dir">Choose File</a>
                       </div>
-                      <input type="submit" value="Save" name="save" class="ccs-art_button"> 
+                      <input type="submit" value="Save" name="save" data-filters="ArtButton"> 
                     </form>
                   </div>
                 </li>
@@ -114,7 +114,7 @@ ${wrappers.head("Beeswax: Query Results", section='query')}
               % if expected_first_row != start_row:
                 <div class="bw-result_warning">Warning:</i> Page offset may have incremented since last view.</div>
               % endif
-              <table class="ccs-data_table" cellpadding="0" cellspacing="0">
+              <table data-filters="HtmlTable" cellpadding="0" cellspacing="0">
                 <thead>
                   <tr>
                     <th>-</th>

+ 1 - 1
apps/beeswax/src/beeswax/templates/watch_wait.mako

@@ -21,7 +21,7 @@ ${wrappers.head("Beeswax: Waiting for query...", section='query')}
     content="3;url=${url('beeswax.views.watch_query', query.id)}?${fwd_params}">
 
 <div class="view partial_refresh" id="watch_wait">
-  <div class="splitview resizable">
+  <div class="resizable" data-filters="SplitView">
     <div class="left_col">
       ${util.render_query_context(query_context)}
       <dl class="jframe_padded">

+ 4 - 4
apps/beeswax/static/css/beeswax.css

@@ -62,7 +62,7 @@ div.beeswax a.bw-history_nav {
 div.beeswax a.bw-config_nav {
 	background: url(/static/art/icons/cog.png) no-repeat;
 }
-div.beeswax a.ccs-art_button.ccs-refresh.large {
+div.beeswax a.ccs-refresh.large {
 	height: 25px;
 }
 div.beeswax .bw-nav li {
@@ -815,10 +815,10 @@ div.beeswax .watch_results .bw-save_query_results label.overTxtLabel {
 div.beeswax .watch_results .bw-save_query_results input[type=text]{
 	margin-left: 17px;
 }
-div.beeswax .watch_results .bw-save_query_results a.ccs-art_button {
+div.beeswax .watch_results .bw-save_query_results a[data-filters*=ArtButton] {
 	margin-left: 17px;
 }
-div.beeswax .watch_results .bw-save_query_results div.ccs-art_button {
+div.beeswax .watch_results .bw-save_query_results div[data-filters*=ArtButton] {
 	margin-top: 5px;
 }
 div.beeswax .watch_results .bw-save_query_results a.ccs-choose_file {
@@ -1093,7 +1093,7 @@ div.beeswax .context-menu li a {
 	display: block;
 	height: 18px;
 }
-div.beeswax table.ccs-data_table tr.table-tr-selected td .context-menu li a {
+div.beeswax table[data-filters*=HtmlTable] tr.table-tr-selected td .context-menu li a {
 	color: #000;
 	text-decoration: none;
 }

+ 2 - 2
apps/beeswax/static/js/Source/Beeswax/CCS.Beeswax.js

@@ -53,7 +53,7 @@ ART.Sheet.define('splitview.bw-editor', {
 					keys: 'enter',
 					shortcut: 'enter',
 					handler: function(e){
-						var table = $(this).getElement('.ccs-data_table');
+						var table = $(this).getElement('[data-filters*=HtmlTable]');
 						if (!table) return;
 						hTable = table.retrieve('HtmlTable');
 						var selected = hTable.selectedRows[0];
@@ -554,7 +554,7 @@ ART.Sheet.define('splitview.bw-editor', {
 			}.bind(this));
 			
 			//add the settings toggle
-			var splitEl = $(this).getElement('div.splitview');
+			var splitEl = $(this).getElement('div[data-filters*=SplitView]');
 			if (splitEl) {
 				//get the instance of splitview
 				var split = splitEl.get('widget');

+ 1 - 1
apps/filebrowser/src/filebrowser/static/css/fb.css

@@ -126,7 +126,7 @@ div.filebrowser .fb-mkdir {
 	border-bottom: 1px solid #ccc;
 	padding: 3px;
 }
-.filebrowser table.ccs-data_table tr.table-tr-selected td .context-menu li a {
+.filebrowser table[data-filters*=HtmlTable] tr.table-tr-selected td .context-menu li a {
 	color: #000;
 	text-decoration: none;
 }

+ 4 - 4
apps/filebrowser/src/filebrowser/static/js/Source/FileBrowser/CCS.FileBrowser.js

@@ -17,7 +17,7 @@
 ---
 description: File Browser
 provides: [CCS.FileBrowser, CCS.FileChooser, CCS.FileSaver]
-requires: [ccs-shared/CCS.JBrowser, fancyupload/FancyUpload3.Attach, More/URI, More/Fx.Reveal, ccs-shared/Element.Data]
+requires: [ccs-shared/CCS.JBrowser, fancyupload/FancyUpload3.Attach, More/URI, More/Fx.Reveal, Widgets/Element.Data]
 script: CCS.FileBrowser.js
 
 ...
@@ -160,7 +160,7 @@ ART.Sheet.define('window.filechooser.browser', {
 					keys: 'enter',
 					shortcut: 'enter',
 					handler: function(e){
-						var table = $(this).getElement('.ccs-data_table');
+						var table = $(this).getElement('[data-filters*=HtmlTable]');
 						if (!table) return;
 						hTable = table.retrieve('HtmlTable');
 						var selected = hTable.selectedRows[0];
@@ -318,7 +318,7 @@ ART.Sheet.define('window.filechooser.browser', {
 					keys: 'enter',
 					shortcut: 'enter',
 					handler: function(e){
-						var table = $(this).getElement('.ccs-data_table');
+						var table = $(this).getElement('[data-filters*=HtmlTable]');
 						if (!table) return;
 						var selectInfo = this.getSelected(table);
 						if (selectInfo == null) return;
@@ -381,7 +381,7 @@ ART.Sheet.define('window.filechooser.browser', {
 				shortcut: 'enter',
 				handler: function(e){
 					if (document.activeElement != this.locationInput) { 
-						var table = $(this).getElement('.ccs-data_table');
+						var table = $(this).getElement('[data-filters*=HtmlTable]');
 						if (!table) return;
 						hTable = table.retrieve('HtmlTable');
 						var selected = hTable.selectedRows[0];

+ 2 - 1
apps/filebrowser/src/filebrowser/static/js/Source/FileBrowser/CCS.FileEditor.js

@@ -84,7 +84,8 @@ CCS.FileEditor = new Class({
 				var buttons = toolbar.getElement('.fe-buttons');
 				['saveAs', 'save'].each(function(button) {
 					var link = new Element("a", {
-						'class': 'fe-' + button + 'Button ccs-art_button ',
+						'class': 'fe-' + button + 'Button',
+						'data-filters': 'ArtButton',
 						'data-icon-styles': "{'width': 16, 'height': 16}",
 						'events': {
 							'click': function (e) {

+ 3 - 3
apps/filebrowser/src/filebrowser/templates/chooser.mako

@@ -21,9 +21,9 @@
   </head>
   <body>
     <div class="toolbar">
-      <div class="fb-actions ccs-button_bar">
-        <a class="fb-upload ccs-art_button" data-icon-styles="{'width': 16, 'height' : 16}" href="${url('filebrowser.views.upload')}?dest=${path|u}&next=${current_request_path|u}">Upload a File</a>
-        <a class="fb-mkdir ccs-art_button" data-icon-styles="{'width': 16, 'height': 16}" href="${url('filebrowser.views.mkdir')}?path=${path|u}&next=${current_request_path|u}">New Directory</a>
+      <div class="fb-actions" data-filters="ArtButtonBar">
+        <a class="fb-upload" data-filters="ArtButton" data-icon-styles="{'width': 16, 'height' : 16}" href="${url('filebrowser.views.upload')}?dest=${path|u}&next=${current_request_path|u}">Upload a File</a>
+        <a class="fb-mkdir" data-filters="ArtButton" data-icon-styles="{'width': 16, 'height': 16}" href="${url('filebrowser.views.mkdir')}?path=${path|u}&next=${current_request_path|u}">New Directory</a>
       </div>
     </div>
     ${dir.list_table_chooser(files, path_enc, current_request_path)}

+ 13 - 13
apps/filebrowser/src/filebrowser/templates/display.mako

@@ -33,31 +33,31 @@
     %>
   </div>
 
-  <div class="fv-actions ccs-button_bar">
+  <div class="fv-actions" data-filters="ArtButtonBar">
     % if view['mode'] == "binary":
-      <a class="fv-viewText ccs-art_button" data-icon-styles="{'width': 16, 'height': 16}" href="${base_url}?offset=${view['offset']}&length=${view['length']}&mode=text&compression=${view['compression']}">View As Text</a>
+      <a class="fv-viewText" data-filters="ArtButton" data-icon-styles="{'width': 16, 'height': 16}" href="${base_url}?offset=${view['offset']}&length=${view['length']}&mode=text&compression=${view['compression']}">View As Text</a>
     % endif
 
     % if view['mode'] == "text":
-      <a class="fv-viewBinary ccs-art_button" data-icon-styles="{'width': 16, 'height': 16}" href="${base_url}?offset=${view['offset']}&length=${view['length']}&mode=binary&compression=${view['compression']}">View As Binary</a>
+      <a class="fv-viewBinary" data-filters="ArtButton" data-icon-styles="{'width': 16, 'height': 16}" href="${base_url}?offset=${view['offset']}&length=${view['length']}&mode=binary&compression=${view['compression']}">View As Binary</a>
     % endif
 
     % if view['compression'] != "gzip" and path.endswith('.gz'):
-      <a class="fv-viewGzip ccs-art_button" data-icon-styles="{'width': 16, 'height': 16}" href="${base_url}?offset=0&length=2000&mode=${view['mode']}&compression=gzip">Preview As Gzip</a>
+      <a class="fv-viewGzip" data-filters="ArtButton" data-icon-styles="{'width': 16, 'height': 16}" href="${base_url}?offset=0&length=2000&mode=${view['mode']}&compression=gzip">Preview As Gzip</a>
     % endif
 
     % if view['compression'] and view['compression'] != "none":
-      <a class="fv-viewGzip ccs-art_button" data-icon-styles="{'width': 16, 'height': 16}" href="${base_url}?offset=0&length=2000&mode=${view['mode']}&compression=none">Stop preview</a>
+      <a class="fv-viewGzip" data-filters="ArtButton" data-icon-styles="{'width': 16, 'height': 16}" href="${base_url}?offset=0&length=2000&mode=${view['mode']}&compression=none">Stop preview</a>
     % endif
 
     % if editable and view['compression'] == "none":
-      <a class="fv-editFile ccs-art_button" data-icon-styles="{'width': 16, 'height': 16}" href="${url('filebrowser.views.edit', path=path_enc)}" target="FileEditor">Edit This File</a>
+      <a class="fv-editFile" data-filters="ArtButton" data-icon-styles="{'width': 16, 'height': 16}" href="${url('filebrowser.views.edit', path=path_enc)}" target="FileEditor">Edit This File</a>
     % endif
-     <a class="fv-download ccs-art_button" target="_blank" data-icon-styles="{'width': 16, 'height': 16}" href="${url('filebrowser.views.download', path=path_enc)}">Download</a>
-     <a class="fv-viewLocation ccs-art_button" data-icon-styles="{'width': 16, 'height': 16}" href="${url('filebrowser.views.view', path=dirname_enc)}" target="FileBrowser">View File Location</a>
+     <a class="fv-download" data-filters="ArtButton" target="_blank" data-icon-styles="{'width': 16, 'height': 16}" href="${url('filebrowser.views.download', path=path_enc)}">Download</a>
+     <a class="fv-viewLocation" data-filters="ArtButton" data-icon-styles="{'width': 16, 'height': 16}" href="${url('filebrowser.views.view', path=dirname_enc)}" target="FileBrowser">View File Location</a>
   </div> 
   </div>
-  <div class="splitview resizable">
+  <div class="resizable" data-filters="SplitView">
     <div class="left_col jframe_padded">
       <div class="fv-controlInfo">
         % if not view['compression'] or view['compression'] == "none":
@@ -98,10 +98,10 @@
               last =  "href='%s?offset=%d&length=%d&compression=none' title='%d - %d'" %(base_url, stats['size']-(stats['size'] % view['length']), view['length'], stats['size']-(stats['size'] % view['length']) + 1, stats['size']) 
         %>
           ###DEFINE REL
-          <a class="ccs-inline fv-firstBlock ccs-pointy_tip" ${first}>First Block</a>
-          <a class="ccs-inline fv-prevBlock ccs-pointy_tip" ${prev}>Previous Block</a>
-          <a class="ccs-inline fv-nextBlock ccs-pointy_tip" ${next}>Next Block</a>
-          <a class="ccs-inline fv-lastBlock ccs-pointy_tip" ${last}>Last Block</a>
+          <a class="ccs-inline fv-firstBlock" data-filters="PointyTip" ${first}>First Block</a>
+          <a class="ccs-inline fv-prevBlock" data-filters="PointyTip" ${prev}>Previous Block</a>
+          <a class="ccs-inline fv-nextBlock" data-filters="PointyTip" ${next}>Next Block</a>
+          <a class="ccs-inline fv-lastBlock" data-filters="PointyTip" ${last}>Last Block</a>
       </div>
 % endif
       <dl class="fv-fileInfo">

+ 2 - 2
apps/filebrowser/src/filebrowser/templates/edit.mako

@@ -27,8 +27,8 @@
 <body>
 <div class="toolbar">
   <div class="fe-path">${truncate(path, 91)}</div>
-  <div class="fe-buttons ccs-button_bar">
-    <a class="fe-viewLocation ccs-art_button" data-icon-styles="{'width': 16, 'height': 16}" href="${url('filebrowser.views.view', path=dirname_enc)}" target="FileBrowser">View Location</a>
+  <div class="fe-buttons" data-filters="ArtButtonBar">
+    <a class="fe-viewLocation" data-filters="ArtButton" data-icon-styles="{'width': 16, 'height': 16}" href="${url('filebrowser.views.view', path=dirname_enc)}" target="FileBrowser">View Location</a>
   </div>
 </div>
 % if form.errors:

+ 4 - 4
apps/filebrowser/src/filebrowser/templates/fb_components.mako

@@ -29,13 +29,13 @@ from django.template.defaultfilters import urlencode, escape
 
         <a href="${url('filebrowser.views.view', path='/')}"><img src="/filebrowser/static/art/icon_large.png" class="fb_icon"/></a>
         % if current_request_path:
-          <div class="fb-actions ccs-button_bar">
+          <div class="fb-actions" data-filters="ArtButtonBar">
             % if home_directory:
-              <a class="fb-home ccs-art_button" data-icon-styles="{'width' : 16, 'height': 16}" href="${url('filebrowser.views.view', path=home_directory)}">My Home</a>
+              <a class="fb-home" data-filters="ArtButton" data-icon-styles="{'width' : 16, 'height': 16}" href="${url('filebrowser.views.view', path=home_directory)}">My Home</a>
             % endif
             % if cwd_set:
-              <a class="fb-upload ccs-art_button" data-icon-styles="{'width' : 16, 'height': 16}" href="${url('filebrowser.views.upload')}?dest=${path|urlencode}&next=${current_request_path|urlencode}">Upload a File</a>
-              <a class="fb-mkdir ccs-art_button" data-icon-styles="{'width' : 16, 'height': 16}" href="${url('filebrowser.views.mkdir')}?path=${path|urlencode}&next=${current_request_path|urlencode}">New Directory</a>
+              <a class="fb-upload" data-filters="ArtButton" data-icon-styles="{'width' : 16, 'height': 16}" href="${url('filebrowser.views.upload')}?dest=${path|urlencode}&next=${current_request_path|urlencode}">Upload a File</a>
+              <a class="fb-mkdir" data-filters="ArtButton" data-icon-styles="{'width' : 16, 'height': 16}" href="${url('filebrowser.views.mkdir')}?path=${path|urlencode}&next=${current_request_path|urlencode}">New Directory</a>
             % endif
           </div>
         % endif

+ 3 - 3
apps/filebrowser/src/filebrowser/templates/listdir_components.mako

@@ -26,7 +26,7 @@ from django.template.defaultfilters import urlencode, stringformat, filesizeform
   ${_table(files, path_enc, current_request_path, 'view', cwd_set)}
 </%def>
 <%def name="_table(files, path_enc, current_request_path, view, cwd_set=False)">
-  <table class="ccs-data_table fb-file-list selectable sortable" cellpadding="0" cellspacing="0">
+  <table data-filters="HtmlTable" class="fb-file-list selectable sortable" cellpadding="0" cellspacing="0">
     <thead>
       <tr>
         % if cwd_set:
@@ -96,9 +96,9 @@ from django.template.defaultfilters import urlencode, stringformat, filesizeform
           %>
           <td class="fb-filesize">
             % if "dir" == file['type']:
-              <span data-sort-value="${sortValue}">~</span>
+              <span data-sort-number="${sortValue}">~</span>
             % else:
-              <span data-sort-value="${sortValue}">${file['stats']['size']|filesizeformat}</span>
+              <span data-sort-number="${sortValue}">${file['stats']['size']|filesizeformat}</span>
             % endif
           </td>
           <td class="fb-user">${file['stats']['user']}</td>

+ 25 - 25
apps/help/src/help/static/css/dv.css

@@ -4,58 +4,58 @@ div.ccs-help div.jframe_contents .help-logo {
 }
 
 div.ccs-help h1 {
-        background: lightBlue;
-        margin-bottom: 10px;
-        padding: 5px;
-        border: solid black 3px;
-        -moz-border-radius: 10px;
-        -webkit-border-radius: 10px;
+	background: lightBlue;
+	margin-bottom: 10px;
+	padding: 5px;
+	border: solid black 3px;
+	-moz-border-radius: 10px;
+	-webkit-border-radius: 10px;
 }
 
 div.ccs-help p, {
-        margin-left: 5px;
+	margin-left: 5px;
 }
 
 div.ccs-help pre {
-        margin-left: 10px;
+	margin-left: 10px;
 }
 
 div.ccs-help .art-splitview-left {
-        background: lightBlue !important;
+	background: lightBlue !important;
 }
 
 div.ccs-help .art-splitview-right {
-        background: white !important;
+	background: white !important;
 }
 
 div.ccs-help .left_col ul {
-        padding-left: 5px;
-        border-left: solid 5px black;
+	padding-left: 5px;
+	border-left: solid 5px black;
 }
 
 div.ccs-help .left_col li {
-        margin: 5px 0px;
-        background-color: white;
-        color: black;
-        padding: 1px 0px 1px 5px;
-        -moz-border-radius: 5px;
-        -webkit-border-radius: 5px;
-        border: solid lightBlue 1px;
+	margin: 5px 0px;
+	background-color: white;
+	color: black;
+	padding: 1px 0px 1px 5px;
+	-moz-border-radius: 5px;
+	-webkit-border-radius: 5px;
+	border: solid lightBlue 1px;
 }
 
 div.ccs-help .left_col li:hover {
-        background-color: lightBlue;
-        border: solid black 1px;
-        color: white;
+	background-color: lightBlue;
+	border: solid black 1px;
+	color: white;
 }
 
 div.ccs-help .left_col a {
-        color: black;
-        display: block;
+	color: black;
+	display: block;
 }
 
 div.ccs-help .left_col a:hover {
-        text-decoration: none;
+	text-decoration: none;
 }
 
 

+ 1 - 1
apps/help/src/help/templates/display.mako

@@ -18,7 +18,7 @@
   <title>${title}</title>
 </head>
 <body>
-  <div class="splitview resizable">
+  <div class="resizable" data-filters="SplitView">
     <div class="left_col jframe_padded">
       <h2>Index</h2>
       <ul>

+ 1 - 1
apps/jframegallery/src/jframegallery/templates/chooser.linker.html

@@ -20,6 +20,6 @@ limitations under the License.
   <title>File Chooser Filter</title>
 </head>
 <body>
-  <input type="text" name="path"/><a class="ccs-choose_file ccs-art_button" data-chooseFor="path">Save As</a>
+  <input type="text" name="path"/><a class="ccs-choose_file" data-filters="ArtButton" data-chooseFor="path">Save As</a>
 </body>
 </html>

+ 2 - 2
apps/jframegallery/src/jframegallery/templates/context-menu.html

@@ -21,7 +21,7 @@ limitations under the License.
 		<title>Context Menu</title>
 	</head>
 	<body>
-		<div class="ccs-shared context-menu-delegate" data-context-menu-actions="[{'events':['contextmenu','click:relay(a.show-options)'],'menu':'ul.context-menu'}]" style="width: 200px; height: 100px; padding: 40px; background: #ccc; border: 1px solid #000; margin: 10px auto;">
+		<div data-filters="ContextMenu" class="ccs-shared" data-context-menu-actions="[{'events':['contextmenu','click:relay(a.show-options)'],'menu':'ul.context-menu'}]" style="width: 200px; height: 100px; padding: 40px; background: #ccc; border: 1px solid #000; margin: 10px auto;">
 			I show a menu if you right click anywhere in me. Or you can click <a class="show-options">this link</a> to show it.
 			<ul class="context-menu ccs-hidden">
 				<li class="cm-one">Item 1</li>
@@ -30,4 +30,4 @@ limitations under the License.
 			</ul>
 		</div>
 	</body>
-</html>
+</html>

+ 2 - 2
apps/jframegallery/src/jframegallery/templates/filter.input.html

@@ -22,12 +22,12 @@ limitations under the License.
 	</head>
 	<body>
 	<div class="toolbar" style="position: absolute; top: 57px; left: 70px">
-		<input type="text" class="headlamp_name_filter ccs-hidden" data-filters="OverText, ArtInput" data-art-input-type="search"
+		<input type="text" class="headlamp_name_filter ccs-hidden" data-filters="OverText, ArtInput, FilterInput" data-art-input-type="search"
 			title="Filter by Name"
 			data-filter-elements="td.city" data-filter-parents="tr" value="New York"/>
 		</div>
 	</div>
-	<table class="ccs-data_table selectable sortable" cellpadding="0" cellspacing="0">
+	<table data-filters="HtmlTable" class="selectable sortable" cellpadding="0" cellspacing="0">
 		<thead>
 			<tr>
 				<th>

+ 1 - 1
apps/jframegallery/src/jframegallery/templates/fit.text.(table).html

@@ -23,7 +23,7 @@ limitations under the License.
 	<body>
 	<h1 class="ccs-hidden">FitText (table)</h1>
 	
-	<table class="ccs-data_table selectable sortable" data-filters="FitText-Children" cellpadding="0" cellspacing="0" data-fit-text="td">
+	<table data-filters="HtmlTable" class="selectable sortable" data-filters="FitText-Children" cellpadding="0" cellspacing="0" data-fit-text="td">
 		<thead>
 			<tr>
 				<th>

+ 1 - 1
apps/jframegallery/src/jframegallery/templates/html-table.html

@@ -23,7 +23,7 @@ limitations under the License.
 	<body>
 	<h1 class="ccs-hidden">HtmlTable</h1>
 	
-	<table class="ccs-data_table selectable sortable" cellpadding="0" cellspacing="0">
+	<table data-filters="HtmlTable" class="selectable sortable" cellpadding="0" cellspacing="0">
 		<thead>
 			<tr>
 				<th>

+ 8 - 8
apps/jframegallery/src/jframegallery/templates/jframe.sizeTo.html

@@ -1,11 +1,3 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<html>
-	<head>
-		<title>Art Button</title>
-	</head>
-	<body>
-		<h1 style="background: #999; height: 30px; padding: 10px">This is a header that's 100px tall</h1>
-		<div data-size-to-height="-70" class="jframe_padded" style="background: #ccc">
 {% comment %}
 Licensed to Cloudera, Inc. under one
 or more contributor license agreements.  See the NOTICE file
@@ -23,6 +15,14 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 {% endcomment %}
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<html>
+	<head>
+		<title>SizeTo</title>
+	</head>
+	<body>
+		<h1 style="background: #999; height: 30px; padding: 10px">This is a header that's 100px tall</h1>
+		<div data-filters="SizeTo" data-size-to-height="-70" class="jframe_padded" style="background: #ccc">
 			<p>This is content that is stretched to the height of the JFrame - 70px (this isn't 100px because of padding added to this container and the header). This element's background is light grey and should go all the way to the bottom of the window. Further, the overflow (scroll) should be limited to this lower element (because it has overflow:auto assigned to it).</p>
 			<p>this is here to provide an overflow.</p>
 			<p>this is here to provide an overflow.</p>

+ 1 - 1
apps/jframegallery/src/jframegallery/templates/partial_refresh.mako

@@ -25,7 +25,7 @@ from datetime import datetime
   <body>
     <div class="jframe_padded partial_refresh">
       <h2 data-partial-id="0">The current time: ${datetime.now().strftime("%Y-%m-%d %H:%M:%S")}</h2>
-      <a class="ccs-art_button" data-partial-id="1">current time: ${datetime.now().strftime("%Y-%m-%d %H:%M:%S")}</a>
+      <a data-filters="ArtButton" data-partial-id="1">current time: ${datetime.now().strftime("%Y-%m-%d %H:%M:%S")}</a>
       <br/>
       <textarea type="text">you can change this</textarea>
       <p>you can interact with the input above while the blocks with the time stamps update. Note that the button is rendered each time and your input changes aren't.</p>

+ 1 - 1
apps/jframegallery/src/jframegallery/templates/show.and.hide.history.html

@@ -23,7 +23,7 @@ limitations under the License.
 	<body>
 		<div class="jframe_padded ccs-hide_history">
 			<p>This document hides the history component in the browser by having the CSS class <em>.ccs-hide_history</em>. The history component will be restored when you go back.</p>
-			<p><a class="ccs-art_button ccs-back ccs-nav_back"></a></p>
+			<p><a data-filters="ArtButton" class="ccs-back ccs-nav_back"></a></p>
 		</div>
 	</body>
 </html>

+ 1 - 1
apps/jframegallery/src/jframegallery/templates/split-view-with-header.html

@@ -24,7 +24,7 @@ limitations under the License.
 			<h1 style="line-height:20px; padding: 12px; background: #bbb; border-bottom: 1px solid #000">
 				Splitview with header
 			</h1>
-			<div class="splitview resizable"  data-split-offset-y="45">
+			<div data-filters="SplitView" class="resizable"  data-split-offset-y="45">
 				<div class="left_col jframe_padded">
 					this is the left column
 				</div>

+ 14 - 14
apps/jframegallery/src/jframegallery/templates/splitview.(vertical).html

@@ -21,20 +21,20 @@ limitations under the License.
 		<title>Splitview (Vertical)</title>
 	</head>
 	<body>
-			<div class="splitview resizable">
-				<div class="top_col jframe_padded">
-					this is the top column<br/>
-					<a data-splitview-resize="{'top':0}">hide the top</a><br/>
-					<a data-splitview-toggle="{'side': 'bottom', 'hideSplitter': true}">toggle the bottom (hide splitter)</a>
-				</div>
-				<div class="splitter_col" style="background: #88f; padding: 4px">
-					<h4>this is the splitter handle</h4>
-				</div>
-				<div class="bottom_col jframe_padded" style="height:100px">
-					and this is the bottom,<br/>
-					you can resize us by dragging the middle bar around.<br/>
-					<a data-splitview-toggle="{'side': 'top', 'hideSplitter': true}">toggle the top</a>
-				</div>
+		<div class="resizable" data-filters="SplitView">
+			<div class="top_col jframe_padded">
+				this is the top column<br/>
+				<a data-splitview-resize="{'top':0}">hide the top</a><br/>
+				<a data-splitview-toggle="{'side': 'bottom', 'hideSplitter': true}">toggle the bottom (hide splitter)</a>
 			</div>
+			<div class="splitter_col" style="background: #88f; padding: 4px">
+				<h4>this is the splitter handle</h4>
+			</div>
+			<div class="bottom_col jframe_padded" style="height:100px">
+				and this is the bottom,<br/>
+				you can resize us by dragging the middle bar around.<br/>
+				<a data-splitview-toggle="{'side': 'top', 'hideSplitter': true}">toggle the top</a>
+			</div>
+		</div>
 	</body>
 </html>

+ 1 - 1
apps/jframegallery/src/jframegallery/templates/splitview.html

@@ -21,7 +21,7 @@ limitations under the License.
 		<title>Splitview</title>
 	</head>
 	<body>
-			<div class="splitview resizable">
+			<div class="resizable" data-filters="SplitView">
 				<div class="left_col jframe_padded">
 					this is the left column.<br/>
 					<a data-splitview-resize="{'left':0}">hide the left side</a><br/>

+ 4 - 4
apps/jframegallery/src/jframegallery/templates/stand-alone.nav.buttons.html

@@ -23,10 +23,10 @@ limitations under the License.
 	<body>
 		<div class="jframe_padded ccs-hide_history">
 			<p>These buttons perform the standard nav actions of back, forward, and refresh. Note that the forward button doesn't do anything (unless you navigate somewhere else from here - say, by clicking the JFrame Gallery icon to go back to the index and then hitting back to come back to this page) as you don't have anything in your forward history. This button is not styled based on that state (i.e. it's not disabled because you cannot go forward). It's use is somewhat limited due to this.</p>
-			<div class="ccs-button_bar">
-				<a class="ccs-art_button ccs-back ccs-nav_back"></a>
-				<a class="ccs-art_button ccs-refresh"></a>
-				<a class="ccs-art_button ccs-next ccs-nav_next"></a>
+			<div data-filters="ArtButtonBar">
+				<a data-filters="ArtButton" class="ccs-back ccs-nav_back"></a>
+				<a data-filters="ArtButton" class="ccs-refresh"></a>
+				<a data-filters="ArtButton" class="ccs-next ccs-nav_next"></a>
 			</div>
 		</div>
 	</body>

+ 47 - 0
apps/jframegallery/src/jframegallery/templates/submit.form.on.change.html

@@ -0,0 +1,47 @@
+{% comment %}
+Licensed to Cloudera, Inc. under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  Cloudera, Inc. licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+{% endcomment %}
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<html>
+	<head>
+		<title>Submit Form on Change</title>
+	</head>
+	<body>
+		{% if post_vars %}
+			<div class="jframe_padded">
+				You submitted the following values:
+				<ul>
+					{% for post_var, val in post_vars %}
+					 <li>{{post_var}}: {{val}}</li>
+					{% endfor %}
+				</ul>
+			</div>
+		{% else %}
+		<p>
+			The form below will submit as soon as you select a value.
+		</p>
+		<form action="/jframegallery/submit.form.on.change.html" method="post" style="margin: 6px 0px 0px;">
+			<select name="select_list">
+				<option value="option 1">option 1</option>
+				<option value="option 2">option 2</option>
+				<option value="option 3">option 3</option>
+			</select>
+			<input type="submit" class="ccs-hidden" name="submit"/>
+		</form>
+		{% endif %}
+	</body>
+</html>

+ 6 - 6
apps/jframegallery/src/jframegallery/templates/tips.html

@@ -23,20 +23,20 @@ limitations under the License.
 	<body>
 		<div class="jframe_padded">
 			<ul>
-				<li><a class="ccs-pointy_tip" rel="I'm the caption." title="I'm the title!">this link has a tip</a></li>
-				<li><a class="ccs-pointy_tip" rel="I point down." title="I'm the title!" data-tip-direction="6">my tip points down</a></li>
-				<li><a class="ccs-pointy_tip" rel="I point up, but I'm on the right." title="I'm the title!" data-tip-direction="11">my tip is offset</a></li>
-				<li><a class="ccs-pointy_tip" rel="I point left." title="I'm the title!" data-tip-direction="9">my tip points to the left</a></li>
+				<li><a data-filters="PointyTip" rel="I'm the caption." title="I'm the title!">this link has a tip</a></li>
+				<li><a data-filters="PointyTip" rel="I point down." title="I'm the title!" data-tip-direction="6">my tip points down</a></li>
+				<li><a data-filters="PointyTip" rel="I point up, but I'm on the right." title="I'm the title!" data-tip-direction="11">my tip is offset</a></li>
+				<li><a data-filters="PointyTip" rel="I point left." title="I'm the title!" data-tip-direction="9">my tip points to the left</a></li>
 			</ul>
 			
 			<ul>
 				<li>
 					I am some text. Nothing special.
-					<p class="ccs-help_text">I'm some help text that gets turned into a help tip</p>
+					<p class="ccs-inline" data-filters="HelpTip">I'm some help text that gets turned into a help tip</p>
 				</li>
 				<li>
 					I am some text. Nothing special.
-					<p class="ccs-info_text">I'm some help text that gets turned into an info tip</p>
+					<p class="ccs-inline" data-filters="InfoTip">I'm some help text that gets turned into an info tip</p>
 				</li>
 			</ul>
 			

+ 2 - 2
apps/jframegallery/src/jframegallery/windmilltests.py

@@ -43,7 +43,7 @@ def test_context_menu():
   client.waits.forElement(jquery='(".CCS-JFRAMEGALLERY .show-options")[0]')
   #simulating right click, as windmill doesn't provide a mechanism for doing so
   #and it's regular (left) click event doesn't include page location information.
-  client.execJS(js="$$('.context-menu-delegate')[0].fireEvent('contextmenu', new Event({type: 'click', page: {x: 20, y: 20}}))")
+  client.execJS(js="$$('[data-filters*=ContextMenu]')[0].fireEvent('contextmenu', new Event({type: 'click', page: {x: 20, y: 20}}))")
   client.asserts.assertJS(js='document.getElement(\'div.CCS-JFRAMEGALLERY .cm-one\').isVisible()')
   client.click(jquery='(".CCS-JFRAMEGALLERY")[0]')
   client.asserts.assertJS(js='!document.getElement(\'div.CCS-JFRAMEGALLERY .cm-one\').isVisible()')
@@ -140,7 +140,7 @@ def test_split_view():
   launch_jframe_gallery(client)
 
   client.click(id='splitview')
-  client.waits.forElement(jquery="('.CCS-JFRAMEGALLERY .splitview')[0]")
+  client.waits.forElement(jquery="('.CCS-JFRAMEGALLERY [data-filters*=SplitView]')[0]")
   client.asserts.assertJS(js="$$('.CCS-JFRAMEGALLERY .art-splitview-left')[0].getStyle('width') == '200px'")
   client.dragDropElem(jquery="('.CCS-JFRAMEGALLERY .art-splitview-splitter')[0]", pixels='-100,0')
   client.asserts.assertJS(js="$$('.CCS-JFRAMEGALLERY .art-splitview-left')[0].getStyle('width') == '101px'")

+ 2 - 2
apps/jobbrowser/src/jobbrowser/templates/attempt.mako

@@ -44,7 +44,7 @@
 
         <ul class="ccs-tab_sections ccs-clear">
           <li>
-            <table class="ccs-data_table jt_meta_table sortable" cellpadding="0" cellspacing="0">
+            <table data-filters="HtmlTable" class="jt_meta_table sortable" cellpadding="0" cellspacing="0">
               <thead>
                 <th>Name</th>
                 <th>Value</th>
@@ -136,4 +136,4 @@ ${ line | h,trim }
         </ul>
       </div>
 
-    ${comps.footer()}
+    ${comps.footer()}

+ 2 - 2
apps/jobbrowser/src/jobbrowser/templates/job.mako

@@ -22,7 +22,7 @@
 %>
 
 <%def name="task_table(tasks)">
-  <table class="ccs-data_table sortable" cellpadding="0" cellspacing="0">
+  <table data-filters="HtmlTable" class="sortable" cellpadding="0" cellspacing="0">
     <thead>
       <tr>
         <th>Tasks</th>
@@ -158,7 +158,7 @@
             
           </li>
           <li>
-            <table class="ccs-data_table jt_meta_table sortable" cellpadding="0" cellspacing="0">
+            <table data-filters="HtmlTable" class="jt_meta_table sortable" cellpadding="0" cellspacing="0">
               <thead>
                 <th>Name</th>
                 <th>Value</th>

+ 2 - 2
apps/jobbrowser/src/jobbrowser/templates/jobbrowser_components.mako

@@ -37,7 +37,7 @@
 <%
   from jobbrowser.views import format_counter_name
 %>
-    <table class="ccs-data_table jt_counter_table">
+    <table data-filters="HtmlTable" class="jt_counter_table">
       <thead>
          <tr>
            <th class="jt_counter_display_name">Counter Name</th>
@@ -65,7 +65,7 @@
   from jobbrowser.views import format_counter_name
 %>
 
-    <table class="ccs-data_table jt_counter_table">
+    <table data-filters="HtmlTable" class="jt_counter_table">
       <thead>
          <tr>
            <th class="jt_counter_display_name">Name</th>

+ 2 - 2
apps/jobbrowser/src/jobbrowser/templates/jobs.mako

@@ -31,7 +31,7 @@
         <div class="toolbar">
           <a href="/jobbrowser/jobs/"><img src="/jobbrowser/static/art/icon_large.png" class="jt_icon"/></a>
           <ul class="jt_filters">
-            <form class="jt_filter_form submit_on_change" method="get" action="/jobbrowser/jobs/">
+            <form class="jt_filter_form" data-filters="SubmitOnChange" method="get" action="/jobbrowser/jobs/">
               <li class="ccs-inline"><b>Filter Jobs:</b></li>
               <li class="ccs-inline">
                 <select name="state">
@@ -53,7 +53,7 @@
         </div>
     
     
-        <table class="ccs-data_table sortable" cellpadding="0" cellspacing="0">
+        <table data-filters="HtmlTable" class="sortable" cellpadding="0" cellspacing="0">
           <thead>
             <tr>
               <th>Name / Id</th>

+ 2 - 2
apps/jobbrowser/src/jobbrowser/templates/task.mako

@@ -40,7 +40,7 @@
 
         <ul class="ccs-tab_sections ccs-clear">
           <li>
-            <table border="0" cellpadding="0" cellspacing="0" class="ccs-data_table jt_meta_table sortable">
+            <table border="0" cellpadding="0" cellspacing="0" data-filters="HtmlTable" class="jt_meta_table sortable">
               <thead>
                 <tr>
                  <th>Attempt ID</th>
@@ -79,7 +79,7 @@
             </table>
           </li>
           <li>
-            <table class="ccs-data_table jt_meta_table sortable" cellpadding="0" cellspacing="0">
+            <table data-filters="HtmlTable" class="jt_meta_table sortable" cellpadding="0" cellspacing="0">
               <thead>
                 <th>Name</th>
                 <th>Value</th>

+ 2 - 2
apps/jobbrowser/src/jobbrowser/templates/tasks.mako

@@ -60,7 +60,7 @@
 
       </div>
       <ul class="jt_filters">
-        <form class="jtv_filter_form submit_on_change" method="get" action="/jobbrowser/jobs/${jobid}/tasks">
+        <form class="jtv_filter_form" data-filters="SubmitOnChange" method="get" action="/jobbrowser/jobs/${jobid}/tasks">
           <li class="ccs-inline">
             <select name="taskstate">
               <option value="">All states</option>
@@ -90,7 +90,7 @@
         </form>
       </ul>
     </div>
-    <table class="ccs-data_table" cellpadding="0" cellspacing="0">
+    <table data-filters="HtmlTable" cellpadding="0" cellspacing="0">
       <thead>
          <tr>
            <th>Task ID</th>

+ 2 - 2
apps/jobbrowser/src/jobbrowser/templates/tasktrackers.mako

@@ -16,7 +16,7 @@
 <%namespace name="comps" file="jobbrowser_components.mako" />
 ${comps.header("Task Trackers :: Job Browser")}
   <h1 class="ccs-hidden">Task Trackers :: Job Browser</h1>
-  <table border="0" cellpadding="0" cellspacing="0" class="ccs-data_table sortable">
+  <table border="0" cellpadding="0" cellspacing="0" data-filters="HtmlTable" class="sortable">
     <thead>
       <tr>
        <th>Name</th>
@@ -48,4 +48,4 @@ ${comps.header("Task Trackers :: Job Browser")}
       % endfor
     </tbody>
   </table>
-${comps.footer()}
+${comps.footer()}

+ 2 - 2
apps/jobbrowser/static/css/jobbrowser.css

@@ -103,7 +103,7 @@ ul.jt_filters li input {
 	margin: 0 auto;
 }
 
-.job_browser_list table.ccs-data_table {
+.job_browser_list table[data-filters*=HtmlTable] {
 	border-bottom: 1px solid #B2B2B2;
 }
 .job_browser_list td div.jt_jobid {
@@ -365,6 +365,6 @@ table.jt_counter_table, table.jt_meta_table {
 	-webkit-border-radius: 0px 0px 2px 2px;
 	padding: 8px;
 }
-.jobbrowser table.ccs-data_table .jt-raw_delimiter {
+.jobbrowser table[data-filters*=HtmlTable] .jt-raw_delimiter {
 	background: #bbb;
 }

+ 1 - 1
apps/jobsub/src/jobsub/templates/edit.html

@@ -20,7 +20,7 @@ limitations under the License.
 {% block content %}
 	<div id="jobsub_edit" class="view">
 		
-		<div class="jobsub_col_wrapper splitview">
+		<div class="jobsub_col_wrapper" data-filters="SplitView">
 			<div class="jobsub_left_col left_col">
 				{% include "types.html" %}
 			</div>

+ 3 - 3
apps/jobsub/src/jobsub/templates/list.html

@@ -20,13 +20,13 @@ limitations under the License.
 {% block content %}
 <div id="jobsub_joblist" class="view">
 	<h1>Job Designer: Job Designs</h1>
-	<div class="jobsub_col_wrapper splitview">
+	<div class="jobsub_col_wrapper" data-filters="SplitView">
 		<div class="jobsub_left_col left_col">
 			{% include "types.html" %}
 		</div>
 		<div class="jobsub_right_col right_col">
 			<div class="jobsub_topsection clearfix">
-				<form class="jobsub_filter submit_on_change" action="{% url jobsub.list %}" method="get">
+				<form class="jobsub_filter" data-filters="SubmitOnChange" action="{% url jobsub.list %}" method="get">
 					<span class="filter_text">Filter by owner:</span>
 					<input data-filters="OverText" name="owner" alt="filter by owner" value="{{ owner }}"/>
 					<input data-filters="OverText" name="name" alt="filter by name" value="{{ name }}"/>
@@ -34,7 +34,7 @@ limitations under the License.
 				</form>
 			</div>
 		
-			<table class="ccs-data_table sortable" cellpadding="0" cellspacing="0">
+			<table data-filters="HtmlTable" class="sortable" cellpadding="0" cellspacing="0">
 				<thead>
 					<tr>
 						<th>Owner</th>

+ 1 - 1
apps/jobsub/src/jobsub/templates/watch.html

@@ -23,7 +23,7 @@ limitations under the License.
 {% block content %}
 	<div id="jobsub_history" class="view">
 		<h1>Recently Launched Jobs</h1>
-		<table class="ccs-data_table sortable">
+		<table data-filters="HtmlTable" class="sortable">
 			<thead>
 				<tr>
 					<th>Owner</th>

+ 1 - 1
apps/jobsub/static/css/jobsub.css

@@ -34,7 +34,7 @@
 	display: none;
 }
 
-.jobsub table.ccs-data_table {
+.jobsub table[data-filters*=HtmlTable] {
 	border: #B2B2B2 solid;
 	border-width: 1px 0px;
 }

+ 1 - 1
apps/useradmin/src/useradmin/templates/list_users.mako

@@ -17,7 +17,7 @@
 
 ${wrappers.head()}
     <div id="useradmin_userlist" class="view">
-      <table class="ccs-data_table sortable" cellpadding="0" cellspacing="0">
+      <table data-table="HtmlTable" class="sortable" cellpadding="0" cellspacing="0">
         <thead>
           <tr>
             <th>Username</th>

+ 21 - 18
desktop/core/static/css/shared.css

@@ -180,7 +180,7 @@
 /* stripy table */
 /*
 see: HtmlTable.js, HtmlTable.Zebra.js, HtmlTable.Select.js, HtmlTable.Sort.js in MooTools More
-<table class="ccs-data_table selectable sortable" cellpadding="0" cellspacing="0">
+<table data-filters="HtmlTable" class="selectable sortable" cellpadding="0" cellspacing="0">
 	<thead>
 		<tr>
 			<th>Header for Column 1</th>
@@ -199,13 +199,13 @@ see: HtmlTable.js, HtmlTable.Zebra.js, HtmlTable.Select.js, HtmlTable.Sort.js in
 give it class "selectable" to allow the user to select rows
 give it class "sortable" to allow the user to sort the table
 */
-table.ccs-data_table {
+table[data-filters*=HtmlTable] {
 	width: 100%;
 }
-table.ccs-data_table thead {
+table[data-filters*=HtmlTable] thead {
 	background: url(/static/art/th_back.png);
 }
-table.ccs-data_table thead th {
+table[data-filters*=HtmlTable] thead th {
 	text-align: left;
 	white-space: nowrap;
 	padding: 0px 6px;
@@ -217,11 +217,11 @@ table.ccs-data_table thead th {
 	font-weight: normal;
 	overflow: hidden;
 }
-table.ccs-data_table th:last-child {
+table[data-filters*=HtmlTable] th:last-child {
 	border-right: none;
 }
 
-table.ccs-data_table td {
+table[data-filters*=HtmlTable] td {
 	white-space: nowrap;
 	padding: 0px 8px;
 	height: 20px;
@@ -229,18 +229,21 @@ table.ccs-data_table td {
 	background: #fff;
 	border: none;
 }
-table.ccs-data_table tr.table-tr-odd td {
+table[data-filters*=HtmlTable] tr.table-tr-odd td {
 	background: #f3f3f3;
 }
-table.ccs-data_table tr:nth-child(odd) td {
+table[data-filters*=HtmlTable] tr:nth-child(odd) td {
 	background: #f3f3f3;
 }
-table.ccs-data_table tr:hover > td, table.ccs-data_table tr.table-tr-hovered td {
+table[data-filters*=HtmlTable] tr:hover > td, table[data-filters*=HtmlTable] tr.table-tr-hovered td {
 	background-color: #d4e7f8;
 	color: #000;
 	cursor: pointer;
 }
-table.ccs-data_table tr.selected td, table.ccs-data_table tr.table-tr-selected td, table.ccs-data_table tr.selected td a, table.ccs-data_table tr.table-tr-selected td a {
+table[data-filters*=HtmlTable].noSelect tr:hover > td, table[data-filters*=HtmlTable].noSelect tr.table-tr-hovered td {
+	cursor: auto;
+}
+table[data-filters*=HtmlTable] tr.selected td, table[data-filters*=HtmlTable] tr.table-tr-selected td, table[data-filters*=HtmlTable] tr.selected td a, table[data-filters*=HtmlTable] tr.table-tr-selected td a {
 	background-color: #3875d7;
 	color: #fff;
 }
@@ -386,12 +389,12 @@ div.jframe_default h5 { font-size: 105%; margin-bottom: 0.3em; padding-top: 8px;
 	border-bottom: 1px solid #ccc;
 	padding: 3px;
 }
-.ccs-shared table.ccs-data_table tr.table-tr-selected td ul.context-menu li a {
+.ccs-shared table[data-filters*=HtmlTable] tr.table-tr-selected td ul.context-menu li a {
 	color: #000;
 	background-color: #fff;
 	text-decoration: none;
 }
-.ccs-shared .context-menu li:hover, .ccs-shared table.ccs-data_table tr.table-tr-selected td ul.context-menu li:hover a, .ccs-shared ul.context-menu li:hover a {
+.ccs-shared .context-menu li:hover, .ccs-shared table[data-filters*=HtmlTable] tr.table-tr-selected td ul.context-menu li:hover a, .ccs-shared ul.context-menu li:hover a {
 	text-decoration: none;
 	background-color: #3875D7;
 	color: #fff;
@@ -400,7 +403,7 @@ div.jframe_default h5 { font-size: 105%; margin-bottom: 0.3em; padding-top: 8px;
 	border: none;
 }
 /* button bar */
-input.ccs-art_button {
+input[data-filters*=ArtButton] {
 	padding: 0px 0px 0px 0px;
 	/* webkit madness: 
 		put this padding statement in place and buttons are still padding 0/8/0/8px
@@ -409,12 +412,12 @@ input.ccs-art_button {
 	*/
 	border: 0px;
 }
-.ccs-shared .ccs-button_bar a, .ccs-shared .ccs-button_subbar_above a, .ccs-shared .ccs-button_subbar_below a {
+.ccs-shared [data-filters*=ArtButtonBar] a {
 	float: left;
 	height: 19px;
 }
 
-.ccs-shared .ccs-button_bar li, .ccs-shared .ccs-button_subbar_above li, .ccs-shared .ccs-button_subbar_below li {
+.ccs-shared [data-filters*=ArtButtonBar] li {
 	margin-right: 0 !important;
 }
 /* side by side select */
@@ -457,7 +460,7 @@ Takes a multi-select box and makes it so you can click to move elements from a s
 }
 
 /* help text links */
-.ccs-help_link, .ccs-info_link {
+[data-filters*=HelpTip], [data-filters*=InfoTip] {
 	display:-moz-inline-box;		/* FF2 */
 	display:inline-block;		   /* webkit and FF3 */
 	#zoom: 1; /* set hasLayout:true to mimic inline-block */
@@ -474,7 +477,7 @@ Takes a multi-select box and makes it so you can click to move elements from a s
 	overflow: hidden;
 }
 
-.ccs-info_link {
+[data-filters*=InfoTip] {
 	background: url(/static/art/info.png);
 }
 
@@ -482,7 +485,7 @@ Takes a multi-select box and makes it so you can click to move elements from a s
 	display: none;
 }
 
-[data-size-to-width], [data-size-to-height] {
+[data-filters*=SizeTo] {
 	overflow: auto;
 }
 

+ 13 - 34
desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.ContextMenu.js → desktop/core/static/js/Source/BehaviorFilters/Behavior.ContextMenu.js

@@ -1,12 +1,3 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
 //
 // Unless required by applicable law or agreed to in writing, software
 // distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,10 +7,9 @@
 /*
 ---
 description: Adds context menu support for any element with a data-context-menu-actions property. See the CCS.ContextMenu class for details on usage.
-provides: [CCS.JFrame.ContextMenu]
-requires: [/CCS.JFrame, /CCS.ContextMenu]
-script: CCS.JFrame.ContextMenu.js
-
+provides: [Behavior.ContextMenu]
+requires: [Widgets/Behavior, /CCS.ContextMenu]
+script: Behavior.ContextMenu.js
 ...
 */
 
@@ -39,7 +29,8 @@ var JframeContextMenu = new Class({
 		this.parent.apply(this, arguments);
 		//pointer to the jframe; it's wrapped in function to prevent a recurssion issue - 
 		//when you run a class instance through $merge (which setOptions does) you get one...
-		this._jframe = $lambda(this.options.jframe)();
+		//this._jframe = $lambda(this.options.jframe)();
+		this.applyDelegates = this.options.applyDelegates;
 	},
 	show: function(x, y){
 		//when the menu is shown, put the place holder after the menu
@@ -47,7 +38,7 @@ var JframeContextMenu = new Class({
 		//move the menu into the container
 		this.activeMenu.inject(this.options.container);
 		//apply click delegates to it since it's likely no longer in the jframe (where the delegates start)
-		this._jframe.applyDelegates(this.activeMenu);
+		this.applyDelegates(this.activeMenu);
 		this.parent(x, y);
 	},
 	hide: function(){
@@ -58,30 +49,18 @@ var JframeContextMenu = new Class({
 	}
 });
 
-CCS.JFrame.addGlobalFilters({
+Behavior.addGlobalFilters({
 
 	//intercept right click behaviors
-	contextMenu: function(container){
-		//get the elements that capture right click events for context menus
-		var delegates = container.getElements('[data-context-menu-actions]');
-		if (!delegates.length) return;
-		
-		//get a pointer to the content contaner of the window; this is the jbrowser container
-		//that contains the jframe
-		var contents = this.getWindow().contents;
-		
+	ContextMenu: function(element, methods){
 		//create an instance of CCS.Context menu for each delegate
-		var menus = delegates.map(function(delegate) {
-			return new JframeContextMenu(delegate, {
-				jframe: $lambda(this), //pass a function that wraps this jframe instance
-				container: contents //inject the menu into the container outside the jframe
-			});
-		}, this);
+		var menu = new JframeContextMenu(element, {
+			applyDelegates: methods.applyDelegates, //pass a function that wraps this jframe instance
+			container: methods.getContentElement() //inject the menu into the container outside the jframe
+		});
 		//detatch these whenever we unload jframe
-		this.markForCleanup(function(){
-			menus.each(function(menu){
+		this.markForCleanup(element, function(){
 				menu.detach();
-			});
 		});
 	}
 

+ 99 - 0
desktop/core/static/js/Source/BehaviorFilters/Behavior.FilterInput.js

@@ -0,0 +1,99 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/*
+---
+description: Behavior filter to filter elements based on the value of a text box with "FilterInput" in its data-filters property, when that text box is changed.
+provides: [Behavior.FilterInput]
+requires: [Widgets/Behavior, Widgets/Element.Data]
+script: Behavior.FilterInput.js
+...
+*/
+
+Behavior.addGlobalFilters({
+	/*
+		data-filter-elements: css selector for group of elements to filter against
+		data-filter-parent: optional, css parent selector, from element, of element to hide/display
+		TODO:  Deal with other types of data to filter relationships.  (sibling, child, etc.)
+	*/
+
+	FilterInput: function(element, methods){
+		var container = methods.getContentElement();
+		//this method will find all the elements and check them for the value
+		var filter = function (){
+			var selector = element.get('data', 'filter-elements');
+			var filterParents = element.get('data', 'filter-parents');
+			if (!selector) {
+				dbug.warn('warning, there was no selector defined for data-filter-elements for this element: ', element);
+				return;
+			}
+			var elements = container.getElements(selector);
+			if (!elements.length) {
+				dbug.warn('warning, this filter element %o has data-filter-elements selector defined as %s but this selector matches no elements.', element, selector);
+				return;
+			}
+			var value = element.get('value').toLowerCase();
+			var parents = new Table();
+			elements.each(function(el){
+				//if the filter value is empty, or the element contains the value
+				var show = !value || el.get('html').toLowerCase().contains(value);
+				//then show the parent:
+				//get the parent or, if there is no parent defined, show/hide the element
+				var parent = filterParents ? el.getParent(filterParents) : el;
+				//if we haven't defined a value for this parent yet, then set it
+				if (parents.get(parent) == undefined) parents.set(parent, show);
+				//else, if we're showing set it to true
+				else if (show) parents.set(parent, true);
+			});
+			//for each parent, check its state and show it
+			parents.each(function(parent, show) {
+				if(show) {
+					display = "block";
+					switch(parent.get('tag')){
+						case "tr":
+							display = "table-row";
+							break;
+						case "td":
+							display = "table-cell";
+							break;
+						case "table":
+							display = "table";
+							break;
+					}
+					parent.show(display);
+				} else {
+					parent.hide();
+				}
+			});
+		};
+		var inputValue = element.get('value');
+		//if there's a predefined value on startup, run the filter
+		if (inputValue) filter();
+
+		var fitEvent = function(){
+			if (inputValue != element.get('value')){
+				inputValue = element.get('value');
+				filter();
+			}
+		};
+
+		element.addEvent('change', fitEvent);
+		this.markForCleanup(element, function(){
+			element.removeEvent('change', fitEvent);
+		});
+	}
+	
+});

+ 47 - 0
desktop/core/static/js/Source/BehaviorFilters/Behavior.FormRequest.js

@@ -0,0 +1,47 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+/*
+---
+description: Creates an instance of Form.Request for every form that JFrame loads.
+provides: [CCS.JFrame.FormRequest]
+requires: [/CCS.JFrame, More/Form.Request]
+script: CCS.JFrame.FormRequest.js
+
+...
+*/
+
+CCS.JFrame.addGlobalFilters({
+
+	formRequest: function(element, events){
+		// Make forms submit inside the jframe
+		container.getElements('form').each(function(form){
+			form.set('action', new URI(form.get('action'), {base: this.currentPath}));
+			//pass null for the update element argument; JFrame does our updating for us
+			var req = new Form.Request(form, null, {
+				//we don't want submission of the form to reset it on AJAX success;
+				//sometimes JFrame gets an error back in the html; JFrame will replace
+				//the form for us.
+				resetForm: false
+			});
+			this._setRequestOptions(req.request, {
+				onSuccess: function(nodes, elements, text){
+					this._requestSuccessHandler(req.request, text);
+				}.bind(this)
+			});
+		}, this);
+	}
+
+});

+ 33 - 0
desktop/core/static/js/Source/BehaviorFilters/Behavior.FormValidatorScroller.js

@@ -0,0 +1,33 @@
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+/*
+---
+description: Makes form validator instances scroll the jframe to the errors.
+provides: [Behavior.FormValidatorScroller]
+requires: [Widgets/Behavior.FormValidator]
+script: Behavior.FormValidatorScroller.js
+...
+*/
+
+Behavior.addGlobalPlugin('FormValidator', 'FormValidatorScroller', function(element, methods){
+	var validator = element.retrieve('validator');
+	validator.setOptions({
+		onShow: function(input, advice, className) {
+			//scroll to errors within the jframe
+			/*JFrame Reference */
+			methods.getScroller().toElement(input);
+		},
+		//not the window
+		scrollToErrorsOnSubmit: false
+	});
+});

+ 24 - 25
desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.SizeTo.js → desktop/core/static/js/Source/BehaviorFilters/Behavior.SizeTo.js

@@ -16,44 +16,43 @@
 /*
 ---
 description: Allows an element to be sized to the dimensions of the jframe portion of the window.
-provides: [CCS.JFrame.SizeTo]
-requires: [/CCS.JFrame, /Element.Data]
-script: CCS.JFrame.SizeTo.js
+provides: [Behavior.SizeTo]
+requires: [Widgets/Element.Data]
+script: Behavior.SizeTo.js
 
 ...
 */
 
-CCS.JFrame.addGlobalFilters({
+Behavior.addGlobalFilters({
 
 	/*
 		elements are given data properties for data-size-to-height or data-size-to-width
 		these values are offsets. So, for example:
 		
-			<div data-size-to-height="-100"></div>
+			<div data-filters="SizeTo" data-size-to-height="-100"></div>
 		
 		will size that div to the height of the window -100 pixels. The value must always
 		be a number. Use zero for 100% height/width.
 	*/
-	sizeTo: function(container) {
-		if (!container.get('html').contains('data-size-to')) return;
-		var sizers = [];
-		container.getElements('[data-size-to-width], [data-size-to-height]').each(function(element) {
-			var axis = 'width';
-			var sizeTo = {
-				x: element.get('data', 'size-to-width'),
-				y: element.get('data', 'size-to-height')
-			};
-			sizers.push(function(x, y){
-				if (sizeTo.x) element.setStyle('width', x + sizeTo.x.toInt());
-				if (sizeTo.y) element.setStyle('height', y + sizeTo.y.toInt());
-			});
-		}, this);
-		var resize = function(x, y) { sizers.each(function(fn){ fn(x, y); }); };
-		resize(this.currentSize.x, this.currentSize.y);
-		this.addEvent('resize', resize);
-		this.markForCleanup(function(){
-			this.removeEvent('resize', resize);
+	SizeTo: function(element, methods) {
+		var sizeTo = {
+			x: element.get('data', 'size-to-width'),
+			y: element.get('data', 'size-to-height')
+		};
+		if (!sizeTo.x && !sizeTo.y) {
+			dbug.log('this element has the SizeTo filter, but no sizes defined for size-to-height/width: ', element);
+			return;
+		}
+		resize = function(x, y){
+			if (sizeTo.x) element.setStyle('width', x + sizeTo.x.toInt());
+			if (sizeTo.y) element.setStyle('height', y + sizeTo.y.toInt());
+		};
+		size = methods.getContainerSize();
+		resize(size.x, size.y);
+		methods.addEvent('resize', resize);
+		this.markForCleanup(element, function(){
+			methods.removeEvent('resize', resize);
 		});
 	}
 
-});
+});

+ 34 - 0
desktop/core/static/js/Source/BehaviorFilters/Behavior.SplitViewPostFold.js

@@ -0,0 +1,34 @@
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+/*
+---
+description: When splitviews are folded open or shut, it will refresh the JFrame with the fake_refresh linker for partial refresh compontents. The clicked link must have a data-splitview-resize or data-splitview-toggle value with a JSON string value for "partialRefresh" = true.
+provides: [Behavior.SplitViewPostFold]
+requires: [Widgets/Behavior.SplitView]
+script: Behavior.SplitViewPostFold.js
+...
+*/
+Behavior.addGlobalPlugin('SplitView', 'SplitViewPostFoldRefresh', function(element, methods){
+	var splitview = element.retrieve('SplitView');
+	if (!splitview) {
+		methods.warn("warning, couldn't find splitview instance for %o", element);
+		return;
+	}
+	splitview.addEvent('postFold', function(data, event, link){
+		if (!document.id(document.body).hasChild(link)) return;
+		if (data.partialRefresh) {
+			if ($type(data.partialRefresh) == "string") link = new Element('a', { href: data.partialRefresh });
+			methods.invokeLinker('.ccs-fake_refresh', link, event);
+		}
+	});
+});

+ 61 - 0
desktop/core/static/js/Source/BehaviorFilters/Behavior.SubmitOnChange.js

@@ -0,0 +1,61 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/*
+---
+
+description: Makes any form with the data-filter SubmitOnChange submit itself whenever any input is changed.
+provides: [Behavior.SubmitOnChange]
+requires: [Widgets/Behavior]
+script: Behavior.SubmitOnChange.js
+
+...
+*/
+
+
+Behavior.addGlobalFilters({
+	
+	/*
+		Notes:
+		This filter doesn't really work as it should because the event delegation functionality in MooTools
+		doesn't currently support events that don't bubble (change, submit, blur, focus, etc). Consequently
+		this filter must select all the inputs and apply event listeners to them individually. This breaks
+		the rule of behavior filters (which are supposed to alter the element the filter is applied to).
+		The alternative is to add the SubmitOnChange filter to every input which I think is too onerous.
+		The consequence here is that elements retired on the fly (inputs) won't have this behavior,
+		but that's a terrible idea anyway (what if I'm filling out the form?). I'm going to leave it here for
+		now.
+	*/
+
+	SubmitOnChange: function(element, methods) {
+		element.getElements('input, select, textarea').each(function(input){
+			var events = {
+				change: function(e){
+					if (e) element.fireEvent('submit', e);
+					else element.fireEvent('submit');
+				},
+				keydown: function(e) {
+					if (e.key == 'enter' && document.id(e.target).get('tag') != 'textarea') element.fireEvent('submit', e);
+				}
+			};
+			input.addEvents(events);
+			this.markForCleanup(element, function(){
+				input.removeEvents(events);
+			});
+		}, this);
+	}
+
+});

+ 29 - 0
desktop/core/static/js/Source/BehaviorFilters/Behavior.Tabs.js

@@ -0,0 +1,29 @@
+/*
+---
+description: Adds a tab interface (TabSwapper instance) for elements with .css-tab_ui. Matched with tab elements that are .ccs-tabs and sections that are .ccs-tab_sections.
+provides: [Behavior.Tabs]
+requires: [Widgets/Behavior, clientcide/TabSwapper]
+script: Behavior.Tabs.js
+
+...
+*/
+
+Behavior.addGlobalFilters({
+
+	Tabs: function(element, methods) {
+		var tabs = element.getElements(element.get('data', 'tabs-selector') || '.tabs>li');
+		var sections = element.getElements(element.get('data', 'sections-selector') || '.tab_sections>li');
+		if (tabs.length != sections.length || tabs.length == 0) {
+			methods.error('warning; sections and sections are not of equal number. tabs: %o, sections: %o', tabs, sections);
+			return;
+		}
+		var ts = new TabSwapper({
+			tabs: tabs,
+			sections: sections,
+			smooth: true,
+			smoothSize: true
+		});
+		element.store('TabSwapper', ts);
+	}
+
+});

+ 70 - 0
desktop/core/static/js/Source/BehaviorFilters/Behavior.Tips.js

@@ -0,0 +1,70 @@
+
+/*
+---
+description: Attaches Tips.Pointy objects to elements with PointyTip in their data-filters property and turns elements with HelpTip or InfoTip in their data-filters property into elements which show a Tips.Pointy object which contains their content, on rollover.
+provides: [Behavior.Tips]
+requires: [Widgets/Behavior, clientcide/Tips.Pointy]
+script: Behavior.Tips.js
+...
+*/
+
+(function() {
+
+var createLink = function(element) {
+	var isHelp = element.hasDataFilter('HelpTip');
+	var link = new Element('a', {
+		'class': element.get('class'),
+		'data-filters': (isHelp ? 'HelpTip' : 'InfoTip'),
+		'html': isHelp ? '?' : 'i'
+	}).inject(element, 'after').store('tip:text', element.get('html'));
+	//see where that text is supposed to have its pointer and group them by point
+	var point = element.get('data', 'help-direction', false, 1);
+	return {point: point, link: link};
+};
+
+var createTip = function(link, point) {
+	var tip = new Tips.Pointy(link, {
+		pointyTipOptions: {
+			destroyOnClose: false,
+			width: 250,
+			point: point.toInt()
+		}
+	});
+	return tip;
+};
+
+Behavior.addGlobalFilters({
+
+	PointyTip: function(element, methods){
+		var point = element.get('data', 'tip-direction', false, 12);
+		var tip = createTip(element, point);
+		//destroy the tips on cleanup
+		this.markForCleanup(element, function(){
+			tip.destroy();
+		});
+	},
+
+	//display help tips for users
+	HelpTip: function(element, methods) {
+		var help = element.hide();
+		var link = createLink(help);
+		//for each point, create a new instance of Tips.Pointy (clientcide plugin)
+		var tip = createTip(link.link, link.point); 
+		//destroy the tips on cleanup
+		this.markForCleanup(element, function(){
+			tip.destroy();
+		});
+	},
+
+	InfoTip: function(element, methods) {
+		var info = element.hide();
+		var link = createLink(info);
+		var tip = createTip(link.link, link.point);
+		this.markForCleanup(element, function(){
+			tip.destroy();
+		});
+	}
+
+});
+
+})();

+ 1 - 1
desktop/core/static/js/Source/CCS/CCS.ContextMenu.js

@@ -17,7 +17,7 @@
 ---
 description: Right-click context menu for CCS.JFrame
 provides: [CCS.ContextMenu]
-requires: [More/Element.Shortcuts, Core/Element.Event, Core/Class.Extras, /Element.Data,
+requires: [More/Element.Shortcuts, Core/Element.Event, Core/Class.Extras, Widgets/Element.Data,
   Core/Element.Dimensions, Core/Selectors]
 script: CCS.ContextMenu.js
 

+ 1 - 1
desktop/core/static/js/Source/CCS/CCS.Desktop.Keys.js

@@ -122,7 +122,7 @@ script: CCS.Desktop.Keys.js
 			this.table = new HtmlTable({
 				headers: ['Key', 'Shortcut Name', 'Description'],
 				properties: {
-					'class':'ccs-data_table'
+					'data-filters':'HtmlTable'
 				}
 			});
 			//a holder for styling

+ 47 - 9
desktop/core/static/js/Source/CCS/CCS.JFrame.js

@@ -31,12 +31,23 @@ requires:
  - More/HtmlTable.Select
  - More/Spinner
  - Widgets/Behavior
- - Widgets/Behavior.OverText
- - Widgets/Behavior.ArtInput
  - Widgets/Behavior.ArtButton
- - /Behavior.SideBySideSelect
+ - Widgets/Behavior.ArtInput
+ - Widgets/Behavior.FormValidator
+ - Widgets/Behavior.HtmlTable
+ - Widgets/Behavior.OverText
+ - Widgets/Behavior.SplitView
+ - /Behavior.ContextMenu
+ - /Behavior.FilterInput
  - /Behavior.FitText
+ - /Behavior.HtmlTableKeys
  - /Behavior.MultiChecks
+ - /Behavior.SideBySideSelect
+ - /Behavior.SizeTo
+ - /Behavior.SplitViewPostFold
+ - /Behavior.SubmitOnChange
+ - /Behavior.Tabs
+ - /Behavior.Tips
  - /CCS
  - /CCS.ContextMenu
 script: CCS.JFrame.js
@@ -105,11 +116,26 @@ CCS.JFrame = new Class({
 		new ART.Keyboard(this, this.keyboardOptions);
 		this.addLinkers(this.options.linkers);
 		this.addFilters(this.options.filters);
-
-		this.behavior = new Behavior(this.element);
-		['attachKeys', 'detachKeys', 'addShortcut', 'addShortcuts', 'removeShortcut', 'removeShortcuts', 'applyDelegates'].each(function(method){
+		this.behavior = new Behavior(this.element, {
+			onError: function(){
+				dbug.warn.apply(dbug, arguments);
+			}
+		});
+		if(this.options.size) this.behavior.resize(this.options.size.width, this.options.size.height);
+		['attachKeys', 'detachKeys', 'addShortcut', 'addShortcuts', 'removeShortcut', 'removeShortcuts',
+		 'applyDelegates', 'getScroller', 'getContentElement', 'invokeLinker'].each(function(method){
 			this.behavior.passMethod(method, this[method].bind(this));
 		}, this);
+		this.behavior.passMethods({
+			getContainerSize: this.getCurrentSize.bind(this),
+			configureRequest: function(request){
+				this._setRequestOptions(request, {
+					onSuccess: function(nodes, elements, text){
+						this._requestSuccessHandler(request, text);
+					}.bind(this)
+				});
+			}.bind(this)
+		});
 		this.addEvent('resize', this.behavior.resize.bind(this.behavior));
 		this.addBehaviors(this.options.behaviors);
 
@@ -299,7 +325,8 @@ CCS.JFrame = new Class({
 		}
 		
 		//determine view and view element
-		var view, viewElement = content.elements.filter('.view')[0] || content.elements.getElement('.view')[0];
+		var view,
+		    viewElement = content.elements.filter('.view')[0] || content.elements.getElement('.view')[0];
 		if (viewElement) {
 			view = viewElement.get('id');
 			viewElement.set('id', '');
@@ -343,6 +370,18 @@ CCS.JFrame = new Class({
 		this.fireEvent('resize', [x, y]);
 	},
 	
+	getCurrentSize: function(){
+		return this.currentSize;
+	},
+
+	getContentElement: function(){
+		return this.getWindow().contents;
+	},
+
+	getScroller: function(){
+		return this.scroller;
+	},
+
 	filters: {},
 
 	/*
@@ -526,7 +565,6 @@ CCS.JFrame = new Class({
 		this._sweep(this.element);
 	},
 
-
 /****************************************************************************************
 	PRIVATE METHODS BELOW
 *****************************************************************************************/
@@ -865,4 +903,4 @@ CCS.JFrame.addGlobalRenderers = function(renderers) {
 	CCS.JFrame.implement({
 		_renderers: renderers
 	});
-};
+};

+ 1 - 1
desktop/core/static/js/Source/CCS/CCS.User.js

@@ -23,7 +23,7 @@ script: CCS.User.js
 ...
 */
 (function(){
-        // Lazily cached user profile data.
+	// Lazily cached user profile data.
 	var data = undefined;
 
 	var outstandingRequest = undefined;

+ 0 - 47
desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.ArtButtons.js

@@ -1,47 +0,0 @@
-
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-/*
----
-description: Converts any element with the class '.ccs-art_button' into an ART button widget.
-provides: [CCS.JFrame.ArtButtons]
-requires: [/CCS.JFrame, Widgets/ART.Button, /Element.Data]
-script: CCS.JFrame.ArtButtons.js
-
-...
-*/
-
-CCS.JFrame.addGlobalFilters({
-
-	artButtons: function(container) {
-		if (!container.get('html').contains('ccs-art_button')) return;
-		var buttonSelector = 'a.ccs-art_button, button.ccs-art_button, input.ccs-art_button';
-		container.getElements('.ccs-button_bar, .ccs-button_subbar_above, .ccs-button_subbar_below').each(function(bar) {
-			var above = bar.hasClass('ccs-button_subbar_above');
-			var below = bar.hasClass('ccs-button_subbar_below');
-			dbug.warn('you are using a deprecated JFrame filter (ccs-button_bar) on %o, use the ArtButtonBar data-filter instead.', bar);
-			bar.addDataFilter('ArtButtonBar');
-			if (above) bar.set('data', 'bar-position', 'above');
-			if (below) bar.set('data', 'bar-position', 'below');
-		}, this);
-
-		container.getElements(buttonSelector).each(function(button){
-			dbug.warn('you are using a deprecated JFrame filter (ccs-art_button) on %o, use the ArtButton data-filter instead.', button);
-			button.addDataFilter('ArtButton');
-		}, this);
-	}
-
-});

+ 1 - 1
desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.DataGroupToggle.js

@@ -17,7 +17,7 @@
 ---
 description: Toggles the display of a group of elements when another is clicked or changed 
 provides: [CCS.JFrame.DataGroupToggle]
-requires: [/CCS.JFrame, /Element.Data]
+requires: [/CCS.JFrame, Widgets/Element.Data]
 script: CCS.JFrame.DataGroupToggle.js
 
 ...

+ 195 - 0
desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.Deprecated.js

@@ -0,0 +1,195 @@
+
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/*
+---
+description: Deprecated JFrame filters here for backwards compatibility.
+provides: [
+ CCS.JFrame.DeprecatedFilters,
+ CCS.JFrame.ContextMenu,
+ CCS.JFrame.ArtButtons,
+ CCS.JFrame.FilterInput,
+ CCS.JFrame.FitText,
+ CCS.JFrame.FormValidator,
+ CCS.JFrame.HtmlTable,
+ CCS.JFrame.Input,
+ CCS.JFrame.OverText,
+ CCS.JFrame.SizeTo,
+ CCS.JFrame.SplitView,
+ CCS.JFrame.SubmitOnChange,
+ CCS.JFrame.Tabs,
+ CCS.JFrame.Tips
+]
+requires: [/CCS.JFrame, Widgets/Element.Data]
+script: CCS.JFrame.ArtButtons.js
+
+...
+*/
+
+(function(){
+
+	var artInputsRegEx = /ccs-search|ccs-input/;
+
+	CCS.JFrame.addGlobalFilters({
+
+		artButtons: function(container) {
+			if (container.get('html').contains('ccs-button_bar')) {
+				container.getElements('.ccs-button_bar, .ccs-button_subbar_above, .ccs-button_subbar_below').each(function(element) {
+					var above = element.hasClass('ccs-button_subbar_above');
+					var below = element.hasClass('ccs-button_subbar_below');
+					dbug.warn('you are using a deprecated JFrame filter (ccs-button_bar) on %o, use the ArtButtonBar data-filter instead.', element);
+					element.addDataFilter('ArtButtonBar');
+					if (above) element.set('data', 'bar-position', 'above');
+					if (below) element.set('data', 'bar-position', 'below');
+				});
+			}
+
+			if (container.get('html').contains('ccs-art_button')) {
+				container.getElements('a.ccs-art_button, button.ccs-art_button, input.ccs-art_button').each(function(element){
+					dbug.warn('you are using a deprecated JFrame filter (ccs-art_button) on %o, use the ArtButton data-filter instead.', element);
+					element.addDataFilter('ArtButton');
+				});
+			}
+		},
+
+		contextMenu: function(container){
+			if (!container.get('html').contains('data-context-menu-actions')) return;
+			container.getElements('[data-context-menu-actions]').each(function(element) {
+				if(!element.hasDataFilter('ContextMenu')) {
+					dbug.warn('you are using a deprecated JFrame filter (data-context-menu-actions) on %o, use the ContextMenu data-filter instead.', element);
+					element.addDataFilter('ContextMenu');
+				}
+			});
+		},
+
+		filterInput: function(container){
+			if (!container.get('html').contains('data-filter-elements')) return;
+			container.getElements('[data-filter-elements]').each(function(element){
+				if (!element.hasDataFilter('FilterInput')) {
+					dbug.warn("you are using a deprecated JFrame filter for filtering the input %o; add FilterInput to the data-filters property.", element);
+					element.addDataFilter('FilterInput');
+				}
+			});
+		},
+
+		truncate: function(container) {
+			if (!container.get('html').contains('ccs-truncate')) return;
+			container.getElements('.ccs-truncate').each(function(element){
+				dbug.warn('you are using a deprecated JFrame filter (truncate) on %o, use the FitText data-filter instead.', element);
+				element.addDataFilter('FitText');
+			});
+		},
+
+		truncateChildren: function(container){
+			if (!container.get('html').contains('data-fit-text')) return;
+			container.getElements('[data-fit-text]').each(function(element){
+				if (!element.hasDataFilter('FitText-Children')) {
+					dbug.warn('you are using a deprecated JFrame filter (data-fit-text) on %o without the data-filter "FitText-Children".', element);
+					element.addDataFilter('FitText-Children');
+				}
+			});
+		},
+
+		form_validator: function(container) {
+			if (!container.get('html').contains('form-validator')) return;
+			container.getElements('form.form-validator').each(function(element) {
+				dbug.warn('you are using a deprecated JFrame filter (form-validator) on %o, use the FormValidator data-filter instead.', element);
+				element.addDataFilter('FormValidator');
+			});
+		},
+
+		htmlTable: function(container){
+			container.getElements('table.ccs-data_table').each(function(element){
+				dbug.warn('You are using a deprecated JFrameFilter (ccs-data_table) on %o, use the DataTable data-filter instead.', element);
+				element.addDataFilter('HtmlTable');	
+			});
+		},
+
+
+		artInputs: function(container) {
+			if (!container.get('html').match(artInputsRegEx)) return;
+			container.getElements('.ccs-search, .ccs-input').each(function(element){
+				dbug.warn('you are using a deprecated JFrame filter (ccs-search or ccs-input) on %o, use the ArtInput data-filter instead.', element);
+				element.addDataFilter('ArtInput');
+				if (element.hasClass('ccs-search')) element.set('data', 'art-input-type', 'search');
+			}, this);
+		},
+
+		overText: function(container){
+			container.getElements('input.overtext, textarea.overtext').map(function(element){
+				dbug.warn('you are using a deprecated JFrame filter (overtext) on %o, use the OverText data-filter instead.', element);
+				element.addDataFilter('OverText');
+			});
+		},
+
+		sizeTo: function(container) {
+			container.getElements('[data-size-to-width], [data-size-to-height]').each(function(element) {
+				if(!element.hasDataFilter('SizeTo')){
+					dbug.warn('you are using a deprecated JFrame filter (data-size-to) on %o, use the SizeTo data-filter instead.', element);
+					element.addDataFilter('SizeTo');
+				}
+			}, this);
+		},
+
+		splitView: function(container) {
+			if (!container.get('html').contains('splitview')) return;
+			container.getElements('div.splitview').map(function(element){
+				dbug.warn('you are using a deprecated JFrame filter (splitview) on %o, use the SplitView data-filter instead.', element);
+				element.addDataFilter('SplitView');
+			}, this);
+		},
+
+		submitOnChange: function(container) {
+			container.getElements('form.submit_on_change').each(function(element) {
+				dbug.warn('you are using a deprecated JFrame filter (submit_on_change) on %o, use the SubmitOnChange data-filter instead.', element);
+				element.addDataFilter('SubmitOnChange');
+			});
+		},
+
+		tabs: function(container) {
+			if (!container.get('html').test('ccs-tab_ui')) return;
+			container.getElements('.ccs-tab_ui').each(function(element){
+				dbug.warn('you are using a deprecated JFrame filter (ccs-tab_ui) on %o, use the Tabs data-filter instead.', element);
+				element.addDataFilter('Tabs');
+			});
+		},
+
+		tips: function(container){
+			if (!container.get('html').match(/ccs\-pointy_tip/)) return;
+			container.getElements('.ccs-pointy_tip').each(function(element){
+				dbug.warn('you are using a deprecated JFrame filter (ccs-pointy_tip) on %o, use the PointyTip data-filter instead.', element);
+				element.addDataFilter('PointyTip');
+			});
+		},
+
+		help_tips: function(container) {
+			if (!container.get('html').match(/[ccs\-help_text][ccs\-info_text]/)) return;
+			container.getElements('.ccs-help_text, .ccs-info_text').each(function(element) {
+				var isHelp = element.hasClass('ccs-help_text');
+				if (isHelp) {
+					dbug.warn('you are using a deprecated JFrame filter (ccs-help_text) on %o, use the HelpTip data-filter instead.', element);
+					element.addDataFilter('HelpTip');
+				} else {
+					dbug.warn('you are using a deprecated JFrame filter (ccs-info_text) on %o, use the HelpTip data-filter instead.', element);
+					element.addDataFilter('InfoTip');
+				}
+			});
+		}
+
+	});
+
+})();

+ 1 - 1
desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.DoubleClickDelegate.js

@@ -17,7 +17,7 @@
 ---
 description: Creates a double click action for any element with the class .dbclick_delegate.
 provides: [CCS.JFrame.DoubleClickDelegate]
-requires: [/CCS.JFrame, /Element.Data]
+requires: [/CCS.JFrame, Widgets/Element.Data]
 script: CCS.JFrame.DoubleClickDelegate.js
 
 ...

+ 0 - 95
desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.FilterInput.js

@@ -1,95 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/*
----
-description: JFrameFilter to filter elements based on the value of a text box when that text box is changed.
-provides: [CCS.JFrame.FilterInput]
-requires: [/CCS.JFrame, /Element.Data]
-script: CCS.JFrame.FilterInput.js
-...
-*/
-
-CCS.JFrame.addGlobalFilters({
-
-	/*
-		
-		data-filter-criterion contains:
-			filter-criterion: css selector for group of elements to filter against
-			filter-parent: css parent selector, from criterion, of element to hide/display
-			TODO:  Deal with other types of data to filter relationships.  (sibling, child, etc.)
-	*/
-	filterInput: function(container){
-		if(!container.get('html').contains('data-filter-elements')) return;
-		//get the inputs to filter
-		var filterInputs = container.getElements('[data-filter-elements]');
-		if (!filterInputs.length) return;
-		filterInputs.each(function(filterInput){
-			//this method will find all the elements and check them for the value
-			var filter = function (){
-				var selector = filterInput.get('data', 'filter-elements');
-				var filterParents = filterInput.get('data', 'filter-parents');
-				if (!selector) return;
-				var elements = container.getElements(selector);
-				if (!elements.length) return;
-				var value = filterInput.get('value').toLowerCase();
-				var parents = new Table();
-				elements.each(function(el){
-					//if the filter value is empty, or the element contains the value
-					var show = !value || el.get('html').toLowerCase().contains(value);
-					//then show the parent:
-					//get the parent or, if there is no parent defined, show/hide the element
-					var parent = filterParents ? el.getParent(filterParents) : el;
-					//if we haven't defined a value for this parent yet, then set it
-					if (parents.get(parent) == undefined) parents.set(parent, show);
-					//else, if we're showing set it to true
-					else if (show) parents.set(parent, true);
-				});
-				//for each parent, check its state and show it
-				parents.each(function(parent, show) {
-					if(show) {
-						display = "block";
-						switch(parent.get('tag')){
-							case "tr":
-								display = "table-row";
-								break;
-							case "td":
-								display = "table-cell";
-								break;
-							case "table":
-								display = "table";
-								break;
-						}
-						parent.show(display);
-					} else {
-						parent.hide();
-					}
-				});
-			};
-			var inputValue = filterInput.get('value');
-			//if there's a predefined value on startup, run the filter
-			if (inputValue) filter();
-
-			filterInput.addEvent('change', function(){
-				if (inputValue != filterInput.get('value')){
-					inputValue = filterInput.get('value');
-					filter();
-				}
-			});
-		});
-	}
-	
-});

+ 0 - 54
desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.FitText.js

@@ -1,54 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-/*
----
-description: Automatically fits text to fit an element adding an elipse to the text using the FitText plugin for any elements with the .ccs-truncate class.
-provides: [CCS.JFrame.FitText]
-requires: [/CCS.JFrame, FitText/FitText, More/Array.Extras]
-script: CCS.JFrame.FitText.js
-
-...
-*/
-
-CCS.JFrame.addGlobalFilters({
-
-	/*
-		truncates text automatically for elements with the class .ccs-truncate
-		elements cannot have child elements (only text)
-	*/
-	truncate: function(container) {
-		if (!container.get('html').contains('ccs-truncate')) return;
-		container.getElements('.ccs-truncate').each(function(el){
-			dbug.warn('you are using a deprecated JFrame filter (truncate) on %o, use the FitText data-filter instead.', el);
-			el.addDataFilter('FitText');
-		}, this);
-	},
-
-	/*
-		finds all elements wth data-fit-text properties - these properties must be selectors
-		for the elements to apply the FitText class to.
-	*/
-	truncateChildren: function(container){
-		if (!container.get('html').contains('data-fit-text')) return;
-		container.getElements('[data-fit-text]').each(function(fitParent){
-			if (!fitParent.hasDataFilter('FitText-Children')) {
-				dbug.warn('you are using a deprecated JFrame filter (data-fit-text) on %o without the data-filter "FitText-Children".', fitParent);
-				fitParent.addDataFilter('FitText-Children');
-			}
-		}, this);
-	}
-
-});

+ 16 - 16
desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.FormRequest.js

@@ -15,7 +15,7 @@
 // limitations under the License.
 /*
 ---
-description: Creates an instance of Form.Request for every form that JFrame loads.
+description: Configures every form to use the Form.Request behavior.
 provides: [CCS.JFrame.FormRequest]
 requires: [/CCS.JFrame, More/Form.Request]
 script: CCS.JFrame.FormRequest.js
@@ -25,23 +25,23 @@ script: CCS.JFrame.FormRequest.js
 
 CCS.JFrame.addGlobalFilters({
 
+	//this runs BEFORE Behavior.FormRequest
 	formRequest: function(container){
-		// Make forms submit inside the jframe
+		//get all forms in the response
 		container.getElements('form').each(function(form){
-			form.set('action', new URI(form.get('action'), {base: this.currentPath}));
-			//pass null for the update element argument; JFrame does our updating for us
-			var req = new Form.Request(form, null, {
-				//we don't want submission of the form to reset it on AJAX success;
-				//sometimes JFrame gets an error back in the html; JFrame will replace
-				//the form for us.
-				resetForm: false
-			});
-			this._setRequestOptions(req.request, {
-				onSuccess: function(nodes, elements, text){
-					this._requestSuccessHandler(req.request, text);
-				}.bind(this)
-			});
-		}, this);
+			//set their action url and add the FormRequest filter
+			form.set('action', new URI(form.get('action'), {base: this.currentPath})).addDataFilter("FormRequest");
+		});
 	}
 
 });
+
+//this runs AFTER Behavior.FormRequest
+Behavior.addGlobalPlugin('FormRequest', 'JFrameFormRequest', function(element, methods){
+	//get the Form.Request instance
+	var req = element.get('formRequest');
+	//tell it not to update anything
+	req.update = null;
+	//configure its request to use JFrame's response handler
+	methods.configureRequest(req.request);
+});

+ 0 - 58
desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.FormValidator.js

@@ -1,58 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-/*
----
-description: Adds an instance of Form.Validator.Inline to any form with the class .form-validator.
-provides: [CCS.JFrame.FormValidator]
-requires: [/CCS.JFrame, More/Form.Validator.Inline]
-script: CCS.JFrame.FormValidator.js
-
-...
-*/
-
-CCS.JFrame.addGlobalFilters({
-
-	//validates any form with the .form-validator class
-	form_validator: function(container) {
-		if (!container.get('html').contains('form-validator')) return;
-		container.getElements('form.form-validator').each(function(form) {
-			//instantiate the form validator
-			var validator = form.retrieve('validator');
-			if (!validator) {
-				validator = new Form.Validator.Inline(form, {
-					useTitles: true
-				});
-			}
-			//stupid monkey patch, for now. TODO(nutron)
-			validator.insertAdvice = function(advice, field){
-				//look for a .ccs-errors advice element that is a sibling of the field and inject errors there
-				var target = field.getParent().getElement('.ccs-errors');
-				if (target) target.adopt(advice);
-				//otherwise inject them as siblings.
-				else field.getParent().adopt(advice);
-			};
-			validator.setOptions({
-				onShow: function(input, advice, className) {
-					//scroll to errors within the jframe
-					this.jframe.scroller.toElement(input);
-				}.bind(this),
-				//not the window
-				scrollToErrorsOnSubmit: false
-			});
-		}, this);
-	}
-
-});

+ 0 - 101
desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.HtmlTable.js

@@ -1,101 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-/*
----
-description: Creates instances of HtmlTable for any table with the css class .ccs-data_table with additional options for sortability and selectability.
-provides: [CCS.JFrame.HtmlTable]
-requires: [/CCS.JFrame, More/HtmlTable.Sort, More/HtmlTable.Zebra, More/HtmlTable.Select, /Element.Data]
-script: CCS.JFrame.HtmlTable.js
-
-...
-*/
-
-//The newHash here is used to attach these parsers at the beginning of the HtmlTable.Parsers hash.  Otherwise, anything that begins with a number is picked up by the 'number' parser, which is not what we want.
-newHash = new Hash();
-//A parser to allow numeric sorting by any value.
-newHash.dataSortValue = {
-        match: /data-sort-value/,
-        convert: function() {
-                text = this.getElement('[data-sort-value]').get('data', 'sort-value');
-                return text.toInt();
-        },
-        number: true
-};
-//A parser to allow lexicographical sorting by any string.
-newHash.dataSortString = {
-        match: /data-sort-string/,
-        convert: function() {
-                text = this.getElement('[data-sort-string]').get('data', 'sort-string');
-                return text;
-        },
-        number: false 
-};
-newHash.combine(HtmlTable.Parsers);
-HtmlTable.Parsers = newHash;
-
-CCS.JFrame.addGlobalFilters({
-
-	htmlTable: function(container){
-		//make all data tables sortable
-		var selectable;
-		var tables = container.getElements('table.ccs-data_table').map(function(table){
-			var isSelectable = (table.hasClass('sortable') && !table.hasClass('noSelect')) || table.hasClass('selectable');
-			var ht = new HtmlTable(table, {
-				sortable: table.hasClass('sortable'),
-				selectable: isSelectable,
-				allowMultiSelect: table.hasClass('allowMultiSelect'),
-				useKeyboard: false
-			});
-			if (isSelectable && !selectable) selectable = ht;
-			return table;
-		}).clean();
-		//This is silly but for now, we only support keyboard shortcuts on the first
-		//table in the UI. dumb, but I don't have time to hack around this.
-		//TODO(nutron)
-		if (selectable) {
-			this.addShortcuts({
-				'Select Previous Row': {
-					keys: 'up',
-					shortcut: 'up arrow',
-					handler: function(e){
-						e.preventDefault();
-						selectable.shiftFocus(-1);
-						if (selectable.hover) selectable.focusRow(selectable.hover);
-					}.bind(this),
-					description: 'Select the previous row in the table.'
-				},
-				'Select Next Row': {
-					keys: 'down',
-					shortcut: 'down arrow',
-					handler: function(e){
-						e.preventDefault();
-						selectable.shiftFocus(1);
-						if (selectable.hover) selectable.focusRow(selectable.hover);
-					}.bind(this),
-					description: 'Select the next row in the table.'
-				}
-			});
-			this.markForCleanup(function(){
-				this.removeShortcuts(['Select Previous Row', 'Select Next Row']);
-			}.bind(this));
-		}
-	}
-
-});
-
-
-
-

+ 0 - 42
desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.Input.js

@@ -1,42 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-/*
----
-description: Inputs.
-provides: [CCS.JFrame.Input]
-requires: [/CCS.JFrame]
-script: CCS.JFrame.Input.js
-
-...
-*/
-(function(){
-
-var re = /ccs-search|ccs-input/;
-
-CCS.JFrame.addGlobalFilters({
-
-	artInputs: function(container) {
-		if (!container.get('html').match(re)) return;
-		container.getElements('.ccs-search, .ccs-input').each(function(input){
-			dbug.warn('you are using a deprecated JFrame filter (ccs-search or ccs-input) on %o, use the ArtInput data-filter instead.', input);
-			input.addDataFilter('ArtInput');
-			if (input.hasClass('ccs-search')) input.set('data', 'art-input-type', 'search');
-		}, this);
-	}
-
-});
-
-})();

+ 0 - 36
desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.OverText.js

@@ -1,36 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-/*
----
-description: Sets up all inputs with the css class .overtext to have an OverText instance for inline labeling. The OverText label element inherits all the classes assigned to the input (at run time) with an "OverText-" prefix, allowing you to style OverText labels on a per-input basis.
-provides: [CCS.JFrame.OverText]
-requires: [/CCS.JFrame]
-script: CCS.JFrame.OverText.js
-
-...
-*/
-
-CCS.JFrame.addGlobalFilters({
-
-	overText: function(container){
-		//get all input.overtext elements and make an OverText for them.
-		var ots = container.getElements('input.overtext, textarea.overtext').map(function(input){
-			dbug.warn('you are using a deprecated JFrame filter (overtext) on %o, use the OverText data-filter instead.', input);
-			input.addDataFilter('OverText');
-		});
-	}
-
-});

+ 0 - 188
desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.SplitView.js

@@ -1,188 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-/*
----
-description: Creates a SplitView instances for all elements that have the css class .splitview (and children with .left_col and .right_col).
-provides: [CCS.JFrame.SplitView]
-requires: [/CCS.JFrame, Widgets/ART.SplitView]
-script: CCS.JFrame.SplitView.js
-
-...
-*/
-
-CCS.JFrame.addGlobalFilters({
-
-	splitView: function(container) {
-		if (!container.get('html').contains('splitview')) return;
-		container.setStyle('overflow', 'hidden');
-		//for all div.splitview containers, get their left and right column and instantiate an ART.SplitView
-		//if the container has the class "resizable" then make it so
-		//ditto for the foldable option
-		//if the left or right columns have explicit style="width: Xpx" assignments
-		//resize the side to match that statement; if both have it, the right one wins
-		var splitviews = container.getElements('div.splitview').map(function(splitview){
-			var left = splitview.getElement('.left_col');
-			var right = splitview.getElement('.right_col');
-			var top = splitview.getElement('.top_col');
-			var bottom = splitview.getElement('.bottom_col');
-			if (!(left && right) && !(top && bottom)) {
-				dbug.warn('found split view element, but could not find top/botom or left/right; exiting');
-				return;
-			}
-			var conf;
-			if (left) {
-				conf = {
-					sides: ['left', 'right'],
-					elements: {
-						left: left,
-						right: right
-					},
-					dimension: 'width'
-				};
-			} else {
-				conf = {
-					sides: ['top', 'bottom'],
-					elements: {
-						top: top,
-						bottom: bottom
-					},
-					dimension: 'height'
-				};
-			}
-			var inlineSize = {};
-			conf.sides.each(function(side) {
-				var size = conf.elements[side].style[conf.dimension];
-				if (size) {
-					inlineSize[side] = size.toInt();
-					conf.fixed = side;
-				}
-				conf.elements[side].setStyle(conf.dimension, 'auto');
-			});
-			
-			var styles = {}, splitterHidden;
-			var splitter = splitview.getElement('.splitter_col');
-			if (splitter) {
-				if (splitter.getStyle('display', 'none')) {
-					splitterHidden = true;
-					splitter.setStyle('display', 'block');
-				}
-				if (left) styles['splitter-width'] = splitter.getSize().x;
-				else styles['splitter-height'] = splitter.getSize().y;
-			}
-			
-			var whichSplit = left ? ART.SplitView : ART.SplitView.Vertical;
-			var split = new whichSplit({
-				resizable: splitview.hasClass("resizable"),
-				foldable: splitview.hasClass("foldable"),
-				splitterContent: splitview.getElement('.splitter_col'),
-				styles: styles,
-				fixed: conf.fixed || 'left'
-			}).inject(this, splitview, 'after').draw();
-			var sized;
-			conf.sides.each(function(side) {
-				split['set' + side.capitalize() + 'Content'](conf.elements[side]);
-				split[side].addClass('save_scroll');
-				if (sized) return;
-				if (conf.elements[side].getStyle('display') == 'none') {
-					split.fold(side, 0, splitterHidden, true);
-					conf.elements[side].setStyle('display', 'block');
-					sized = true;
-				} else if (inlineSize[side]) {
-					split['resize'+side.capitalize()](inlineSize[side]);
-					sized = true;
-				}
-			});
-			var classes = splitview.get('class').split(' ');
-			splitview.destroy();
-			classes.each(split.addClass, split);
-			split.resizer = function(){
-				if (this.parentWidget && this.parentWidget.contentSize) {
-					var offsets = {
-						x: splitview.get('data', 'split-offset-x', true),
-						y: splitview.get('data', 'split-offset-y', true)
-					};
-					var w = this.parentWidget.contentSize.x;
-					var h = this.parentWidget.contentSize.y;
-					if (offsets.x) w = w - offsets.x;
-					if (offsets.y) h = h - offsets.y;
-					if (w != undefined && h != undefined) split.resize(w, h);
-					else split.resizer.delay(1);
-				} else {
-					split.resizer.delay(1);
-				}
-			}.bind(this);
-			this.addEvents({
-				resize: split.resizer,
-				show: split.resizer
-			});
-			split.resizer();
-			return split;
-		}, this);
-		this.markForCleanup(function(){
-			splitviews.each(function(splitview) {
-				this.removeEvent('resize', splitview.resizer);
-				splitview.eject();
-			}, this);
-		}.bind(this));
-
-		return splitviews;
-	}
-
-});
-
-(function(){
-
-var getWidget = function(link) {
-	var splitview = link.getParent('.splitview');
-	if (!splitview) return;
-	return splitview.get('widget');
-};
-CCS.JFrame.addGlobalLinkers({
-
-	'[data-splitview-resize]': function(e, link){
-		if ($(e.target).get('tag') == 'a') e.preventDefault();
-		var widget = getWidget(link);
-		if (!widget) return;
-		var resize = link.get('data', 'splitview-resize', true);
-		if (!resize) return;
-		var side;
-		var sides = ['left', 'right', 'top', 'bottom'];
-		for (key in resize) {
-			if (sides.contains(key)) side = key;
-		}
-		widget.fold(side, resize[side], resize.hideSplitter).chain(partialPostFold.bind(this, [resize, e, link]));
-	},
-
-	'[data-splitview-toggle]': function(e, link){
-		if ($(e.target).get('tag') == 'a') e.preventDefault();
-		var widget = getWidget(link);
-		if (!widget) return;
-		var resize = link.get('data', 'splitview-toggle', true);
-		if (!resize) return;
-		widget.toggle(resize.side, resize.hideSplitter).chain(partialPostFold.bind(this, [resize, e, link]));
-	}
-
-});
-
-var partialPostFold = function(data, event, link){
-	if (!$(document.body).hasChild(link)) return;
-	if (data.partialRefresh) {
-		if ($type(data.partialRefresh) == "string") link = new Element('a', { href: data.partialRefresh });
-		this.invokeLinker('.ccs-fake_refresh', link, event);
-	}
-};
-
-})();

+ 0 - 45
desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.SubmitOnChange.js

@@ -1,45 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-/*
----
-description: Makes any form with the css class .submit_on_change submit itself whenever any input is changed.
-provides: [CCS.JFrame.SubmitOnChange]
-requires: [/CCS.JFrame]
-script: CCS.JFrame.SubmitOnChange.js
-
-...
-*/
-
-
-CCS.JFrame.addGlobalFilters({
-
-	submitOnChange: function(container) {
-		container.getElements('form.submit_on_change').each(function(form) {
-			form.getElements('input, select, textarea').each(function(input){
-				input.addEvents({
-					change: function(e){
-						if (e) form.fireEvent('submit', e);
-						else form.fireEvent('submit');
-					},
-					keydown: function(e) {
-						if (e.key == 'enter') form.fireEvent('submit', e);
-					}
-				});
-			});
-		});
-	}
-
-});

+ 0 - 47
desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.Tabs.js

@@ -1,47 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-/*
----
-description: Adds a tab interface (TabSwapper instance) for elements with .css-tab_ui. Matched with tab elements that are .ccs-tabs and sections that are .ccs-tab_sections.
-provides: [CCS.JFrame.Tabs]
-requires: [/CCS.JFrame, clientcide/TabSwapper]
-script: CCS.JFrame.Tabs.js
-
-...
-*/
-
-CCS.JFrame.addGlobalFilters({
-
-	tabs: function(container) {
-		if (!container.get('html').test('ccs-tab_ui')) return;
-		container.getElements('.ccs-tab_ui').each(function(tabGroup){
-			var tabs = tabGroup.getElements('.ccs-tabs>li');
-			var sections = tabGroup.getElements('.ccs-tab_sections>li');
-			if (tabs.length != sections.length) {
-				dbug.warn('warning; sections and sections are not of equal number. tabs: %o, sections: %o', tabs, sections);
-				return;
-			}
-			var ts = new TabSwapper({
-				tabs: tabs,
-				sections: sections,
-				smooth: true,
-				smoothSize: true
-			});
-			tabGroup.store('TabSwapper', ts);
-		}, this);
-	}
-
-});

+ 0 - 86
desktop/core/static/js/Source/JFrameFilters/CCS.JFrame.Tips.js

@@ -1,86 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/*
----
-description: Shows or hides the history component from the widget.
-provides: [CCS.JFrame.Tips]
-requires: [/CCS.JFrame, clientcide/Tips.Pointy]
-script: CCS.JFrame.Tips.js
-
-...
-*/
-
-CCS.JFrame.addGlobalFilters({
-
-	tips: function(container){
-		if (!container.get('html').match(/ccs\-pointy_tip/)) return;
-		var points = {};
-		container.getElements('.ccs-pointy_tip').each(function(el){
-			var point = el.get('data', 'tip-direction', false, 12);
-			points[point] = points[point] || [];
-			points[point].push(el);
-		}, this);
-		//for each point, create a new instance of Tips.Pointy (clientcide plugin)
-		$each(points, function(links, point) {
-			var tips = new Tips.Pointy(links, {
-				pointyTipOptions: {
-					destroyOnClose: false,
-					width: 250,
-					point: point.toInt()
-				}
-			});
-			//destroy the tips on cleanup
-			this.markForCleanup(function(){
-				tips.destroy();
-			});
-		}, this);
-	},
-	//display help tips for users
-	help_tips: function(container) {
-		if (!container.get('html').match(/[ccs\-help_text][ccs\-info_text]/)) return;
-		//hide all the help text in the document
-		var helps = container.getElements('.ccs-help_text, .ccs-info_text').hide();
-		var points = {};
-		//create a link for each help text we found
-		helps.each(function(help) {
-			var isHelp = help.hasClass('ccs-help_text');
-			var link = new Element('a', {
-				'class': 'ccs-inline ' + (isHelp ? 'ccs-help_link' : 'ccs-info_link'),
-				'html': isHelp ? '?' : 'i'
-			}).inject(help, 'after').store('tip:text', help.get('html'));
-			//see where that text is supposed to have its pointer and group them by point
-			var point = help.get('data', 'help-direction', false, 1);
-			points[point] = points[point] || [];
-			points[point].push(link);
-		});
-		//for each point, create a new instance of Tips.Pointy (clientcide plugin)
-		$each(points, function(links, point) {
-			var tips = new Tips.Pointy(links, {
-				pointyTipOptions: {
-					destroyOnClose: false,
-					width: 250,
-					point: point.toInt()
-				}
-			});
-			//destroy the tips on cleanup
-			this.markForCleanup(function(){
-				tips.destroy();
-			});
-		}, this);
-	}
-
-});

+ 69 - 0
desktop/core/static/js/Source/JFrameLinkers/CCS.JFrame.SplitViewLinkers.js

@@ -0,0 +1,69 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/*
+---
+description: Handles the resize linkers for the SplitView behavior.
+provides: [CCS.JFrame.SplitViewLinkers]
+requires: [/CCS.JFrame]
+script: CCS.JFrame.SplitViewLinkers.js
+
+...
+*/
+
+(function(){
+
+var getWidget = function(link) {
+	var splitview = link.getParent('.splitview');
+	if (!splitview) return;
+	return splitview.get('widget');
+};
+CCS.JFrame.addGlobalLinkers({
+
+	'[data-splitview-resize]': function(e, link){
+		if ($(e.target).get('tag') == 'a') e.preventDefault();
+		var widget = getWidget(link);
+		if (!widget) return;
+		var resize = link.get('data', 'splitview-resize', true);
+		if (!resize) return;
+		var side;
+		var sides = ['left', 'right', 'top', 'bottom'];
+		for (key in resize) {
+			if (sides.contains(key)) side = key;
+		}
+		widget.fold(side, resize[side], resize.hideSplitter).chain(partialPostFold.bind(this, [resize, e, link]));
+	},
+
+	'[data-splitview-toggle]': function(e, link){
+		if ($(e.target).get('tag') == 'a') e.preventDefault();
+		var widget = getWidget(link);
+		if (!widget) return;
+		var resize = link.get('data', 'splitview-toggle', true);
+		if (!resize) return;
+		widget.toggle(resize.side, resize.hideSplitter).chain(partialPostFold.bind(this, [resize, e, link]));
+	}
+
+});
+
+var partialPostFold = function(data, event, link){
+	if (!$(document.body).hasChild(link)) return;
+	if (data.partialRefresh) {
+		if ($type(data.partialRefresh) == "string") link = new Element('a', { href: data.partialRefresh });
+		this.invokeLinker('.ccs-fake_refresh', link, event);
+	}
+};
+
+})();

+ 3 - 3
desktop/core/static/js/Source/JFrameRenderers/CCS.JFrame.Alert.js

@@ -57,9 +57,9 @@ CCS.JFrame.addGlobalRenderers({
 				this.getWindow().hide();
 			} else {
 				var alert = this.alert(content.title, target);
-                                target.getElements(":widget").each(function(widget) {
-                                        widget.get("widget").register(widget.getParent(":widget").get("widget"));
-                                });
+				target.getElements(":widget").each(function(widget) {
+					widget.get("widget").register(widget.getParent(":widget").get("widget"));
+				});
 				if (options) {
 					if (options.blankWindowWithError) {
 						alert.addEvent('destroy', function(){

+ 1 - 1
desktop/core/static/js/Source/JFrameRenderers/CCS.JFrame.PartialRefresh.js

@@ -2,7 +2,7 @@
 ---
 description: Any JFrame response that has a root-level child element with the class .partial_refresh will find all elements that have a property defined for data-partial-id that is unique to the response and only update them. If there is a mismatch in the response such that the number of and ids of partials in the previous state do not match the return state, an alert will be shown the user that the entire view will be updated that they can cancel, if they so choose. 
 provides: [CCS.JFrame.PartialRefresh]
-requires: [/CCS.JFrame, Widgets/ART.Alerts, Table/Table, /Element.Data]
+requires: [/CCS.JFrame, Widgets/ART.Alerts, Table/Table, Widgets/Element.Data]
 script: CCS.JFrame.PartialRefresh.js
 
 ...

+ 4 - 4
desktop/core/static/js/Source/JFrameRenderers/CCS.JFrame.Prompt.js

@@ -33,7 +33,7 @@ CCS.JFrame.addGlobalRenderers({
 
 		var target = new Element('div', {'class': 'jframe_prompt'}).hide().inject($(this));
 		this.fill(target, content);
-                target.show();
+		target.show();
 		var toolbar = target.getElements('.toolbar');
 		if (toolbar.length) toolbar.hide();
 
@@ -44,9 +44,9 @@ CCS.JFrame.addGlobalRenderers({
 		}, {
 			resizable: true
 		});
-                target.getElements(":widget").each(function(widget) {
-                        widget.get("widget").register(widget.getParent(":widget").get("widget"));
-                });
+		target.getElements(":widget").each(function(widget) {
+			widget.get("widget").register(widget.getParent(":widget").get("widget"));
+		});
 		if (form) {
 			form.addEvent('submit', function(){
 				prompt.hide();

+ 2 - 84
desktop/core/static/js/Source/Native/Element.Data.js

@@ -15,92 +15,10 @@
 // limitations under the License.
 /*
 ---
-description: Stores data in HTML5 data properties
+description: This file is deprecated; the functionality has been moved to the ART Widgets repo. This is here for dependency backwards compatibility.
 provides: [Element.Data]
-requires: [Core/Element, Core/JSON]
+requires: [Widgets/Element.Data]
 script: Element.Data.js
 
 ...
 */
-(function(){
-
-	var isSecure = function(string){
-		//this verfies that the string is parsable JSON and not malicious (borrowed from JSON.js in MooTools, which in turn borrowed it from Crockford)
-		//this version is a little more permissive, as it allows single quoted attributes because forcing the use of double quotes
-		//is a pain when this stuff is used as HTML properties
-		var secure = (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '').replace(/'[^'\\\n\r]*'/g, ''));
-                if(!secure) {
-                        dbug.log("JSON string is insecure:" + string + ".");
-                }
-                return secure;                    
-	};
-
-	Element.implement({
-		/*
-			sets an HTML5 data property.
-			arguments:
-				name - (string) the data name to store; will be automatically prefixed with 'data-'.
-				value - (string, number) the value to store.
-		*/
-		setData: function(name, value) {
-			return this.set('data-' + name, value);
-		},
-
-		getData: function(name, default_value){
-			var value = this.get('data-' + name);
-			if (value) {
-				return value;
-			} else if (default_value){
-				this.setData(name, default_value);
-				return default_value;
-			}
-		},
-
-		/* 
-			arguments:
-				name - (string) the data name to store; will be automatically prefixed with 'data-'
-				value - (string, array, or object) if an object or array the object will be JSON encoded; otherwise stored as provided.
-		*/
-		setJSONData: function(name, value) {
-			return this.setData(name, JSON.encode(value));
-		},
-
-		/*
-			retrieves a property from HTML5 data property you specify
-		
-			arguments:
-				name - (retrieve) the data name to store; will be automatically prefixed with 'data-'
-				strict - (boolean) if true, will set the JSON.decode's secure flag to true; otherwise the value is still tested but allows single quoted attributes.
-				default_value - (string, array, or object) the value to set if no value is found (see storeData above)
-		*/
-		getJSONData: function(name, strict, default_value){
-			var value = this.get('data-' + name);
-			if (value) {
-				return isSecure(value) ? JSON.decode(value, strict) : null;
-			} else if (default_value){
-				this.setJSONData(name, default_value);
-				return default_value;
-			}
-		}
-
-	});
-
-	Element.Properties.data = {
-
-		set: function(name, value, encode){
-			if (encode) return this.setJSONData(name, value);
-			else return this.setData(name, value);
-		},
-
-		get: function(name, decode, default_value, strict){
-			if (decode) return this.getJSONData(name, default_value, strict);
-			else return this.getData(name, default_value);
-		},
-
-		erase: function(name){
-			this.erase('data-' + name);
-		}
-
-	};
-
-})();

+ 3 - 3
desktop/core/static/js/Source/UI/ART.SideBySideSelect.js

@@ -34,13 +34,13 @@ ART.SideBySideSelect = new Class({
 		className: 'sideBySideSelect clearfix',
 		deselectedOptions: {
 			properties: {
-				'class': 'ccs-data_table'
+				'data-filters': 'HtmlTable'
 			},
 			headers: ['Deselected']
 		},
 		selectedOptions: {
 			properties: {
-				'class': 'ccs-data_table'
+				'data-filters': 'HtmlTable'
 			},
 			headers: ['Selected']
 		},
@@ -318,7 +318,7 @@ ART.SideBySideSelect = new Class({
 			var startSelected = $(this.selected).hasChild(start);
 			var end = row;
 			//see if the end is a child of the selected table
-			var endSelected = $(this.selected).hasChild(start);
+			var endSelected = $(this.selected).hasChild(end);
 			//if both are in the same table, select the range
 			if (startSelected == endSelected) {
 				var rows;

+ 8 - 13
desktop/core/static/js/package.yml

@@ -2,28 +2,16 @@ copyright: Apache License v2.0
 description: Shared components for Hue
 name: ccs-shared
 sources: [
-  Source/JFrameFilters/CCS.JFrame.ArtButtons.js,
   Source/JFrameFilters/CCS.JFrame.NoOverflow.js,
   Source/JFrameFilters/CCS.JFrame.FormRequest.js,
-  Source/JFrameFilters/CCS.JFrame.SplitView.js,
-  Source/JFrameFilters/CCS.JFrame.Tabs.js,
-  Source/JFrameFilters/CCS.JFrame.ContextMenu.js,
   Source/JFrameFilters/CCS.JFrame.Clearfix.js,
   Source/JFrameFilters/CCS.JFrame.AutoRefresh.js,
   Source/JFrameFilters/CCS.JFrame.DoubleClickDelegate.js,
-  Source/JFrameFilters/CCS.JFrame.SubmitOnChange.js,
   Source/JFrameFilters/CCS.JFrame.Collapsible.js,
-  Source/JFrameFilters/CCS.JFrame.FormValidator.js,
   Source/JFrameFilters/CCS.JFrame.ToggleHistory.js,
-  Source/JFrameFilters/CCS.JFrame.Tips.js,
-  Source/JFrameFilters/CCS.JFrame.OverText.js,
-  Source/JFrameFilters/CCS.JFrame.HtmlTable.js,
   Source/JFrameFilters/CCS.JFrame.DataGroupToggle.js,
   Source/JFrameFilters/CCS.JFrame.SelectWithOther.js,
-  Source/JFrameFilters/CCS.JFrame.Input.js,
-  Source/JFrameFilters/CCS.JFrame.SizeTo.js,
-  Source/JFrameFilters/CCS.JFrame.FilterInput.js,
-  Source/JFrameFilters/CCS.JFrame.FitText.js,
+  Source/JFrameFilters/CCS.JFrame.Deprecated.js,
   Source/Fx/Fx.Shake.js,
   Source/JFrameRenderers/CCS.JFrame.Alert.js,
   Source/JFrameRenderers/CCS.JFrame.Prompt.js,
@@ -63,8 +51,15 @@ sources: [
   Source/StaticThirdParty/DynamicTextarea.js,
   Source/CCS/CCS.PostEditor.Simple.js,
   Source/UI/ART.SideBySideSelect.js,
+  Source/BehaviorFilters/Behavior.ContextMenu.js,
+  Source/BehaviorFilters/Behavior.FilterInput.js,
   Source/BehaviorFilters/Behavior.FitText.js,
   Source/BehaviorFilters/Behavior.MultiChecks.js,
   Source/BehaviorFilters/Behavior.SideBySideSelect.js,
+  Source/BehaviorFilters/Behavior.SizeTo.js,
+  Source/BehaviorFilters/Behavior.SplitViewPostFold.js,
+  Source/BehaviorFilters/Behavior.SubmitOnChange.js,
+  Source/BehaviorFilters/Behavior.Tabs.js,
+  Source/BehaviorFilters/Behavior.Tips.js,
 ]
 version: Unknown

+ 1 - 1
ext/thirdparty/js/art-widgets.hash

@@ -1 +1 @@
-fb7d9d2c6e1afd63b57c6642b5d0f75b2fe330e6
+4d07560e1defc325ef10b92d968d6472d87db133

+ 1 - 1
ext/thirdparty/js/mootools-more.hash

@@ -1 +1 @@
-26eee33478d302464c895ad3533950b09085ab73
+4074ee73688f1e70ce22176d83d2a2fb8af983e6