<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>CHANGELOG</filename>
    </added>
    <added>
      <filename>install.rb</filename>
    </added>
    <added>
      <filename>tasks/tiny_mce_helper_tasks.rake</filename>
    </added>
    <added>
      <filename>test/app_root/config/config_bak/tiny_mce_options.yml</filename>
    </added>
    <added>
      <filename>test/app_root/config/tiny_mce_options.yml</filename>
    </added>
    <added>
      <filename>test/app_root/config_bak/tiny_mce_options.yml</filename>
    </added>
    <added>
      <filename>test/test_helper.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,9 +1,14 @@
 = tiny_mce_helper
 
-tiny_mce_helper .
+tiny_mce_helper adds helper methods for creating the TinyMCE initialization
+script.
 
 == Resources
 
+API
+
+* http://api.pluginaweek.org/tiny_mce_helper
+
 Wiki
 
 * http://wiki.pluginaweek.org/Tiny_mce_helper
@@ -20,14 +25,32 @@ Development
 
 * http://dev.pluginaweek.org/browser/trunk/plugins/action_pack/tiny_mce_helper
 
+== Requirements
+
+Currently, you must be running a version of Linux in order to run the rake
+tasks.
+
 == Description
 
-== References
 
-This plugin provides for the installation and utilization of TinyMCE in Ruby on Rails applications. TinyMCE is a WYSIWYG HTML editing component 
-released under the GNU Public License (GPL) by Moxiecode Systems (http://tinymce.moxiecode.com/).
 
-This plugin is maintained by Blake Watters &lt;blake@near-time.com&gt;
+=== Installing TinyMCE
+
+
+
+=== Updating configuration options
+
+
+
+=== Creating TinyMCE script
+
+
+
+== References
+
+This plugin provides for the installation and utilization of TinyMCE in Ruby on
+Rails applications. TinyMCE is a WYSIWYG HTML editing component  released under
+the GNU Public License (GPL) by Moxiecode Systems (http://tinymce.moxiecode.com/).
 
-Bundled TinyMCE version: 2.0.6.1
-Documentation from the TinyMCE distribution is available in the doc subdirectory of the plugin
\ No newline at end of file
+This plugin was originally created by by Blake Watters &lt;blake@near-time.com&gt; and
+later modified by Aaron Pfeifer &amp; Neil Abraham.</diff>
      <filename>README</filename>
    </modified>
    <modified>
      <diff>@@ -31,7 +31,7 @@ spec = Gem::Specification.new do |s|
   s.name            = PKG_NAME
   s.version         = PKG_VERSION
   s.platform        = Gem::Platform::RUBY
-  s.summary         = 'Adds helper methods for determining if a specified date/time was yesterday, today, or tomorrow.'
+  s.summary         = 'Adds helper methods for creating the TinyMCE initialization script.'
   
   s.files           = FileList['{lib,tasks,test}/**/*'].to_a + %w(init.rb MIT-LICENSE Rakefile README)
   s.require_path    = 'lib'
@@ -77,4 +77,4 @@ task :release =&gt; [:gem, :package] do
     
     ruby_forge.add_release(RUBY_FORGE_PROJECT, PKG_NAME, PKG_VERSION, file)
   end
-end
\ No newline at end of file
+end</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -1 +1 @@
-require 'tiny_mce_helper'
\ No newline at end of file
+require 'tiny_mce_helper'</diff>
      <filename>init.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,187 +1,152 @@
-module PluginAWeek
-  module Helpers
-    #
+module PluginAWeek #:nodoc:
+  module Helpers #:nodoc:
+    # Adds helper methods for generating the TinyMCE initialization script
+    # within your Rails views
     module TinyMCEHelper
+      # The path to the file which contains all valid options that can be used
+      # to configure TinyMCE
+      OPTIONS_FILE_PATH = &quot;#{RAILS_ROOT}/config/tiny_mce_options.yml&quot;
+      
+      # A list of all valid options that can be used to configure TinyMCE
       mattr_accessor :valid_options
-      @@valid_options =
-        # General
-        %w(
-           mode
-           theme
-           plugins
-           language
-           ask
-           textarea_trigger
-           editor_selector
-           editor_deselector
-           elements
-           docs_language
-           debug
-           focus_alert
-           directionality
-           auto_reset_designmode
-           auto_focus
-           nowrap
-           button_tile_map
-           auto_resize
-           browsers
-           dialog_type
-           accessibility_warnings
-           accessibility_focus
-           event_elements
-           table_inline_editing
-           object_resizing
-           custom_shortcuts
-           strict_loading_mode
-           gecko_spellcheck
-           hide_selects_on_submit
-        ) +
-        
-        # Callbacks
-        %w(
-          urlconverter_callback
-          insertlink_callback
-          insertimage_callback
-          setupcontent_callback
-          save_callback
-          onchange_callback
-          init_instance_callback
-          file_browser_callback
-          cleanup_callback
-          handle_event_callback
-          execcommand_callback
-          oninit
-          onpageload
-        ) + 
-        
-        # Cleanup/Output
-        %w(
-          cleanup
-          valid_elements
-          extended_valid_elements
-          invalid_elements
-          verify_css_classes
-          verify_html
-          preformatted
-          encoding
-          cleanup_on_startup
-          fix_content_duplication
-          inline_styles
-          convert_newlines_to_brs
-          force_br_newlines
-          force_p_newlines
-          entities
-          entity_encoding
-          remove_linebreaks
-          convert_fonts_to_spans
-          font_size_classes
-          font_size_style_values
-          merge_styles_invalid_parents
-          force_hex_style_colors
-          apply_source_formatting
-          trim_span_elements
-          doctype
-          fix_list_elements
-          fix_table_elements
-          valid_child_elements
-          cleanup_serializer
-        ) + 
-        
-        # URL
-        %w(
-          convert_urls
-          relative_urls
-          remove_script_host
-          document_base_url
-        ) + 
-        
-        # Layout
-        %w(
-          content_css
-          popups_css
-          popups_css_add
-          editor_css
-          width
-          height
-        ) + 
-        
-        # Visual aids
-        %w(
-          visual
-          visual_table_class
-        ) + 
-        
-        # Undo/Redo
-        %w(
-          custom_undo_redo
-          custom_undo_redo_levels
-          custom_undo_redo_keyboard_shortcuts
-          custom_undo_redo_restore_selection
-        ) + 
-        
-        # File lists
-        %w(
-          external_link_list_url
-          external_image_list_url
-        ) + 
-        
-        # Tab specific
-        %w(
-          display_tab_class
-          hidden_tab_class
-        ) + 
-        
-        # Triggers/patches
-        %w(
-          add_form_submit_trigger
-          add_unload_trigger
-          submit_patch
-        ) + 
-        
-        # Advanced theme
-        %w(
-          theme_advanced_layout_manager
-          theme_advanced_blockformats
-          theme_advanced_styles
-          theme_advanced_source_editor_width
-          theme_advanced_source_editor_height
-          theme_advanced_source_editor_wrap
-          theme_advanced_toolbar_location
-          theme_advanced_toolbar_align
-          theme_advanced_statusbar_location
-          theme_advanced_buttons1
-          theme_advanced_buttons1_add
-          theme_advanced_buttons1_add_before
-          theme_advanced_buttons2
-          theme_advanced_buttons2_add
-          theme_advanced_buttons2_add_before
-          theme_advanced_buttons3
-          theme_advanced_buttons3_add
-          theme_advanced_buttons3_add_before
-          theme_advanced_disable
-          theme_advanced_containers
-          theme_advanced_containers_default_class
-          theme_advanced_containers_default_align
-          theme_advanced_container_&lt;container&gt;
-          theme_advanced_container_&lt;container&gt;_class
-          theme_advanced_container_&lt;container&gt;_align
-          theme_advanced_custom_layout
-          theme_advanced_link_targets
-          theme_advanced_resizing
-          theme_advanced_resizing_use_cookie
-          theme_advanced_resize_horizontal
-          theme_advanced_path
-          theme_advanced_fonts
-          theme_advanced_text_colors
-          theme_advanced_background_colors
-        )
+      @@valid_options = File.exists?(OPTIONS_FILE_PATH) ? File.open(OPTIONS_FILE_PATH) {|f| YAML.load(f.read)} : []
+      
+      class &lt;&lt; self
+        # Installs TinyMCE by downloading it and adding it to your application's
+        # javascripts folder.
+        # 
+        # == Versions
+        # 
+        # By default, this will install the latest version of TinyMCE.  You can
+        # install a specific version of TinyMCE (if you are using an old API) by
+        # passing in the version number.
+        # 
+        # For example,
+        #   PluginAWeek::Helpers::TinyMCEHelper.install           #=&gt; Installs the latest version
+        #   PluginAWeek::Helpers::TinyMCEHelper.install('2.0.8')  #=&gt; Installs version 2.0.8
+        # 
+        # An exception will be raised if the specified version cannot be found.
+        # 
+        # == Target path
+        # 
+        # By default, this will install TinyMCE into RAILS_ROOT/public/javascripts/tinymce.
+        # If you want to install it to a different directory, you can pass in
+        # a parameter with the relative path from RAILS_ROOT.
+        # 
+        # For example,
+        #   PluginAWeek::Helpers::TinyMCEHelper.install(nil, 'public/javascripts/richtext')
+        def install(version = nil, base_target = nil, force = false)
+          base_target ||= 'public/javascripts/tinymce'
+          source_path = 'tinymce'
+          target_path = File.join(RAILS_ROOT, base_target)
+          
+          # If TinyMCE is already installed, make sure the user wants to continue
+          if !force &amp;&amp; File.exists?(target_path)
+            print &quot;TinyMCE already be installed in #{target_path}. Overwrite? (y/n): &quot;
+            while !%w(y n).include?(option = STDIN.gets.chop)
+              print &quot;Invalid option. Overwrite #{target_path}? (y/n): &quot;
+            end
+            return if option == 'n'
+          end
+          
+          require 'hpricot'
+          require 'open-uri'
+          
+          # Get the url of the TinyMCE version
+          doc = Hpricot(open('http://sourceforge.net/project/showfiles.php?group_id=103281&amp;package_id=111430'))
+          if version
+            version.gsub!('.', '_')
+            file_element = (doc/'tr[@id*=&quot;rel0_&quot;] a').detect {|file| file.innerHTML =~ /#{version}.tgz$/}
+            raise ArgumentError, &quot;Could not find TinyMCE version #{version}&quot; if !file_element
+          else
+            file_element = (doc/'tr[@id^=&quot;pkg0_1rel0_&quot;] a').detect {|file| file.innerHTML.to_s =~ /\d\.tgz$/}
+            raise ArgumentError, 'Could not find latest TinyMCE version' if !file_element
+          end
+          
+          filename = file_element.innerHTML
+          file_url = file_element['href']
+          
+          # Download and install it
+          Dir.chdir('/tmp/') do
+            begin
+              puts 'Downloading TinyMCE source...'
+              system(&quot;wget '#{file_url}' &amp;&gt; wget.log&quot;)
+              puts 'Extracting...'
+              system(&quot;tar xf #{filename} &amp;&gt; tar.log&quot;)
+              File.delete(filename)
+              FileUtils.mkdir_p(target_path)
+              FileUtils.mv(source_path, target_path, :force =&gt; true)
+              puts 'Done!'
+            rescue Object =&gt; e
+              puts &quot;Error: See the last modified log file (wget.log or tar.log) in /tmp/.&quot;
+            end
+          end
+        end
         
+        # Updates the list of possible configuration options that can be used
+        # when initializing the TinyMCE script.  These are always installed to
+        # the application folder, config/tiny_mce_options.yml.  If this file
+        # does not exist, then the TinyMCE helper will not be able to verify
+        # that all of the initialization options are valid.
+        def update_options
+          require 'hpricot'
+          require 'open-uri'
+          require 'yaml'
+          
+          puts 'Downloading configuration options from TinyMCE Wiki...'
+          doc = Hpricot(open('http://wiki.moxiecode.com/index.php/TinyMCE:Configuration'))
+          options = (doc/'a[@title*=&quot;Configuration/&quot;]/').collect {|option| option.to_s}.sort
+          options.reject! {|option| option =~ /theme_advanced_buttons|theme_advanced_container/}
+          
+          File.open('config/tiny_mce_options.yml', 'w') do |out|
+            YAML.dump(options, out)
+          end
+          puts 'Done!'
+        end
+      end
+      
       # Are we using TinyMCE?
       def using_tiny_mce?
         !@uses_tiny_mce.nil?
       end
       
-      # Create the script that will initialize TinyMCE
+      # Create the TinyMCE initialization scripts.  The default configuration
+      # is for a simple theme that replaces all textareas on the page.  For
+      # example, the default initialization script will generate the following:
+      # 
+      #  tinyMCE.init({
+      #    'mode' : 'textareas',
+      #    'theme' : 'simple'
+      #  });
+      # 
+      # == Customizing initialization options
+      # 
+      # To customize the options to be included in the initialization script,
+      # you can pass in a hash to #tiny_mce_init_script.  For example,
+      # 
+      #   tiny_mce_init_script(
+      #     :theme =&gt; 'advanced',
+      #     :editor_selector =&gt; 'rich_text',
+      #     :content_css =&gt; '/stylesheets/tiny_mce_content.css',
+      #     :editor_css =&gt; '/stylesheets/tiny_mce_editor.css',
+      #     :auto_reset_designmode =&gt; true
+      #   )
+      # 
+      # will generate:
+      # 
+      #  tinyMCE.init({
+      #    'mode' : 'textareas',
+      #    'theme' : 'advanced',
+      #    'editor_selected' : 'rich_text',
+      #    'content_css' : '/stylesheets/tiny_mce_content.css'
+      #  });
+      # 
+      # == Validating options
+      # 
+      # If additional options are passed in to initialize TinyMCE, they will be
+      # validated against the list of valid options in PluginAWeek::Helpers::TinyMCEHelper#valid_options.
+      # These options are configured in the file config/tiny_mce_options.yml.
+      # You can generate this file by invoke the rake task tiny_mce:update_options.
       def tiny_mce_init_script(options = @tiny_mce_options)
         options ||= {}
         options.stringify_keys!.reverse_merge!(
@@ -192,7 +157,7 @@ module PluginAWeek
         # Check validity
         plugins = options['plugins']
         options_to_validate = options.reject {|option, value| plugins &amp;&amp; plugins.include?(option.split('_')[0]) || option =~ /theme_advanced_container_/}
-        options_to_validate.assert_valid_keys(@@valid_options)
+        options_to_validate.assert_valid_keys(@@valid_options) if @@valid_options.any?
         
         init_script = 'tinyMCE.init({'
         
@@ -209,7 +174,7 @@ module PluginAWeek
             when FalseClass
               init_script &lt;&lt; 'false'
             else
-              raise InvalidOption.new(&quot;Invalid value of type #{value.class} passed for TinyMCE option #{key}&quot;)
+              raise ArgumentError, &quot;Cannot parse value of type #{value.class} passed for TinyMCE option #{key}&quot;
           end
           
           init_script &lt;&lt; ','
@@ -223,16 +188,29 @@ module PluginAWeek
         javascript_tag tiny_mce_init_script(*args)
       end
       
+      # The name of the TinyMCE javascript file to use.  In development, this
+      # will use the source (uncompressed) file in order to help with debugging
+      # issues that occur within TinyMCE.  In production, the compressed version
+      # of TinyMCE will be used in order to increased download speed.
       def tiny_mce_file_name
-        RAILS_ENV == 'development' ? 'tiny_mce/tiny_mce_src' : 'tiny_mce/tiny_mce'
+        RAILS_ENV == 'development' ? 'tinymce/tiny_mce_src' : 'tinymce/tiny_mce'
       end
       
+      # Generates the javascript include for TinyMCE.  For example,
+      # 
+      #   javascript_include_tiny_mce
+      # 
+      # will generate:
+      # 
+      #   &lt;script type=&quot;text/javascript&quot; src=&quot;/javascripts/tinymce/tiny_mce.js&quot;&gt;&lt;/script&gt;
       def javascript_include_tiny_mce
         javascript_include_tag tiny_mce_file_name
       end
       
+      # Conditionally includes the TinyMCE javascript file if the variable
+      # @uses_tiny_mce has been set to true.
       def javascript_include_tiny_mce_if_used
-        javascript_include_tiny_mce if @uses_tiny_mce
+        javascript_include_tiny_mce if using_tiny_mce?
       end
     end
   end
@@ -240,4 +218,4 @@ end
 
 ActionController::Base.class_eval do
   helper PluginAWeek::Helpers::TinyMCEHelper
-end
\ No newline at end of file
+end</diff>
      <filename>lib/tiny_mce_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,67 +1,26 @@
-require File.dirname(__FILE__) + '/../../../../test/test_helper'
-require File.expand_path(File.dirname(__FILE__) + '/helper_testcase')
+require File.dirname(__FILE__) + '/test_helper'
 
-class TinyMceHelperTest &lt; HelperTestCase
-  include TinyMCEHelper
-
-  def setup
-    @uses_tiny_mce = nil
-    super
-  end
-  
-  def test_javascript_include_tiny_mce
-    assert_match /\/javascripts\/tiny_mce\/tiny_mce.js/, javascript_include_tiny_mce
-    # We don't match the full string because asset timestamping gets in the way...
-  end
-  
-  def test_javascript_include_tiny_mce_if_used
-    assert_nil javascript_include_tiny_mce_if_used
-    @uses_tiny_mce = true
-    assert_match /\/javascripts\/tiny_mce\/tiny_mce.js/, javascript_include_tiny_mce_if_used
-  end
-  
-  def test_tiny_mce_alias_is_available_for_helper
-    assert respond_to?(:tiny_mce)
-    assert_equal tiny_mce_init, tiny_mce
-  end
+class TinyMceHelperTest &lt; Test::Unit::TestCase
+  include PluginAWeek::Helpers::TinyMCEHelper
   
-  def test_tiny_mce_with_default_options_produces_tiny_mce_with_simple_theme_in_textareas_mode
-    assert_equal &quot;&lt;script type=\&quot;text/javascript\&quot;&gt;\n//&lt;![CDATA[\ntinyMCE.init({\nmode : 'textareas',\ntheme : 'simple'\n});\n//]]&gt;\n&lt;/script&gt;&quot;, tiny_mce
-  end
-  
-  def test_tiny_mce_with_array_of_plugins_produces_comma_separated_values
-    assert_equal &quot;&lt;script type=\&quot;text/javascript\&quot;&gt;\n//&lt;![CDATA[\ntinyMCE.init({\nmode : 'textareas',\nplugins : \&quot;table,contextmenu,paste,-externalplugin\&quot;,\ntheme : 'simple'\n});\n//]]&gt;\n&lt;/script&gt;&quot;,
-                 tiny_mce_init(:plugins =&gt; %w{table contextmenu paste -externalplugin})
-  end
-  
-  def test_tiny_mce_with_true_value_for_debug_produces_true_literal
-    assert_equal &quot;&lt;script type=\&quot;text/javascript\&quot;&gt;\n//&lt;![CDATA[\ntinyMCE.init({\ndebug : true,\nmode : 'textareas',\ntheme : 'simple'\n});\n//]]&gt;\n&lt;/script&gt;&quot;,
-                 tiny_mce_init('debug' =&gt; true)
-  end
-  
-  def test_tiny_mce_with_false_value_for_debug_produces_false_literal
-    assert_equal &quot;&lt;script type=\&quot;text/javascript\&quot;&gt;\n//&lt;![CDATA[\ntinyMCE.init({\ndebug : false,\nmode : 'textareas',\ntheme : 'simple'\n});\n//]]&gt;\n&lt;/script&gt;&quot;,
-                 tiny_mce_init(:debug =&gt; false)
-  end
-  
-  def test_tiny_mce_overriding_default_values
-    assert_equal &quot;&lt;script type=\&quot;text/javascript\&quot;&gt;\n//&lt;![CDATA[\ntinyMCE.init({\nmode : 'specific_textareas',\ntheme : 'advanced'\n});\n//]]&gt;\n&lt;/script&gt;&quot;,
-                 tiny_mce_init(:theme =&gt; 'advanced', :mode =&gt; 'specific_textareas')
+  def setup
+    @config_root = &quot;#{RAILS_ROOT}/config&quot;
+    FileUtils.cp_r(&quot;#{RAILS_ROOT}/config_bak&quot;, @config_root)
+    @original_config_files = Dir[&quot;#{RAILS_ROOT}/config/**/*&quot;].sort
+    
+    @public_root = &quot;#{RAILS_ROOT}/public&quot;
+    FileUtils.cp_r(&quot;#{RAILS_ROOT}/public_bak&quot;, @public_root)
+    @original_public_files = Dir[&quot;#{RAILS_ROOT}/public/**/*&quot;].sort
   end
   
-  def test_tiny_mce_with_numeric_value_for_width_produces_string
-    assert_equal &quot;&lt;script type=\&quot;text/javascript\&quot;&gt;\n//&lt;![CDATA[\ntinyMCE.init({\nmode : 'textareas',\ntheme : 'simple',\nwidth : '50'\n});\n//]]&gt;\n&lt;/script&gt;&quot;,
-                 tiny_mce_init(:width =&gt; 50)
+  def test_valid_options_should_not_be_empty
+    assert PluginAWeek::Helpers::TinyMCEHelper.valid_options.any?
   end
   
-  def test_tiny_mce_raises_exception
-    assert_raise(TinyMCEHelper::InvalidOption) {tiny_mce(:invalid_option =&gt; true)}
-    assert_raise(TinyMCEHelper::InvalidOption) {tiny_mce(:mode =&gt; Class)}
+  def test_should_install_latest_version_to_default_target
   end
   
-  def test_using_tiny_mce_eh
-    assert !using_tiny_mce?
-    @uses_tiny_mce = true
-    assert using_tiny_mce?
+  def teardown
+    FileUtils.rmtree(@public_root)
   end
 end</diff>
      <filename>test/tiny_mce_helper_test.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>test/helper_testcase.rb</filename>
    </removed>
    <removed>
      <filename>test/tiny_mce_test.rb</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>589245af5169df121bd483e995200565eef6915c</id>
    </parent>
  </parents>
  <author>
    <name>Aaron Pfeifer</name>
    <email>aaron.pfeifer@gmail.com</email>
  </author>
  <url>http://github.com/pluginaweek/tiny_mce_helper/commit/dd8c82a22866d635020c92f275ec1af8efde9b46</url>
  <id>dd8c82a22866d635020c92f275ec1af8efde9b46</id>
  <committed-date>2007-08-18T22:40:05-07:00</committed-date>
  <authored-date>2007-08-18T22:40:05-07:00</authored-date>
  <message>Add working unit tests
Add installation and uninstallation scripts
Add rake tasks tiny_mce:install and tiny_mce:update_options</message>
  <tree>aaadfb8b54eea6fb79eaf5d54642b3ff51f67e4f</tree>
  <committer>
    <name>Aaron Pfeifer</name>
    <email>aaron.pfeifer@gmail.com</email>
  </committer>
</commit>
