commit 51b79e7298ba1cb03ee03526f80202b46efac24b Author: Eugene Korbut Date: Thu Jan 8 05:27:12 2009 +1000 init import from old mailr project (http://svn.littlegreen.org/mailr/trunk) diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..18b4288 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,718 @@ +*0.14.2 (RC3)* (October 26th, 2005) + +* Constants set in the development/test/production environment file are set in Object + +* Scaffold generator pays attention to the controller name. #2562 [self@mattmower.com] + +* Include tasks from vendor/plugins/*/tasks in the Rakefile #2545 [Rick Olson] + + +*0.14.1 (RC2)* (October 19th, 2005) + +* Don't clean RAILS_ROOT on windows + +* Remove trailing '/' from RAILS_ROOT [Nicholas Seckar] + +* Upgraded to Active Record 1.12.1 and Action Pack 1.10.1 + + +*0.14.0 (RC1)* (October 16th, 2005) + +* Moved generator folder from RAILS_ROOT/generators to RAILS_ROOT/lib/generators [Tobias Luetke] + +* Fix rake dev and related commands [Nicholas Seckar] + +* The rails command tries to deduce your MySQL socket by running `mysql_config +--socket`. If it fails, default to /path/to/your/mysql.sock + +* Made the rails command use the application name for database names in the tailored database.yml file. Example: "rails ~/projects/blog" will use "blog_development" instead of "rails_development". [Florian Weber] + +* Added Rails framework freezing tasks: freeze_gems (freeze to current gems), freeze_edge (freeze to Rails SVN trunk), unfreeze_rails (float with newest gems on system) + +* Added update_javascripts task which will fetch all the latest js files from your current rails install. Use after updating rails. [Tobias Luetke] + +* Added cleaning of RAILS_ROOT to useless elements such as '../non-dot-dot/'. Provides cleaner backtraces and error messages. [Nicholas Seckar] + +* Made the instantiated/transactional fixtures settings be controlled through Rails::Initializer. Transactional and non-instantiated fixtures are default from now on. [Florian Weber] + +* Support using different database adapters for development and test with ActiveRecord::Base.schema_format = :ruby [Sam Stephenson] + +* Make webrick work with session(:off) + +* Add --version, -v option to the Rails command. Closes #1840. [stancell] + +* Update Prototype to V1.4.0_pre11, script.aculo.us to V1.5_rc3 [2504] and fix the rails generator to include the new .js files [Thomas Fuchs] + +* Make the generator skip a file if it already exists and is identical to the new file. + +* Add experimental plugin support #2335 + +* Made Rakefile aware of new .js files in script.aculo.us [Thomas Fuchs] + +* Make table_name and controller_name in generators honor AR::Base.pluralize_table_names. #1216 #2213 [kazuhiko@fdiary.net] + +* Clearly label functional and unit tests in rake stats output. #2297 [lasse.koskela@gmail.com] + +* Make the migration generator only check files ending in *.rb when calculating the next file name #2317 [Chad Fowler] + +* Added prevention of duplicate migrations from the generator #2240 [fbeausoleil@ftml.net] + +* Add db_schema_dump and db_schema_import rake tasks to work with the new ActiveRecord::SchemaDumper (for dumping a schema to and reading a schema from a ruby file). + +* Reformed all the config/environments/* files to conform to the new Rails::Configuration approach. Fully backwards compatible. + +* Added create_sessions_table, drop_sessions_table, and purge_sessions_table as rake tasks for databases that supports migrations (MySQL, PostgreSQL, SQLite) to get a table for use with CGI::Session::ActiveRecordStore + +* Added dump of schema version to the db_structure_dump task for databases that support migrations #1835 [Rick Olson] + +* Fixed script/profiler for Ruby 1.8.2 #1863 [Rick Olson] + +* Fixed clone_structure_to_test task for SQLite #1864 [jon@burningbush.us] + +* Added -m/--mime-types option to the WEBrick server, so you can specify a Apache-style mime.types file to load #2059 [ask@develooper.com] + +* Added -c/--svn option to the generator that'll add new files and remove destroyed files using svn add/revert/remove as appropriate #2064 [kevin.clark@gmail.com] + +* Added -c/--charset option to WEBrick server, so you can specify a default charset (which without changes is UTF-8) #2084 [wejn@box.cz] + +* Make the default stats task extendable by modifying the STATS_DIRECTORIES constant + +* Allow the selected environment to define RAILS_DEFAULT_LOGGER, and have Rails::Initializer use it if it exists. + +* Moved all the shared tasks from Rakefile into Rails, so that the Rakefile is empty and doesn't require updating. + +* Added Rails::Initializer and Rails::Configuration to abstract all of the common setup out of config/environment.rb (uses config/boot.rb to bootstrap the initializer and paths) + +* Fixed the scaffold generator to fail right away if the database isn't accessible instead of in mid-air #1169 [Chad Fowler] + +* Corrected project-local generator location in scripts.rb #2010 [Michael Schuerig] + +* Don't require the environment just to clear the logs #2093 [Scott Barron] + +* Make the default rakefile read *.rake files from config/tasks (for easy extension of the rakefile by e.g. generators) + +* Only load breakpoint in development mode and when BREAKPOINT_SERVER_PORT is defined. + +* Allow the --toggle-spin switch on process/reaper to be negated + +* Replace render_partial with render :partial in scaffold generator [Nicholas Seckar] + +* Added -w flag to ps in process/reaper #1934 [Scott Barron] + +* Allow ERb in the database.yml file (just like with fixtures), so you can pull out the database configuration in environment variables #1822 [Duane Johnson] + +* Added convenience controls for FCGI processes (especially when managed remotely): spinner, spawner, and reaper. They reside in script/process. More details can be had by calling them with -h/--help. + +* Added load_fixtures task to the Rakefile, which will load all the fixtures into the database for the current environment #1791 [Marcel Molina] + +* Added an empty robots.txt to public/, so that web servers asking for it won't trigger a dynamic call, like favicon.ico #1738 [michael@schubert] + +* Dropped the 'immediate close-down' of FCGI processes since it didn't work consistently and produced bad responses when it didn't. So now a TERM ensures exit after the next request (just as if the process is handling a request when it receives the signal). This means that you'll have to 'nudge' all FCGI processes with a request in order to ensure that they have all reloaded. This can be done by something like ./script/process/repear --nudge 'http://www.myapp.com' --instances 10, which will load the myapp site 10 times (and thus hit all of the 10 FCGI processes once, enough to shut down). + + +*0.13.1* (11 July, 2005) + +* Look for app-specific generators in RAILS_ROOT/generators rather than the clunky old RAILS_ROOT/script/generators. Nobody really uses this feature except for the unit tests, so it's a negligible-impact change. If you want to work with third-party generators, drop them in ~/.rails/generators or simply install gems. + +* Fixed that each request with the WEBrick adapter would open a new database connection #1685 [Sam Stephenson] + +* Added support for SQL Server in the database rake tasks #1652 [ken.barker@gmail.com] Note: osql and scptxfr may need to be installed on your development environment. This involves getting the .exes and a .rll (scptxfr) from a production SQL Server (not developer level SQL Server). Add their location to your Environment PATH and you are all set. + +* Added a VERSION parameter to the migrate task that allows you to do "rake migrate VERSION=34" to migrate to the 34th version traveling up or down depending on the current version + +* Extend Ruby version check to include RUBY_RELEASE_DATE >= '2005-12-25', the final Ruby 1.8.2 release #1674 [court3nay@gmail.com] + +* Improved documentation for environment config files #1625 [court3nay@gmail.com] + + +*0.13.0* (6 July, 2005) + +* Changed the default logging level in config/environment.rb to INFO for production (so SQL statements won't be logged) + +* Added migration generator: ./script/generate migration add_system_settings + +* Added "migrate" as rake task to execute all the pending migrations from db/migrate + +* Fixed that model generator would make fixtures plural, even if ActiveRecord::Base.pluralize_table_names was false #1185 [Marcel Molina] + +* Added a DOCTYPE of HTML transitional to the HTML files generated by Rails #1124 [Michael Koziarski] + +* SIGTERM also gracefully exits dispatch.fcgi. Ignore SIGUSR1 on Windows. + +* Add the option to manually manage garbage collection in the FastCGI dispatcher. Set the number of requests between GC runs in your public/dispatch.fcgi [skaes@web.de] + +* Allow dynamic application reloading for dispatch.fcgi processes by sending a SIGHUP. If the process is currently handling a request, the request will be allowed to complete first. This allows production fcgi's to be reloaded without having to restart them. + +* RailsFCGIHandler (dispatch.fcgi) no longer tries to explicitly flush $stdout (CgiProcess#out always calls flush) + +* Fixed rakefile actions against PostgreSQL when the password is all numeric #1462 [michael@schubert.cx] + +* ActionMailer::Base subclasses are reloaded with the other rails components #1262 + +* Made the WEBrick adapter not use a mutex around action performance if ActionController::Base.allow_concurrency is true (default is false) + +* Fixed that mailer generator generated fixtures/plural while units expected fixtures/singular #1457 [Scott Barron] + +* Added a 'whiny nil' that's aim to ensure that when users pass nil to methods where that isn't appropriate, instead of NoMethodError? and the name of some method used by the framework users will see a message explaining what type of object was expected. Only active in test and development environments by default #1209 [Michael Koziarski] + +* Fixed the test_helper.rb to be safe for requiring controllers from multiple spots, like app/controllers/article_controller.rb and app/controllers/admin/article_controller.rb, without reloading the environment twice #1390 [Nicholas Seckar] + +* Fixed Webrick to escape + characters in URL's the same way that lighttpd and apache do #1397 [Nicholas Seckar] + +* Added -e/--environment option to script/runner #1408 [fbeausoleil@ftml.net] + +* Modernize the scaffold generator to use the simplified render and test methods and to change style from @params["id"] to params[:id]. #1367 + +* Added graceful exit from pressing CTRL-C during the run of the rails command #1150 [Caleb Tennis] + +* Allow graceful exits for dispatch.fcgi processes by sending a SIGUSR1. If the process is currently handling a request, the request will be allowed to complete and then will terminate itself. If a request is not being handled, the process is terminated immediately (via #exit). This basically works like restart graceful on Apache. [Jamis Buck] + +* Made dispatch.fcgi more robust by catching fluke errors and retrying unless its a permanent condition. [Jamis Buck] + +* Added console --profile for profiling an IRB session #1154 [Jeremy Kemper] + +* Changed console_sandbox into console --sandbox #1154 [Jeremy Kemper] + + +*0.12.1* (20th April, 2005) + +* Upgraded to Active Record 1.10.1, Action Pack 1.8.1, Action Mailer 0.9.1, Action Web Service 0.7.1 + + +*0.12.0* (19th April, 2005) + +* Fixed that purge_test_database would use database settings from the development environment when recreating the test database #1122 [rails@cogentdude.com] + +* Added script/benchmarker to easily benchmark one or more statement a number of times from within the environment. Examples: + + # runs the one statement 10 times + script/benchmarker 10 'Person.expensive_method(10)' + + # pits the two statements against each other with 50 runs each + script/benchmarker 50 'Person.expensive_method(10)' 'Person.cheap_method(10)' + +* Added script/profiler to easily profile a single statement from within the environment. Examples: + + script/profiler 'Person.expensive_method(10)' + script/profiler 'Person.expensive_method(10)' 10 # runs the statement 10 times + +* Added Rake target clear_logs that'll truncate all the *.log files in log/ to zero #1079 [Lucas Carlson] + +* Added lazy typing for generate, such that ./script/generate cn == ./script/generate controller and the likes #1051 [k@v2studio.com] + +* Fixed that ownership is brought over in pg_dump during tests for PostgreSQL #1060 [pburleson@gmail.com] + +* Upgraded to Active Record 1.10.0, Action Pack 1.8.0, Action Mailer 0.9.0, Action Web Service 0.7.0, Active Support 1.0.4 + + +*0.11.1* (27th March, 2005) + +* Fixed the dispatch.fcgi use of a logger + +* Upgraded to Active Record 1.9.1, Action Pack 1.7.0, Action Mailer 0.8.1, Action Web Service 0.6.2, Active Support 1.0.3 + + +*0.11.0* (22th March, 2005) + +* Removed SCRIPT_NAME from the WEBrick environment to prevent conflicts with PATH_INFO #896 [Nicholas Seckar] + +* Removed ?$1 from the dispatch.f/cgi redirect line to get rid of 'complete/path/from/request.html' => nil being in the @params now that the ENV["REQUEST_URI"] is used to determine the path #895 [dblack/Nicholas Seckar] + +* Added additional error handling to the FastCGI dispatcher to catch even errors taking down the entire process + +* Improved the generated scaffold code a lot to take advantage of recent Rails developments #882 [Tobias Luetke] + +* Combined the script/environment.rb used for gems and regular files version. If vendor/rails/* has all the frameworks, then files version is used, otherwise gems #878 [Nicholas Seckar] + +* Changed .htaccess to allow dispatch.* to be called from a sub-directory as part of the push with Action Pack to make Rails work on non-vhost setups #826 [Nicholas Seckar/Tobias Luetke] + +* Added script/runner which can be used to run code inside the environment by eval'ing the first parameter. Examples: + + ./script/runner 'ReminderService.deliver' + ./script/runner 'Mailer.receive(STDIN.read)' + + This makes it easier to do CRON and postfix scripts without actually making a script just to trigger 1 line of code. + +* Fixed webrick_server cookie handling to allow multiple cookes to be set at once #800, #813 [dave@cherryville.org] + +* Fixed the Rakefile's interaction with postgresql to: + + 1. Use PGPASSWORD and PGHOST in the environment to fix prompting for + passwords when connecting to a remote db and local socket connections. + 2. Add a '-x' flag to pg_dump which stops it dumping privileges #807 [rasputnik] + 3. Quote the user name and use template0 when dumping so the functions doesn't get dumped too #855 [pburleson] + 4. Use the port if available #875 [madrobby] + +* Upgraded to Active Record 1.9.0, Action Pack 1.6.0, Action Mailer 0.8.0, Action Web Service 0.6.1, Active Support 1.0.2 + + +*0.10.1* (7th March, 2005) + +* Fixed rake stats to ignore editor backup files like model.rb~ #791 [skanthak] + +* Added exception shallowing if the DRb server can't be started (not worth making a fuss about to distract new users) #779 [Tobias Luetke] + +* Added an empty favicon.ico file to the public directory of new applications (so the logs are not spammed by its absence) + +* Fixed that scaffold generator new template should use local variable instead of instance variable #778 [Dan Peterson] + +* Allow unit tests to run on a remote server for PostgreSQL #781 [adamm@galacticasoftware.com] + +* Added web_service generator (run ./script/generate web_service for help) #776 [Leon Bredt] + +* Added app/apis and components to code statistics report #729 [Scott Barron] + +* Fixed WEBrick server to use ABSOLUTE_RAILS_ROOT instead of working_directory #687 [Nicholas Seckar] + +* Fixed rails_generator to be usable without RubyGems #686 [Cristi BALAN] + +* Fixed -h/--help for generate and destroy generators #331 + +* Added begin/rescue around the FCGI dispatcher so no uncaught exceptions can bubble up to kill the process (logs to log/fastcgi.crash.log) + +* Fixed that association#count would produce invalid sql when called sequentialy #659 [kanis@comcard.de] + +* Fixed test/mocks/testing to the correct test/mocks/test #740 + +* Added early failure if the Ruby version isn't 1.8.2 or above #735 + +* Removed the obsolete -i/--index option from the WEBrick servlet #743 + +* Upgraded to Active Record 1.8.0, Action Pack 1.5.1, Action Mailer 0.7.1, Action Web Service 0.6.0, Active Support 1.0.1 + + +*0.10.0* (24th February, 2005) + +* Changed default IP binding for WEBrick from 127.0.0.1 to 0.0.0.0 so that the server is accessible both locally and remotely #696 [Marcel] + +* Fixed that script/server -d was broken so daemon mode couldn't be used #687 [Nicholas Seckar] + +* Upgraded to breakpoint 92 which fixes: + + * overload IRB.parse_opts(), fixes #443 + => breakpoints in tests work even when running them via rake + * untaint handlers, might fix an issue discussed on the Rails ML + * added verbose mode to breakpoint_client + * less noise caused by breakpoint_client by default + * ignored TerminateLineInput exception in signal handler + => quiet exit on Ctrl-C + +* Added support for independent components residing in /components. Example: + + Controller: components/list/items_controller.rb + (holds a List::ItemsController class with uses_component_template_root called) + + Model : components/list/item.rb + (namespace is still shared, so an Item model in app/models will take precedence) + + Views : components/list/items/show.rhtml + + +* Added --sandbox option to script/console that'll roll back all changes made to the database when you quit #672 [Jeremy Kemper] + +* Added 'recent' as a rake target that'll run tests for files that changed in the last 10 minutes #612 [Jeremy Kemper] + +* Changed script/console to default to development environment and drop --no-inspect #650 [Jeremy Kemper] + +* Added that the 'fixture :posts' syntax can be used for has_and_belongs_to_many fixtures where a model doesn't exist #572 [Jeremy Kemper] + +* Added that running test_units and test_functional now performs the clone_structure_to_test as well #566 [rasputnik] + +* Added new generator framework that informs about its doings on generation and enables updating and destruction of generated artifacts. See the new script/destroy and script/update for more details #487 [Jeremy Kemper] + +* Added Action Web Service as a new add-on framework for Action Pack [Leon Bredt] + +* Added Active Support as an independent utility and standard library extension bundle + +* Upgraded to Active Record 1.7.0, Action Pack 1.5.0, Action Mailer 0.7.0 + + +*0.9.5* (January 25th, 2005) + +* Fixed dependency reloading by switching to a remove_const approach where all Active Records, Active Record Observers, and Action Controllers are reloading by undefining their classes. This enables you to remove methods in all three types and see the change reflected immediately and it fixes #539. This also means that only those three types of classes will benefit from the const_missing and reloading approach. If you want other classes (like some in lib/) to reload, you must use require_dependency to do it. + +* Added Florian Gross' latest version of Breakpointer and friends that fixes a variaty of bugs #441 [Florian Gross] + +* Fixed skeleton Rakefile to work with sqlite3 out of the box #521 [rasputnik] + +* Fixed that script/breakpointer didn't get the Ruby path rewritten as the other scripts #523 [brandt@kurowski.net] + +* Fixed handling of syntax errors in models that had already been succesfully required once in the current interpreter + +* Fixed that models that weren't referenced in associations weren't being reloaded in the development mode by reinstating the reload + +* Fixed that generate scaffold would produce bad functional tests + +* Fixed that FCGI can also display SyntaxErrors + +* Upgraded to Active Record 1.6.0, Action Pack 1.4.0 + + +*0.9.4.1* (January 18th, 2005) + +* Added 5-second timeout to WordNet alternatives on creating reserved-word models #501 [Marcel Molina] + +* Fixed binding of caller #496 [Alexey] + +* Upgraded to Active Record 1.5.1, Action Pack 1.3.1, Action Mailer 0.6.1 + + +*0.9.4* (January 17th, 2005) + +* Added that ApplicationController will catch a ControllerNotFound exception if someone attempts to access a url pointing to an unexisting controller [Tobias Luetke] + +* Flipped code-to-test ratio around to be more readable #468 [Scott Baron] + +* Fixed log file permissions to be 666 instead of 777 (so they're not executable) #471 [Lucas Carlson] + +* Fixed that auto reloading would some times not work or would reload the models twice #475 [Tobias Luetke] + +* Added rewrite rules to deal with caching to public/.htaccess + +* Added the option to specify a controller name to "generate scaffold" and made the default controller name the plural form of the model. + +* Added that rake clone_structure_to_test, db_structure_dump, and purge_test_database tasks now pick up the source database to use from + RAILS_ENV instead of just forcing development #424 [Tobias Luetke] + +* Fixed script/console to work with Windows (that requires the use of irb.bat) #418 [octopod] + +* Fixed WEBrick servlet slowdown over time by restricting the load path reloading to mod_ruby + +* Removed Fancy Indexing as a default option on the WEBrick servlet as it made it harder to use various caching schemes + +* Upgraded to Active Record 1.5, Action Pack 1.3, Action Mailer 0.6 + + +*0.9.3* (January 4th, 2005) + +* Added support for SQLite in the auto-dumping/importing of schemas for development -> test #416 + +* Added automated rewriting of the shebang lines on installs through the gem rails command #379 [Manfred Stienstra] + +* Added ActionMailer::Base.deliver_method = :test to the test environment so that mail objects are available in ActionMailer::Base.deliveries + for functional testing. + +* Added protection for creating a model through the generators with a name of an existing class, like Thread or Date. + It'll even offer you a synonym using wordnet.princeton.edu as a look-up. No, I'm not kidding :) [Florian Gross] + +* Fixed dependency management to happen in a unified fashion for Active Record and Action Pack using the new Dependencies module. This means that + the environment options needs to change from: + + Before in development.rb: + ActionController::Base.reload_dependencies = true   + ActiveRecord::Base.reload_associations     = true + + Now in development.rb: + Dependencies.mechanism = :load + + Before in production.rb and test.rb: + ActionController::Base.reload_dependencies = false + ActiveRecord::Base.reload_associations     = false + + Now in production.rb and test.rb: + Dependencies.mechanism = :require + +* Fixed problems with dependency caching and controller hierarchies on Ruby 1.8.2 in development mode #351 + +* Fixed that generated action_mailers doesnt need to require the action_mailer since thats already done in the environment #382 [Lucas Carlson] + +* Upgraded to Action Pack 1.2.0 and Active Record 1.4.0 + + +*0.9.2* + +* Fixed CTRL-C exists from the Breakpointer to be a clean affair without error dumping [Kent Sibilev] + +* Fixed "rake stats" to work with sub-directories in models and controllers and to report the code to test ration [Scott Baron] + +* Added that Active Record associations are now reloaded instead of cleared to work with the new const_missing hook in Active Record. + +* Added graceful handling of an inaccessible log file by redirecting output to STDERR with a warning #330 [rainmkr] + +* Added support for a -h/--help parameter in the generator #331 [Ulysses] + +* Fixed that File.expand_path in config/environment.rb would fail when dealing with symlinked public directories [mjobin] + +* Upgraded to Action Pack 1.1.0 and Active Record 1.3.0 + + +*0.9.1* + +* Upgraded to Action Pack 1.0.1 for important bug fix + +* Updated gem dependencies + + +*0.9.0* + +* Renamed public/dispatch.servlet to script/server -- it wasn't really dispatching anyway as its delegating calls to public/dispatch.rb + +* Renamed AbstractApplicationController and abstract_application.rb to ApplicationController and application.rb, so that it will be possible + for the framework to automatically pick up on app/views/layouts/application.rhtml and app/helpers/application.rb + +* Added script/console that makes it even easier to start an IRB session for interacting with the domain model. Run with no-args to + see help. + +* Added breakpoint support through the script/breakpointer client. This means that you can break out of execution at any point in + the code, investigate and change the model, AND then resume execution! Example: + + class WeblogController < ActionController::Base + def index + @posts = Post.find_all + breakpoint "Breaking out from the list" + end + end + + So the controller will accept the action, run the first line, then present you with a IRB prompt in the breakpointer window. + Here you can do things like: + + Executing breakpoint "Breaking out from the list" at .../webrick_server.rb:16 in 'breakpoint' + + >> @posts.inspect + => "[#nil, \"body\"=>nil, \"id\"=>\"1\"}>, + #\"Rails you know!\", \"body\"=>\"Only ten..\", \"id\"=>\"2\"}>]" + >> @posts.first.title = "hello from a breakpoint" + => "hello from a breakpoint" + + ...and even better is that you can examine how your runtime objects actually work: + + >> f = @posts.first + => #nil, "body"=>nil, "id"=>"1"}> + >> f. + Display all 152 possibilities? (y or n) + + Finally, when you're ready to resume execution, you press CTRL-D + +* Changed environments to be configurable through an environment variable. By default, the environment is "development", but you + can change that and set your own by configuring the Apache vhost with a string like (mod_env must be available on the server): + + SetEnv RAILS_ENV production + + ...if you're using WEBrick, you can pick the environment to use with the command-line parameters -e/--environment, like this: + + ruby public/dispatcher.servlet -e production + +* Added a new default environment called "development", which leaves the production environment to be tuned exclusively for that. + +* Added a start_server in the root of the Rails application to make it even easier to get started + +* Fixed public/.htaccess to use RewriteBase and share the same rewrite rules for all the dispatch methods + +* Fixed webrick_server to handle requests in a serialized manner (the Rails reloading infrastructure is not thread-safe) + +* Added support for controllers in directories. So you can have: + + app/controllers/account_controller.rb # URL: /account/ + app/controllers/admin/account_controller.rb # URL: /admin/account/ + + NOTE: You need to update your public/.htaccess with the new rules to pick it up + +* Added reloading for associations and dependencies under cached environments like FastCGI and mod_ruby. This makes it possible to use + those environments for development. This is turned on by default, but can be turned off with + ActiveRecord::Base.reload_associations = false and ActionController::Base.reload_dependencies = false in production environments. + +* Added support for sub-directories in app/models. So now you can have something like Basecamp with: + + app/models/accounting + app/models/project + app/models/participants + app/models/settings + + It's poor man's namespacing, but only for file-system organization. You still require files just like before. + Nothing changes inside the files themselves. + + +* Fixed a few references in the tests generated by new_mailer [Jeremy Kemper] + +* Added support for mocks in testing with test/mocks + +* Cleaned up the environments a bit and added global constant RAILS_ROOT + + +*0.8.5* (9) + +* Made dev-util available to all tests, so you can insert breakpoints in any test case to get an IRB prompt at that point [Jeremy Kemper]: + + def test_complex_stuff + @david.projects << @new_project + breakpoint "Let's have a closer look at @david" + end + + You need to install dev-utils yourself for this to work ("gem install dev-util"). + +* Added shared generator behavior so future upgrades should be possible without manually copying over files [Jeremy Kemper] + +* Added the new helper style to both controller and helper templates [Jeremy Kemper] + +* Added new_crud generator for creating a model and controller at the same time with explicit scaffolding [Jeremy Kemper] + +* Added configuration of Test::Unit::TestCase.fixture_path to test_helper to concide with the new AR fixtures style + +* Fixed that new_model was generating singular table/fixture names + +* Upgraded to Action Mailer 0.4.0 + +* Upgraded to Action Pack 0.9.5 + +* Upgraded to Active Record 1.1.0 + + +*0.8.0 (15)* + +* Removed custom_table_name option for new_model now that the Inflector is as powerful as it is + +* Changed the default rake action to just do testing and separate API generation and coding statistics into a "doc" task. + +* Fixed WEBrick dispatcher to handle missing slashes in the URLs gracefully [alexey] + +* Added user option for all postgresql tool calls in the rakefile [elvstone] + +* Fixed problem with running "ruby public/dispatch.servlet" instead of "cd public; ruby dispatch.servlet" [alexey] + +* Fixed WEBrick server so that it no longer hardcodes the ruby interpreter used to "ruby" but will get the one used based + on the Ruby runtime configuration. [Marcel Molina Jr.] + +* Fixed Dispatcher so it'll route requests to magic_beans to MagicBeansController/magic_beans_controller.rb [Caio Chassot] + +* "new_controller MagicBeans" and "new_model SubscriptionPayments" will now both behave properly as they use the new Inflector. + +* Fixed problem with MySQL foreign key constraint checks in Rake :clone_production_structure_to_test target [Andreas Schwarz] + +* Changed WEBrick server to by default be auto-reloading, which is slower but makes source changes instant. + Class compilation cache can be turned on with "-c" or "--cache-classes". + +* Added "-b/--binding" option to WEBrick dispatcher to bind the server to a specific IP address (default: 127.0.0.1) [Kevin Temp] + +* dispatch.fcgi now DOESN'T set FCGI_PURE_RUBY as it was slowing things down for now reason [Andreas Schwarz] + +* Added new_mailer generator to work with Action Mailer + +* Included new framework: Action Mailer 0.3 + +* Upgraded to Action Pack 0.9.0 + +* Upgraded to Active Record 1.0.0 + + +*0.7.0* + +* Added an optional second argument to the new_model script that allows the programmer to specify the table name, + which will used to generate a custom table_name method in the model and will also be used in the creation of fixtures. + [Kevin Radloff] + +* script/new_model now turns AccountHolder into account_holder instead of accountholder [Kevin Radloff] + +* Fixed the faulty handleing of static files with WEBrick [Andreas Schwarz] + +* Unified function_test_helper and unit_test_helper into test_helper + +* Fixed bug with the automated production => test database dropping on PostgreSQL [dhawkins] + +* create_fixtures in both the functional and unit test helper now turns off the log during fixture generation + and can generate more than one fixture at a time. Which makes it possible for assignments like: + + @people, @projects, @project_access, @companies, @accounts = + create_fixtures "people", "projects", "project_access", "companies", "accounts" + +* Upgraded to Action Pack 0.8.5 (locally-scoped variables, partials, advanced send_file) + +* Upgraded to Active Record 0.9.5 (better table_name guessing, cloning, find_all_in_collection) + + +*0.6.5* + +* No longer specifies a template for rdoc, so it'll use whatever is default (you can change it in the rakefile) + +* The new_model generator will now use the same rules for plural wordings as Active Record + (so Category will give categories, not categorys) [Kevin Radloff] + +* dispatch.fcgi now sets FCGI_PURE_RUBY to true to ensure that it's the Ruby version that's loaded [danp] + +* Made the GEM work with Windows + +* Fixed bug where mod_ruby would "forget" the load paths added when switching between controllers + +* PostgreSQL are now supported for the automated production => test database dropping [Kevin Radloff] + +* Errors thrown by the dispatcher are now properly handled in FCGI. + +* Upgraded to Action Pack 0.8.0 (lots and lots and lots of fixes) + +* Upgraded to Active Record 0.9.4 (a bunch of fixes) + + +*0.6.0* + +* Added AbstractionApplicationController as a superclass for all controllers generated. This class can be used + to carry filters and methods that are to be shared by all. It has an accompanying ApplicationHelper that all + controllers will also automatically have available. + +* Added environments that can be included from any script to get the full Active Record and Action Controller + context running. This can be used by maintenance scripts or to interact with the model through IRB. Example: + + require 'config/environments/production' + + for account in Account.find_all + account.recalculate_interests + end + + A short migration script for an account model that had it's interest calculation strategy changed. + +* Accessing the index of a controller with "/weblog" will now redirect to "/weblog/" (only on Apache, not WEBrick) + +* Simplified the default Apache config so even remote requests are served off CGI as a default. + You'll now have to do something specific to activate mod_ruby and FCGI (like using the force urls). + This should make it easier for new comers that start on an external server. + +* Added more of the necessary Apache options to .htaccess to make it easier to setup + +* Upgraded to Action Pack 0.7.9 (lots of fixes) + +* Upgraded to Active Record 0.9.3 (lots of fixes) + + +*0.5.7* + +* Fixed bug in the WEBrick dispatcher that prevented it from getting parameters from the URL + (through GET requests or otherwise) + +* Added lib in root as a place to store app specific libraries + +* Added lib and vendor to load_path, so anything store within can be loaded directly. + Hence lib/redcloth.rb can be loaded with require "redcloth" + +* Upgraded to Action Pack 0.7.8 (lots of fixes) + +* Upgraded to Active Record 0.9.2 (minor upgrade) + + +*0.5.6* + +* Upgraded to Action Pack 0.7.7 (multipart form fix) + +* Updated the generated template stubs to valid XHTML files + +* Ensure that controllers generated are capitalized, so "new_controller TodoLists" + gives the same as "new_controller Todolists" and "new_controller todolists". + + +*0.5.5* + +* Works on Windows out of the box! (Dropped symlinks) + +* Added webrick dispatcher: Try "ruby public/dispatch.servlet --help" [Florian Gross] + +* Report errors about initialization to browser (instead of attempting to use uninitialized logger) + +* Upgraded to Action Pack 0.7.6 + +* Upgraded to Active Record 0.9.1 + +* Added distinct 500.html instead of reusing 404.html + +* Added MIT license + + +*0.5.0* + +* First public release diff --git a/MIT-LICENSE b/MIT-LICENSE new file mode 100644 index 0000000..67625d0 --- /dev/null +++ b/MIT-LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2005, 2006 VibrantPlanet Ltd. +Copyright (c) 2005, 2006 Luben Manolov +Copyright (c) 2005, 2006 Nick Penkov + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/README b/README new file mode 100644 index 0000000..8e41e2b --- /dev/null +++ b/README @@ -0,0 +1,26 @@ + +Installation Guide +Requirements + + * Ruby 1.8.2 or higher + * Rails 0.14.2 + * MySQL or PostgreSQL with Ruby bindings + * Ruby-GetText? 0.8.0 or higher (http://ponx.s5.xrea.com/hiki/ruby-gettext.html) + +Installation + + 1. Checkout the source code + 2. Create database called mailr. Create the database schema using db/schema.mysql.sql or db/schema.pgsql.sql + 3. Change the config/database.yml to reflect your newly created database configuration + 4. If you need to override some of the default constants used in the application take a look at config/default_site.rb. Then create config/site.rb that contains only the keys which you want to override. Example content of config/site.rb is: + + module CDF + + LOCALCONFIG = { + :imap_server => 'your.imap.server' + } + end + + + 5. Start your web server and login in the application with your IMAP user and password. + diff --git a/README_LOCALIZE b/README_LOCALIZE new file mode 100644 index 0000000..9a75d75 --- /dev/null +++ b/README_LOCALIZE @@ -0,0 +1,27 @@ +Here we will describe how to make translations for Mailr + +1. Supose we will translate Mailr in French +2. In locale directory create subirectory fr_FR +3. In newly created directory fr_FR create subdirectory LC_MESSAGES + +result: + | + |_ locale + | + |- bg_BG + | + |- fr_FR + | + |- LC_MESSAGES +4. Run script for extracting strings from rails application to po files + +script/localize + +5. Run PoEdit (http://poedit.sourceforge.net/) + +6. Make translations to your newlly created file (locale/fr_FR/LC_MESSAGES/messages.po) + +7. Compile po file to mo file using PoEdit + + +NOTE: Switching of locales is made in ApplicationController localize filter - by default mailr looks for HTTP_ACCEPT_LANGUAGE of remote browser and switches translation diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..cffd19f --- /dev/null +++ b/Rakefile @@ -0,0 +1,10 @@ +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/switchtower.rake, and they will automatically be available to Rake. + +require(File.join(File.dirname(__FILE__), 'config', 'boot')) + +require 'rake' +require 'rake/testtask' +require 'rake/rdoctask' + +require 'tasks/rails' \ No newline at end of file diff --git a/app/controllers/application.rb b/app/controllers/application.rb new file mode 100644 index 0000000..f628e5b --- /dev/null +++ b/app/controllers/application.rb @@ -0,0 +1,170 @@ +# The filters added to this controller will be run for all controllers in the application. +# Likewise will all the methods added be available for all controllers. +class ApplicationController < ActionController::Base + before_filter :localize + before_filter :user_login_filter + before_filter :add_scripts + + model :customer + + protected + def secure_user?() true end + def secure_cust?() false end + def additional_scripts() "" end + def onload_function() "" end + + private + def add_scripts + @additional_scripts = additional_scripts() + @onload_function = onload_function() + end + + def user_login_filter + if (secure_user? or secure_cust? )and logged_user.nil? + @session["return_to"] = @request.request_uri + redirect_to :controller=>"/login", :action => "index" + return false + end + end + + alias login_required user_login_filter + + def logged_user # returns customer id + @session['user'] + end + + def logged_customer + @session['user'] + end + + def localize + # We will use instance vars for the locale so we can make use of them in + # the templates. + @charset = 'utf-8' + @headers['Content-Type'] = "text/html; charset=#{@charset}" + # Here is a very simplified approach to extract the prefered language + # from the request. If all fails, just use 'en_EN' as the default. + temp = if @request.env['HTTP_ACCEPT_LANGUAGE'].nil? + [] + else + @request.env['HTTP_ACCEPT_LANGUAGE'].split(',').first.split('-') rescue [] + end + language = temp.slice(0) + dialect = temp.slice(1) + @language = language.nil? ? 'en' : language.downcase # default is en + # If there is no dialect use the language code ('en' becomes 'en_EN'). + @dialect = dialect.nil? ? @language.upcase : dialect + # The complete locale string consists of + # language_DIALECT (en_EN, en_GB, de_DE, ...) + @locale = "#{@language}_#{@dialect.upcase}" + @htmllang = @language == @dialect ? @language : "#{@language}-#{@dialect}" + # Finally, bind the textdomain to the locale. From now on every used + # _('String') will get translated into the right language. (Provided + # that we have a corresponding mo file in the right place). + bindtextdomain('messages', "#{RAILS_ROOT}/locale", @locale, @charset) + end + + public + + def include_tinymce(mode="textareas",elements="") + tinymce='' + tinymce << ' + + ' + tinymce + end + + helper_method :include_tinymce + + def include_simple_tinymce(mode="textareas",elements="") + tinymce = '' + tinymce << ' + ' + tinymce + end + + helper_method :include_simple_tinymce + +end diff --git a/app/controllers/login_controller.rb b/app/controllers/login_controller.rb new file mode 100644 index 0000000..48bcc50 --- /dev/null +++ b/app/controllers/login_controller.rb @@ -0,0 +1,67 @@ +require 'ezcrypto' +class LoginController < ApplicationController + + model :customer + + def index + if not(logged_user.nil?) + redirect_to :controller =>"webmail", :action=>"index" + else + @login_user = Customer.new + end + end + + def authenticate + if user = auth(@params['login_user']["email"], @params['login_user']["password"]) + @session["user"] = user.id + if CDF::CONFIG[:crypt_session_pass] + @session["wmp"] = EzCrypto::Key.encrypt_with_password(CDF::CONFIG[:encryption_password], CDF::CONFIG[:encryption_salt], @params['login_user']["password"]) + else + # dont use crypt + @session["wmp"] = @params['login_user']["password"] + end + if @session["return_to"] + redirect_to_path(@session["return_to"]) + @session["return_to"] = nil + else + redirect_to :action=>"index" + end + else + @login_user = Customer.new + flash["error"] = _('Wrong email or password specified.') + redirect_to :action => "index" + end + end + + def logout + reset_session + flash["status"] = _('User successfully logged out') + redirect_to :action => "index" + end + + protected + + def need_subdomain?() true end + def secure_user?() false end + + private + + def auth(email, password) + mailbox = IMAPMailbox.new + begin + mailbox.connect(email, password) + rescue + return nil + end + mailbox.disconnect + mailbox = nil + if user = Customer.find_by_email(email) + return user + else + # create record in database + user = Customer.create("email"=>email) + MailPref.create('customer_id' => user.id) + return user + end + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb new file mode 100644 index 0000000..fac9c0d --- /dev/null +++ b/app/helpers/application_helper.rb @@ -0,0 +1,137 @@ +# The methods added to this helper will be available to all templates in the application. +module ApplicationHelper + + protected + + def format_datetime(datetime) + datetime.strftime "%d.%m.%Y %H:%M" + end + + def errors_base(form_name) + errors = instance_variable_get("@#{form_name}").errors.on_base() + errors_out = "" + if errors + errors = [errors] unless errors.is_a? Array + errors.each do |e| + errors_out << "#{e}" + end + end + errors_out + end + + # Useful abstraction for form input fields - combines an input field with error message (if any) + # and writes an appropriate style (for errors) + # Usage: + # form_input :text_field, 'postform', 'subject' + # form_input :text_area, 'postform', 'text', 'Please enter text:', 'cols' => 80 + # form_input :hidden_field, 'postform', 'topic_id' + def form_input(helper_method, form_name, field_name, prompt = field_name.capitalize, options = {}) + case helper_method.to_s + when 'hidden_field' + self.hidden_field(form_name, field_name) + when /^.*button$/ + <<-EOL + + #{self.send(helper_method, form_name, prompt, options)} + + EOL + else + field = ( + if :select == helper_method + self.send(helper_method, form_name, field_name, options.delete('values'), options) + elsif :collection_select == helper_method + self.send(helper_method, form_name, field_name, options.delete('collection'), options.delete('value_method'), options.delete('text_method'), options) + else + self.send(helper_method, form_name, field_name, options) + end) + errors = instance_variable_get("@#{form_name}").errors[field_name] unless instance_variable_get("@#{form_name}").nil? + errors = Array.new if errors.nil? + errors_out = "" + if errors + errors = [errors] unless errors.is_a? Array + errors.each do |e| + errors_out << "#{e}" + end + end + if options['class'] == 'two_columns' + <<-EOL + + + #{field}#{errors_out} + + EOL + else + <<-EOL + #{prompt}: + #{field}#{errors_out} + EOL + end + end + end + + # Helper method that has the same signature as real input field helpers, but simply displays + # the value of a given field enclosed within

tags. + # Usage: + # <%= form_input :read_only_field, 'new_user', 'name', _('user_name')) %> + def read_only_field(form_name, field_name, html_options) + "#{instance_variable_get('@' + form_name)[field_name]}" + end + + def submit_button(form_name, prompt, html_options) + %{} + end + + # Converts a hash to XML attributes string. E.g.: + # to_attributes('a' => 'aaa', 'b' => 1) + # => 'a="aaa" b="1" ' + def attributes(hash) + hash.keys.inject("") { |attrs, key| attrs + %{#{key}="#{hash[key]}" } } + end + + def initListClass + @itClass = 1 + end + + def popListClass + ret = getListClass + @itClass = @itClass + 1 + return ret + end + + def getListClass + return "even" if @itClass%2 == 0 + return "odd" if @itClass%2 == 1 + end + + def get_meta_info + '' + '' + '' + '' + '' + end + + def user + @user = Customer.find(@session["user"]) if @user.nil? + @user + end + + def link_main + link_to(_('Contacts'), :controller => '/contacts/contact', :action => 'list') + end + + def alternator + if @alternator.nil? + @alternator = 1 + end + + @alternator = -@alternator + + if @alternator == -1 + return "even" + else + return "odd" + end + end + +end diff --git a/app/helpers/pagination_helper.rb b/app/helpers/pagination_helper.rb new file mode 100644 index 0000000..6314096 --- /dev/null +++ b/app/helpers/pagination_helper.rb @@ -0,0 +1,487 @@ +# == Pagination Helper +# +# === Action Pack pagination for Active Record collections +# +# Sam Stephenson +# +# Pagination Helper aids in the process of paging large collections of Active +# Record objects. It offers macro-style automatic fetching of your model for +# multiple views, or explicit fetching for single actions. And if the magic +# isn't flexible enough for your needs, you can create your own paginators +# with a minimal amount of code. +# +# Unlike most helpers, Pagination Helper is available to all of Action Pack: +# it helps you query your models with Action Controller and render links in +# Action View. +# +# ---- +# +# === Controller examples +# +# Pagination Helper can handle as much or as little as you wish. In the +# controller, have it automatically query your model for pagination; or, +# if you prefer, create Paginator objects yourself. +# +# ==== Automatic pagination for every action in a controller +# +# class PersonController < ApplicationController +# helper :pagination +# model :person +# +# paginate :people, :order_by => 'last_name, first_name', +# :per_page => 20 +# +# # ... +# end +# +# Each action in this controller now has access to a @people instance +# variable, which is an ordered collection of model objects for the current +# page (at most 20, sorted by last name and first name), and a +# @person_pages Paginator instance. The current page is determined by +# the @params['page'] variable. +# +# ==== Pagination for a single action +# +# def list +# @person_pages, @people = +# paginate :people, :order_by => 'last_name, first_name' +# end +# +# Like the previous example, but explicitly creates @person_pages and +# @people for a single action, and uses the default of 10 items per +# page. +# +# ==== Custom/"classic" pagination +# +# def list +# @person_pages = Paginator.new self, Person.count, 10, @params['page'] +# @people = Person.find_all nil, 'last_name, first_name', +# @person_pages.current.to_sql +# end +# +# Explicitly creates the paginator from the previous example and uses +# Paginator#to_sql to retrieve @people from the model. +# +# === View examples +# +# Paginator Helper includes various methods to help you display pagination +# links in your views. (For information on displaying the paginated +# collections you retrieve in the controller, see the documentation for +# ActionView::Partials#render_collection_of_partials.) +# +# ==== Using Paginator#basic_html +# +# Use the +basic_html+ method to get a simple list of pages (always including +# the first and last page) with a window around the current page. In your +# view, using one of the controller examples above, +# +# <%= @person_pages.basic_html(self) %> +# +# will render a list of links. For a list of parameters, see the documentation +# for Page#basic_html. +# +# ==== Using a paginator partial +# +# If you need more advanced control over pagination links and need to paginate +# multiple actions and controllers, consider using a shared paginator partial. +# For instance, _why suggests this partial, which you might place in +# app/views/partial/_paginator.rhtml: +# +#
+# Displaying <%= paginator.current.first_item %> +# - <%= paginator.current.last_item %> +# of <%= paginator.item_count %>     +# +# <%= link_to(h('< Previous'), paginator.current.previous.to_link) + +# " | " if paginator.current.previous %> +# <%= paginator.basic_html(self, 4) %> +# <%= " | " + link_to(h('Next >'), paginator.current.next.to_link) if +# paginator.current.next %> +#
+# +# Then in your views, simply call +# +# <%= render_partial "partial/paginator", @person_pages %> +# +# wherever you want your pagination links to appear. +# +# ---- +# +# ==== Thanks +# +# Thanks to the following people for their contributions to Pagination Helper: +# * Marcel Molina Jr (noradio), who provided the idea for and original +# implementation of Paginator::Window, as well as endless mental support. +# * evl, who pointed out that Page#link_to should take and merge in a hash of +# additional parameters. +# * why the lucky stiff, who wrote a lovely article on the original Pagination +# Helper alongside the first implementation of Paginator#base_html, created +# Page#first_item and Page#last_item, and who provided inspiration for +# revising Pagination Helper to make it more "Rails-ish." +# * xal, who saw the limitations of having only the macro-style paginate +# method and suggested the single-action version, and who also suggested the +# automatic inclusion into ActionController::Base. +# * jbd for feedback and debugging help. +# * ##rubyonrails on Freenode and the Rails mailing list. +# +module PaginationHelper + # A hash holding options for controllers using macro-style pagination + OPTIONS = Hash.new + + # The default options for pagination + DEFAULT_OPTIONS = { + :class_name => nil, + :per_page => 10, + :parameter => 'page', + :conditions => nil, + :order_by => nil + } + + def self.included(base) #:nodoc: + super + base.extend(ClassMethods) + end + + def self.validate_options!(collection_id, options, in_action) #:nodoc: + options.merge!(DEFAULT_OPTIONS) {|key, old, new| old} + + valid_options = [:class_name, :per_page, + :parameter, :conditions, :order_by] + valid_options << :actions unless in_action + + unknown_option_keys = options.keys - valid_options + raise ActionController::ActionControllerError, + "Unknown options: #{unknown_option_keys.join(', ')}" unless + unknown_option_keys.empty? + + options[:singular_name] = Inflector.singularize(collection_id.to_s) + options[:class_name] ||= Inflector.camelize(options[:singular_name]) + end + + # Returns a paginator and a collection of Active Record model instances for + # the paginator's current page. This is designed to be used in a single + # action; to automatically paginate multiple actions, consider + # ClassMethods#paginate. + # + # +options+ are: + # :class_name:: the class name to use, if it can't be inferred by + # singularizing the collection name. + # :per_page:: the maximum number of items to include in a + # single page. Defaults to 10. + # :parameter:: the CGI parameter from which the current page is + # determined. Defaults to 'page'; i.e., the current + # page is specified by @params['page']. + # :conditions:: optional conditions passed to Model.find_all. + # :order_by:: optional order parameter passed to Model.find_all + # and Model.count. + def paginate(collection_id, options={}) + PaginationHelper.validate_options!(collection_id, options, true) + paginator_and_collection_for(collection_id, options) + end + + # These methods become class methods on any controller which includes + # PaginationHelper. + module ClassMethods + # Creates a +before_filter+ which automatically paginates an Active Record + # model for all actions in a controller (or certain actions if specified + # with the :actions option). + # + # +options+ are the same as PaginationHelper#paginate, with the addition + # of: + # :actions:: an array of actions for which the pagination is + # active. Defaults to +nil+ (i.e., every action). + def paginate(collection_id, options={}) + PaginationHelper.validate_options!(collection_id, options, false) + module_eval do + before_filter :create_paginators_and_retrieve_collections + OPTIONS[self] ||= Hash.new + OPTIONS[self][collection_id] = options + end + end + end + + def create_paginators_and_retrieve_collections #:nodoc: + PaginationHelper::OPTIONS[self.class].each do |collection_id, options| + next unless options[:actions].include? action_name if options[:actions] + + paginator, collection = + paginator_and_collection_for(collection_id, options) + + paginator_name = "@#{options[:singular_name]}_pages" + self.instance_variable_set(paginator_name, paginator) + + collection_name = "@#{collection_id.to_s}" + self.instance_variable_set(collection_name, collection) + end + end + + # Returns the total number of items in the collection to be paginated for + # the +model+ and given +conditions+. Override this method to implement a + # custom counter. + def count_collection_for_pagination(model, conditions) + model.count(conditions) + end + + # Returns a collection of items for the given +model+ and +conditions+, + # ordered by +order_by+, for the current page in the given +paginator+. + # Override this method to implement a custom finder. + def find_collection_for_pagination(model, conditions, order_by, paginator) + model.find_all(conditions, order_by, paginator.current.to_sql) + end + + protected :create_paginators_and_retrieve_collections, + :count_collection_for_pagination, :find_collection_for_pagination + + def paginator_and_collection_for(collection_id, options) #:nodoc: + klass = eval options[:class_name] + page = @params[options[:parameter]] + count = count_collection_for_pagination(klass, options[:conditions]) + + paginator = Paginator.new(self, count, + options[:per_page], page, options[:parameter]) + + collection = find_collection_for_pagination(klass, + options[:conditions], options[:order_by], paginator) + + return paginator, collection + end + + private :paginator_and_collection_for + + # A class representing a paginator for an Active Record collection. + class Paginator + include Enumerable + + # Creates a new Paginator on the given +controller+ for a set of items of + # size +item_count+ and having +items_per_page+ items per page. Raises + # ArgumentError if items_per_page is out of bounds (i.e., less than or + # equal to zero). The page CGI parameter for links defaults to "page" and + # can be overridden with +page_parameter+. + def initialize(controller, item_count, items_per_page, current_page=1, + page_parameter='page') + raise ArgumentError, 'must have at least one item per page' if + items_per_page <= 0 + + @controller = controller + @item_count = item_count || 0 + @items_per_page = items_per_page + @page_parameter = page_parameter + + self.current_page = current_page + end + attr_reader :controller, :item_count, :items_per_page, :page_parameter + + # Sets the current page number of this paginator. If +page+ is a Page + # object, its +number+ attribute is used as the value; if the page does + # not belong to this Paginator, an ArgumentError is raised. + def current_page=(page) + if page.is_a? Page + raise ArgumentError, 'Page/Paginator mismatch' unless + page.paginator == self + end + page = page.to_i + @current_page = has_page_number?(page) ? page : 1 + end + + # Returns a Page object representing this paginator's current page. + def current_page + self[@current_page] + end + alias current :current_page + + # Returns a new Page representing the first page in this paginator. + def first_page + self[1] + end + alias first :first_page + + # Returns a new Page representing the last page in this paginator. + def last_page + self[page_count] + end + alias last :last_page + + # Returns the number of pages in this paginator. + def page_count + return 1 if @item_count.zero? + (@item_count / @items_per_page.to_f).ceil + end + alias length :page_count + + # Returns true if this paginator contains the page of index +number+. + def has_page_number?(number) + return false unless number.is_a? Fixnum + number >= 1 and number <= page_count + end + + # Returns a new Page representing the page with the given index +number+. + def [](number) + Page.new(self, number) + end + + # Successively yields all the paginator's pages to the given block. + def each(&block) + page_count.times do |n| + yield self[n+1] + end + end + + # Creates a basic HTML link bar for the given +view+. The first and last + # pages of the paginator are always shown, along with +window_size+ pages + # around the current page. By default, the current page is displayed, but + # not linked; to change this behavior, pass true to the + # +link_to_current_page+ argument. Specify additional link_to parameters + # with +params+. + def basic_html(view, window_size=2, link_to_current_page=false, params={}) + window_pages = current.window(window_size).pages + return if window_pages.length <= 1 unless link_to_current_page + + html = '' + unless window_pages[0].first? + html << view.link_to(first.number, first.to_link(params)) + html << ' ... ' if window_pages[0].number - first.number > 1 + html << ' ' + end + + window_pages.each do |page| + if current == page and not link_to_current_page + html << page.number.to_s + else + html << view.link_to(page.number, page.to_link(params)) + end + html << ' ' + end + + unless window_pages.last.last? + html << ' ... ' if last.number - window_pages[-1].number > 1 + html << view.link_to(last.number, last.to_link(params)) + end + + html + end + + # A class representing a single page in a paginator. + class Page + include Comparable + + # Creates a new Page for the given +paginator+ with the index +number+. + # If +number+ is not in the range of valid page numbers or is not a + # number at all, it defaults to 1. + def initialize(paginator, number) + @paginator = paginator + @number = number.to_i + @number = 1 unless @paginator.has_page_number? @number + end + attr_reader :paginator, :number + alias to_i :number + + # Compares two Page objects and returns true when they represent the + # same page (i.e., their paginators are the same and they have the same + # page number). + def ==(page) + @paginator == page.paginator and + @number == page.number + end + + # Compares two Page objects and returns -1 if the left-hand page comes + # before the right-hand page, 0 if the pages are equal, and 1 if the + # left-hand page comes after the right-hand page. Raises ArgumentError + # if the pages do not belong to the same Paginator object. + def <=>(page) + raise ArgumentError unless @paginator == page.paginator + @number <=> page.number + end + + # Returns the item offset for the first item in this page. + def offset + @paginator.items_per_page * (@number - 1) + end + + # Returns the number of the first item displayed. + def first_item + offset + 1 + end + + # Returns the number of the last item displayed. + def last_item + [@paginator.items_per_page * @number, @paginator.item_count].min + end + + # Returns true if this page is the first page in the paginator. + def first? + self == @paginator.first + end + + # Returns true if this page is the last page in the paginator. + def last? + self == @paginator.last + end + + # Returns a new Page object representing the page just before this page, + # or nil if this is the first page. + def previous + if first? then nil else Page.new(@paginator, @number - 1) end + end + + # Returns a new Page object representing the page just after this page, + # or nil if this is the last page. + def next + if last? then nil else Page.new(@paginator, @number + 1) end + end + + # Returns a new Window object for this page with the specified + # +padding+. + def window(padding=2) + Window.new(self, padding) + end + + # Returns a hash appropriate for using with link_to or url_for. Takes an + # optional +params+ hash for specifying additional link parameters. + def to_link(params={}) + {:params => {@paginator.page_parameter => @number.to_s}.merge(params)} + end + + # Returns the SQL "LIMIT ... OFFSET" clause for this page. + def to_sql + ['? OFFSET ?', @paginator.items_per_page, offset] + end + end + + # A class for representing ranges around a given page. + class Window + # Creates a new Window object for the given +page+ with the specified + # +padding+. + def initialize(page, padding=2) + @paginator = page.paginator + @page = page + self.padding = padding + end + attr_reader :paginator, :page + + # Sets the window's padding (the number of pages on either side of the + # window page). + def padding=(padding) + @padding = padding < 0 ? 0 : padding + # Find the beginning and end pages of the window + @first = @paginator.has_page_number?(@page.number - @padding) ? + @paginator[@page.number - @padding] : @paginator.first + @last = @paginator.has_page_number?(@page.number + @padding) ? + @paginator[@page.number + @padding] : @paginator.last + end + attr_reader :padding, :first, :last + + # Returns an array of Page objects in the current window. + def pages + (@first.number..@last.number).to_a.map {|n| @paginator[n]} + end + alias to_a :pages + end + end +end + +module ActionController #:nodoc: + class Base #:nodoc: + # Automatically include PaginationHelper. + include PaginationHelper + end +end diff --git a/app/views/layouts/chooser.rhtml b/app/views/layouts/chooser.rhtml new file mode 100644 index 0000000..ffe7b25 --- /dev/null +++ b/app/views/layouts/chooser.rhtml @@ -0,0 +1,18 @@ + + + +<%=@title%> + + + + + +<%=@additional_scripts%> + + +<%= @content_for_layout %> + + + + diff --git a/app/views/layouts/public.rhtml b/app/views/layouts/public.rhtml new file mode 100644 index 0000000..a7bf860 --- /dev/null +++ b/app/views/layouts/public.rhtml @@ -0,0 +1,25 @@ + + + + <%=_('Mailr')%> + + + + + + + <%=(@content_for_scripts ? @content_for_scripts : @additional_scripts )%> + + +
+
+ +
<%= @content_for_layout %>
+
+
+
+ + diff --git a/app/views/login/index.rhtml b/app/views/login/index.rhtml new file mode 100644 index 0000000..f4ccce2 --- /dev/null +++ b/app/views/login/index.rhtml @@ -0,0 +1,41 @@ + + + + Mailr » Please Log In + + + + +
> +

Mailr

+ <% if @flash['error'] %> +
<%= @flash['error'] %>
+ <% elsif @flash['status'] %> +
<%= @flash['status'] %>
+ <% end %> +
+ + + + + + + + + + + + +
<%= text_field "login_user", "email" %>
<%= password_field "login_user", "password" %>
+ +
+
+ + + + +
+ + diff --git a/components/contacts/contact.rb b/components/contacts/contact.rb new file mode 100644 index 0000000..768c7e1 --- /dev/null +++ b/components/contacts/contact.rb @@ -0,0 +1,68 @@ +require 'cdfutils' +require_association 'contact_group' + +class Contact < ActiveRecord::Base + + has_and_belongs_to_many :groups, :class_name => "ContactGroup", :join_table => "contact_contact_groups", :association_foreign_key => "contact_group_id", :foreign_key => "contact_id" + + # Finder methods follow + def Contact.find_by_user(user_id) + find(:all, :conditions => ["customer_id = ?", user_id], :order => "fname asc", :limit => 10) + end + + def Contact.find_by_user_email(user_id, email) + find(:first, :conditions => ["customer_id = #{user_id} and email = ?", email]) + end + + def Contact.find_by_group_user(user_id, grp_id) + result = Array.new + find(:all, :conditions => ["customer_id = ?", user_id], :order => "fname asc").each { |c| + begin + c.groups.find(grp_id) + result << c + rescue ActiveRecord::RecordNotFound + end + } + result + end + + def Contact.find_by_user_letter(user_id, letter) + find_by_sql("select * from contacts where customer_id=#{user_id} and substr(UPPER(fname),1,1) = '#{letter}' order by fname") + end + + def full_name + "#{fname} #{lname}" + end + + def show_name + "#{fname} #{lname}" + end + + def full_address + "#{fname} #{lname}<#{email}>" + end + + protected + def validate + errors.add 'fname', _('Please enter your first name (2 to 20 characters).') unless self.fname =~ /^.{2,20}$/i + errors.add 'lname', _('Please enter your surname (2 to 20 characters).') unless self.lname =~ /^.{2,20}$/i + + # Contact e-mail cannot be changed + unless self.new_record? + old_record = Contact.find(self.id) + errors.add 'email', _('Contacts email cannot be changed.') unless old_record.email == self.email + end + end + + def validate_on_create + # Contact e-mail cannot be changed, so we only need to validate it on create + errors.add 'email', _('Please enter a valid email address.') unless valid_email?(self.email) + # Already existing e-mail in contacts for this user is not allowed + if self.new_record? + if Contact.find_first("email = '#{email}' and customer_id = #{customer_id}") + errors.add('email', _('An account for your email address already exists.')) + end + end + end + +end diff --git a/components/contacts/contact/add.rhtml b/components/contacts/contact/add.rhtml new file mode 100644 index 0000000..77950fd --- /dev/null +++ b/components/contacts/contact/add.rhtml @@ -0,0 +1,79 @@ +

<%=_('Edit/Create contact')%>

+ + +
+
+ + + <%= + form_tag( + link_contact_save, + 'method' => 'post', + 'class' => 'two_columns' + ) + %> + <%= form_input(:hidden_field, 'contact', 'id') %> + <%= form_input(:hidden_field, 'contact', 'customer_id') %> + + + <%= form_input(:text_field, 'contact', 'fname', _('First name'), 'class'=>'two_columns') %> + <%= form_input(:text_field, 'contact', 'lname', _('Last name'), 'class'=>'two_columns') %> + <%= form_input((@contact.new_record? ? :text_field : :read_only_field), 'contact', 'email', _('E-mail'), 'class'=>'two_columns')%> +
+ + <% for group in @contactgroups %> + + <% end %> + <% if not(@contactgroups.empty?) %> + <%=_('Contact belong to these groups')%>: + + + <% + end + col = 1 + for group in @contactgroups %> + + <% if col%2 == 0 %> + + + <% end + col = col + 1 %> + <% end %> + <% if col%2 == 0 and not(@contactgroups.empty?) %> + + <% end %> + <% if not(@contactgroups.empty?) %> + +
+ > +  <%=group.name %> +
 
+ <% end %> + + + + + +
+ + +
+ <%= end_form_tag %> +
+
diff --git a/components/contacts/contact/add_multiple.rhtml b/components/contacts/contact/add_multiple.rhtml new file mode 100644 index 0000000..4bfcf3c --- /dev/null +++ b/components/contacts/contact/add_multiple.rhtml @@ -0,0 +1,26 @@ +

<%=_('Add multiple contacts')%>

+<% if @flash["errors"] and not @flash["errors"].empty?%> + <%= _('Errors')%> +
    + <% @flash["errors"].each do |message| %> +
  • <%= message %> + <% end %> +
+<% end %> +
+ <%= radio_button("contact", "file_type", "1")%> <%= _('Comma-separated (CSV) file')%> + <%= radio_button("contact", "file_type", "2")%> <%= _('Tab-delimited text file')%> + + + + + + + + +
+ + + +
+
\ No newline at end of file diff --git a/components/contacts/contact/choose.rhtml b/components/contacts/contact/choose.rhtml new file mode 100644 index 0000000..65fb2ac --- /dev/null +++ b/components/contacts/contact/choose.rhtml @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/components/contacts/contact/import_preview.rhtml b/components/contacts/contact/import_preview.rhtml new file mode 100644 index 0000000..3077b94 --- /dev/null +++ b/components/contacts/contact/import_preview.rhtml @@ -0,0 +1,43 @@ +

<%= _('Contacts You Are About To Import')%>

+ +<% if @flash["errors"] and not @flash["errors"].empty?%> + <%= _('Errors')%> +
    + <% @flash["errors"].each do |message| %> +
  • <%= message %> + <% end %> +
+<% end %> + +
+ + + + + + + + + <% + for i in 0...@contacts.length + contact = @contacts[i] + %> + + + + + + + + <% end %> + + + + +
 <%= _('First name')%><%= _('Last name')%><%= _('E-mail')%>
<%=i+1%>
+ + + + +
+
diff --git a/components/contacts/contact/list.rhtml b/components/contacts/contact/list.rhtml new file mode 100644 index 0000000..4fe98d8 --- /dev/null +++ b/components/contacts/contact/list.rhtml @@ -0,0 +1,114 @@ +

<%= _('Contacts')%>

+ + +
+
+ + <% if @flash["alert"] %>
  • <%= @flash["alert"] %>
<% end %> +
+ + <% if @group_id and not @group_id.nil? %> + + <% end %> + + + + + + + + <% if @mode == "choose" %> + + + + + +<% for contact in @contacts %> + + + + + + <% end %> + +<% for group in @contactgroups %> + + + + + + <% end %> + + + +<% elsif @mode == "groups"%> + + + + + +<% for contact in @contacts %> + + + + + + + <% end %> + + + + <% else %> + + + + + +<% for contact in @contacts %> + + + + + + <% end %> + <% end %> +
+ <% + letters = CDF::CONFIG[:contact_letters] + for letterIndex in 0...letters.size + letter = letters[letterIndex] %> + <%= link_to(letter, :controller=>"contact", :action=>"listLetter", :id=>letterIndex, :params=>{"mode"=>@mode, "group_id"=>(@group_id ? @group_id : nil)}) %> + <% end %> +      <%= link_to(_('Show all'), :controller=>"contact", :action=>"list", :id=>(@group_id ? @group_id : nil), :params=>{"mode"=>@mode})%> +
<%= @contact_pages.basic_html(self, 2, false, {"mode"=>@mode}) %>
<%= _('To CC BCC')%><%= _('Name')%><%= _('E-mail')%>
+ + <%=contact.full_name%><%=contact.email%>
<%=_('Groups')%>:
+ + <%=group.name%> 
+ + +
<%= _('Name')%><%= _('E-mail')%>
><%=contact.full_name%><%=contact.email%>
+ + +
<%= _('Name')%><%= _('E-mail')%> 
<%= link_to(contact.full_name, :controller=>"/contacts/contact", :action => "edit", :id => contact.id ) %><%= link_to( contact.email, :controller => "/webmail", :action => "compose", :params => { "mail[to]" => contact.email } ) %><%= link_to(_('delete'), {:controller=>'/contacts/contact', :action=>'delete', :id=>contact.id}, {:confirm=>sprintf(_('DELETE CONTACT?\r\n\Name - %s\r\nE-mail - %s'), contact.show_name, contact.email)})%>
+
+
+
diff --git a/components/contacts/contact_controller.rb b/components/contacts/contact_controller.rb new file mode 100644 index 0000000..88e3129 --- /dev/null +++ b/components/contacts/contact_controller.rb @@ -0,0 +1,398 @@ +class Contacts::ContactController < ApplicationController + + uses_component_template_root + + model :customer + model :contact + model :contact_group + helper :pagination + layout :select_layout + + def index + redirect_to(:action =>"list") + end + + def list + @contact_pages = Paginator.new(self, Contact.count("customer_id = #{logged_user}"), CDF::CONFIG[:contacts_per_page], @params['page']) + @contacts = Contact.find(:all, :conditions=>["customer_id = #{logged_user}"], :order=>['fname'], :limit=>CDF::CONFIG[:contacts_per_page], :offset=>@contact_pages.current.offset) + + if @params["mode"] == "groups" + if @params["id"] and not @params["id"].nil? and not @params["id"] == '' + @group_id = @params["id"].to_i + @contacts_for_group = Hash.new + for contact in @contacts + @contacts_for_group[contact.id] = 0 # initialize + for gr in contact.groups + if gr.contact_group_id.to_i == @group_id + @contacts_for_group[contact.id] = 1 # checked + end + end + end + end + end + end + + def listLetter + letters = CDF::CONFIG[:contact_letters] + @contact_pages = Paginator.new(self, Contact.count( + ["customer_id = %s and substr(UPPER(fname),1,1) = '%s'", logged_user, letters[@params['id'].to_i]]), CDF::CONFIG[:contacts_per_page], @params['page']) + @contacts = Contact.find(:all, :conditions=>["customer_id = %s and substr(UPPER(fname),1,1) = '%s'", logged_user, letters[@params['id'].to_i]], + :order=>['fname'], :limit=>CDF::CONFIG[:contacts_per_page], :offset=>@contact_pages.current.offset) + + if @params["mode"] == "groups" + if @params["group_id"] and not @params["group_id"].nil? and not @params["group_id"] == '' + @group_id = @params["group_id"].to_i + @contacts_for_group = Hash.new + for contact in @contacts + @contacts_for_group[contact.id] = 0 # initialize + for gr in contact.groups + if gr.contact_group_id.to_i == @group_id + @contacts_for_group[contact.id] = 1 # checked + end + end + end + end + end + + render :action => "list" + end + + def add + @contact = Contact.new + @contact.customer_id = logged_user + + # load related lists + loadLists + + # Init groups: because of checkbox + # Set all to 0 => unchecked + @groups = Hash.new + @contactgroups.each {|g| + @groups[g.id] = 0 + } + end + + def add_multiple + @contact = Contact.new + @contact["file_type"] = "1" + end + + def add_from_mail + cstr = @params['cstr'] + retmsg = @params['retmsg'] + @session["return_to"] = url_for(:controller=>'/webmail/webmail', + :action=>'folders', + :msg_id=>retmsg) + # parse string + if i = cstr.index("<") + name, email = cstr.slice(0, i), cstr.slice((i+1)..(cstr.strip().index(">")-1)) + fname = name.split().first + lname = name.split().last if name.split().size() > 1 + else + fname, lname, email = "", "", cstr + end + + if @contact = Contact.find_by_user_email(logged_user, email) + # load related lists + loadLists + + @contact.fname, @contact.lname = fname, lname + + # groups = @contact.groups + @groups = Hash.new + @contactgroups.each {|g| + groupSelected = false + @contact.groups.each {|gr| + if gr.contact_group_id.to_i == g.id.to_i + groupSelected = true + break + end + } + if groupSelected + @groups[g.id] = 1 # checked + else + @groups[g.id] = 0 # unchecked + end + } + else + @contact = Contact.new("fname"=>fname, "lname" => lname, "email" => email) + @contact.customer_id = logged_user + + # load related lists + loadLists + + # Init groups: because of checkbox + # Set all to 0 => unchecked + @groups = Hash.new + @contactgroups.each {|g| + @groups[g.id] = 0 + } + end + render :action => "add" + end + + def import_preview + file = @params["contact"]["data"] + + flash["errors"] = Array.new + + if file.size == 0 + flash["errors"] << _('You haven\'t selected file or the file is empty') + @contact = Contact.new + @contact["file_type"] = @params["contact"]["file_type"] + render :action => "add_multiple" + end + + file_type = @params["contact"]["file_type"] + if file_type.nil? or file_type == '1' + separator = ',' + else + separator = /\t/ + + end + + @contacts = Array.new + emails = Array.new + + file.each {|line| + cdata = line.strip.chomp.split(separator) + cont = Contact.new + cont.fname = cdata[0].to_s.strip.chomp + cont.lname = cdata[1].to_s.strip.chomp + cont.email = cdata[2].to_s.strip.chomp + + # Check for duplicate emails in the file + if emails.include?(cont.email) + flash["errors"] << sprintf(_('Contact %'), file.lineno.to_s) + ": " + _('The e-mail duplicates the e-mail of another record!') + else + emails << cont.email + end + + @contacts << cont + } + + end + + def import + contacts_count = @params["contact"].length + contacts_to_import = @params["contact"] + @contacts = Array.new + emails = Array.new + + flash["errors"] = Array.new + + for i in 0...contacts_count + contact = Contact.new + contact.customer_id = logged_user + contact.fname = contacts_to_import[i.to_s]["fname"] + contact.lname = contacts_to_import[i.to_s]["lname"] + contact.email = contacts_to_import[i.to_s]["email"] + + begin + # Check for duplicate emails in the submitted data + if emails.include?(contact.email) + flash["errors"] << sprintf(_('Contact %'), (i+1).to_s) + ": " + _('The e-mail duplicates the e-mail of another record!') + else + emails << contact.email + end + # Check if contact is valid + contact.valid? + rescue CDF::ValidationError => e + if not contact.errors.empty? + ["fname", "lname", "email"].each do |attr| + attr_errors = contact.errors.on(attr) + attr_errors = [attr_errors] unless attr_errors.nil? or attr_errors.is_a? Array + + if not attr_errors.nil? + attr_errors.each do |msg| + flash["errors"] << l(:contact_addmultiple_errorforcontact, (i+1).to_s) + ": " + l(msg) + end + end + end + end + end # rescue + + @contacts << contact + end # for + + # If there are validation errors - display them + if not flash["errors"].nil? and not flash["errors"].empty? + render :action => "import_preview" + else + # save + begin + for contact in @contacts + Contact.create(contact.attributes) + end + # Set message for successful import + flash["alert"] = Array.new + flash["alert"] << l(:contact_addmultiple_success, @contacts.length.to_s) + keep_flash() + redirect_to(:action=>"list") + rescue Exception => exc + flash["errors"] << exc + render :action => "import_preview" + end + end + end + + + def choose + if @params["mode"] == "groups" + save_groups + end + + @tos, @ccs, @bccs = Array.new, Array.new, Array.new + + @params["contacts_to"].each{ |id,value| @tos << Contact.find(id) if value == "1" } if @params["contacts_to"] + @params["contacts_cc"].each{ |id,value| @ccs << Contact.find(id) if value == "1" } if @params["contacts_cc"] + @params["contacts_bcc"].each{ |id,value| @bccs << Contact.find(id) if value == "1" } if @params["contacts_bcc"] + + @params["groups_to"].each{ |id,value| + ContactGroup.find(id).contacts.each {|c| @tos << c} if value == "1" } if @params["groups_to"] + @params["groups_cc"].each{ |id,value| + ContactGroup.find(id).contacts.each {|c| @ccs << c} if value == "1" } if @params["groups_cc"] + @params["groups_bcc"].each{ |id,value| + ContactGroup.find(id).contacts.each {|c| @bccs << c} if value == "1" } if @params["groups_bcc"] + end + + def save_groups + contacts_for_group = @params["contacts_for_group"] + group_id = @params["group_id"] + contact_group = ContactGroup.find(group_id) + + + contacts_for_group.each { |contact_id,value| + contact = Contact.find(contact_id) + if value == "1" and not contact_group.contacts.include?(contact) + contact_group.contacts << contact + end + if value == "0" and contact_group.contacts.include?(contact) + contact_group.contacts.delete(contact) + end + } + redirect_to(:action=>"list", :id=>group_id, :params=>{"mode"=>@params["mode"]}) + end + + def edit + @contact = Contact.find(@params["id"]) + # load related lists + loadLists + + # groups = @contact.groups + @groups = Hash.new + @contactgroups.each {|g| + groupSelected = false + @contact.groups.each {|gr| + if gr.contact_group_id.to_i == g.id.to_i + groupSelected = true + break + end + } + if groupSelected + @groups[g.id] = 1 # checked + else + @groups[g.id] = 0 # unchecked + end + } + render :action => "add" + end + + # Insert or update + def save + logger.info("BEGIN") + if @params["contact"]["id"] == "" + # New contact + @contact = Contact.create(@params["contact"]) + else + # Edit existing + @contact = Contact.find(@params["contact"]["id"]) + @contact.attributes = @params["contact"] + end + + @contactgroups = ContactGroup.find_by_user(logged_user) + # Groups displayed + groups = @params['groups'] + tempGroups = Array.new + tempGroups.concat(@contact.groups) + + @contactgroups.each { |cgroup| + includesCGroup = false + tempGroups.each {|gr| + if gr.contact_group_id.to_i == cgroup.id.to_i + includesCGroup = true + break + end + } + if groups["#{cgroup.id}"] == "1" and not includesCGroup + @contact.groups << cgroup + end + + if groups["#{cgroup.id}"] == "0" and includesCGroup + @contact.groups.delete(cgroup) + end + } + if @contact.save + if @params["paction"] == _('Save') + redirect_to :controller => "/contacts/contact", :action =>"list" + else + redirect_to :controller => "/contacts/contact", :action =>"add" + end + else + loadLists + @groups = Hash.new + @contactgroups.each {|g| + if @contact.groups.include?(g) + @groups[g.id] = 1 + else + @groups[g.id] = 0 + end + } + render :action => "add" + end + end + + def delete + Contact.destroy(@params['id']) + redirect_to(:action=>'list') + end + + protected + def secure_user?() true end + def additional_scripts() + add_s = '' + if action_name == "choose" + add_s<<'' + add_s<<'' + end + add_s + end + + def onload_function() + if action_name == "choose" + "javascript:respondToCaller();" + else + "" + end + end + private + def select_layout + if @params["mode"] == "choose" + @mode = "choose" + @contactgroups = ContactGroup.find_by_user(logged_user) + 'chooser' + elsif @params["mode"] == "groups" + @mode = "groups" + 'public' + else + @mode = "normal" + 'public' + end + end + + def loadLists + if @contactgroups.nil? + @contactgroups = ContactGroup.find_by_user(logged_user) + end + end +end diff --git a/components/contacts/contact_group.rb b/components/contacts/contact_group.rb new file mode 100644 index 0000000..628d69a --- /dev/null +++ b/components/contacts/contact_group.rb @@ -0,0 +1,25 @@ +class ContactGroup < ActiveRecord::Base + has_and_belongs_to_many :contacts, :class_name => "Contact", :join_table => "contact_contact_groups", :association_foreign_key => "contact_id", :foreign_key => "contact_group_id" + + def ContactGroup.find_by_user(user_id) + find_by_sql("select * from contact_groups where customer_id = #{user_id} order by name asc") + end + + protected + def validate + errors.add('name', :contactgroup_name_invalid) unless self.name =~ /^.{1,50}$/i + end + + def validate_on_create + if ContactGroup.find_first(["name = '#{name}' and customer_id = #{user_id}"]) + errors.add("name", _('Please enter group name (1 to 50 characters)')) + end + end + + def validate_on_update + if ContactGroup.find_first(["name = '#{name}' and customer_id = #{user_id} and id <> #{id}"]) + errors.add("name", _('You already have contact group with this name')) + end + end + +end diff --git a/components/contacts/contact_group/edit.rhtml b/components/contacts/contact_group/edit.rhtml new file mode 100644 index 0000000..16dad94 --- /dev/null +++ b/components/contacts/contact_group/edit.rhtml @@ -0,0 +1,24 @@ +

<%=_('Edit/Create Contact Group')%>

+ <%= + form_tag( + link_save, + 'method' => 'post', + 'class' => 'two_columns' + ) + %> +<%= form_input(:hidden_field, 'contactgroup', 'id') %> +<%= form_input(:hidden_field, 'contactgroup', 'customer_id') %> + + + <%= form_input(:text_field, 'contactgroup', 'name', _('Name'), 'class'=>'two_columns') %> +
+ + + + +
+ + +
+ + <%= end_form_tag %> diff --git a/components/contacts/contact_group/list.rhtml b/components/contacts/contact_group/list.rhtml new file mode 100644 index 0000000..4043cae --- /dev/null +++ b/components/contacts/contact_group/list.rhtml @@ -0,0 +1,26 @@ +

<%=_('Contact Groups')%>

+ +
+<%= hidden_field "contactgroup", "user_id" %> + + + + + +<% + for contactgroup in @contactgroups %> + + + + + + +<% end %> + + + +
<%=_('Name')%> 
<%= contactgroup.name %><%= link_to(_('members'), :controller=>'contact', :action=>'list', :id=>contactgroup.id, :params=>{"mode"=>"groups"}) %><%= link_to(_('edit'), :controller=>'/contacts/contact_group', :action=>'edit', :id=>contactgroup.id) %><%= link_to(_('delete'), {:controller=>'/contacts/contact_group', :action=>'delete', :id=>contactgroup.id}, {:confirm=>sprintf(_('DELETE CONTACT GROUP \'%s\'?'), contactgroup.name)})%>
+ + +
+
\ No newline at end of file diff --git a/components/contacts/contact_group_controller.rb b/components/contacts/contact_group_controller.rb new file mode 100644 index 0000000..8654d45 --- /dev/null +++ b/components/contacts/contact_group_controller.rb @@ -0,0 +1,60 @@ +class Contacts::ContactGroupController < ApplicationController + + uses_component_template_root + + model :contact_group + layout 'public' + + def index + redirect_to(:action=>"list") + end + + def list + @contactgroup = ContactGroup.new + @contactgroup.customer_id = logged_user + @contactgroups = ContactGroup.find_by_user(logged_user) + end + + def add + @contactgroup = ContactGroup.new + @contactgroup.customer_id = logged_user + render("/contact_group/edit") + end + + def delete + contactgroup = ContactGroup.find(@params["id"]) + contactgroup.destroy + redirect_to(:action=>"list") + end + + def edit + @contactgroup = ContactGroup.find(@params["id"]) + end + + def save + begin + if @params["contactgroup"]["id"].nil? or @params["contactgroup"]["id"] == "" + # New contactgroup + @contactgroup = ContactGroup.create(@params["contactgroup"]) + else + # Edit existing + @contactgroup = ContactGroup.find(@params["contactgroup"]["id"]) + @contactgroup.attributes = @params["contactgroup"] + end + + if @contactgroup.save + redirect_to(:action=>"list") + else + render "/contact_group/edit" + end + rescue CDF::ValidationError => e + logger.info("RESCUE") + @contactgroup = e.entity + render("/contact_group/edit") + end + end + + protected + def secure_user?() true end + +end diff --git a/components/contacts/contact_group_helper.rb b/components/contacts/contact_group_helper.rb new file mode 100644 index 0000000..a4f14e8 --- /dev/null +++ b/components/contacts/contact_group_helper.rb @@ -0,0 +1,4 @@ +module ContactGroupHelper + def link_save() "/contact_group/save" end + def link_list() "/contact_group/list" end +end diff --git a/components/contacts/contact_helper.rb b/components/contacts/contact_helper.rb new file mode 100644 index 0000000..f84236c --- /dev/null +++ b/components/contacts/contact_helper.rb @@ -0,0 +1,40 @@ +module Contacts::ContactHelper + def link_import_preview() "/contacts/contact/import_preview" end + def link_main_index() "/webmail/webmail/folders" end + def link_contact_save() "/contacts/contact/save" end + def link_contact_import() "/contacts/contact/import" end + def link_contact_choose() "/contacts/contact/choose" end + + def link_contact_list + link_to(_('List'), :controller => "/contacts/contact", :action => "list") + end + + def link_contact_add_one + link_to(_('Add one contact'), :controller => "/contacts/contact", :action => "add") + end + + def link_contact_add_multiple + link_to(_('Add multiple'), :controller => "/contacts/contact", :action => "add_multiple") + end + + def link_contact_group_list + link_to(_('Groups'), :controller => "/contacts/contact_group", :action => "list") + end + + def link_folders + link_to(_('Folders'), :controller=>"/webmail/webmail", :action=>"messages") + end + + def link_send_mail + link_to(_('Compose'), :controller=>"/webmail/webmail", :action=>"compose") + end + + def link_mail_prefs + link_to(_('Preferences'), :controller=>"/webmail/webmail", :action=>"prefs") + end + + def link_mail_filters + link_to(_('Filters'), :controller=>"/webmail/webmail", :action=>"filters") + end + +end diff --git a/components/contacts/customer.rb b/components/contacts/customer.rb new file mode 100644 index 0000000..27737c3 --- /dev/null +++ b/components/contacts/customer.rb @@ -0,0 +1,32 @@ +require_dependency 'maildropserializator' +class Customer < ActiveRecord::Base + include MaildropSerializator + + has_many :filters, :order => "order_num" + has_one :mail_pref + attr_accessor :password + + def mail_temporary_path + "#{CDF::CONFIG[:mail_temp_path]}/#{self.email}" + end + + def friendlly_local_email + encode_email("#{self.fname} #{self.lname}", check_for_domain(email)) + end + + def mail_filter_path + "#{CDF::CONFIG[:mail_filters_path]}/#{self.email}" + end + + def local_email + self.email + end + + def check_for_domain(email) + if email and !email.nil? and !email.include?("@") + email + "@" + CDF::CONFIG[:send_from_domain] + else + email + end + end +end diff --git a/components/layouts/chooser.rhtml b/components/layouts/chooser.rhtml new file mode 100644 index 0000000..ffe7b25 --- /dev/null +++ b/components/layouts/chooser.rhtml @@ -0,0 +1,18 @@ + + + +<%=@title%> + + + + + +<%=@additional_scripts%> + + +<%= @content_for_layout %> + + + + diff --git a/components/layouts/public.rhtml b/components/layouts/public.rhtml new file mode 100644 index 0000000..a69afb1 --- /dev/null +++ b/components/layouts/public.rhtml @@ -0,0 +1,26 @@ + + + + <%=_('Mailr')%> + + + + + + + <%=(@content_for_scripts ? @content_for_scripts : @additional_scripts )%> + + +
+
+
<%= link_to _('[Logout]'), :controller=>'/login', :action=>'logout' %>
+ +
<%= @content_for_layout %>
+
+
+
+ + diff --git a/components/webmail/bounced_mail.rb b/components/webmail/bounced_mail.rb new file mode 100644 index 0000000..3b30562 --- /dev/null +++ b/components/webmail/bounced_mail.rb @@ -0,0 +1,8 @@ +class BouncedMail < ActiveRecord::Base + belongs_to :customer + belongs_to :contact + + def BouncedMail.find_by_customer_contact(cust_id, contact_id) + find_all(["customer_id = ? and contact_id = ?", cust_id, cotact_id], ["msg_date desc"]) + end +end diff --git a/components/webmail/cdfmail.rb b/components/webmail/cdfmail.rb new file mode 100644 index 0000000..4c34170 --- /dev/null +++ b/components/webmail/cdfmail.rb @@ -0,0 +1,303 @@ +require 'tmail' +require 'net/smtp' +require 'mail_transform' + +class CDF::Mail + include ActionMailer::Quoting + + def initialize(senderTempLocation) + @attachments = Array.new + @sender_temp_location = senderTempLocation + @to_contacts = Array.new + end + + def customer_id() @customer_id end + + def customer_id=(arg) @customer_id = arg end + + def from() @from end + + def from=(arg) @from = arg end + + def to() @to end + + def to=(arg) @to = arg end + + def to_contacts() @to_contacts end + + def to_contacts=(arg) @to_contacts = arg end + + def toc=(arg) + @to_contacts = Array.new + arg.split(",").each { |token| @to_contacts << token.to_i unless token == "" or token.strip() == "undefined"} unless arg.nil? or arg == "undefined" + end + + def toc + ret = String.new + @to_contacts.each { |contact| + ret << "," unless ret == "" + if contact.kind_of?(Integer) + ret << contact.to_s unless contact.nil? or contact == 0 + else + ret << contact.id.to_s unless contact.nil? or contact.id.nil? + end + } + ret + end + + def bcc() @bcc end + + def bcc=(arg) @bcc = arg end + + def cc() @cc end + + def cc=(arg) @cc = arg end + + def subject() @subject end + + def subject=(arg) @subject = arg end + + def attachments + @attachments + end + + def add_attachment(attachment) + @attachments << attachment + end + + def multipart? + @attachments && @attachments.size > 0 + end + + def delete_attachment(att_filename) + @attachments.each { |att| att.delete_temp_data() if arr.filename == att_filename } + @attachments.delete_if() { |att| att.filename == att_filename } + end + + def delete_attachments() + @attachments.each { |att| att.delete_temp_data() } + @attachments = Array.new + end + + def body() @body end + + def body=(arg) @body = arg end + + def content_type() @content_type end + + def content_type=(arg) @content_type = arg end + + def temp_location() @sender_temp_location end + + def send_mail(db_msg_id = 0) + m = TMail::Mail.new + m.from, m.body = self.from, self.body + m.date = Time.now + m.subject, = quote_any_if_necessary("UTF-8", self.subject) + m.to = decode_addresses(self.to) + + m.cc, m.bcc = decode_addresses(self.cc), decode_addresses(self.bcc) + + if multipart? + m.set_content_type("multipart/mixed") + p = TMail::Mail.new(TMail::StringPort.new("")) + if @content_type.include?("text/plain") # here maybe we should encode in 7bit??!! + prepare_text(p, self.content_type, self.body) + elsif self.content_type.include?("text/html") + prepare_html(p, self.content_type, self.body) + elsif self.content_type.include?("multipart") + prepare_alternative(p, self.body) + end + m.parts << p + else + if @content_type.include?("text/plain") # here maybe we should encode in 7bit??!! + prepare_text(m, self.content_type, self.body) + elsif self.content_type.include?("text/html") + prepare_html(m, self.content_type, self.body) + elsif self.content_type.include?("multipart") + prepare_alternative(m, self.body) + end + end + # attachments + @attachments.each { |a| + m.parts << a.encoded + } + encmail = m.encoded + RAILS_DEFAULT_LOGGER.debug("Sending message \n #{encmail}") + Net::SMTP.start(ActionMailer::Base.server_settings[:address], ActionMailer::Base.server_settings[:port], + ActionMailer::Base.server_settings[:domain], ActionMailer::Base.server_settings[:user_name], + ActionMailer::Base.server_settings[:password], ActionMailer::Base.server_settings[:authentication]) do |smtp| + smtp.sendmail(encmail, m.from, m.destinations) + end + return encmail + end + + def forward(tmail, fb) + decoded_subject = mime_encoded?(tmail.subject) ? mime_decode(tmail.subject) : tmail.subject + self.subject = "[Fwd: #{decoded_subject}]" + attachment = CDF::Attachment.new(self) + attachment.body(tmail, fb) + end + + def reply(tmail, fb, type) + decoded_subject = mime_encoded?(tmail.subject) ? mime_decode(tmail.subject) : tmail.subject + self.subject = "[Re: #{decoded_subject}]" + tm = tmail.setup_reply(tmail) + self.to = tm.to + footer = "" + msg_id = "" + mt = MailTransform.new + self.body = mt.get_body(tmail, type) + end + + private + + def delimeter + if self.content_type == "text/plain" + "\n" + else + "
" + end + end + + def text2html(str) CGI.escapeHTML(str).gsub("\n", "
") end + + def html2text(txt) + clear_html(txt) + end + + def prepare_text(msg, ctype, bdy) + msg.set_content_type(ctype, nil, {"charset"=>"utf-8"}) + msg.transfer_encoding = "8bit" + msg.body = bdy + end + + def prepare_html(msg, ctype, bdy) + msg.set_content_type(ctype, nil, {"charset"=>"utf8"}) + msg.transfer_encoding = "8bit" + msg.body = bdy + end + + def prepare_alternative(msg, bdy) + bound = ::TMail.new_boundary + + msg.set_content_type("multipart/alternative", nil, {"charset"=>"utf8", "boundary"=>bound}) + msg.transfer_encoding = "8bit" + + ptext = TMail::Mail.new(TMail::StringPort.new("")) + phtml = TMail::Mail.new(TMail::StringPort.new("")) + + prepare_text(ptext, "text/plain", html2text(bdy)) + prepare_html(phtml, "text/html", bdy) + + msg.parts << ptext + msg.parts << phtml + end + + def decode_addresses(str) + ret = String.new + str.split(",").each { |addr| + if addr.slice(0,4) == "Grp+" + grp_id = addr.scan(/Grp\+([0-9]*):(.*)/)[0][0] + ContactGroup.find(:first, :conditions=>['customer_id = ? and id = ?', @customer_id, grp_id]).contacts.each { |contact| + ret << "," if not(ret == "") + @to_contacts << contact unless contact.nil? + ret << contact.full_address + ad, = quote_any_address_if_necessary(CDF::CONFIG[:mail_charset], contact.full_address) + ret << ad + } + else + ret << "," if not(ret == "") + ad, = quote_any_address_if_necessary(CDF::CONFIG[:mail_charset], addr) if not(addr.nil? or addr == "") + ret << ad if not(addr.nil? or addr == "") + end + } unless str.nil? or str.strip() == "" + ret + end +end + +class CDF::Attachment + + def initialize(arg) + @mail = arg + @mail.add_attachment(self) + @index = @mail.attachments.size - 1 + end + + def filename=(arg) + @filename = arg.tr('\\/:*?"\'<>|', '__________') + end + + def filename() @filename end + + def temp_filename=(arg) @temp_filename = arg end + + def temp_filename() @temp_filename end + + def content_type=(arg) @content_type = arg end + + def content_type() @content_type end + + def delete_temp_data() + File.delete(self.temp_filename) + end + + def file + File.open(self.temp_filename, "rb") { |fp| fp.read } + end + + def file=(data) + return if data.size == 0 + @content_type = data.content_type + self.filename = data.original_filename.scan(/[^\\]*$/).first + self.temp_filename = "#{@mail.temp_location}/#{@filename}" + check_store_path + data.rewind + File.open(@temp_filename, "wb") { |f| f.write(data.read) } + end + + def body(data, fb) + @content_type = "message/rfc822" + filename = data.content_type['filename'] + self.filename = filename.nil? ? (mime_encoded?(data.subject) ? mime_decode(data.subject) : data.subject) : filename + self.temp_filename = "#{@mail.temp_location}/#{@filename}" + check_store_path + File.open(@temp_filename, "wb") { |f| f.write(fb) } + end + + def check_store_path() + path = "" + "#{@mail.temp_location}".split(File::SEPARATOR).each { |p| + path << p + begin + Dir.mkdir(path) + rescue + end + path << File::SEPARATOR + } + end + + def encoded + p = TMail::Mail.new(TMail::StringPort.new("")) + data = self.file + p.body = data + if @content_type.include?("text/plain") # here maybe we should encode in 7bit??!! + p.set_content_type(@content_type, nil, {"charset"=>"utf-8"}) + p.transfer_encoding = "8bit" + elsif @content_type.include?("text/html") + p.set_content_type(@content_type, nil, {"charset"=>"utf8"}) + p.transfer_encoding = "8bit" + elsif @content_type.include?("rfc822") + p.set_content_type(@content_type, nil, {"charset"=>"utf8"}) + p.set_disposition("inline;") + p.transfer_encoding = "8bit" + else + p.set_content_type(@content_type, nil, {"name"=>@filename}) + p.set_disposition("inline; filename=#{@filename}") unless @filename.nil? + p.set_disposition("inline;") if @filename.nil? + p.transfer_encoding='Base64' + p.body = TMail::Base64.folding_encode(data) + end + return p + end +end diff --git a/components/webmail/environment.rb b/components/webmail/environment.rb new file mode 100644 index 0000000..46ce795 --- /dev/null +++ b/components/webmail/environment.rb @@ -0,0 +1,5 @@ +require 'maildropserializator' +Customer.class_eval do + include MaildropSerializator + has_many :filters, :order => "order_num", :dependent => true +end \ No newline at end of file diff --git a/components/webmail/expression.rb b/components/webmail/expression.rb new file mode 100644 index 0000000..868588b --- /dev/null +++ b/components/webmail/expression.rb @@ -0,0 +1,2 @@ +class Expression < ActiveRecord::Base +end diff --git a/components/webmail/filter.rb b/components/webmail/filter.rb new file mode 100644 index 0000000..22dd703 --- /dev/null +++ b/components/webmail/filter.rb @@ -0,0 +1,3 @@ +class Filter < ActiveRecord::Base + has_many :expressions +end diff --git a/components/webmail/imap_message.rb b/components/webmail/imap_message.rb new file mode 100644 index 0000000..da0b989 --- /dev/null +++ b/components/webmail/imap_message.rb @@ -0,0 +1,38 @@ +require 'mail2screen' +class ImapMessage < ActiveRecord::Base + include Mail2Screen + + def set_folder(folder) + @folder = folder + end + + def full_body + @folder.mailbox.imap.uid_fetch(uid, "BODY[]").first.attr["BODY[]"] + end + + def from_addr=(fa) + self.from = fa.to_yaml + self.from_flat = short_address(fa) + end + + def from_addr + begin + YAML::load(from) + rescue Object + from + end + end + + def to_addr=(ta) + self.to = ta.to_yaml + self.to_flat = short_address(ta) + end + + def to_addr + begin + YAML::load(to) + rescue Object + to + end + end +end \ No newline at end of file diff --git a/components/webmail/imapmailbox.rb b/components/webmail/imapmailbox.rb new file mode 100644 index 0000000..4539c45 --- /dev/null +++ b/components/webmail/imapmailbox.rb @@ -0,0 +1,497 @@ +# Copyright (c) 2005, Benjamin Stiglitz +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# Modifications (c) 2005 by littlegreen +# +require 'net/imap' + +Net::IMAP.debug = true if CDF::CONFIG[:debug_imap] + +class Net::IMAP + class PlainAuthenticator + def process(data) + return "\0#{@user}\0#{@password}" + end + + private + def initialize(user, password) + @user = user + @password = password + end + end + add_authenticator('PLAIN', PlainAuthenticator) + + class Address + def to_s + if(name) + "#{name} #{mailbox}@#{host}" + else + "#{mailbox}@#{host}" + end + end + end +end + +class AuthenticationError < RuntimeError +end + +class IMAPMailbox + attr_reader :connected + attr_accessor :selected_mailbox + cattr_accessor :logger + + def initialize + @selected_mailbox = '' + @folders = {} + @connected = false + end + + def connect(username, password) + unless @connected + use_ssl = CDF::CONFIG[:imap_use_ssl] ? true : false + port = CDF::CONFIG[:imap_port] || (use_ssl ? 993 : 143) + begin + @imap = Net::IMAP.new(CDF::CONFIG[:imap_server], port, use_ssl) + rescue Net::IMAP::ByeResponseError => bye + # make a timeout and retry + begin + System.sleep(CDF::CONFIG[:imap_bye_timeout_retry_seconds]) + @imap = Net::IMAP.new(CDF::CONFIG[:imap_server], port, use_ssl) + rescue Error => ex + logger.error "Error on authentication!" + logger.error bye.backtrace.join("\n") + raise AuthenticationError.new + end + rescue Net::IMAP::NoResponseError => noresp + logger.error "Error on authentication!" + logger.error noresp.backtrace.join("\n") + raise AuthenticationError.new + rescue Net::IMAP::BadResponseError => bad + logger.error "Error on authentication!" + logger.error bad.backtrace.join("\n") + raise AuthenticationError.new + rescue Net::IMAP::ResponseError => resp + logger.error "Error on authentication!" + logger.error resp.backtrace.join("\n") + raise AuthenticationError.new + end + @username = username + begin + logger.error "IMAP authentication - #{CDF::CONFIG[:imap_auth]}." + if CDF::CONFIG[:imap_auth] == 'NOAUTH' + @imap.login(username, password) + else + @imap.authenticate(CDF::CONFIG[:imap_auth], username, password) + end + @connected = true + rescue Exception => ex + logger.error "Error on authentication!" + logger.error ex.backtrace.join("\n") + raise AuthenticationError.new + end + end + end + + def imap + @imap + end + + # Function chnage password works only if root has run imap_backend + # and users courier-authlib utility authtest - from courier-imap version 4.0.1 + def change_password(username, password, new_password) + ret = "" + cin, cout, cerr = Open3.popen3("/usr/sbin/authtest #{username} #{password} #{new_password}") + ret << cerr.gets + if ret.include?("Password change succeeded.") + return true + else + logger.error "[!] Error on change password! - #{ret}" + return false + end + end + + def disconnect + if @connected + @imap.logout + @imap.disconnect + @imap = nil + @connected = false + end + end + + def [](mailboxname) + @last_folder = IMAPFolderList.new(self, @username)[mailboxname] + end + + def folders + # reference just to stop GC + @folder_list ||= IMAPFolderList.new(self, @username) + @folder_list + end + + def reload + @folder_list.reload if @folder_list + end + + def create_folder(name) + begin + @imap.create(name) + reload + rescue Exception=>e + end + end + + def delete_folder(name) + begin + @imap.delete(name) + reload + rescue Exception=>e + logger.error("Exception on delete #{name} folder #{e}") + end + end + + def message_sent(message) + # ensure we have sent folder + begin + @imap.create(CDF::CONFIG[:mail_sent]) + rescue Exception=>e + end + begin + @imap.append(CDF::CONFIG[:mail_sent], message) + folders[CDF::CONFIG[:mail_sent]].cached = false if folders[CDF::CONFIG[:mail_sent]] + rescue Exception=>e + logger.error("Error on append - #{e}") + end + + end + + def message_bulk(message) + # ensure we have sent folder + begin + @imap.create(CDF::CONFIG[:mail_bulk_sent]) + rescue Exception=>e + end + begin + @imap.append(CDF::CONFIG[:mail_bulk_sent], message) + folders[CDF::CONFIG[:mail_sent]].cached = false if folders[CDF::CONFIG[:mail_bulk_sent]] + rescue Exception=>e + logger.error("Error on bulk - #{e}") + end + end +end + +class IMAPFolderList + include Enumerable + cattr_accessor :logger + + def initialize(mailbox, username) + @mailbox = mailbox + @folders = Hash.new + @username = username + end + + def each + refresh if @folders.empty? + #@folders.each_value { |folder| yield folder } + # We want to allow sorted access; for now only (FIXME) + + @folders.sort.each { |pair| yield pair.last } + end + + def reload + refresh + end + + def [](name) + refresh if @folders.empty? + @folders[name] + end + + private + def refresh + @folders = {} + result = @mailbox.imap.list('', '*') + if result + result.each do |info| + @folders[info.name] = IMAPFolder.new(@mailbox, info.name, @username, info.attr, info.delim) + end + else + # if there are no folders subscribe to INBOX - this is on first use + @mailbox.imap.subscribe(CDF::CONFIG[:mail_inbox]) + # try again to list them - we should find INBOX + @mailbox.imap.list('', '*').each do |info| + @folders[info.name] = IMAPFolder.new(@mailbox, info.name, @username, info.attr, info.delim) + end + end + @folders + end +end + +class IMAPFolder + attr_reader :mailbox + attr_reader :name + attr_reader :username + attr_reader :delim + attr_reader :attribs + + attr_writer :cached + attr_writer :mcached + + cattr_accessor :logger + + @@fetch_attr = ['ENVELOPE','BODYSTRUCTURE', 'FLAGS', 'UID', 'RFC822.SIZE'] + + def initialize(mailbox, name, username, attribs, delim) + @mailbox = mailbox + @name = name + @username = username + @messages = Array.new + @delim = delim + @attribs = attribs + @cached = false + @mcached = false + end + + def activate + if(@mailbox.selected_mailbox != @name) + @mailbox.selected_mailbox = @name + @mailbox.imap.select(@name) + load_total_unseen if !@cached + end + end + + # Just delete message without interaction with Trash folder + def delete(message) + uid = (message.kind_of?(Integer) ? message : message.uid) + @mailbox.imap.uid_store(uid, "+FLAGS", :Deleted) + @mailbox.imap.expunge + # Sync with trash cannot be made - new uid generated - so just delete message from current folder + ImapMessage.delete_all(["username = ? and folder_name = ? and uid = ?", @username, @name, uid]) + @cached = false + end + + # Deleted messages - move to trash folder + def delete_multiple(uids) + # ensure we have trash folder + begin + @mailbox.imap.create(CDF::CONFIG[:mail_trash]) + rescue + end + move_multiple(uids, CDF::CONFIG[:mail_trash]) + end + + def copy(message, dst_folder) + uid = (message.kind_of?(Integer) ? message : message.uid) + activate + @mailbox.imap.uid_copy(uid, dst_folder) + @mailbox.folders[dst_folder].cached = false if @mailbox.folders[dst_folder] + @mailbox.folders[dst_folder].mcached = false if @mailbox.folders[dst_folder] + end + + def copy_multiple(message_uids, dst_folder) + activate + @mailbox.imap.uid_copy(message_uids, dst_folder) + @mailbox.folders[dst_folder].cached = false if @mailbox.folders[dst_folder] + @mailbox.folders[dst_folder].mcached = false if @mailbox.folders[dst_folder] + end + + def move(message, dst_folder) + uid = (message.kind_of?(Integer) ? message : message.uid) + activate + @mailbox.imap.uid_copy(uid, dst_folder) + @mailbox.imap.uid_store(uid, "+FLAGS", :Deleted) + @mailbox.folders[dst_folder].cached = false if @mailbox.folders[dst_folder] + @mailbox.folders[dst_folder].mcached = false if @mailbox.folders[dst_folder] + @mailbox.imap.expunge + ImapMessage.delete_all(["username = ? and folder_name = ? and uid = ? ", @username, @name, uid]) + @cached = false + @mcached = false + end + + def move_multiple(message_uids, dst_folder) + activate + @mailbox.imap.uid_copy(message_uids, dst_folder) + @mailbox.imap.uid_store(message_uids, "+FLAGS", :Deleted) + @mailbox.folders[dst_folder].cached = false if @mailbox.folders[dst_folder] + @mailbox.folders[dst_folder].mcached = false if @mailbox.folders[dst_folder] + @mailbox.imap.expunge + ImapMessage.delete_all(["username = ? and folder_name = ? and uid in ( ? )", @username, @name, message_uids]) + @cached = false + @mcached = false + end + + def mark_read(message_uid) + activate + cached = ImapMessage.find(:first, :conditions => ["username = ? and folder_name = ? and uid = ?", @username, @name, message_uid]) + if cached.unread + cached.unread = false + cached.save + @mailbox.imap.select(@name) + @mailbox.imap.uid_store(message_uid, "+FLAGS", :Seen) + @unseen_messages = @unseen_messages - 1 + end + end + + def mark_unread(message_uid) + activate + cached = ImapMessage.find(:first, :conditions => ["username = ? and folder_name = ? and uid = ?", @username, @name, message_uid]) + if !cached.unread + cached.unread = true + cached.save + @mailbox.imap.select(@name) + @mailbox.imap.uid_store(message_uid, "-FLAGS", :Seen) + @unseen_messages = @unseen_messages + 1 + end + end + + def expunge + activate + @mailbox.imap.expunge + end + + def synchronize_cache + startSync = Time.now + activate + startUidFetch = Time.now + server_messages = @mailbox.imap.uid_fetch(1..-1, ['UID', 'FLAGS']) + + startDbFetch = Time.now + cached_messages = ImapMessage.find(:all, :conditions => ["username = ? and folder_name = ?", @username, @name]) + + cached_unread_uids = Array.new + cached_read_uids = Array.new + uids_to_be_deleted = Array.new + + cached_messages.each { |msg| + cached_unread_uids << msg.uid if msg.unread + cached_read_uids << msg.uid unless msg.unread + uids_to_be_deleted << msg.uid + } + + uids_to_be_fetched = Array.new + server_msg_uids = Array.new + + uids_unread = Array.new + uids_read = Array.new + + server_messages.each { |server_msg| + uid, flags = server_msg.attr['UID'], server_msg.attr['FLAGS'] + server_msg_uids << uid + unless uids_to_be_deleted.include?(uid) + uids_to_be_fetched << uid + else + if flags.member?(:Seen) && cached_unread_uids.include?(uid) + uids_read << uid + elsif !flags.member?(:Seen) && cached_read_uids.include?(uid) + uids_unread << uid + end + end + uids_to_be_deleted.delete(uid) + } unless server_messages.nil? + + ImapMessage.delete_all(["username = ? and folder_name = ? and uid in ( ? )", @username, @name, uids_to_be_deleted]) unless uids_to_be_deleted.empty? + ImapMessage.update_all('unread = 0', ["username = ? and folder_name = ? and uid in ( ? )", @username, @name, uids_read]) unless uids_read.empty? + ImapMessage.update_all('unread = 1', ["username = ? and folder_name = ? and uid in ( ? )", @username, @name, uids_unread]) unless uids_unread.empty? + + + # fetch and store not cached messages + unless uids_to_be_fetched.empty? + imapres = @mailbox.imap.uid_fetch(uids_to_be_fetched, @@fetch_attr) + imapres.each { |cache| + envelope = cache.attr['ENVELOPE']; + message = ImapMessage.create( :folder_name => @name, + :username => @username, + :msg_id => envelope.message_id, + :uid => cache.attr['UID'], + :from_addr => envelope.from, + :to_addr => envelope.to, + :subject => envelope.subject, + :content_type => cache.attr['BODYSTRUCTURE'].multipart? ? 'multipart' : 'text', + :date => envelope.date, + :unread => !(cache.attr['FLAGS'].member? :Seen), + :size => cache.attr['RFC822.SIZE']) + } + end + @mcached = true + logger.debug("Synchonization done for folder #{@name} in #{Time.now - startSync} ms.") + end + + def messages(offset = 0, limit = 10, sort = 'date desc') + # Synchronize first retrieval time + synchronize_cache unless @mcached + + if limit == -1 + @messages = ImapMessage.find(:all, :conditions => ["username = ? and folder_name = ?", @username, @name], :order => sort) + else + @messages = ImapMessage.find(:all, :conditions => ["username = ? and folder_name = ?", @username, @name], :order => sort, :limit => limit, :offset => offset ) + end + end + + def messages_search(query = ["ALL"], sort = 'date desc') + activate + uids = @mailbox.imap.uid_search(query) + if uids.size > 1 + ImapMessage.find(:all, :conditions => ["username = ? and folder_name = ? and uid in ( ? )", @username, @name, uids], :order => sort ) + elsif uids.size == 1 + ImapMessage.find(:all, :conditions => ["username = ? and folder_name = ? and uid = ? ", @username, @name, uids.first], :order => sort ) + else + return Array.new + end + + end + + def message(uid) + activate + message = ImapMessage.find(:first, :conditions => ["username = ? and folder_name = ? and uid = ?", @username, @name, uid]) + message.set_folder(self) + message + end + + def unseen + activate + load_total_unseen if !@cached + @unseen_messages + end + + def total + activate + load_total_unseen if !@cached + @total_messages + end + + def load_total_unseen + stat = @mailbox.imap.status(@name, ["MESSAGES", "UNSEEN"]) + @total_messages, @unseen_messages = stat["MESSAGES"], stat['UNSEEN'] + @cached = true + end + + def update_status + @status ||= @mailbox.imap.status(@name, ["MESSAGES"]) + end + + def subscribe + @mailbox.imap.subscribe(@name) + end +end diff --git a/components/webmail/mail2screen.rb b/components/webmail/mail2screen.rb new file mode 100644 index 0000000..50f4792 --- /dev/null +++ b/components/webmail/mail2screen.rb @@ -0,0 +1,167 @@ +require 'cdfutils' +module Mail2Screen + def mail2html(mail, msg_id) + footer = "" + parsed_body = create_body(mail, msg_id, footer) + + ret = "\n" + ret << "\n" + ret << " \n" + ret << " \n" + if @mail.cc_addrs + ret << " \n" + end + if @mail.bcc_addrs + ret << " \n" + end + ret << " \n" + if footer != '' + ret << " \n" + end + ret << " \n" + ret << "
#{_('From')}:#{address(mail.from_addrs, @msg_id)}
#{_('To')}:#{address(mail.to_addrs, @msg_id)}
#{_('CC')}:#{address(mail.cc_addrs, @msg_id)}
#{_('BCC')}:#{address(mail.bcc_addrs, @msg_id)}
#{_('Subject')}:#{h(mime_encoded?(mail.subject) ? mime_decode(mail.subject) : mail.subject)}\n" + ret << "
#{_('Date')}:#{h message_date(mail.date)}
#{image_tag('attachment.png')}#{footer}
\n" + + ret << "
\n" + ret << parsed_body + ret << "
\n" + end + + def create_body(mail, msg_id, footer) + charset = (mail.charset.nil? ? 'iso-8859-1' : mail.charset) + if mail.multipart? + ret = "" + if mail.content_type == 'multipart/alternative' + # take only HTML part + mail.parts.each { |part| + if part.content_type == "text/html" or part.multipart? + ret << create_body(part, msg_id, footer) + end + } + return ret + else + mail.parts.each { |part| + if part.multipart? + ret << create_body(part, msg_id, footer) + else + footer << ", " if footer != '' + footer << add_attachment(part.header['content-type'], msg_id) + if part.content_type == "text/plain" or part.content_type.nil? + charset = (part.charset.nil? ? charset : mail.charset) + ret << add_text(part, part.transfer_encoding, charset) + elsif part.content_type == "text/html" + charset = (part.charset.nil? ? charset : mail.charset) + ret << add_html(part, part.transfer_encoding, charset) + elsif part.content_type.include?("image/") + ctype = part.header['content-type'] + ret << add_image(ctype, msg_id) + elsif part.content_type.include?("message/rfc822") + ret << "
#{_('Follows attached message')}:
" << mail2html(TMail::Mail.parse(part.body), msg_id) + end + end + } + return ret + end + else + ret = "" + if mail.content_type == "text/plain" or mail.content_type.nil? + ret << add_text(mail, mail.transfer_encoding, charset) + elsif mail.content_type == "text/html" + ret << add_html(mail, mail.transfer_encoding, charset) + end + return ret + end + end + + def add_text(part, encoding, charset) + CGI.escapeHTML(decode_part_text("#{part}", encoding, charset)).gsub(/\r\n/,"
").gsub(/\r/, "
").gsub(/\n/,"
") + end + + def add_html(part, encoding, charset) + strip_html(decode_part_text("#{part}", encoding, charset)) + end + + def decode_part_text(part_str, encoding, charset) + # Parse mail + header, text = "", "" + + # Get header and body + #Content-type: text/plain; charset="ISO-8859-1" + #Content-transfer-encoding: quoted-printable + isBody = false + part_str.each_line { |line| + if isBody + text << line + else + if line.strip == "" + isBody = true + else + header << line + end + end + } + # Manage encoding + if not(encoding.nil?) and encoding.downcase == "quoted-printable" + ret = from_qp(text) + elsif not(encoding.nil?) and encoding.downcase == "base64" + ret = "#{text.unpack("m")}" + else + ret = text + end + # manage charset + if ret.nil? or charset.nil? or charset.downcase == "utf-8" + return ret + else + begin + return Iconv.conv("UTF-8",charset.downcase, ret) + rescue Exception => ex + RAILS_DEFAULT_LOGGER.debug("Exception occured #{ex}\n#{ex.backtrace.join('\n')}") + return ret + end + end + end + + def add_attachment(content_type, msg_id) + filename = (content_type.nil? or content_type['name'].nil? ? "" : content_type['name']) + if filename == "" + "" + else + " #{filename}" + end + end + + def add_image(content_type, msg_id) + filename = (content_type.nil? or content_type['name'].nil? ? "" : content_type['name']) + "

#{filename}
" + end + + def friendly_address(addr) + addr.kind_of?(Net::IMAP::Address) ? ((addr.name.nil? or addr.name.strip == "") ? "#{addr.mailbox}@#{addr.host}" : "#{(mime_encoded?(addr.name.strip) ? mime_decode(addr.name.to_s): addr.name.to_s)}<#{addr.mailbox}@#{addr.host}>") : ((addr.name.nil? or addr.name.strip == "") ? "#{addr.spec}" : "#{(mime_encoded?(addr.name.strip) ? mime_decode(addr.name.to_s): addr.name.to_s)}<#{addr.spec}>") + end + + def friendly_address_or_name(addr) + addr.kind_of?(Net::IMAP::Address) ? ((addr.name.nil? or addr.name.to_s == "") ? "#{addr.mailbox}@#{addr.host}" : (mime_encoded?(addr.name.to_s) ? mime_decode(addr.name.to_s): addr.name.to_s)) : ((addr.name.nil? or addr.name.to_s == "") ? "#{addr.spec}" : (mime_encoded?(addr.name.to_s) ? mime_decode(addr.name.to_s): addr.name.to_s)) + end + + def add_to_contact(addr, msg_id) + " Add to contacts" + end + + def short_address(addresses) + ret = "" + addresses.each { |addr| #split(/,\s*/) + ret << "," unless ret == "" + ret << CGI.escapeHTML(friendly_address_or_name(addr)) + } unless addresses.nil? + ret + end + + def address(addresses, msg_id) + ret = "" + addresses.each { |addr| #split(/,\s*/) + ret << "," unless ret == "" + ret << CGI.escapeHTML(friendly_address_or_name(addr)) << add_to_contact(addr, msg_id) + } unless addresses.nil? + return ret + end +end \ No newline at end of file diff --git a/components/webmail/mail_pref.rb b/components/webmail/mail_pref.rb new file mode 100644 index 0000000..7df7824 --- /dev/null +++ b/components/webmail/mail_pref.rb @@ -0,0 +1,9 @@ +require_association 'customer' + +class MailPref < ActiveRecord::Base + belongs_to :customer + + def MailPref.find_by_customer(customer_id) + find_first(["customer_id = #{customer_id}"]) + end +end diff --git a/components/webmail/mail_transform.rb b/components/webmail/mail_transform.rb new file mode 100644 index 0000000..30fe03c --- /dev/null +++ b/components/webmail/mail_transform.rb @@ -0,0 +1,75 @@ +require 'mail2screen' + +class MailTransform + include Mail2Screen + + def get_body(tmail, type) + @mail = tmail + footer = "" + msg_id = "" + ret = mail2html(tmail, msg_id) + ret = ret.gsub(//,"\n").gsub(/ /, " ").gsub(/</, "<").gsub(/>/, ">").gsub(/&/, "&").gsub(//, "\n").gsub(/\n/, "\n> ") if type == 'text/plain' + ret = ret.gsub(/\r\n/,"
").gsub(/\r/, "
").gsub(/\n/,"
").gsub(//, "
> ") unless type == 'text/plain' + return ret + end + + def mail2html(mail, msg_id) + footer = "" + parsed_body = create_body(mail, msg_id, footer) + + ret = "-----Original Message-----\n#{_('From')}:#{address(mail.from_addrs, @msg_id)}\n" + ret << "#{_('To')}:#{address(mail.to_addrs, @msg_id)}\n" + if @mail.cc_addrs + ret << " #{_('CC')}:#{address(mail.cc_addrs, @msg_id)}\n" + end + if @mail.bcc_addrs + ret << "#{_('BCC')}:#{address(mail.bcc_addrs, @msg_id)}\n" + end + ret << "#{_('Subject')}:#{mime_encoded?(mail.subject) ? mime_decode(mail.subject) : mail.subject}\n" + ret << "#{_('Date')}:#{message_date(mail.date)}\n" + ret << "\n" + ret << "\n" + ret << parsed_body + ret << "\n" + end + + def message_date(datestr) + t = Time.now + begin + if datestr.kind_of?(String) + d = (Time.rfc2822(datestr) rescue Time.parse(value)).localtime + else + d = datestr + end + if d.day == t.day and d.month == t.month and d.year == t.year + d.strftime("%H:%M") + else + d.strftime("%Y-%m-%d") + end + rescue + begin + d = imap2time(datestr) + if d.day == t.day and d.month == t.month and d.year == t.year + d.strftime("%H:%M") + else + d.strftime("%Y-%m-%d") + end + rescue + datestr + end + end + end + + # Overwrite some staff + def add_to_contact(addr, msg_id) + "" + end + def add_attachment(content_type, msg_id) + "" + end + + def add_image(content_type, msg_id) + "" + end + +end \ No newline at end of file diff --git a/components/webmail/maildropserializator.rb b/components/webmail/maildropserializator.rb new file mode 100644 index 0000000..cc5424a --- /dev/null +++ b/components/webmail/maildropserializator.rb @@ -0,0 +1,51 @@ +module MaildropSerializator + def serialize_to_file + mail_drop_filter = File.new(self.mail_filter_path, "w") + for filter in filters + mail_drop_filter << "# filter '#{filter.name}'\n" + mail_drop_filter << "if (#{filter_expressions(filter)})\n" + mail_drop_filter << "{\n" + mail_drop_filter << " exception {\n" + mail_drop_filter << " to #{dest_folder(filter)}\n" + mail_drop_filter << " }\n" + mail_drop_filter << "}\n" + end + mail_drop_filter.close() + end + + private + def dest_folder(filter) + '$DEFAULT/'< 'webmail/webmail', :action => 'messages' + + diff --git a/components/webmail/virtual_email.rb b/components/webmail/virtual_email.rb new file mode 100644 index 0000000..8547cf9 --- /dev/null +++ b/components/webmail/virtual_email.rb @@ -0,0 +1,3 @@ +class VirtualEmail < ActiveRecord::Base + def self.table_name() "cdf.wm_virtual" end +end diff --git a/components/webmail/webmail/_contacts.rhtml b/components/webmail/webmail/_contacts.rhtml new file mode 100644 index 0000000..4908f51 --- /dev/null +++ b/components/webmail/webmail/_contacts.rhtml @@ -0,0 +1,5 @@ +
    +<% for contact in @contacts do -%> +
  • <%=h contact.fname %> <%= h contact.lname %>
  • +<% end -%> +
\ No newline at end of file diff --git a/components/webmail/webmail/_expr.rhtml b/components/webmail/webmail/_expr.rhtml new file mode 100644 index 0000000..f7fa44c --- /dev/null +++ b/components/webmail/webmail/_expr.rhtml @@ -0,0 +1,18 @@ + <% @expression = @expressions[expr_counter] %> + + + + + + + <%= text_field 'expression', 'expr_value', 'index'=>expr_counter %> + + + <%= hidden_field "expression", 'case_sensitive', 'index'=>expr_counter %> + <%= check_box "expression", 'case_sensitive', {'onclick'=>'toggleCheckbox(this)', "index"=>expr_counter } %>  <%= _('case sensitive') %> + + \ No newline at end of file diff --git a/components/webmail/webmail/_filter.rhtml b/components/webmail/webmail/_filter.rhtml new file mode 100644 index 0000000..f4fbe10 --- /dev/null +++ b/components/webmail/webmail/_filter.rhtml @@ -0,0 +1,19 @@ + + <%=h @user.filters[filter_counter].name%> + + <% if filter_counter > 0 %> + <%=link_filter_up(@user.filters[filter_counter].id)%> + <% else %> +   + <% end %> + + + <% if filter_counter < @user.filters.size - 1 %> + <%=link_filter_down(@user.filters[filter_counter].id)%> + <% else %> +   + <% end %> + + <%=link_filter_edit(@user.filters[filter_counter].id)%> + <%=link_filter_delete(@user.filters[filter_counter].id)%> + \ No newline at end of file diff --git a/components/webmail/webmail/_message_row.rhtml b/components/webmail/webmail/_message_row.rhtml new file mode 100644 index 0000000..e5f003c --- /dev/null +++ b/components/webmail/webmail/_message_row.rhtml @@ -0,0 +1,14 @@ + + + <% if @folder_name == CDF::CONFIG[:mail_sent] %> + <%= short_address(message_row.to_addr) %> +<% else %> + <%= short_address(message_row.from_addr) %> +<% end %> +
+ <%= link_to(parse_subject(message_row.subject) << " " , :controller=>'webmail', :action=>'message', :msg_id=>message_row.uid)%> + + <%= message_date(message_row.date) %> + <%= message_size(message_row.size) %> + <%= message_row.content_type == 'multipart' ? image_tag('attachment.png') : ' ' %> + diff --git a/components/webmail/webmail/_search.rhtml b/components/webmail/webmail/_search.rhtml new file mode 100644 index 0000000..641e261 --- /dev/null +++ b/components/webmail/webmail/_search.rhtml @@ -0,0 +1,13 @@ + + <%=_('Search')%>open + + diff --git a/components/webmail/webmail/compose.rhtml b/components/webmail/webmail/compose.rhtml new file mode 100644 index 0000000..8bee588 --- /dev/null +++ b/components/webmail/webmail/compose.rhtml @@ -0,0 +1,67 @@ +

<%=_('Mailbox')%>

+
+ +
+
+ +
+ + +
+ + + + + +
<%= text_field_with_auto_complete(:mail, :to, {"size"=>65}, :skip_style => true, :tokens=> ",") %>
<%= text_field_with_auto_complete(:mail, :cc, {"size"=>65}, :skip_style => true, :tokens=> ",") %>
<%= text_field_with_auto_complete(:mail, :bcc, {"size"=>65}, :skip_style => true, :tokens=> ",") %>
<%= text_field('mail', 'subject', {"size"=>65}) %>
+ <%= hidden_field('mail', 'from') %> + <%= hidden_field('mail', 'content_type') %> +
+ +
+ <%= text_area "mail", "body", "rows"=>20, "cols"=>75 %> +
+ +
+ <% if @mail.attachments and @mail.attachments.size > 0%> + + <% i = 0 + @mail.attachments.each { |att| %> + + <% i = i + 1 + }%> +
<%=attachment(att, i)%>
+ <% end %> +
+ <%=%> + +
+
+
+
+ +<% content_for("scripts") { %> +<%= @additional_scripts %> +<% if ['text/html', 'multipart'].include?(@mail.content_type) %> +<%= include_tinymce %> +<% end %> +<%= javascript_include_tag "controls" %> +<%= javascript_include_tag "dragdrop" %> +<%= javascript_include_tag "effects" %> +<% %> +<% } %> diff --git a/components/webmail/webmail/error_connection.rhtml b/components/webmail/webmail/error_connection.rhtml new file mode 100644 index 0000000..dbdcefc --- /dev/null +++ b/components/webmail/webmail/error_connection.rhtml @@ -0,0 +1,28 @@ +

<%=_('Mailbox')%>

+ +
+
+ +<% content_for('sidebar') { %> +
+

<%=_('Folders')%>
<%=link_manage_folders%>

+
+ <%=_('Error occured obtaining connection to mail server. Please excuse us!')%> +
+<% } %> +
+
+ +
diff --git a/components/webmail/webmail/filter.rhtml b/components/webmail/webmail/filter.rhtml new file mode 100644 index 0000000..cfe840c --- /dev/null +++ b/components/webmail/webmail/filter.rhtml @@ -0,0 +1,41 @@ +

<%=_('Mailbox')%>

+ +
+
+ +
+
+ <%=hidden_field 'filter', 'id' %> + + + + + + + <%= render_partial_collection "expr", @expressions %> + + + + + + +
<%=text_field 'filter', 'name' %>
<%=_('Messages matching')%>
+ +
+ + +
+ +
+
+
diff --git a/components/webmail/webmail/filters.rhtml b/components/webmail/webmail/filters.rhtml new file mode 100644 index 0000000..91358b6 --- /dev/null +++ b/components/webmail/webmail/filters.rhtml @@ -0,0 +1,39 @@ +

<%=_('Mailbox')%>

+ +
+
+ +
+
+<% if @user.filters and @user.filters.size > 0 %> + + + + + + + + + <%= render_partial_collection "filter", @user.filters %> +
<%=_('Filter name')%>    
+<% end %> +
+ <% if @flash['error'] %> +
<%= @flash['error'] %>
+ <% elsif @flash['status'] %> +
<%= @flash['status'] %>
+ <% end %> +
+
diff --git a/components/webmail/webmail/folders.rhtml b/components/webmail/webmail/folders.rhtml new file mode 100644 index 0000000..0356db2 --- /dev/null +++ b/components/webmail/webmail/folders.rhtml @@ -0,0 +1,35 @@ +

<%=_('Mailbox')%>

+ +
+
+ +<% content_for('sidebar') { %> +
+

<%=_('Folders')%>
<%=link_manage_folders%>

+
+
    <% for folder in @folders %> +
  • <%=folder_link(folder)%>
  • <% end %> +
+
+<% } %> +
+<% if not(@request['msg_id'] == '') %> +<%= render_component(:controller => "webmail/webmail", :action => "message", :params => { 'msg_id' => @request['msg_id']})%> +<% else %> +<%= render_component(:controller => "webmail/webmail", :action => "messages") %> +<% end %> +
+ +
diff --git a/components/webmail/webmail/mailsent.rhtml b/components/webmail/webmail/mailsent.rhtml new file mode 100644 index 0000000..f0ee977 --- /dev/null +++ b/components/webmail/webmail/mailsent.rhtml @@ -0,0 +1,31 @@ +

<%=_('Mailbox')%>

+ +
+
+ +
+
+
<%=_('To')%>
<%= CGI.escapeHTML(@mail.to) %>
+ <% if @mail.cc %> +
<%=_('CC')%>
<%= CGI.escapeHTML(@mail.cc) %>
+ <% end + if @mail.bcc %> +
<%=_('BCC')%>
<%= CGI.escapeHTML(@mail.bcc) %>
+ <% end %> +
<%=_('Subject')%>
<%= CGI.escapeHTML(@mail.subject) %>
+
+
+
+
diff --git a/components/webmail/webmail/manage_folders.rhtml b/components/webmail/webmail/manage_folders.rhtml new file mode 100644 index 0000000..038cca7 --- /dev/null +++ b/components/webmail/webmail/manage_folders.rhtml @@ -0,0 +1,48 @@ +

<%=_('Mailbox')%>

+ +
+
+ +<% content_for('sidebar') { %> +
+

<%=_('Add folder')%>

+
+
+
    +
  • +
  • +
  • +
+
+
+<% } %> + +
+
+ + + + <% for folder in @folders %> + + + + + <% end %> + +
<%=_('Folder')%><%= _('Total messages') %><%= _('Unseen') %>
<%=folder_manage_link(folder)%><%= folder.total %><%= folder.unseen > 0 ? "#{folder.unseen}" : "#{folder.unseen}" %>
+
+
+
+
diff --git a/components/webmail/webmail/message.rhtml b/components/webmail/webmail/message.rhtml new file mode 100644 index 0000000..97d957f --- /dev/null +++ b/components/webmail/webmail/message.rhtml @@ -0,0 +1,48 @@ +

<%=_('Mailbox')%>

+ +
+
+ +<% content_for('sidebar') { %> +
+

<%=_('Folders')%>
<%=link_manage_folders%>

+
+
    <% for folder in @folders %> +
  • <%=folder_link(folder)%>
  • <% end %> +
+
+<% } %> +
+ +
+
+
    +
  • + <%= link_to(_("« Back to list"), :controller=>"/webmail/webmail", :action=>"messages") %> +
  • +
  • <%=link_reply_to_sender(@msg_id)%>
  • +
  • <%=link_forward_message(@msg_id)%>
  • +
  • <%=link_flag_for_deletion(@msg_id)%>
  • +
  • <%=link_view_source(@msg_id)%>
  • +
+
+ + <%= mail2html(@mail, @msg_id) %> +
+ +
+ +
+ diff --git a/components/webmail/webmail/messages.rhtml b/components/webmail/webmail/messages.rhtml new file mode 100644 index 0000000..637a23c --- /dev/null +++ b/components/webmail/webmail/messages.rhtml @@ -0,0 +1,89 @@ +

<%=_('Mailbox')%>

+ +
+
+ +<% content_for('sidebar') { %> +
+

<%=_('Folders')%>
<%=link_manage_folders%>

+
+
    <% for folder in @folders %> +
  • <%=folder_link(folder)%>
  • <% end %> +
+
+
+ +
+<% } %> + +
+
+

<%= @folder_name %>

+ <%= start_form_tag({:controller=>'/webmail/webmail', :action=>'messages'})%> +
+ + + + <%=_('Operations')%>open + + +
+

<%=_('Operations on marked messages')%>

+ + <%= submit_tag(_('delete'), :name=>'op')%> + <%= submit_tag(_('copy'), :name=> 'op')%> + <%= submit_tag(_('move'), :name=>'op')%> + <%= submit_tag(_('mark read'), :name=>'op')%> + <%= submit_tag(_('mark unread'), :name=>'op')%> +
+ + <%=_('Destination for move and copy operations')%>  + + +
+ <%= render_partial "search" %> + <%= page_navigation_webmail @pages if @pages.page_count > 1 %> + + + + + <% if @folder_name == CDF::CONFIG[:mail_sent] %> + + <% else %> + + <% end%> + + + + + + + + <% for message in @messages %> + <%= render_partial 'webmail/webmail/message_row', message %> + <% end %> + +
<%= link_to(_('To'), :controller=>'/webmail/webmail', :action=>'messages', :op=>'SORT', :page=>@page, :scc=>'to_flat')%><%= link_to(_('From'), :controller=>'/webmail/webmail', :action=>'messages', :op=>'SORT', :page=>@page, :scc=>'from_flat')%><%= link_to(_('Subject'), :controller=>'/webmail/webmail', :action=>'messages', :op=>'SORT', :page=>@page, :scc=>'subject')%><%= link_to(_('Date'), :controller=>'/webmail/webmail', :action=>'messages', :op=>'SORT', :page=>@page, :scc=>'date')%><%= link_to(_('Size'), :controller=>'/webmail/webmail', :action=>'messages', :op=>'SORT', :page=>@page, :scc=>'size')%> 
+ <%= page_navigation_webmail @pages if @pages.page_count > 1 %> + +
+
+ +
+
diff --git a/components/webmail/webmail/noattachment.rhtml b/components/webmail/webmail/noattachment.rhtml new file mode 100644 index 0000000..3599892 --- /dev/null +++ b/components/webmail/webmail/noattachment.rhtml @@ -0,0 +1 @@ +No attachment found! \ No newline at end of file diff --git a/components/webmail/webmail/prefs.rhtml b/components/webmail/webmail/prefs.rhtml new file mode 100644 index 0000000..80a4a33 --- /dev/null +++ b/components/webmail/webmail/prefs.rhtml @@ -0,0 +1,52 @@ +

<%=_('Mailbox')%>

+ +
+
+
+
+ <%= hidden_field "mailpref", "id" %> + <%= hidden_field "mailpref", "customer_id" %> + + <%= form_input(:text_field, 'customer', 'fname', _('First name'), 'class'=>'two_columns') %> + <%= form_input(:text_field, 'customer', 'lname', _('Last name'), 'class'=>'two_columns') %> + + + + + + + + + + + + + + + + + + +
+ <%=check_box('mailpref', 'check_external_mail')%> + <%=_('Note that by selecting this option webmail system will try to log you using your original email on a local server.')%> +
+ + +
+
+
+
+
diff --git a/components/webmail/webmail/view_source.rhtml b/components/webmail/webmail/view_source.rhtml new file mode 100644 index 0000000..44e2f6a --- /dev/null +++ b/components/webmail/webmail/view_source.rhtml @@ -0,0 +1,13 @@ + + + + <%=_('Mailr')%> + + + +
+ <%=@msg_source%> +
+ + diff --git a/components/webmail/webmail_controller.rb b/components/webmail/webmail_controller.rb new file mode 100644 index 0000000..5120516 --- /dev/null +++ b/components/webmail/webmail_controller.rb @@ -0,0 +1,494 @@ +require 'cdfmail' +require 'net/smtp' +require 'net/imap' +require 'mail2screen' +require 'ezcrypto' + +class Webmail::WebmailController < ApplicationController + uses_component_template_root + + # Administrative functions + before_filter :login_required + + before_filter :obtain_cookies_for_search_and_nav, :only=>[:messages] + + layout "public", :except => [:view_source, :download] + + before_filter :load_imap_session + + after_filter :close_imap_session + + model :filter, :expression, :mail_pref, :customer + + BOOL_ON = "on" + + def index + redirect_to(:action=>"messages") + end + + def error_connection + end + + def refresh + @mailbox.reload + @folders = @mailbox.folders + redirect_to(:action=>'messages') + end + + def manage_folders + if operation_param == _('Add folder') + @mailbox.create_folder(CDF::CONFIG[:mail_inbox]+"."+@params["folder_name"]) + elsif operation_param == _('(Delete)') + @mailbox.delete_folder(@params["folder_name"]) + elsif operation_param == _('(Subscribe)') + elsif operation_param == _('(Select)') + end + @folders = @mailbox.folders + end + + def messages + @session["return_to"] = nil + @search_field = @params['search_field'] + @search_value = @params['search_value'] + + # handle sorting - tsort session field contains last reverse or no for field + # and lsort - last sort field + if @session['tsort'].nil? or @session['lsort'].nil? + @session['lsort'] = "DATE" + @session['tsort'] = {"DATE" => true, "FROM" => true, "SUBJECT" => true, "TO" => false} + end + + case operation_param + when _('copy') # copy + msg_ids = [] + messages_param.each { |msg_id, bool| + msg_ids << msg_id.to_i if bool == BOOL_ON and dst_folder != @folder_name } if messages_param + folder.copy_multiple(msg_ids, dst_folder) if msg_ids.size > 0 + when _('move') # move + msg_ids = [] + messages_param.each { |msg_id, bool| + msg_ids << msg_id.to_i if bool == BOOL_ON and dst_folder != @folder_name } if messages_param + folder.move_multiple(msg_ids, dst_folder) if msg_ids.size > 0 + when _('delete') # delete + msg_ids = [] + messages_param.each { |msg_id, bool| msg_ids << msg_id.to_i if bool == BOOL_ON } if messages_param + folder.delete_multiple(msg_ids) if msg_ids.size > 0 + when _('mark read') # mark as read + messages_param.each { |msg_id, bool| msg = folder.mark_read(msg_id.to_i) if bool == BOOL_ON } if messages_param + when _('mark unread') # mark as unread + messages_param.each { |msg_id, bool| msg = folder.mark_unread(msg_id.to_i) if bool == BOOL_ON } if messages_param + when "SORT" + @session['lsort'] = sort_query = @params["scc"] + @session['tsort'][sort_query] = (@session['tsort'][sort_query]? false : true) + @search_field, @search_value = @session['search_field'], @session['search_value'] + when _('Search') # search + @session['search_field'] = @search_field + @session['search_value'] = @search_value + when _('Show all') # search + @session['search_field'] = @search_field = nil + @session['search_value'] = @search_value = nil + else + # get search criteria from session + @search_field = @session['search_field'] + @search_value = @session['search_value'] + end + + sort_query = @session['lsort'] + reverse_sort = @session['tsort'][sort_query] + query = ["ALL"] + @page = @params["page"] + @page ||= @session['page'] + @session['page'] = @page + if @search_field and @search_value and not(@search_field.strip() == "") and not(@search_value.strip() == "") + @pages = Paginator.new self, 0, get_mail_prefs.wm_rows, @page + @messages = folder.messages_search([@search_field, @search_value], sort_query + (reverse_sort ? ' desc' : ' asc')) + else + @pages = Paginator.new self, folder.total, get_mail_prefs.wm_rows, @page + @messages = folder.messages(@pages.current.first_item - 1, get_mail_prefs.wm_rows, sort_query + (reverse_sort ? ' desc' : ' asc')) + end + + end + + def delete + @msg_id = msg_id_param.to_i + folder.messages().delete(@msg_id) + redirect_to(:action=>"messages") + end + + def reply # not ready at all + @msg_id = msg_id_param.to_i + @imapmail = folder.message(@msg_id) + fb = @imapmail.full_body + @tmail = TMail::Mail.parse(fb) + + @mail = prepare_mail + @mail.reply(@tmail, fb, get_mail_prefs.mail_type) + + render_action("compose") + end + + def forward + @msg_id = msg_id_param.to_i + @imapmail = folder.message(@msg_id) + fb = @imapmail.full_body + @tmail = TMail::Mail.parse(fb) + + @mail = prepare_mail + @mail.forward(@tmail, fb) + + render_action("compose") + end + + def compose + if @mail.nil? + operation = operation_param + if operation == _('Send') + @mail = create_mail + encmail = @mail.send_mail + get_imap_session + @mailbox.message_sent(encmail) + + # delete temporary files (attachments) + @mail.delete_attachments() + return render("webmail/webmail/mailsent") + elsif operation == _('Add') + @mail = create_mail + attachment = CDF::Attachment.new(@mail) + attachment.file = @params['attachment'] + else + # default - new email create + @mail = create_mail + end + end + end + + def empty # empty trash folder (works for any one else :-)) + folder.messages(0, -1).each{ |message| + folder.delete(message) + } + folder.expunge + redirect_to(:action=>"messages") + end + + def message + @msg_id = msg_id_param + @imapmail = folder.message(@msg_id) + folder.mark_read(@imapmail.uid) if @imapmail.unread + @mail = TMail::Mail.parse(@imapmail.full_body) + end + + def download + msg_id = msg_id_param + imapmail = folder.message(msg_id) + mail = TMail::Mail.parse(imapmail.full_body) + + if mail.multipart? + get_parts(mail).each { |part| + return send_part(part) if part.header and part.header['content-type']['name'] == @params['ctype'] + } + render("webmail/webmail/noattachment") + else + render("webmail/webmail/noattachment") + end + end + + def prefs + @customer = Customer.find(logged_customer) + if not(@mailpref = MailPref.find_by_customer(logged_customer)) + @mailpref = MailPref.create("customer_id"=>logged_customer) + end + + if @params['op'] == _('Save') + if @params['customer'] + @customer.fname = @params['customer']['fname'] + @customer.lname = @params['customer']['lname'] + @customer.save + end + @mailpref.attributes = @params["mailpref"] + @mailpref.save + @session["wmimapseskey"] = nil + redirect_to(:action=>"messages") + end + end + + # Message filters management + def filters + end + + def filter + if @params['op'] + @filter = Filter.new(@params['filter']) + @filter.customer_id = logged_customer + @params['expression'].each { |index, expr| @filter.expressions << Expression.new(expr) unless expr["expr_value"].nil? or expr["expr_value"].strip == "" } + case @params['op'] + when _('Add') + @filter.expressions << Expression.new + when _('Save') + if @params['filter']['id'] and @params['filter']['id'] != "" + @sf = Filter.find(@params['filter']['id']) + @sf.name, @sf.destination_folder = @filter.name, @filter.destination_folder + @sf.expressions.each{|expr| Expression.delete(expr.id) } + @filter.expressions.each {|expr| @sf.expressions << Expression.create(expr.attributes) } + else + @sf = Filter.create(@filter.attributes) + @sf.order_num = @user.filters.size + @filter.expressions.each {|expr| @sf.expressions << Expression.create(expr.attributes) } + end + # may be some validation will be needed + @sf.save + @user.serialize_to_file + return redirect_to(:action=>"filters") + end + @expressions = @filter.expressions + else + @filter = Filter.find(@params["id"]) if @params["id"] + @expressions = @filter.expressions + end + @destfolders = get_to_folders + end + + def filter_delete + Filter.delete(@params["id"]) + # reindex other filters + @user = Customer.find(logged_customer) + findex = 0 + @user.filters.each { |filter| + findex = findex + 1 + filter.order_num = findex + filter.save + } + @user.serialize_to_file + redirect_to :action=>"filters" + end + + def filter_up + filt = @user.filters.find(@params['id']) + ufilt = @user.filters.find_all("order_num = #{filt.order_num - 1}").first + ufilt.order_num = ufilt.order_num + 1 + filt.order_num = filt.order_num - 1 + ufilt.save + filt.save + @user.serialize_to_file + redirect_to :action=>"filters" + end + + def filter_down + filt = Filter.find(@params["id"]) + dfilt = @user.filters[filt.order_num] + dfilt.order_num = dfilt.order_num - 1 + filt.order_num = filt.order_num + 1 + dfilt.save + filt.save + @user.serialize_to_file + redirect_to :action=>"filters" + end + + def filter_add + @filter = Filter.new + @filter.expressions << Expression.new + @expressions = @filter.expressions + @destfolders = get_to_folders + render_action("filter") + end + # end of filters + + def view_source + @msg_id = msg_id_param.to_i + @imapmail = folder.message(@msg_id) + @msg_source = CGI.escapeHTML(@imapmail.full_body).gsub("\n", "
") + end + + def auto_complete_for_mail_to + auto_complete_responder_for_contacts params[:mail][:to] + end + + def auto_complete_for_mail_cc + auto_complete_responder_for_contacts params[:mail][:cc] + end + + def auto_complete_for_mail_bcc + auto_complete_responder_for_contacts params[:mail][:bcc] + end + + private + + def auto_complete_responder_for_contacts(value) + # first split by "," and take last name + searchName = value.split(',').last.strip + + # if there are 2 names search by them + if searchName.split.size > 1 + fname, lname = searchName.split.first, searchName.split.last + conditions = ['customer_id = ? and LOWER(fname) LIKE ? and LOWER(lname) like ?', logged_customer, fname.downcase + '%', lname.downcase + '%'] + else + conditions = ['customer_id = ? and LOWER(fname) LIKE ?', logged_customer, searchName.downcase + '%'] + end + @contacts = Contact.find(:all, :conditions => conditions, :order => 'fname ASC',:limit => 8) + render :partial => 'contacts' + end + + protected + + def additional_scripts() + ''<< + '' + end + + private + + def get_upass + if CDF::CONFIG[:crypt_session_pass] + EzCrypto::Key.decrypt_with_password(CDF::CONFIG[:encryption_password], CDF::CONFIG[:encryption_salt], @session["wmp"]) + else + # retrun it plain + @session["wmp"] + end + end + + def get_to_folders + res = Array.new + @folders.each{|f| res << f unless f.name == CDF::CONFIG[:mail_sent] or f.name == CDF::CONFIG[:mail_inbox] } + res + end + + def load_imap_session + return if ['compose', 'prefs', 'error_connection'].include?(action_name) + get_imap_session + end + + def get_imap_session + begin + @mailbox = IMAPMailbox.new + uname = (get_mail_prefs.check_external_mail == 1 ? user.email : user.local_email) + upass = get_upass + @mailbox.connect(uname, upass) + load_folders + rescue Exception => ex + logger.error("Exception on loggin webmail session - #{ex} - #{ex.backtrace.join("\t\n")}") + render_action "error_connection" + end + end + + def close_imap_session + return if @mailbox.nil? or not(@mailbox.connected) + @mailbox.disconnect + @mailbox = nil + end + + def have_to_load_folders? + return true if ['messages', 'delete', 'reply', 'forward', 'empty', 'message', 'download', + 'filter', 'filter_add', 'view_source'].include?(action_name) + return false + end + + def load_folders + if have_to_load_folders?() + if @params["folder_name"] + @folder_name = @params["folder_name"] + else + @folder_name = @session["folder_name"] ? @session["folder_name"] : CDF::CONFIG[:mail_inbox] + end + @session["folder_name"] = @folder_name + @folders = @mailbox.folders if @folders.nil? + end + end + + def create_mail + m = CDF::Mail.new(user.mail_temporary_path) + if @params["mail"] + ma = @params["mail"] + m.body, m.content_type, m.from, m.to, m.cc, m.bcc, m.subject = ma["body"], ma["content_type"], ma["from"], ma["to"], ma["cc"], ma["bcc"], ma["subject"] + if @params["att_files"] + att_files, att_tfiles, att_ctypes = @params["att_files"], @params["att_tfiles"], @params["att_ctypes"] + att_files.each {|i, value| + att = CDF::Attachment.new(m) + att.filename, att.temp_filename, att.content_type = value, att_tfiles[i], att_ctypes[i] + } + end + else + m.from, m.content_type = user.friendlly_local_email, get_mail_prefs.mail_type + end + m.customer_id = logged_customer + m + end + + def prepare_mail + m = CDF::Mail.new(user.mail_temporary_path) + m.from, m.content_type = user.friendlly_local_email, get_mail_prefs.mail_type + m + end + + def user + @user = Customer.find(logged_customer) if @user.nil? + @user + end + + def get_mail_prefs + if not(@mailprefs) + if not(@mailprefs = MailPref.find_by_customer(logged_customer)) + @mailprefs = MailPref.create("customer_id"=>logged_customer) + end + end + @mailprefs + end + + def send_part(part) + if part.content_type == "text/html" + disposition = "inline" + elsif part.content_type.include?("image/") + disposition = "inline" + else + disposition = "attachment" + end + @headers['Content-Length'] = part.body.size + @response.headers['Accept-Ranges'] = 'bytes' + @headers['Content-type'] = part.content_type.strip + @headers['Content-Disposition'] = disposition << %(; filename="#{part.header['content-type']['name']}") + render_text part.body + end + + def get_parts(mail) + parts = Array.new + parts << mail + mail.parts.each { |part| + if part.multipart? + parts = parts.concat(get_parts(part)) + elsif part.content_type and part.content_type.include?("rfc822") + parts = parts.concat(get_parts(TMail::Mail.parse(part.body))) << part + else + parts << part + end + } + parts + end + + def obtain_cookies_for_search_and_nav + @srch_class = ((cookies['_wmlms'] and cookies['_wmlms'] == 'closed') ? 'closed' : 'open') + @srch_img_src = ((cookies['_wmlms'] and cookies['_wmlms'] == 'closed') ? 'closed' : 'opened') + @ops_class = ((cookies['_wmlmo'] and cookies['_wmlmo'] == 'closed') ? 'closed' : 'open') + @ops_img_src = ((cookies['_wmlmo'] and cookies['_wmlmo'] == 'closed') ? 'closed' : 'opened') + end + + ################################################################### + ### Some fixed parameters and session variables + ################################################################### + def folder + @folders[@folder_name] + end + + def msg_id_param + @params["msg_id"] + end + + def messages_param + @params["messages"] + end + + def dst_folder + @params["cpdest"] + end + + def operation_param + @params["op"] + end +end diff --git a/components/webmail/webmail_helper.rb b/components/webmail/webmail_helper.rb new file mode 100644 index 0000000..df76db1 --- /dev/null +++ b/components/webmail/webmail_helper.rb @@ -0,0 +1,211 @@ +require 'cdfutils' +require 'mail2screen' + +module Webmail::WebmailHelper + include Mail2Screen + def link_folders + link_to(_('Folders'), :controller=>"/webmail/webmail", :action=>"messages") + end + + def link_send_mail + link_to(_('Compose'), :controller=>"/webmail/webmail", :action=>"compose") + end + + def link_compose_new + link_to(_('Compose new mail'), :controller=>"/webmail/webmail", :action=>"compose") + end + + def link_refresh + link_to(_('Refresh'), :controller=>"/webmail/webmail", :action=>"refresh") + end + + def link_message_list + link_to(_('Message list'), :controller=>"/webmail/webmail", :action=>"messages") + end + + def link_reply_to_sender(msg_id) + link_to(_('Reply'), :controller=>"/webmail/webmail", :action=>"reply", :params=>{"msg_id"=>msg_id}) + end + + def link_forward_message(msg_id) + link_to(_('Forward'), :controller=>"/webmail/webmail", :action=>"forward", :params=>{"msg_id"=>msg_id}) + end + + def link_flag_for_deletion(msg_id) + link_to(_('Delete'), :controller=>"/webmail/webmail", :action=>"delete", :params=>{"msg_id"=>msg_id}) + end + + def link_view_source(msg_id) + link_to(_('View source'), {:controller=>"/webmail/webmail", :action=>"view_source", :params=>{"msg_id"=>msg_id}}, {'target'=>"_blank"}) + end + + def link_manage_folders + link_to(_('add/edit'), :controller=>"/webmail/webmail", :action=>"manage_folders") + end + + def link_back_to_messages + link_to("«" << _('Back to messages'), :controller=>"/webmail/webmail", :action=>"messages") + end + + def link_mail_prefs + link_to(_('Preferences'), :controller=>"/webmail/webmail", :action=>"prefs") + end + + def link_mail_filters + link_to(_('Filters'), :controller=>"/webmail/webmail", :action=>"filters") + end + + def link_filter_add + link_to(_('Add filter'), :controller=>'/webmail/webmail', :action=>'filter_add') + end + + def folder_link(folder) + if folder.attribs.include? :Noselect + return folder.name + end + unseen_messages = folder.unseen + if unseen_messages > 0 + fn = "#{short_fn(folder)} (#{folder.unseen})" + else + fn = "#{short_fn(folder)}" + end + if folder.name == CDF::CONFIG[:mail_trash] + (unseen_messages > 0 ? "" : "" ) << + link_to( fn, :controller=>"/webmail/webmail", :action=>"messages", :params=>{"folder_name"=>folder.name}) << + " " << link_to(_('(Empty)'), {:controller=>"/webmail/webmail", :action=>"empty", :params=>{"folder_name"=>folder.name}}, :confirm => _('Do you really want to empty trash?')) << + (unseen_messages > 0 ? "" : "" ) + else + (unseen_messages > 0 ? "" : "" ) << + link_to( fn, :controller=>"/webmail/webmail", :action=>"messages", :params=>{"folder_name"=>folder.name}) << + (unseen_messages > 0 ? "" : "" ) + end + end + + def short_fn(folder) + if folder.name.include? folder.delim + "   " + folder.name.split(folder.delim).last + else + folder.name + end + end + + def folder_manage_link(folder) + if folder.name == CDF::CONFIG[:mail_trash] or folder.name == CDF::CONFIG[:mail_inbox] or folder.name == CDF::CONFIG[:mail_sent] + short_fn(folder) + else + return short_fn(folder) + + (" " + link_to(_('(Delete)'), :controller=>"/webmail/webmail", :action=>"manage_folders", :params=>{"op"=>_('(Delete)'), "folder_name"=>folder.name})) + end + end + + def message_date(datestr) + t = Time.now + begin + if datestr.kind_of?(String) + d = (Time.rfc2822(datestr) rescue Time.parse(value)).localtime + else + d = datestr + end + if d.day == t.day and d.month == t.month and d.year == t.year + d.strftime("%H:%M") + else + d.strftime("%Y-%m-%d") + end + rescue + begin + d = imap2time(datestr) + if d.day == t.day and d.month == t.month and d.year == t.year + d.strftime("%H:%M") + else + d.strftime("%Y-%m-%d") + end + rescue + datestr + end + end + end + + def attachment(att, index) + ret = "#{att.filename}" + # todo: add link to delete attachment + #ret << + ret << "" + ret << "" + ret << "" + end + + def link_filter_up(filter_id) + link_to(_('Up'), :controller=>"/webmail/webmail", :action=>"filter_up", :id=>filter_id) + end + + def link_filter_down(filter_id) + link_to(_('Down'), :controller=>"/webmail/webmail", :action=>"filter_down", :id=>filter_id) + end + + def link_filter_edit(filter_id) + link_to(_('Edit'), :controller=>"/webmail/webmail", :action=>"filter", :id=>filter_id) + end + + def link_filter_delete(filter_id) + link_to(_('Delete'), :controller=>"/webmail/webmail", :action=>"filter_delete", :id=>filter_id) + end + + def page_navigation_webmail(pages) + nav = "

" + + nav << "(#{pages.length} #{_('Pages')})   " + + window_pages = pages.current.window.pages + nav << "..." unless window_pages[0].first? + for page in window_pages + if pages.current == page + nav << page.number.to_s << " " + else + nav << link_to(page.number, :controller=>"/webmail/webmail", :action=>'messages', :page=>page.number) << " " + end + end + nav << "..." unless window_pages[-1].last? + nav << "   " + + nav << link_to(_('First'), :controller=>"/webmail/webmail", :action=>'messages', :page=>@pages.first.number) << " | " unless @pages.current.first? + nav << link_to(_('Prev'), :controller=>"/webmail/webmail", :action=>'messages', :page=>@pages.current.previous.number) << " | " if @pages.current.previous + nav << link_to(_('Next'), :controller=>"/webmail/webmail", :action=>'messages', :page=>@pages.current.next.number) << " | " if @pages.current.next + nav << link_to(_('Last'), :controller=>"/webmail/webmail", :action=>'messages', :page=>@pages.last.number) << " | " unless @pages.current.last? + + nav << "

" + + return nav + end + + def parse_subject(subject) + begin + if mime_encoded?(subject) + if mime_decode(subject) == '' + _('(No subject)') + else + mime_decode(subject) + end + else + if from_qp(subject) == '' + _('(No subject)') + else + from_qp(subject) + end + end + rescue Exception => ex + RAILS_DEFAULT_LOGGER.debug('Exception occured - #{ex}') + return "" + end + end + + def message_size(size) + if size / (1024*1024) > 0 + return "#{(size / (1024*1024)).round} MB" + elsif size / 1024 > 0 + return "#{(size / (1024)).round} KB" + else + return "#{size} B" + end + end +end + diff --git a/config/boot.rb b/config/boot.rb new file mode 100644 index 0000000..b829644 --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,17 @@ +unless defined?(RAILS_ROOT) + root_path = File.join(File.dirname(__FILE__), '..') + unless RUBY_PLATFORM =~ /mswin32/ + require 'pathname' + root_path = Pathname.new(root_path).cleanpath.to_s + end + RAILS_ROOT = root_path +end + +if File.directory?("#{RAILS_ROOT}/vendor/rails") + require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer" +else + require 'rubygems' + require 'initializer' +end + +Rails::Initializer.run(:set_load_path) \ No newline at end of file diff --git a/config/database.yml.example b/config/database.yml.example new file mode 100644 index 0000000..1d68aa8 --- /dev/null +++ b/config/database.yml.example @@ -0,0 +1,20 @@ +development: + adapter: mysql + database: mailr_dev + host: localhost + username: root + password: + +test: + adapter: mysql + database: mailr_tests + host: localhost + username: root + password: + +production: + adapter: mysql + database: mailr + host: localhost + username: root + password: diff --git a/config/default_site.rb b/config/default_site.rb new file mode 100644 index 0000000..6ab509c --- /dev/null +++ b/config/default_site.rb @@ -0,0 +1,51 @@ +# Site-specific parameters +# These are Mailr constants. If you want to overwrite +# some of them - create file config/site.rb +# containing new constants in LOCALCONFIG module variable - they +# will overwrite default values. Example site.rb: +# +# module CDF +# LOCALCONFIG = { +# :mysql_version => '4.1', +# :default_encoding => 'utf-8', +# :imap_server => 'your.imap.server', +# :imap_auth => 'LOGIN' +# } +# end + +module CDF + CONFIG = { + :mysql_version => '4.0', + :default_language => 'en', + :default_encoding => 'ISO-8859-1', + :mail_charset => 'ISO-8859-1', + :mail_inbox => 'INBOX', + :mail_trash => 'INBOX.Trash', + :mail_sent => 'INBOX.Sent', + :mail_bulk_sent => "INBOX.SentBulk", + :mail_spam => "INBOX.Spam", + :mail_temp_path => 'mail_temp', + :mail_filters_path => '/home/vmail/mailfilters', + :mail_send_types => {"Plain text" => "text/plain", "HTML"=>"text/html", "HTML and PlainText" => "multipart"}, + :mail_message_rows => [5, 10, 15, 20, 25, 30, 50], + :mail_filters_fields => {'From' => '^From', 'To' => '^To', 'CC' => '^CC', 'Subject' => '^Subject', 'Body' => '^Body'}, + :mail_filters_expressions => ['contains', 'starts with'], + :mail_search_fields => ['FROM', 'TO', 'CC', 'SUBJECT', 'BODY'], + :temp_file_location => ".", + :contacts_per_page => 15, + :contact_letters => ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'], + :upload_file_temp_path => "/tmp", + :imap_server => 'localhost', + :imap_use_ssl => false, + :imap_port => 143, + :imap_auth => 'PLAIN', # 'LOGIN', 'NOAUTH' + :encryption_salt => 'EnCr1p10n$@lt', + :encryption_password => '$0MeEncr1pt10nP@a$sw0rd', + :debug_imap => false, + :crypt_session_pass => true, # Set it to false (in site.rb) if you get any error messages like + # "Unsupported cipher algorithm (aes-128-cbc)." - meaning that OpenSSL modules for crypt algo is not loaded. Setting it to false will store password in session in plain format! + :send_from_domain => nil, # Set this variable to your domain name in site.rb if you make login to imap only with username (without '@domain') + :imap_bye_timeout_retry_seconds => 2 + } +end + diff --git a/config/environment.rb b/config/environment.rb new file mode 100644 index 0000000..2c5d125 --- /dev/null +++ b/config/environment.rb @@ -0,0 +1,74 @@ +# Be sure to restart your webserver when you modify this file. + +# Uncomment below to force Rails into production mode +# (Use only when you can't set environment variables through your web/app server) +# ENV['RAILS_ENV'] = 'production' + +# Bootstrap the Rails environment, frameworks, and default configuration +require File.join(File.dirname(__FILE__), 'boot') + +Rails::Initializer.run do |config| + # Skip frameworks you're not going to use + # config.frameworks -= [ :action_web_service, :action_mailer ] + + # Add additional load paths for your own custom dirs + config.load_paths += %W( #{RAILS_ROOT}/vendor/ezcrypto-0.1.1/lib ) + + # Force all environments to use the same logger level + # (by default production uses :info, the others :debug) + # config.log_level = :debug + + # Use the database for sessions instead of the file system + # (create the session table with 'rake create_sessions_table') + config.action_controller.session_store = :active_record_store + + # Enable page/fragment caching by setting a file-based store + # (remember to create the caching directory and make it readable to the application) + # config.action_controller.fragment_cache_store = :file_store, "#{RAILS_ROOT}/cache" + + # Activate observers that should always be running + # config.active_record.observers = :cacher, :garbage_collector + + # Make Active Record use UTC-base instead of local time + config.active_record.default_timezone = :utc + + # Use Active Record's schema dumper instead of SQL when creating the test database + # (enables use of different database adapters for development and test environments) + # config.active_record.schema_format = :ruby + + # See Rails::Configuration for more options +end + +# Add new inflection rules using the following format +# (all these examples are active by default): +# Inflector.inflections do |inflect| +# inflect.plural /^(ox)$/i, '\1en' +# inflect.singular /^(ox)en/i, '\1' +# inflect.irregular 'person', 'people' +# inflect.uncountable %w( fish sheep ) +# end + +# Include your application configuration below + +default_config_path = 'config/default_site' +default_config = File.join(RAILS_ROOT, default_config_path) +require default_config +begin + require File.join(RAILS_ROOT, 'config/site') + CDF::CONFIG.update(CDF::LOCALCONFIG) if CDF::LOCALCONFIG +rescue LoadError + STDERR.puts 'WARNING: config/site.rb not found, using default settings from ' + default_config_path +end + +require 'tmail_patch' +require 'gettext_extension' +$KCODE = 'u' +require 'jcode' + +# set UTF8 as a client interface to Database +RAILS_DEFAULT_LOGGER.debug("Using MySQL Version #{CDF::CONFIG[:mysql_version]}") +ActiveRecord::Base.connection.execute("SET NAMES utf8", 'Set Client encoding to UTF8') if CDF::CONFIG[:mysql_version] == '4.1' +ActiveRecord::Base.connection.execute("set character set utf8", 'Set Connection encoding to UTF8') if CDF::CONFIG[:mysql_version] == '4.1' + +require 'imapmailbox' +[IMAPMailbox, IMAPFolderList, IMAPFolder].each { |mod| mod.logger ||= RAILS_DEFAULT_LOGGER } diff --git a/config/environments/development.rb b/config/environments/development.rb new file mode 100644 index 0000000..a151c3b --- /dev/null +++ b/config/environments/development.rb @@ -0,0 +1,17 @@ +# In the development environment your application's code is reloaded on +# every request. This slows down response time but is perfect for development +# since you don't have to restart the webserver when you make code changes. +config.cache_classes = false + +# Log error messages when you accidentally call methods on nil. +config.whiny_nils = true + +# Enable the breakpoint server that script/breakpointer connects to +config.breakpoint_server = true + +# Show full error reports and disable caching +config.action_controller.consider_all_requests_local = true +config.action_controller.perform_caching = false + +# Don't care if the mailer can't send +config.action_mailer.raise_delivery_errors = false diff --git a/config/environments/production.rb b/config/environments/production.rb new file mode 100644 index 0000000..f2b9ed6 --- /dev/null +++ b/config/environments/production.rb @@ -0,0 +1,17 @@ +# The production environment is meant for finished, "live" apps. +# Code is not reloaded between requests +config.cache_classes = true + +# Use a different logger for distributed setups +# config.logger = SyslogLogger.new + + +# Full error reports are disabled and caching is turned on +config.action_controller.consider_all_requests_local = false +config.action_controller.perform_caching = true + +# Enable serving of images, stylesheets, and javascripts from an asset server +# config.action_controller.asset_host = "http://assets.example.com" + +# Disable delivery errors if you bad email addresses should just be ignored +# config.action_mailer.raise_delivery_errors = false diff --git a/config/environments/test.rb b/config/environments/test.rb new file mode 100644 index 0000000..66b823d --- /dev/null +++ b/config/environments/test.rb @@ -0,0 +1,23 @@ +# The test environment is used exclusively to run your application's +# test suite. You never need to work with it otherwise. Remember that +# your test database is "scratch space" for the test suite and is wiped +# and recreated between test runs. Don't rely on the data there! +config.cache_classes = true + +# Log error messages when you accidentally call methods on nil. +config.whiny_nils = true + +# Show full error reports and disable caching +config.action_controller.consider_all_requests_local = true +config.action_controller.perform_caching = false + +# Tell ActionMailer not to deliver emails to the real world. +# The :test delivery method accumulates sent emails in the +# ActionMailer::Base.deliveries array. +config.action_mailer.delivery_method = :test + +# Overwrite the default settings for fixtures in tests. See Fixtures +# for more details about these settings. +# config.transactional_fixtures = true +# config.instantiated_fixtures = false +# config.pre_loaded_fixtures = false \ No newline at end of file diff --git a/config/lighttpd.conf b/config/lighttpd.conf new file mode 100644 index 0000000..380d9e1 --- /dev/null +++ b/config/lighttpd.conf @@ -0,0 +1,79 @@ +server.port = 80 +server.bind = "127.0.0.1" +#server.event-handler = "freebsd-kqueue" + +server.modules = ( "mod_rewrite", "mod_fastcgi", ) +server.indexfiles = ( "dispatch.fcgi" ) +server.document-root = "public/" +server.error-handler-404 = "/dispatch.fcgi" +server.errorlog = "log/error.log" + +url.rewrite = ( "^/$" => "/login", "^([^.]+)$" => "$1.html" ) + +#### fastcgi module +fastcgi.server = ( + ".fcgi" => ( + "mailr" => ( + "min-procs" => 2, + "max-procs" => 2, + "socket" => "/tmp/mailr1.socket", + "bin-path" => "public/dispatch.fcgi", + "idle-timeout" => 120, + "bin-environment" => ( "RAILS_ENV" => "production" ) + ) + ) +) + + +mimetype.assign = ( + ".rpm" => "application/x-rpm", + ".pdf" => "application/pdf", + ".sig" => "application/pgp-signature", + ".spl" => "application/futuresplash", + ".class" => "application/octet-stream", + ".ps" => "application/postscript", + ".torrent" => "application/x-bittorrent", + ".dvi" => "application/x-dvi", + ".gz" => "application/x-gzip", + ".pac" => "application/x-ns-proxy-autoconfig", + ".swf" => "application/x-shockwave-flash", + ".tar.gz" => "application/x-tgz", + ".tgz" => "application/x-tgz", + ".tar" => "application/x-tar", + ".zip" => "application/zip", + ".mp3" => "audio/mpeg", + ".m3u" => "audio/x-mpegurl", + ".wma" => "audio/x-ms-wma", + ".wax" => "audio/x-ms-wax", + ".ogg" => "audio/x-wav", + ".wav" => "audio/x-wav", + ".gif" => "image/gif", + ".jpg" => "image/jpeg", + ".jpeg" => "image/jpeg", + ".png" => "image/png", + ".xbm" => "image/x-xbitmap", + ".xpm" => "image/x-xpixmap", + ".xwd" => "image/x-xwindowdump", + ".css" => "text/css", + ".html" => "text/html", + ".htm" => "text/html", + ".js" => "text/javascript", + ".asc" => "text/plain", + ".c" => "text/plain", + ".conf" => "text/plain", + ".text" => "text/plain", + ".txt" => "text/plain", + ".dtd" => "text/xml", + ".xml" => "text/xml", + ".mpeg" => "video/mpeg", + ".mpg" => "video/mpeg", + ".mov" => "video/quicktime", + ".qt" => "video/quicktime", + ".avi" => "video/x-msvideo", + ".asf" => "video/x-ms-asf", + ".asx" => "video/x-ms-asf", + ".wmv" => "video/x-ms-wmv", + ".bz2" => "application/x-bzip", + ".tbz" => "application/x-bzip-compressed-tar", + ".tar.bz2" => "application/x-bzip-compressed-tar" + ) diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 0000000..8ebec23 --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,23 @@ +ActionController::Routing::Routes.draw do |map| + # Add your own custom routes here. + # The priority is based upon order of creation: first created -> highest priority. + + # Here's a sample route: + # map.connect 'products/:id', :controller => 'catalog', :action => 'view' + # Keep in mind you can assign values other than :controller and :action + map.connect '', :controller=>'webmail/webmail', :action=>'index' + + map.connect 'webmail', :controller=>'webmail/webmail', :action=>'index' + + map.connect 'webmail/:action', :controller=>'webmail/webmail' + + map.connect 'contacts/contact/:action', :controller=>'contacts/contact' + + map.connect 'admin/main', :controller=> 'login', :action=>'logout' + # Allow downloading Web Service WSDL as a file with an extension + # instead of a file named 'wsdl' + map.connect ':controller/service.wsdl', :action => 'wsdl' + + # Install the default route as the lowest priority. + map.connect ':controller/:action/:id' +end diff --git a/db/schema.mysql.sql b/db/schema.mysql.sql new file mode 100644 index 0000000..081577d --- /dev/null +++ b/db/schema.mysql.sql @@ -0,0 +1,111 @@ +CREATE TABLE customers ( + id bigint(20) NOT NULL auto_increment, + fname varchar(50) default NULL, + lname varchar(50) default NULL, + email varchar(100) NOT NULL, + PRIMARY KEY (id), + UNIQUE INDEX (email) +) TYPE=MyISAM; + +CREATE TABLE filters ( + id bigint(20) NOT NULL auto_increment, + name varchar(50) default NULL, + destination_folder varchar(50) default NULL, + customer_id bigint(20) NOT NULL, + order_num int default 1, + PRIMARY KEY (id), + INDEX (customer_id), + FOREIGN KEY (customer_id) REFERENCES customers(id) +) TYPE=MyISAM; + +CREATE TABLE expressions ( + id bigint(20) NOT NULL auto_increment, + field_name varchar(20) default '^Subject' NOT NULL, + operator varchar(20) default 'contains' NOT NULL, + expr_value varchar(100) default '' NOT NULL, + case_sensitive bool default 0, + filter_id bigint(20) NOT NULL, + PRIMARY KEY (id), + INDEX (filter_id), + FOREIGN KEY (filter_id) REFERENCES filters(id) +) TYPE=MyISAM; + +CREATE TABLE `mail_prefs` ( + `id` int(11) NOT NULL auto_increment, + `mail_type` varchar(10) default 'text/plain', + `wm_rows` int(11) default '20', + `customer_id` bigint(20) default NULL, + `check_external_mail` tinyint(1) default '0', + PRIMARY KEY (`id`), + UNIQUE KEY `customer_id` (`customer_id`) +) TYPE=MyISAM; + +CREATE TABLE contacts ( + id bigint(20) NOT NULL auto_increment, + fname varchar(50) default NULL, + lname varchar(50) default NULL, + email varchar(100) default NULL, + hphone varchar(20) default NULL, + wphone varchar(20) default NULL, + mobile varchar(20) default NULL, + fax varchar(20) default NULL, + notes text, + create_date datetime default NULL, + delete_date datetime default NULL, + customer_id bigint(20) default NULL, + PRIMARY KEY (id), + INDEX (customer_id), + INDEX (customer_id, email), + INDEX (email), + FOREIGN KEY (customer_id) REFERENCES customers(id) +) TYPE=MyISAM; + +CREATE TABLE contact_groups ( + id bigint(20) NOT NULL auto_increment, + name varchar(50) default NULL, + customer_id bigint(20) default NULL, + PRIMARY KEY (id), + INDEX (customer_id), + FOREIGN KEY (customer_id) REFERENCES customers(id) +) TYPE=MyISAM; + +CREATE TABLE contact_contact_groups ( + contact_id bigint(20) NOT NULL, + contact_group_id bigint(20) NOT NULL, + PRIMARY KEY (contact_id, contact_group_id), + INDEX (contact_id), + INDEX (contact_group_id), + FOREIGN KEY (contact_id) REFERENCES contacts(id), + FOREIGN KEY (contact_group_id) REFERENCES contact_groups(id) +) TYPE=MyISAM; + +-- Mysql Sessions +create table sessions ( + id bigint(20) NOT NULL auto_increment, + session_id varchar(255), + data text, + updated_at timestamp, + primary key(id), + index(session_id) +); + +-- Cache +CREATE TABLE imap_messages ( + id bigint(20) NOT NULL auto_increment, + folder_name varchar(100) NOT NULL, + username varchar(100) NOT NULL, + msg_id varchar(100), + uid bigint(20) NOT NULL, + `from` varchar(255), + `from_flat` varchar(255), + `to` varchar(255), + `to_flat` varchar(255), + `subject` varchar(255), + `content_type` varchar(30), + `date` timestamp, + `unread` tinyint(1), + `size` bigint(20), + PRIMARY KEY (id), + INDEX (folder_name, username), + INDEX (folder_name, username,uid) +) TYPE=MyISAM; \ No newline at end of file diff --git a/db/schema.pgsql.sql b/db/schema.pgsql.sql new file mode 100644 index 0000000..8601175 --- /dev/null +++ b/db/schema.pgsql.sql @@ -0,0 +1,111 @@ +CREATE TABLE customers ( + id bigserial NOT NULL, + fname varchar(50) default NULL, + lname varchar(50) default NULL, + email varchar(100) NOT NULL, + PRIMARY KEY (id) +); +CREATE UNIQUE INDEX customers_email_idx ON customers(email); + +CREATE TABLE filters ( + id bigserial NOT NULL, + name varchar(50) default NULL, + destination_folder varchar(50) default NULL, + customer_id bigint NOT NULL, + order_num int default 1, + PRIMARY KEY (id), + FOREIGN KEY (customer_id) REFERENCES customers(id) +); +CREATE INDEX filters_customer_id_idx ON filters(customer_id); + +CREATE TABLE expressions ( + id bigserial NOT NULL, + field_name varchar(20) default '^Subject' NOT NULL, + operator varchar(20) default 'contains' NOT NULL, + expr_value varchar(100) default '' NOT NULL, + case_sensitive bool default FALSE, + filter_id bigint NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (filter_id) REFERENCES filters(id) +); +CREATE INDEX expressions_filter_id_idx ON expressions(filter_id); + +CREATE TABLE mail_prefs ( + id serial NOT NULL, + mail_type varchar(10) default 'text/plain', + wm_rows int default '20', + customer_id bigint default NULL, + check_external_mail bool default false, + PRIMARY KEY (id) +); +CREATE UNIQUE INDEX mail_prefs_customer_id_idx ON mail_prefs(customer_id); + +CREATE TABLE contacts ( + id bigserial NOT NULL, + fname varchar(50) default NULL, + lname varchar(50) default NULL, + email varchar(100) default NULL, + hphone varchar(20) default NULL, + wphone varchar(20) default NULL, + mobile varchar(20) default NULL, + fax varchar(20) default NULL, + notes text, + create_date timestamp default NULL, + delete_date timestamp default NULL, + customer_id bigint default NULL, + PRIMARY KEY (id), + FOREIGN KEY (customer_id) REFERENCES customers(id) +); +CREATE INDEX contacts_customer_id_idx ON contacts(customer_id); +CREATE INDEX contacts_customer_id_email_idx ON contacts(customer_id,email); +CREATE INDEX contacts_email_idx ON contacts(email); + + +CREATE TABLE contact_groups ( + id bigserial NOT NULL, + name varchar(50) default NULL, + customer_id bigint default NULL, + PRIMARY KEY (id), + FOREIGN KEY (customer_id) REFERENCES customers(id) +); +CREATE INDEX contact_groups_customer_id_idx ON contact_groups(customer_id); + +CREATE TABLE contact_contact_groups ( + contact_id bigint NOT NULL, + contact_group_id bigint NOT NULL, + PRIMARY KEY (contact_id, contact_group_id), + FOREIGN KEY (contact_id) REFERENCES contacts(id), + FOREIGN KEY (contact_group_id) REFERENCES contact_groups(id) +); +CREATE INDEX contact_contact_groups_contact_id_idx ON contact_contact_groups(contact_id); +CREATE INDEX contact_contact_groups_contact_group_id_idx ON contact_contact_groups(contact_group_id); + +create table sessions ( + id BIGSERIAL NOT NULL, + session_id VARCHAR(255) NULL, + data TEXT NULL, + updated_at TIMESTAMP default null, + PRIMARY KEY (id) +); +CREATE INDEX session_idx ON sessions(session_id); + +CREATE TABLE imap_messages ( + id BIGSERIAL NOT NULL, + folder_name VARCHAR(100) NOT NULL, + username VARCHAR(100) NOT NULL, + msg_id VARCHAR(100), + uid BIGINT NOT NULL, + "from" TEXT, + "from_flat" TEXT, + "to" TEXT, + "to_flat" TEXT, + "subject" TEXT, + "content_type" VARCHAR(30), + "date" TIMESTAMP, + "unread" BOOL default false, + "size" BIGINT, + PRIMARY KEY (id) +); + +CREATE INDEX msg_cache_fu_idx ON imap_messages(folder_name, username); +CREATE INDEX msg_cache_fuui_idx ON imap_messages(folder_name, username, uid); diff --git a/doc/README_FOR_APP b/doc/README_FOR_APP new file mode 100644 index 0000000..ac6c149 --- /dev/null +++ b/doc/README_FOR_APP @@ -0,0 +1,2 @@ +Use this README file to introduce your application and point to useful places in the API for learning more. +Run "rake appdoc" to generate API documentation for your models and controllers. \ No newline at end of file diff --git a/lib/cdfutils.rb b/lib/cdfutils.rb new file mode 100644 index 0000000..e780a01 --- /dev/null +++ b/lib/cdfutils.rb @@ -0,0 +1,183 @@ +MIME_ENCODED = /=\?([a-z\-0-9]*)\?[QB]\?([a-zA-Z0-9+\/=\_\-]+)\?=/i +IMAP_EMAIL_ENVELOPE_FORMAT = /([a-zA-Z\-\.\_]*@[a-zA-Z\-\.\_]*)/ +IMAP_EMAIL_ENVELOPE_FORMAT2 = /(.*)<([a-zA-Z\-\.\_]*@[a-zA-Z\-\.\_]*)>/ + +require 'iconv' + +def valid_email?(email) + email.size < 100 && email =~ /.@.+\../ && email.count('@') == 1 +end + +def mime_encoded?( str ) + return false if str.nil? + not (MIME_ENCODED =~ str).nil? +end + +def from_qp(str, remove_underscore = true) + return '' if str.nil? + result = str.gsub(/=\r\n/, "") + result = result.gsub(/_/, " ") if remove_underscore + result.gsub!(/\r\n/m, $/) + result.gsub!(/=([\da-fA-F]{2})/) { $1.hex.chr } + result +end + +def mime_decode(str, remove_underscore = true) + return '' if str.nil? + str.gsub(MIME_ENCODED) {|s| + enc = s.scan(MIME_ENCODED).flatten + if /\?Q\?/i =~ s + begin + Iconv.conv("UTF-8", enc[0], from_qp(enc[1], remove_underscore)) + rescue + from_qp(enc[1], remove_underscore) + end + else + begin + Iconv.conv("UTF-8", enc[0], enc[1].unpack("m*").to_s) + rescue + enc[1].unpack("m*").to_s + end + end + } +end + +def imap2friendlly_email(str) + begin + if str === IMAP_EMAIL_ENVELOPE_FORMAT + email = str.scan(IMAP_EMAIL_ENVELOPE_FORMAT)[0][0] + else + email = str.scan(IMAP_EMAIL_ENVELOPE_FORMAT2)[0][0] + end + name = str.slice(0, str.rindex(email)-1) + name = decode(name).to_s if mime_encoded?(name) + return "#{name.nil? ? '' : name.strip}<#{email}>" + rescue + "Error parsing str - #{str.scan(IMAP_EMAIL_ENVELOPE_FORMAT)} - #{str.scan(IMAP_EMAIL_ENVELOPE_FORMAT2)}" + end +end + +def imap2friendlly_name(str) + begin + email = str.scan(IMAP_EMAIL_ENVELOPE_FORMAT)[0][0] + name = str.slice(0, str.rindex(email)) + if name.nil? or name.strip == "" + return email + else + return name + end + rescue + str + end +end + +def imap2friendlly_full_name(str) + begin + email = str.scan(IMAP_EMAIL_ENVELOPE_FORMAT)[0][0] + name = str.slice(0, str.rindex(email)) + if name.nil? or name.strip == "" + return email + else + return "#{name}<#{email}>" + end + rescue + str + end +end + +def imap2name_only(str) + email = str.scan(IMAP_EMAIL_ENVELOPE_FORMAT)[0][0] + name = str.slice(0, str.rindex(email)) + return "#{name.nil? ? '' : name.strip}" +end + +def imap2time(str) + begin + vals = str.scan(/(...), (.?.) (...) (....) (..):(..):(..) (.*)/)[0] + Time.local(vals[3],vals[2],vals[1],vals[4],vals[5],vals[6]) + rescue + Time.now + end +end + +def encode_email(names, email) + nameen = "" + names.each_byte { | ch | nameen = nameen +"=" + sprintf("%X",ch) } + return "=?#{CDF::CONFIG[:mail_charset]}?Q?#{nameen}?= <#{email}>" +end + +# ############################# +# HTML utils +# ############################# +def replace_tag(tag, attrs) + replacements = {"body" => "", + "/body" => "", + "meta" => "", + "/meta" => "", + "head" => "", + "/head" => "", + "html" => "", + "/html" => "", + "title" => "
", + "/title" => "
", + "div" => "", + "/div" => "", + "span" => "", + "/span" => "", + "layer" => "", + "/layer" => "", + "br" => "
", + "/br" => "
", + "iframe" => "", + "/iframe" => "", + "link" => "", + "/link" => "", + "style" => "
", + "/style" => "
", + "script" => "
", + "/script" => "
" } + replacements.fetch(tag.downcase, ("<" << tag.downcase << replace_attr(attrs) << ">")) +end + +def replace_attr(attrs) + if attrs + attrs.downcase.gsub("onload", "onfilter"). + gsub("onclick", "onfilter"). + gsub("onkeypress", "onfilter"). + gsub("javascript", "_javascript"). + gsub("JavaScript", "_javascript") + else + "" + end +end + +def clear_html(text) + attribute_key = /[\w:_-]+/ + attribute_value = /(?:[A-Za-z0-9\-_#\%\.,\/\:]+|(?:'[^']*?'|"[^"]*?"))/ + attribute = /(?:#{attribute_key}(?:\s*=\s*#{attribute_value})?)/ + attributes = /(?:#{attribute}(?:\s+#{attribute})*)/ + tag_key = attribute_key + tag = %r{<([!/?\[]?(?:#{tag_key}|--))((?:\s+#{attributes})?\s*(?:[!/?\]]+|--)?)>} + text.gsub(tag, '').gsub(/\s+/, ' ').strip + CGI::escape(text) +end + +def strip_html(text) + attribute_key = /[\w:_-]+/ + attribute_value = /(?:[A-Za-z0-9\-_#\%\.,\/\:]+|(?:'[^']*?'|"[^"]*?"))/ + attribute = /(?:#{attribute_key}(?:\s*=\s*#{attribute_value})?)/ + attributes = /(?:#{attribute}(?:\s+#{attribute})*)/ + tag_key = attribute_key + tag = %r{<([!/?\[]?(?:#{tag_key}|--))((?:\s+#{attributes})?\s*(?:[!/?\]]+|--)?)>} + res = text.gsub(tag) { |match| + ret = "" + match.scan(tag) { |token| + ret << replace_tag(token[0], token[1]) + } + ret + } + # remove doctype tags + xattributes = /(?:#{attribute_value}(?:\s+#{attribute_value})*)/ + xtag = %r{} + res.gsub(xtag, '') +end diff --git a/lib/gettext_extension.rb b/lib/gettext_extension.rb new file mode 100755 index 0000000..a4a35ab --- /dev/null +++ b/lib/gettext_extension.rb @@ -0,0 +1,11 @@ +require 'gettext' +include GetText # we want to be able to translate everywhere + +module GetText + # GetText has this behaviour that it saves the binding to the mo file + # on a file by file basis. Every ruby file gets its own binding. We have to + # override this behaviour because it doesn't make any sense for a web + # application. We want one message catalog for all our files. + module_function + def callersrc; '*' end +end diff --git a/lib/tmail_patch.rb b/lib/tmail_patch.rb new file mode 100644 index 0000000..bb86dd7 --- /dev/null +++ b/lib/tmail_patch.rb @@ -0,0 +1,38 @@ +module TMail + class Mail + def parse_header( f ) + name = field = nil + unixfrom = nil + + while line = f.gets + case line + when /\A[ \t]/ # continue from prev line + raise SyntaxError, 'mail is began by space' unless field + field << ' ' << line.strip + + when /\A([^\: \t]+):\s*/ # new header line + add_hf name, field if field + name = $1 + field = $' #.strip + + when /\A\-*\s*\z/ # end of header + add_hf name, field if field + name = field = nil + break + + when /\AFrom (\S+)/ + unixfrom = $1 + else + # treat as continue from previos + raise SyntaxError, 'mail is began by space' unless field + field << ' ' << line.strip + end + end + add_hf name, field if name + + if unixfrom + add_hf 'Return-Path', "<#{unixfrom}>" unless @header['return-path'] + end + end + end +end diff --git a/locale/.messages.pot b/locale/.messages.pot new file mode 100644 index 0000000..b1f9059 --- /dev/null +++ b/locale/.messages.pot @@ -0,0 +1,466 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2005-04-07 18:17+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: app/controllers/webmail_controller.rb:57 /tmp/erb-gettext18743.0:30 +msgid "Add new folder" +msgstr "" + +#: app/controllers/webmail_controller.rb:59 app/helpers/webmail_helper.rb:74 app/helpers/webmail_helper.rb:74 +msgid "(Delete)" +msgstr "" + +#: app/controllers/webmail_controller.rb:61 +msgid "(Subscribe)" +msgstr "" + +#: app/controllers/webmail_controller.rb:62 +msgid "(Select)" +msgstr "" + +#: app/controllers/webmail_controller.rb:79 /tmp/erb-gettext18743.0:23 +msgid "copy" +msgstr "" + +#: app/controllers/webmail_controller.rb:83 /tmp/erb-gettext18743.0:24 +msgid "move" +msgstr "" + +#: app/controllers/webmail_controller.rb:87 /tmp/erb-gettext18743.0:89 /tmp/erb-gettext18743.0:16 +#: /tmp/erb-gettext18743.0:22 +msgid "delete" +msgstr "" + +#: app/controllers/webmail_controller.rb:91 /tmp/erb-gettext18743.0:25 +msgid "mark read" +msgstr "" + +#: app/controllers/webmail_controller.rb:98 /tmp/erb-gettext18743.0:26 +msgid "mark unread" +msgstr "" + +#: app/controllers/webmail_controller.rb:110 /tmp/erb-gettext18743.0:17 /tmp/erb-gettext18743.0:8 +msgid "Search" +msgstr "" + +#: app/controllers/webmail_controller.rb:115 /tmp/erb-gettext18743.0:18 /tmp/erb-gettext18743.0:9 +msgid "Show all" +msgstr "" + +#: app/controllers/webmail_controller.rb:143 +msgid "Password changed successfully" +msgstr "" + +#: app/controllers/webmail_controller.rb:146 +msgid "Password not changed - please enter correct password." +msgstr "" + +#: app/controllers/webmail_controller.rb:181 /tmp/erb-gettext18743.0:18 +msgid "Send" +msgstr "" + +#: app/controllers/webmail_controller.rb:190 app/controllers/webmail_controller.rb:245 +#: /tmp/erb-gettext18743.0:23 /tmp/erb-gettext18743.0:46 /tmp/erb-gettext18743.0:27 +msgid "Add" +msgstr "" + +#: app/controllers/webmail_controller.rb:228 app/controllers/webmail_controller.rb:247 +#: /tmp/erb-gettext18743.0:51 /tmp/erb-gettext18743.0:73 /tmp/erb-gettext18743.0:18 +#: /tmp/erb-gettext18743.0:33 /tmp/erb-gettext18743.0:35 +msgid "Save" +msgstr "" + +#: app/controllers/login_controller.rb:26 +msgid "Wrong email or password specified." +msgstr "" + +#: app/controllers/login_controller.rb:33 +msgid "User successfully logged out" +msgstr "" + +#: app/controllers/contact_controller.rb:135 +msgid "You havent selected file or the file is empty" +msgstr "" + +#: app/controllers/contact_controller.rb:161 app/controllers/contact_controller.rb:189 +msgid "Contact %" +msgstr "" + +#: app/controllers/contact_controller.rb:161 app/controllers/contact_controller.rb:189 +msgid "The e-mail duplicates the e-mail of another record!" +msgstr "" + +#: app/models/contact.rb:47 +msgid "Please enter your first name (2 to 20 characters)." +msgstr "" + +#: app/models/contact.rb:48 +msgid "Please enter your surname (2 to 20 characters)." +msgstr "" + +#: app/models/contact.rb:53 +msgid "Contacts email cannot be changed." +msgstr "" + +#: app/models/contact.rb:59 +msgid "Please enter a valid email address." +msgstr "" + +#: app/models/contact.rb:63 +msgid "An account for your email address already exists." +msgstr "" + +#: app/models/contact_group.rb:15 +msgid "Please enter group name (1 to 50 characters)" +msgstr "" + +#: app/models/contact_group.rb:21 +msgid "You already have contact group with this name" +msgstr "" + +#: app/helpers/webmail_helper.rb:6 +msgid "Folders" +msgstr "" + +#: app/helpers/webmail_helper.rb:10 +msgid "Compose" +msgstr "" + +#: app/helpers/webmail_helper.rb:14 +msgid "Refresh" +msgstr "" + +#: app/helpers/webmail_helper.rb:18 +msgid "Message list" +msgstr "" + +#: app/helpers/webmail_helper.rb:22 +msgid "Reply" +msgstr "" + +#: app/helpers/webmail_helper.rb:26 +msgid "Forward" +msgstr "" + +#: app/helpers/webmail_helper.rb:30 app/helpers/webmail_helper.rb:123 +msgid "Delete" +msgstr "" + +#: app/helpers/webmail_helper.rb:34 +msgid "View source" +msgstr "" + +#: app/helpers/webmail_helper.rb:38 +msgid "Manage folders" +msgstr "" + +#: app/helpers/webmail_helper.rb:42 /tmp/erb-gettext18743.0:1 +msgid "Change password" +msgstr "" + +#: app/helpers/webmail_helper.rb:46 +msgid "Preferences" +msgstr "" + +#: app/helpers/webmail_helper.rb:50 +msgid "Mail Filters" +msgstr "" + +#: app/helpers/webmail_helper.rb:54 /tmp/erb-gettext18743.0:1 /tmp/erb-gettext18743.0:19 +msgid "Contacts" +msgstr "" + +#: app/helpers/webmail_helper.rb:58 +msgid "Logout" +msgstr "" + +#: app/helpers/webmail_helper.rb:63 +msgid "(Empty)" +msgstr "" + +#: app/helpers/webmail_helper.rb:111 +msgid "Up" +msgstr "" + +#: app/helpers/webmail_helper.rb:115 +msgid "Down" +msgstr "" + +#: app/helpers/webmail_helper.rb:119 +msgid "Edit" +msgstr "" + +#: app/helpers/application_helper.rb:156 +msgid "First" +msgstr "" + +#: app/helpers/application_helper.rb:157 +msgid "Prev" +msgstr "" + +#: app/helpers/application_helper.rb:158 +msgid "Next" +msgstr "" + +#: app/helpers/application_helper.rb:159 +msgid "Last" +msgstr "" + +#: app/views/contact/add.rhtml:1 +msgid "Edit/Create contact" +msgstr "" + +#: app/views/contact/add.rhtml:13 /tmp/erb-gettext18743.0:17 /tmp/erb-gettext18743.0:17 +msgid "First name" +msgstr "" + +#: app/views/contact/add.rhtml:14 /tmp/erb-gettext18743.0:18 /tmp/erb-gettext18743.0:18 +msgid "Last name" +msgstr "" + +#: app/views/contact/add.rhtml:15 /tmp/erb-gettext18743.0:19 /tmp/erb-gettext18743.0:28 +#: /tmp/erb-gettext18743.0:59 /tmp/erb-gettext18743.0:80 /tmp/erb-gettext18743.0:14 +msgid "E-mail" +msgstr "" + +#: app/views/contact/add.rhtml:22 +msgid "Contact belong to these groups" +msgstr "" + +#: app/views/contact/add.rhtml:52 +msgid "Save and add another" +msgstr "" + +#: app/views/contact/add.rhtml:53 /tmp/erb-gettext18743.0:38 /tmp/erb-gettext18743.0:21 +msgid "Back to contacts" +msgstr "" + +#: app/views/contact/add.rhtml:55 /tmp/erb-gettext18743.0:99 +msgid "Back to message" +msgstr "" + +#: app/views/contact/import_preview.rhtml:1 +msgid "Contacts You Are About To Import" +msgstr "" + +#: app/views/contact/import_preview.rhtml:4 /tmp/erb-gettext18743.0:3 +msgid "Errors" +msgstr "" + +#: app/views/contact/import_preview.rhtml:36 /tmp/erb-gettext18743.0:20 +msgid "Import" +msgstr "" + +#: app/views/contact/import_preview.rhtml:37 +msgid "Choose another file" +msgstr "" + +#: app/views/contact/import_preview.rhtml:39 app/views/contact/list.rhtml:96 /tmp/erb-gettext18743.0:22 +#: /tmp/erb-gettext18743.0:22 +msgid "Back to folders" +msgstr "" + +#: app/views/contact/list.rhtml:26 +msgid "To CC BCC" +msgstr "" + +#: app/views/contact/list.rhtml:27 app/views/contact/list.rhtml:58 app/views/contact/list.rhtml:79 +#: /tmp/erb-gettext18743.0:7 /tmp/erb-gettext18743.0:13 +msgid "Name" +msgstr "" + +#: app/views/contact/list.rhtml:39 app/views/contact/list.rhtml:97 +msgid "Groups" +msgstr "" + +#: app/views/contact/list.rhtml:51 +msgid "choose" +msgstr "" + +#: app/views/contact/list.rhtml:52 +msgid "cancel" +msgstr "" + +#: app/views/contact/list.rhtml:74 /tmp/erb-gettext18743.0:19 +msgid "Back to groups" +msgstr "" + +#: app/views/contact/list.rhtml:89 +msgid "DELETE CONTACT?\r\name - %s\r\nE-mail - %s" +msgstr "" + +#: app/views/contact/list.rhtml:94 +msgid "Add One Contact" +msgstr "" + +#: app/views/contact/list.rhtml:95 +msgid "Add Multiple Contacts" +msgstr "" + +#: app/views/contact/add_multiple.rhtml:1 +msgid "Add multiple contacts" +msgstr "" + +#: app/views/contact/add_multiple.rhtml:11 +msgid "Comma-separated (CSV) file" +msgstr "" + +#: app/views/contact/add_multiple.rhtml:12 +msgid "Tab-delimited text file" +msgstr "" + +#: app/views/contact/add_multiple.rhtml:15 +msgid "Select file" +msgstr "" + +#: app/views/login/index.rhtml:20 app/views/login/index.rhtml:20 +msgid "Email" +msgstr "" + +#: app/views/login/index.rhtml:24 app/views/login/index.rhtml:24 /tmp/erb-gettext18743.0:16 +msgid "Password" +msgstr "" + +#: app/views/login/index.rhtml:29 +msgid "Log In" +msgstr "" + +#: app/views/layouts/public.rhtml:5 /tmp/erb-gettext18743.0:5 +msgid "Mailr" +msgstr "" + +#: app/views/contact_group/list.rhtml:1 +msgid "Contact Groups" +msgstr "" + +#: app/views/contact_group/list.rhtml:14 +msgid "members" +msgstr "" + +#: app/views/contact_group/list.rhtml:15 +msgid "edit" +msgstr "" + +#: app/views/contact_group/list.rhtml:16 +msgid "DELETE CONTACT GROUP %s?" +msgstr "" + +#: app/views/contact_group/list.rhtml:21 +msgid "Add Contact Group" +msgstr "" + +#: app/views/contact_group/edit.rhtml:1 +msgid "Edit/Create Contact Group" +msgstr "" + +#: app/views/webmail/filter.rhtml:1 /tmp/erb-gettext18743.0:1 /tmp/erb-gettext18743.0:1 +#: /tmp/erb-gettext18743.0:1 /tmp/erb-gettext18743.0:1 /tmp/erb-gettext18743.0:1 +#: /tmp/erb-gettext18743.0:1 /tmp/erb-gettext18743.0:1 /tmp/erb-gettext18743.0:1 +msgid "Mailbox of (%s)" +msgstr "" + +#: app/views/webmail/filter.rhtml:18 /tmp/erb-gettext18743.0:18 +msgid "Filter name" +msgstr "" + +#: app/views/webmail/filter.rhtml:21 +msgid "Messages matching" +msgstr "" + +#: app/views/webmail/filter.rhtml:25 +msgid "Will be placed in" +msgstr "" + +#: app/views/webmail/filter.rhtml:34 /tmp/erb-gettext18743.0:36 +msgid "Cancel" +msgstr "" + +#: app/views/webmail/manage_folders.rhtml:15 +msgid "Folder list" +msgstr "" + +#: app/views/webmail/manage_folders.rhtml:30 +msgid "Folder name" +msgstr "" + +#: app/views/webmail/messages.rhtml:20 +msgid "Operations on marked messages" +msgstr "" + +#: app/views/webmail/messages.rhtml:29 +msgid "Destination for move and copy operations" +msgstr "" + +#: app/views/webmail/messages.rhtml:44 /tmp/erb-gettext18743.0:16 /tmp/erb-gettext18743.0:21 +msgid "To" +msgstr "" + +#: app/views/webmail/messages.rhtml:46 +msgid "From" +msgstr "" + +#: app/views/webmail/messages.rhtml:48 /tmp/erb-gettext18743.0:23 /tmp/erb-gettext18743.0:24 +msgid "Subject" +msgstr "" + +#: app/views/webmail/messages.rhtml:49 +msgid "Date" +msgstr "" + +#: app/views/webmail/change_password.rhtml:18 +msgid "New password" +msgstr "" + +#: app/views/webmail/change_password.rhtml:20 +msgid "Change" +msgstr "" + +#: app/views/webmail/folders.rhtml:16 +msgid "Mailbox folders" +msgstr "" + +#: app/views/webmail/prefs.rhtml:20 +msgid "Send type message" +msgstr "" + +#: app/views/webmail/prefs.rhtml:27 +msgid "Messages per page" +msgstr "" + +#: app/views/webmail/mailsent.rhtml:18 /tmp/erb-gettext18743.0:22 +msgid "CC" +msgstr "" + +#: app/views/webmail/mailsent.rhtml:21 /tmp/erb-gettext18743.0:23 +msgid "BCC" +msgstr "" + +#: app/views/webmail/_search.rhtml:2 +msgid "Search in message field" +msgstr "" + +#: app/views/webmail/_search.rhtml:6 +msgid "for" +msgstr "" + +#: app/views/webmail/compose.rhtml:45 +msgid "Attachment" +msgstr "" + +#: app/views/webmail/_expr.rhtml:15 +msgid "case sensitive" +msgstr "" diff --git a/locale/bg_BG/LC_MESSAGES/messages.mo b/locale/bg_BG/LC_MESSAGES/messages.mo new file mode 100644 index 0000000..ca1894e Binary files /dev/null and b/locale/bg_BG/LC_MESSAGES/messages.mo differ diff --git a/locale/bg_BG/LC_MESSAGES/messages.po b/locale/bg_BG/LC_MESSAGES/messages.po new file mode 100644 index 0000000..f74fb3d --- /dev/null +++ b/locale/bg_BG/LC_MESSAGES/messages.po @@ -0,0 +1,527 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: Mailr 1.0\n" +"POT-Creation-Date: 2005-04-07 18:17+0300\n" +"PO-Revision-Date: 2005-04-07 18:39+0200\n" +"Last-Translator: Nick Penkov \n" +"Language-Team: bg \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Bulgarian\n" +"X-Poedit-Country: BULGARIA\n" +"X-Poedit-SourceCharset: iso-8859-1\n" +"X-Poedit-Basepath: /projects/mailr\n" + +#: app/controllers/webmail_controller.rb:57 +#: /tmp/erb-gettext18743.0:30 +msgid "Add new folder" +msgstr "Добавяне на папка" + +#: app/controllers/webmail_controller.rb:59 +#: app/helpers/webmail_helper.rb:74 +msgid "(Delete)" +msgstr "(Изтриване)" + +#: app/controllers/webmail_controller.rb:61 +msgid "(Subscribe)" +msgstr "(Абонирне)" + +#: app/controllers/webmail_controller.rb:62 +msgid "(Select)" +msgstr "(Избиране)" + +#: app/controllers/webmail_controller.rb:79 +#: /tmp/erb-gettext18743.0:23 +msgid "copy" +msgstr "копирай" + +#: app/controllers/webmail_controller.rb:83 +#: /tmp/erb-gettext18743.0:24 +msgid "move" +msgstr "премести" + +#: app/controllers/webmail_controller.rb:87 +#: /tmp/erb-gettext18743.0:89 +#: /tmp/erb-gettext18743.0:16 +#: /tmp/erb-gettext18743.0:22 +msgid "delete" +msgstr "изтриий" + +#: app/controllers/webmail_controller.rb:91 +#: /tmp/erb-gettext18743.0:25 +msgid "mark read" +msgstr "прочетено" + +#: app/controllers/webmail_controller.rb:98 +#: /tmp/erb-gettext18743.0:26 +msgid "mark unread" +msgstr "непрочетено" + +#: app/controllers/webmail_controller.rb:110 +#: /tmp/erb-gettext18743.0:17 +#: /tmp/erb-gettext18743.0:8 +msgid "Search" +msgstr "Търси" + +#: app/controllers/webmail_controller.rb:115 +#: /tmp/erb-gettext18743.0:18 +#: /tmp/erb-gettext18743.0:9 +msgid "Show all" +msgstr "Покажи всички" + +#: app/controllers/webmail_controller.rb:143 +msgid "Password changed successfully" +msgstr "Паролата е сменена успешно." + +#: app/controllers/webmail_controller.rb:146 +msgid "Password not changed - please enter correct password." +msgstr "Паролата не е сменена - моля въведете коректна парола." + +#: app/controllers/webmail_controller.rb:181 +#: /tmp/erb-gettext18743.0:18 +msgid "Send" +msgstr "Изпрати" + +#: app/controllers/webmail_controller.rb:190 +#: app/controllers/webmail_controller.rb:245 +#: /tmp/erb-gettext18743.0:23 +#: /tmp/erb-gettext18743.0:46 +#: /tmp/erb-gettext18743.0:27 +msgid "Add" +msgstr "Добави" + +#: app/controllers/webmail_controller.rb:228 +#: app/controllers/webmail_controller.rb:247 +#: /tmp/erb-gettext18743.0:51 +#: /tmp/erb-gettext18743.0:73 +#: /tmp/erb-gettext18743.0:18 +#: /tmp/erb-gettext18743.0:33 +#: /tmp/erb-gettext18743.0:35 +msgid "Save" +msgstr "Съхрани" + +#: app/controllers/login_controller.rb:26 +msgid "Wrong email or password specified." +msgstr "Грешен e-mail или парола са въведени." + +#: app/controllers/login_controller.rb:33 +msgid "User successfully logged out" +msgstr "Потребителя успешно излезе от системата." + +#: app/controllers/contact_controller.rb:135 +msgid "You havent selected file or the file is empty" +msgstr "Не сте избрали файл или файлът е празен." + +#: app/controllers/contact_controller.rb:161 +#: app/controllers/contact_controller.rb:189 +msgid "Contact %" +msgstr "Адрес %" + +#: app/controllers/contact_controller.rb:161 +#: app/controllers/contact_controller.rb:189 +msgid "The e-mail duplicates the e-mail of another record!" +msgstr "The e-mail duplicates the e-mail of another record!" + +#: app/models/contact.rb:47 +msgid "Please enter your first name (2 to 20 characters)." +msgstr "Please enter your first name (2 to 20 characters)." + +#: app/models/contact.rb:48 +msgid "Please enter your surname (2 to 20 characters)." +msgstr "Please enter your surname (2 to 20 characters)." + +#: app/models/contact.rb:53 +msgid "Contacts email cannot be changed." +msgstr "Contacts email cannot be changed." + +#: app/models/contact.rb:59 +msgid "Please enter a valid email address." +msgstr "Please enter a valid email address." + +#: app/models/contact.rb:63 +msgid "An account for your email address already exists." +msgstr "An account for your email address already exists." + +#: app/models/contact_group.rb:15 +msgid "Please enter group name (1 to 50 characters)" +msgstr "Please enter group name (1 to 50 characters)" + +#: app/models/contact_group.rb:21 +msgid "You already have contact group with this name" +msgstr "You already have contact group with this name" + +#: app/helpers/webmail_helper.rb:6 +msgid "Folders" +msgstr "Папки" + +#: app/helpers/webmail_helper.rb:10 +msgid "Compose" +msgstr "Ново писмо" + +#: app/helpers/webmail_helper.rb:14 +msgid "Refresh" +msgstr "Refresh" + +#: app/helpers/webmail_helper.rb:18 +msgid "Message list" +msgstr "Списък съобщения" + +#: app/helpers/webmail_helper.rb:22 +msgid "Reply" +msgstr "Отговори" + +#: app/helpers/webmail_helper.rb:26 +msgid "Forward" +msgstr "Препрати" + +#: app/helpers/webmail_helper.rb:30 +#: app/helpers/webmail_helper.rb:123 +msgid "Delete" +msgstr "Изтрий" + +#: app/helpers/webmail_helper.rb:34 +msgid "View source" +msgstr "Преглед на оригинала" + +#: app/helpers/webmail_helper.rb:38 +msgid "Manage folders" +msgstr "Управление на папки" + +#: app/helpers/webmail_helper.rb:42 +#: /tmp/erb-gettext18743.0:1 +msgid "Change password" +msgstr "Смени парола" + +#: app/helpers/webmail_helper.rb:46 +msgid "Preferences" +msgstr "Настройки" + +#: app/helpers/webmail_helper.rb:50 +msgid "Mail Filters" +msgstr "Филтри" + +#: app/helpers/webmail_helper.rb:54 +#: /tmp/erb-gettext18743.0:1 +#: /tmp/erb-gettext18743.0:19 +msgid "Contacts" +msgstr "Адреси" + +#: app/helpers/webmail_helper.rb:58 +msgid "Logout" +msgstr "Изход" + +#: app/helpers/webmail_helper.rb:63 +msgid "(Empty)" +msgstr "(Empty)" + +#: app/helpers/webmail_helper.rb:111 +msgid "Up" +msgstr "Нагоре" + +#: app/helpers/webmail_helper.rb:115 +msgid "Down" +msgstr "Надолу" + +#: app/helpers/webmail_helper.rb:119 +msgid "Edit" +msgstr "Редактирай" + +#: app/helpers/application_helper.rb:156 +msgid "First" +msgstr "Първи" + +#: app/helpers/application_helper.rb:157 +msgid "Prev" +msgstr "Следващ" + +#: app/helpers/application_helper.rb:158 +msgid "Next" +msgstr "Предишен" + +#: app/helpers/application_helper.rb:159 +msgid "Last" +msgstr "Последен" + +#: app/views/contact/add.rhtml:1 +msgid "Edit/Create contact" +msgstr "Edit/Create contact" + +#: app/views/contact/add.rhtml:13 +#: /tmp/erb-gettext18743.0:17 +msgid "First name" +msgstr "First name" + +#: app/views/contact/add.rhtml:14 +#: /tmp/erb-gettext18743.0:18 +msgid "Last name" +msgstr "Last name" + +#: app/views/contact/add.rhtml:15 +#: /tmp/erb-gettext18743.0:19 +#: /tmp/erb-gettext18743.0:28 +#: /tmp/erb-gettext18743.0:59 +#: /tmp/erb-gettext18743.0:80 +#: /tmp/erb-gettext18743.0:14 +msgid "E-mail" +msgstr "E-mail" + +#: app/views/contact/add.rhtml:22 +msgid "Contact belong to these groups" +msgstr "Contact belong to these groups" + +#: app/views/contact/add.rhtml:52 +msgid "Save and add another" +msgstr "Save and add another" + +#: app/views/contact/add.rhtml:53 +#: /tmp/erb-gettext18743.0:38 +#: /tmp/erb-gettext18743.0:21 +msgid "Back to contacts" +msgstr "Back to contacts" + +#: app/views/contact/add.rhtml:55 +#: /tmp/erb-gettext18743.0:99 +msgid "Back to message" +msgstr "Back to message" + +#: app/views/contact/import_preview.rhtml:1 +msgid "Contacts You Are About To Import" +msgstr "Contacts You Are About To Import" + +#: app/views/contact/import_preview.rhtml:4 +#: /tmp/erb-gettext18743.0:3 +msgid "Errors" +msgstr "Errors" + +#: app/views/contact/import_preview.rhtml:36 +#: /tmp/erb-gettext18743.0:20 +msgid "Import" +msgstr "Import" + +#: app/views/contact/import_preview.rhtml:37 +msgid "Choose another file" +msgstr "Choose another file" + +#: app/views/contact/import_preview.rhtml:39 +#: app/views/contact/list.rhtml:96 +#: /tmp/erb-gettext18743.0:22 +msgid "Back to folders" +msgstr "Back to folders" + +#: app/views/contact/list.rhtml:26 +msgid "To CC BCC" +msgstr "To CC BCC" + +#: app/views/contact/list.rhtml:27 +#: app/views/contact/list.rhtml:58 +#: app/views/contact/list.rhtml:79 +#: /tmp/erb-gettext18743.0:7 +#: /tmp/erb-gettext18743.0:13 +msgid "Name" +msgstr "Name" + +#: app/views/contact/list.rhtml:39 +#: app/views/contact/list.rhtml:97 +msgid "Groups" +msgstr "Groups" + +#: app/views/contact/list.rhtml:51 +msgid "choose" +msgstr "choose" + +#: app/views/contact/list.rhtml:52 +msgid "cancel" +msgstr "cancel" + +#: app/views/contact/list.rhtml:74 +#: /tmp/erb-gettext18743.0:19 +msgid "Back to groups" +msgstr "Back to groups" + +#: app/views/contact/list.rhtml:89 +msgid "" +"DELETE CONTACT?\r\n" +"ame - %s\r\n" +"E-mail - %s" +msgstr "" +"DELETE CONTACT?\r\n" +"ame - %s\r\n" +"E-mail - %s" + +#: app/views/contact/list.rhtml:94 +msgid "Add One Contact" +msgstr "Add One Contact" + +#: app/views/contact/list.rhtml:95 +msgid "Add Multiple Contacts" +msgstr "Add Multiple Contacts" + +#: app/views/contact/add_multiple.rhtml:1 +msgid "Add multiple contacts" +msgstr "Add multiple contacts" + +#: app/views/contact/add_multiple.rhtml:11 +msgid "Comma-separated (CSV) file" +msgstr "Comma-separated (CSV) file" + +#: app/views/contact/add_multiple.rhtml:12 +msgid "Tab-delimited text file" +msgstr "Tab-delimited text file" + +#: app/views/contact/add_multiple.rhtml:15 +msgid "Select file" +msgstr "Select file" + +#: app/views/login/index.rhtml:20 +msgid "Email" +msgstr "Email" + +#: app/views/login/index.rhtml:24 +#: /tmp/erb-gettext18743.0:16 +msgid "Password" +msgstr "Password" + +#: app/views/login/index.rhtml:29 +msgid "Log In" +msgstr "Log In" + +#: app/views/layouts/public.rhtml:5 +#: /tmp/erb-gettext18743.0:5 +msgid "Mailr" +msgstr "Mailr" + +#: app/views/contact_group/list.rhtml:1 +msgid "Contact Groups" +msgstr "Contact Groups" + +#: app/views/contact_group/list.rhtml:14 +msgid "members" +msgstr "members" + +#: app/views/contact_group/list.rhtml:15 +msgid "edit" +msgstr "edit" + +#: app/views/contact_group/list.rhtml:16 +msgid "DELETE CONTACT GROUP %s?" +msgstr "DELETE CONTACT GROUP %s?" + +#: app/views/contact_group/list.rhtml:21 +msgid "Add Contact Group" +msgstr "Add Contact Group" + +#: app/views/contact_group/edit.rhtml:1 +msgid "Edit/Create Contact Group" +msgstr "Edit/Create Contact Group" + +#: app/views/webmail/filter.rhtml:1 +#: /tmp/erb-gettext18743.0:1 +msgid "Mailbox of (%s)" +msgstr "Пощенска кутия на (%s)" + +#: app/views/webmail/filter.rhtml:18 +#: /tmp/erb-gettext18743.0:18 +msgid "Filter name" +msgstr "Filter name" + +#: app/views/webmail/filter.rhtml:21 +msgid "Messages matching" +msgstr "Messages matching" + +#: app/views/webmail/filter.rhtml:25 +msgid "Will be placed in" +msgstr "Will be placed in" + +#: app/views/webmail/filter.rhtml:34 +#: /tmp/erb-gettext18743.0:36 +msgid "Cancel" +msgstr "Cancel" + +#: app/views/webmail/manage_folders.rhtml:15 +msgid "Folder list" +msgstr "Folder list" + +#: app/views/webmail/manage_folders.rhtml:30 +msgid "Folder name" +msgstr "Folder name" + +#: app/views/webmail/messages.rhtml:20 +msgid "Operations on marked messages" +msgstr "Operations on marked messages" + +#: app/views/webmail/messages.rhtml:29 +msgid "Destination for move and copy operations" +msgstr "Destination for move and copy operations" + +#: app/views/webmail/messages.rhtml:44 +#: /tmp/erb-gettext18743.0:16 +#: /tmp/erb-gettext18743.0:21 +msgid "To" +msgstr "To" + +#: app/views/webmail/messages.rhtml:46 +msgid "From" +msgstr "From" + +#: app/views/webmail/messages.rhtml:48 +#: /tmp/erb-gettext18743.0:23 +#: /tmp/erb-gettext18743.0:24 +msgid "Subject" +msgstr "Subject" + +#: app/views/webmail/messages.rhtml:49 +msgid "Date" +msgstr "Date" + +#: app/views/webmail/change_password.rhtml:18 +msgid "New password" +msgstr "New password" + +#: app/views/webmail/change_password.rhtml:20 +msgid "Change" +msgstr "Change" + +#: app/views/webmail/folders.rhtml:16 +msgid "Mailbox folders" +msgstr "Mailbox folders" + +#: app/views/webmail/prefs.rhtml:20 +msgid "Send type message" +msgstr "Send type message" + +#: app/views/webmail/prefs.rhtml:27 +msgid "Messages per page" +msgstr "Messages per page" + +#: app/views/webmail/mailsent.rhtml:18 +#: /tmp/erb-gettext18743.0:22 +msgid "CC" +msgstr "CC" + +#: app/views/webmail/mailsent.rhtml:21 +#: /tmp/erb-gettext18743.0:23 +msgid "BCC" +msgstr "BCC" + +#: app/views/webmail/_search.rhtml:2 +msgid "Search in message field" +msgstr "Search in message field" + +#: app/views/webmail/_search.rhtml:6 +msgid "for" +msgstr "for" + +#: app/views/webmail/compose.rhtml:45 +msgid "Attachment" +msgstr "Attachment" + +#: app/views/webmail/_expr.rhtml:15 +msgid "case sensitive" +msgstr "case sensitive" + diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..8e8d1fe --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,40 @@ +# General Apache options +AddHandler fastcgi-script .fcgi +AddHandler cgi-script .cgi +Options +FollowSymLinks +ExecCGI + +# If you don't want Rails to look in certain directories, +# use the following rewrite rules so that Apache won't rewrite certain requests +# +# Example: +# RewriteCond %{REQUEST_URI} ^/notrails.* +# RewriteRule .* - [L] + +# Redirect all requests not available on the filesystem to Rails +# By default the cgi dispatcher is used which is very slow +# +# For better performance replace the dispatcher with the fastcgi one +# +# Example: +# RewriteRule ^(.*)$ dispatch.fcgi [QSA,L] +RewriteEngine On + +# If your Rails application is accessed via an Alias directive, +# then you MUST also set the RewriteBase in this htaccess file. +# +# Example: +# Alias /myrailsapp /path/to/myrailsapp/public +# RewriteBase /myrailsapp + +RewriteRule ^$ /login [QSA] +RewriteRule ^([^.]+)$ $1.html [QSA] +RewriteCond %{REQUEST_FILENAME} !-f +RewriteRule ^(.*)$ dispatch.cgi [QSA,L] + +# In case Rails experiences terminal errors +# Instead of displaying this message you can supply a file here which will be rendered instead +# +# Example: +# ErrorDocument 500 /500.html + +ErrorDocument 500 "

Application error

Rails application failed to start properly" diff --git a/public/404.html b/public/404.html new file mode 100644 index 0000000..0e18456 --- /dev/null +++ b/public/404.html @@ -0,0 +1,8 @@ + + + +

File not found

+

Change this error message for pages not found in public/404.html

+ + \ No newline at end of file diff --git a/public/500.html b/public/500.html new file mode 100644 index 0000000..a1001a0 --- /dev/null +++ b/public/500.html @@ -0,0 +1,8 @@ + + + +

Application error (Apache)

+

Change this error message for exceptions thrown outside of an action (like in Dispatcher setups or broken Ruby code) in public/500.html

+ + \ No newline at end of file diff --git a/public/dispatch.cgi b/public/dispatch.cgi new file mode 100755 index 0000000..32fa3b2 --- /dev/null +++ b/public/dispatch.cgi @@ -0,0 +1,10 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT) + +# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like: +# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired +require "dispatcher" + +ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun) +Dispatcher.dispatch diff --git a/public/dispatch.fcgi b/public/dispatch.fcgi new file mode 100755 index 0000000..664dbbb --- /dev/null +++ b/public/dispatch.fcgi @@ -0,0 +1,24 @@ +#!/usr/bin/env ruby +# +# You may specify the path to the FastCGI crash log (a log of unhandled +# exceptions which forced the FastCGI instance to exit, great for debugging) +# and the number of requests to process before running garbage collection. +# +# By default, the FastCGI crash log is RAILS_ROOT/log/fastcgi.crash.log +# and the GC period is nil (turned off). A reasonable number of requests +# could range from 10-100 depending on the memory footprint of your app. +# +# Example: +# # Default log path, normal GC behavior. +# RailsFCGIHandler.process! +# +# # Default log path, 50 requests between GC. +# RailsFCGIHandler.process! nil, 50 +# +# # Custom log path, normal GC behavior. +# RailsFCGIHandler.process! '/var/log/myapp_fcgi_crash.log' +# +require File.dirname(__FILE__) + "/../config/environment" +require 'fcgi_handler' + +RailsFCGIHandler.process! diff --git a/public/dispatch.rb b/public/dispatch.rb new file mode 100755 index 0000000..32fa3b2 --- /dev/null +++ b/public/dispatch.rb @@ -0,0 +1,10 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT) + +# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like: +# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired +require "dispatcher" + +ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun) +Dispatcher.dispatch diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..e69de29 diff --git a/public/images/attachment.png b/public/images/attachment.png new file mode 100644 index 0000000..0fcf464 Binary files /dev/null and b/public/images/attachment.png differ diff --git a/public/images/d6deec.gif b/public/images/d6deec.gif new file mode 100644 index 0000000..c3b04b6 Binary files /dev/null and b/public/images/d6deec.gif differ diff --git a/public/images/deselect.png b/public/images/deselect.png new file mode 100644 index 0000000..a487186 Binary files /dev/null and b/public/images/deselect.png differ diff --git a/public/images/icon-folder-open.gif b/public/images/icon-folder-open.gif new file mode 100644 index 0000000..5cfb2c6 Binary files /dev/null and b/public/images/icon-folder-open.gif differ diff --git a/public/images/list_closed.gif b/public/images/list_closed.gif new file mode 100644 index 0000000..0e76b13 Binary files /dev/null and b/public/images/list_closed.gif differ diff --git a/public/images/list_opened.gif b/public/images/list_opened.gif new file mode 100644 index 0000000..7e1561b Binary files /dev/null and b/public/images/list_opened.gif differ diff --git a/public/images/noprogress.gif b/public/images/noprogress.gif new file mode 100644 index 0000000..facbced Binary files /dev/null and b/public/images/noprogress.gif differ diff --git a/public/images/select.png b/public/images/select.png new file mode 100644 index 0000000..2037e27 Binary files /dev/null and b/public/images/select.png differ diff --git a/public/images/white.gif b/public/images/white.gif new file mode 100644 index 0000000..d7960f2 Binary files /dev/null and b/public/images/white.gif differ diff --git a/public/images/white.png b/public/images/white.png new file mode 100644 index 0000000..90166ec Binary files /dev/null and b/public/images/white.png differ diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..d780f8e --- /dev/null +++ b/public/index.html @@ -0,0 +1,78 @@ + + + + Rails: Welcome on board + + + + +

Congratulations, you've put Ruby on Rails!

+ +

Before you move on, verify that the following conditions have been met:

+ +
    +
  1. The log and public directories must be writable to the web server (chmod -R 775 log and chmod -R 775 public). +
  2. + The shebang line in the public/dispatch* files must reference your Ruby installation.
    + You might need to change it to #!/usr/bin/env ruby or point directly at the installation. +
  3. +
  4. + Rails on Apache needs to have the cgi handler and mod_rewrite enabled.
    + Somewhere in your httpd.conf, you should have:
    + AddHandler cgi-script .cgi
    + LoadModule rewrite_module libexec/httpd/mod_rewrite.so
    + AddModule mod_rewrite.c +
  5. +
+ +

Take the following steps to get started:

+ +
    +
  1. Create empty development and test databases for your application.
    + Recommendation: Use *_development and *_test names, such as basecamp_development and basecamp_test
    + Warning: Don't point your test database at your development database, it'll destroy the latter on test runs! +
  2. Edit config/database.yml with your database settings. +
  3. Create controllers and models using the generator in script/generate
    + Help: Run the generator with no arguments for documentation +
  4. See all the tests run by running rake. +
  5. Develop your Rails application! +
  6. Setup Apache with FastCGI (and Ruby bindings), if you need better performance +
  7. Remove the dispatches you don't use (so if you're on FastCGI, delete/move dispatch.rb, dispatch.cgi and gateway.cgi)
  8. +
+ +

+ Trying to setup a default page for Rails using Routes? You'll have to delete this file (public/index.html) to get under way. Then define a new route in config/routes.rb of the form: +

  map.connect '', :controller => 'wiki/page', :action => 'show', :title => 'Welcome'
+

+ +

+ Having problems getting up and running? First try debugging it yourself by looking at the log files.
+ Then try the friendly Rails community on the web or on IRC + (FreeNode#rubyonrails). +

+ + + diff --git a/public/javascripts/contact_choose.js b/public/javascripts/contact_choose.js new file mode 100755 index 0000000..fc27f07 --- /dev/null +++ b/public/javascripts/contact_choose.js @@ -0,0 +1,52 @@ + +var fieldTo = "" +var fieldToc = "" +var fieldCC = "" +var fieldBCC = "" + +function respondTo(str) { + if (fieldTo == "") fieldTo += str + else fieldTo += "," + str +} + +function respondTo(str, contactId) { + if (fieldTo == "") fieldTo += str + else fieldTo += "," + str + + if (fieldToc == "") fieldToc += contactId + else fieldToc += "," + contactId +} + +function respondCC(str) { + if (fieldCC == "") fieldCC += str + else fieldCC += "," + str +} + +function respondBCC(str) { + if (fieldBCC == "") fieldBCC += str + else fieldBCC += "," + str +} + +function respondToCaller() { + if (window.opener) { + doc = window.opener.document; + setAddrField(getFormFieldPoint(doc, 'mail_to'), fieldTo); + setAddrField(getFormFieldPoint(doc, 'mail_toc'), fieldToc); + setAddrField(getFormFieldPoint(doc, 'mail_cc'), fieldCC); + setAddrField(getFormFieldPoint(doc, 'mail_bcc'), fieldBCC); + window.close(); + } +} + +function getFormFieldPoint(doc, id) { + if ( doc.getElementById ) elem = doc.getElementById( id ); + else if ( doc.all ) elem = doc.eval( "document.all." + id ); + return elem +} + +function setAddrField(fld, value) { + if (value != "") { + if (fld.value == "") fld.value = value; + else fld.value += "," + value; + } +} \ No newline at end of file diff --git a/public/javascripts/controls.js b/public/javascripts/controls.js new file mode 100644 index 0000000..a7436bc --- /dev/null +++ b/public/javascripts/controls.js @@ -0,0 +1,708 @@ +// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// (c) 2005 Ivan Krstic (http://blogs.law.harvard.edu/ivan) +// (c) 2005 Jon Tirsen (http://www.tirsen.com) +// Contributors: +// Richard Livsey +// Rahul Bhargava +// Rob Wills +// +// See scriptaculous.js for full license. + +// Autocompleter.Base handles all the autocompletion functionality +// that's independent of the data source for autocompletion. This +// includes drawing the autocompletion menu, observing keyboard +// and mouse events, and similar. +// +// Specific autocompleters need to provide, at the very least, +// a getUpdatedChoices function that will be invoked every time +// the text inside the monitored textbox changes. This method +// should get the text for which to provide autocompletion by +// invoking this.getToken(), NOT by directly accessing +// this.element.value. This is to allow incremental tokenized +// autocompletion. Specific auto-completion logic (AJAX, etc) +// belongs in getUpdatedChoices. +// +// Tokenized incremental autocompletion is enabled automatically +// when an autocompleter is instantiated with the 'tokens' option +// in the options parameter, e.g.: +// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' }); +// will incrementally autocomplete with a comma as the token. +// Additionally, ',' in the above example can be replaced with +// a token array, e.g. { tokens: [',', '\n'] } which +// enables autocompletion on multiple tokens. This is most +// useful when one of the tokens is \n (a newline), as it +// allows smart autocompletion after linebreaks. + +var Autocompleter = {} +Autocompleter.Base = function() {}; +Autocompleter.Base.prototype = { + baseInitialize: function(element, update, options) { + this.element = $(element); + this.update = $(update); + this.hasFocus = false; + this.changed = false; + this.active = false; + this.index = 0; + this.entryCount = 0; + + if (this.setOptions) + this.setOptions(options); + else + this.options = options || {}; + + this.options.paramName = this.options.paramName || this.element.name; + this.options.tokens = this.options.tokens || []; + this.options.frequency = this.options.frequency || 0.4; + this.options.minChars = this.options.minChars || 1; + this.options.onShow = this.options.onShow || + function(element, update){ + if(!update.style.position || update.style.position=='absolute') { + update.style.position = 'absolute'; + Position.clone(element, update, {setHeight: false, offsetTop: element.offsetHeight}); + } + Effect.Appear(update,{duration:0.15}); + }; + this.options.onHide = this.options.onHide || + function(element, update){ new Effect.Fade(update,{duration:0.15}) }; + + if (typeof(this.options.tokens) == 'string') + this.options.tokens = new Array(this.options.tokens); + + this.observer = null; + + this.element.setAttribute('autocomplete','off'); + + Element.hide(this.update); + + Event.observe(this.element, "blur", this.onBlur.bindAsEventListener(this)); + Event.observe(this.element, "keypress", this.onKeyPress.bindAsEventListener(this)); + }, + + show: function() { + if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update); + if(!this.iefix && (navigator.appVersion.indexOf('MSIE')>0) && (Element.getStyle(this.update, 'position')=='absolute')) { + new Insertion.After(this.update, + ''); + this.iefix = $(this.update.id+'_iefix'); + } + if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50); + }, + + fixIEOverlapping: function() { + Position.clone(this.update, this.iefix); + this.iefix.style.zIndex = 1; + this.update.style.zIndex = 2; + Element.show(this.iefix); + }, + + hide: function() { + this.stopIndicator(); + if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update); + if(this.iefix) Element.hide(this.iefix); + }, + + startIndicator: function() { + if(this.options.indicator) Element.show(this.options.indicator); + }, + + stopIndicator: function() { + if(this.options.indicator) Element.hide(this.options.indicator); + }, + + onKeyPress: function(event) { + if(this.active) + switch(event.keyCode) { + case Event.KEY_TAB: + case Event.KEY_RETURN: + this.selectEntry(); + Event.stop(event); + case Event.KEY_ESC: + this.hide(); + this.active = false; + Event.stop(event); + return; + case Event.KEY_LEFT: + case Event.KEY_RIGHT: + return; + case Event.KEY_UP: + this.markPrevious(); + this.render(); + if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); + return; + case Event.KEY_DOWN: + this.markNext(); + this.render(); + if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); + return; + } + else + if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN) + return; + + this.changed = true; + this.hasFocus = true; + + if(this.observer) clearTimeout(this.observer); + this.observer = + setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000); + }, + + onHover: function(event) { + var element = Event.findElement(event, 'LI'); + if(this.index != element.autocompleteIndex) + { + this.index = element.autocompleteIndex; + this.render(); + } + Event.stop(event); + }, + + onClick: function(event) { + var element = Event.findElement(event, 'LI'); + this.index = element.autocompleteIndex; + this.selectEntry(); + this.hide(); + }, + + onBlur: function(event) { + // needed to make click events working + setTimeout(this.hide.bind(this), 250); + this.hasFocus = false; + this.active = false; + }, + + render: function() { + if(this.entryCount > 0) { + for (var i = 0; i < this.entryCount; i++) + this.index==i ? + Element.addClassName(this.getEntry(i),"selected") : + Element.removeClassName(this.getEntry(i),"selected"); + + if(this.hasFocus) { + this.show(); + this.active = true; + } + } else this.hide(); + }, + + markPrevious: function() { + if(this.index > 0) this.index-- + else this.index = this.entryCount-1; + }, + + markNext: function() { + if(this.index < this.entryCount-1) this.index++ + else this.index = 0; + }, + + getEntry: function(index) { + return this.update.firstChild.childNodes[index]; + }, + + getCurrentEntry: function() { + return this.getEntry(this.index); + }, + + selectEntry: function() { + this.active = false; + this.updateElement(this.getCurrentEntry()); + }, + + updateElement: function(selectedElement) { + if (this.options.updateElement) { + this.options.updateElement(selectedElement); + return; + } + + var value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); + var lastTokenPos = this.findLastToken(); + if (lastTokenPos != -1) { + var newValue = this.element.value.substr(0, lastTokenPos + 1); + var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/); + if (whitespace) + newValue += whitespace[0]; + this.element.value = newValue + value; + } else { + this.element.value = value; + } + this.element.focus(); + + if (this.options.afterUpdateElement) + this.options.afterUpdateElement(this.element, selectedElement); + }, + + updateChoices: function(choices) { + if(!this.changed && this.hasFocus) { + this.update.innerHTML = choices; + Element.cleanWhitespace(this.update); + Element.cleanWhitespace(this.update.firstChild); + + if(this.update.firstChild && this.update.firstChild.childNodes) { + this.entryCount = + this.update.firstChild.childNodes.length; + for (var i = 0; i < this.entryCount; i++) { + var entry = this.getEntry(i); + entry.autocompleteIndex = i; + this.addObservers(entry); + } + } else { + this.entryCount = 0; + } + + this.stopIndicator(); + + this.index = 0; + this.render(); + } + }, + + addObservers: function(element) { + Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this)); + Event.observe(element, "click", this.onClick.bindAsEventListener(this)); + }, + + onObserverEvent: function() { + this.changed = false; + if(this.getToken().length>=this.options.minChars) { + this.startIndicator(); + this.getUpdatedChoices(); + } else { + this.active = false; + this.hide(); + } + }, + + getToken: function() { + var tokenPos = this.findLastToken(); + if (tokenPos != -1) + var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,''); + else + var ret = this.element.value; + + return /\n/.test(ret) ? '' : ret; + }, + + findLastToken: function() { + var lastTokenPos = -1; + + for (var i=0; i lastTokenPos) + lastTokenPos = thisTokenPos; + } + return lastTokenPos; + } +} + +Ajax.Autocompleter = Class.create(); +Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), { + initialize: function(element, update, url, options) { + this.baseInitialize(element, update, options); + this.options.asynchronous = true; + this.options.onComplete = this.onComplete.bind(this); + this.options.defaultParams = this.options.parameters || null; + this.url = url; + }, + + getUpdatedChoices: function() { + entry = encodeURIComponent(this.options.paramName) + '=' + + encodeURIComponent(this.getToken()); + + this.options.parameters = this.options.callback ? + this.options.callback(this.element, entry) : entry; + + if(this.options.defaultParams) + this.options.parameters += '&' + this.options.defaultParams; + + new Ajax.Request(this.url, this.options); + }, + + onComplete: function(request) { + this.updateChoices(request.responseText); + } + +}); + +// The local array autocompleter. Used when you'd prefer to +// inject an array of autocompletion options into the page, rather +// than sending out Ajax queries, which can be quite slow sometimes. +// +// The constructor takes four parameters. The first two are, as usual, +// the id of the monitored textbox, and id of the autocompletion menu. +// The third is the array you want to autocomplete from, and the fourth +// is the options block. +// +// Extra local autocompletion options: +// - choices - How many autocompletion choices to offer +// +// - partialSearch - If false, the autocompleter will match entered +// text only at the beginning of strings in the +// autocomplete array. Defaults to true, which will +// match text at the beginning of any *word* in the +// strings in the autocomplete array. If you want to +// search anywhere in the string, additionally set +// the option fullSearch to true (default: off). +// +// - fullSsearch - Search anywhere in autocomplete array strings. +// +// - partialChars - How many characters to enter before triggering +// a partial match (unlike minChars, which defines +// how many characters are required to do any match +// at all). Defaults to 2. +// +// - ignoreCase - Whether to ignore case when autocompleting. +// Defaults to true. +// +// It's possible to pass in a custom function as the 'selector' +// option, if you prefer to write your own autocompletion logic. +// In that case, the other options above will not apply unless +// you support them. + +Autocompleter.Local = Class.create(); +Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), { + initialize: function(element, update, array, options) { + this.baseInitialize(element, update, options); + this.options.array = array; + }, + + getUpdatedChoices: function() { + this.updateChoices(this.options.selector(this)); + }, + + setOptions: function(options) { + this.options = Object.extend({ + choices: 10, + partialSearch: true, + partialChars: 2, + ignoreCase: true, + fullSearch: false, + selector: function(instance) { + var ret = []; // Beginning matches + var partial = []; // Inside matches + var entry = instance.getToken(); + var count = 0; + + for (var i = 0; i < instance.options.array.length && + ret.length < instance.options.choices ; i++) { + + var elem = instance.options.array[i]; + var foundPos = instance.options.ignoreCase ? + elem.toLowerCase().indexOf(entry.toLowerCase()) : + elem.indexOf(entry); + + while (foundPos != -1) { + if (foundPos == 0 && elem.length != entry.length) { + ret.push("
  • " + elem.substr(0, entry.length) + "" + + elem.substr(entry.length) + "
  • "); + break; + } else if (entry.length >= instance.options.partialChars && + instance.options.partialSearch && foundPos != -1) { + if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) { + partial.push("
  • " + elem.substr(0, foundPos) + "" + + elem.substr(foundPos, entry.length) + "" + elem.substr( + foundPos + entry.length) + "
  • "); + break; + } + } + + foundPos = instance.options.ignoreCase ? + elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : + elem.indexOf(entry, foundPos + 1); + + } + } + if (partial.length) + ret = ret.concat(partial.slice(0, instance.options.choices - ret.length)) + return "
      " + ret.join('') + "
    "; + } + }, options || {}); + } +}); + +// AJAX in-place editor +// +// see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor + +Ajax.InPlaceEditor = Class.create(); +Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99"; +Ajax.InPlaceEditor.prototype = { + initialize: function(element, url, options) { + this.url = url; + this.element = $(element); + + this.options = Object.extend({ + okText: "ok", + cancelText: "cancel", + savingText: "Saving...", + clickToEditText: "Click to edit", + okText: "ok", + rows: 1, + onComplete: function(transport, element) { + new Effect.Highlight(element, {startcolor: this.options.highlightcolor}); + }, + onFailure: function(transport) { + alert("Error communicating with the server: " + transport.responseText.stripTags()); + }, + callback: function(form) { + return Form.serialize(form); + }, + handleLineBreaks: true, + loadingText: 'Loading...', + savingClassName: 'inplaceeditor-saving', + loadingClassName: 'inplaceeditor-loading', + formClassName: 'inplaceeditor-form', + highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor, + highlightendcolor: "#FFFFFF", + externalControl: null, + ajaxOptions: {} + }, options || {}); + + if(!this.options.formId && this.element.id) { + this.options.formId = this.element.id + "-inplaceeditor"; + if ($(this.options.formId)) { + // there's already a form with that name, don't specify an id + this.options.formId = null; + } + } + + if (this.options.externalControl) { + this.options.externalControl = $(this.options.externalControl); + } + + this.originalBackground = Element.getStyle(this.element, 'background-color'); + if (!this.originalBackground) { + this.originalBackground = "transparent"; + } + + this.element.title = this.options.clickToEditText; + + this.onclickListener = this.enterEditMode.bindAsEventListener(this); + this.mouseoverListener = this.enterHover.bindAsEventListener(this); + this.mouseoutListener = this.leaveHover.bindAsEventListener(this); + Event.observe(this.element, 'click', this.onclickListener); + Event.observe(this.element, 'mouseover', this.mouseoverListener); + Event.observe(this.element, 'mouseout', this.mouseoutListener); + if (this.options.externalControl) { + Event.observe(this.options.externalControl, 'click', this.onclickListener); + Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener); + Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener); + } + }, + enterEditMode: function() { + if (this.saving) return; + if (this.editing) return; + this.editing = true; + this.onEnterEditMode(); + if (this.options.externalControl) { + Element.hide(this.options.externalControl); + } + Element.hide(this.element); + this.createForm(); + this.element.parentNode.insertBefore(this.form, this.element); + Field.focus(this.editField); + // stop the event to avoid a page refresh in Safari + if (arguments.length > 1) { + Event.stop(arguments[0]); + } + }, + createForm: function() { + this.form = document.createElement("form"); + this.form.id = this.options.formId; + Element.addClassName(this.form, this.options.formClassName) + this.form.onsubmit = this.onSubmit.bind(this); + + this.createEditField(); + + if (this.options.textarea) { + var br = document.createElement("br"); + this.form.appendChild(br); + } + + okButton = document.createElement("input"); + okButton.type = "submit"; + okButton.value = this.options.okText; + this.form.appendChild(okButton); + + cancelLink = document.createElement("a"); + cancelLink.href = "#"; + cancelLink.appendChild(document.createTextNode(this.options.cancelText)); + cancelLink.onclick = this.onclickCancel.bind(this); + this.form.appendChild(cancelLink); + }, + hasHTMLLineBreaks: function(string) { + if (!this.options.handleLineBreaks) return false; + return string.match(/
    /i); + }, + convertHTMLLineBreaks: function(string) { + return string.replace(/
    /gi, "\n").replace(//gi, "\n").replace(/<\/p>/gi, "\n").replace(/

    /gi, ""); + }, + createEditField: function() { + var text; + if(this.options.loadTextURL) { + text = this.options.loadingText; + } else { + text = this.getText(); + } + + if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) { + this.options.textarea = false; + var textField = document.createElement("input"); + textField.type = "text"; + textField.name = "value"; + textField.value = text; + textField.style.backgroundColor = this.options.highlightcolor; + var size = this.options.size || this.options.cols || 0; + if (size != 0) textField.size = size; + this.editField = textField; + } else { + this.options.textarea = true; + var textArea = document.createElement("textarea"); + textArea.name = "value"; + textArea.value = this.convertHTMLLineBreaks(text); + textArea.rows = this.options.rows; + textArea.cols = this.options.cols || 40; + this.editField = textArea; + } + + if(this.options.loadTextURL) { + this.loadExternalText(); + } + this.form.appendChild(this.editField); + }, + getText: function() { + return this.element.innerHTML; + }, + loadExternalText: function() { + Element.addClassName(this.form, this.options.loadingClassName); + this.editField.disabled = true; + new Ajax.Request( + this.options.loadTextURL, + Object.extend({ + asynchronous: true, + onComplete: this.onLoadedExternalText.bind(this) + }, this.options.ajaxOptions) + ); + }, + onLoadedExternalText: function(transport) { + Element.removeClassName(this.form, this.options.loadingClassName); + this.editField.disabled = false; + this.editField.value = transport.responseText.stripTags(); + }, + onclickCancel: function() { + this.onComplete(); + this.leaveEditMode(); + return false; + }, + onFailure: function(transport) { + this.options.onFailure(transport); + if (this.oldInnerHTML) { + this.element.innerHTML = this.oldInnerHTML; + this.oldInnerHTML = null; + } + return false; + }, + onSubmit: function() { + // onLoading resets these so we need to save them away for the Ajax call + var form = this.form; + var value = this.editField.value; + + // do this first, sometimes the ajax call returns before we get a chance to switch on Saving... + // which means this will actually switch on Saving... *after* we've left edit mode causing Saving... + // to be displayed indefinitely + this.onLoading(); + + new Ajax.Updater( + { + success: this.element, + // don't update on failure (this could be an option) + failure: null + }, + this.url, + Object.extend({ + parameters: this.options.callback(form, value), + onComplete: this.onComplete.bind(this), + onFailure: this.onFailure.bind(this) + }, this.options.ajaxOptions) + ); + // stop the event to avoid a page refresh in Safari + if (arguments.length > 1) { + Event.stop(arguments[0]); + } + return false; + }, + onLoading: function() { + this.saving = true; + this.removeForm(); + this.leaveHover(); + this.showSaving(); + }, + showSaving: function() { + this.oldInnerHTML = this.element.innerHTML; + this.element.innerHTML = this.options.savingText; + Element.addClassName(this.element, this.options.savingClassName); + this.element.style.backgroundColor = this.originalBackground; + Element.show(this.element); + }, + removeForm: function() { + if(this.form) { + if (this.form.parentNode) Element.remove(this.form); + this.form = null; + } + }, + enterHover: function() { + if (this.saving) return; + this.element.style.backgroundColor = this.options.highlightcolor; + if (this.effect) { + this.effect.cancel(); + } + Element.addClassName(this.element, this.options.hoverClassName) + }, + leaveHover: function() { + if (this.options.backgroundColor) { + this.element.style.backgroundColor = this.oldBackground; + } + Element.removeClassName(this.element, this.options.hoverClassName) + if (this.saving) return; + this.effect = new Effect.Highlight(this.element, { + startcolor: this.options.highlightcolor, + endcolor: this.options.highlightendcolor, + restorecolor: this.originalBackground + }); + }, + leaveEditMode: function() { + Element.removeClassName(this.element, this.options.savingClassName); + this.removeForm(); + this.leaveHover(); + this.element.style.backgroundColor = this.originalBackground; + Element.show(this.element); + if (this.options.externalControl) { + Element.show(this.options.externalControl); + } + this.editing = false; + this.saving = false; + this.oldInnerHTML = null; + this.onLeaveEditMode(); + }, + onComplete: function(transport) { + this.leaveEditMode(); + this.options.onComplete.bind(this)(transport, this.element); + }, + onEnterEditMode: function() {}, + onLeaveEditMode: function() {}, + dispose: function() { + if (this.oldInnerHTML) { + this.element.innerHTML = this.oldInnerHTML; + } + this.leaveEditMode(); + Event.stopObserving(this.element, 'click', this.onclickListener); + Event.stopObserving(this.element, 'mouseover', this.mouseoverListener); + Event.stopObserving(this.element, 'mouseout', this.mouseoutListener); + if (this.options.externalControl) { + Event.stopObserving(this.options.externalControl, 'click', this.onclickListener); + Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener); + Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener); + } + } +}; \ No newline at end of file diff --git a/public/javascripts/dragdrop.js b/public/javascripts/dragdrop.js new file mode 100644 index 0000000..5445d74 --- /dev/null +++ b/public/javascripts/dragdrop.js @@ -0,0 +1,516 @@ +// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// +// Element.Class part Copyright (c) 2005 by Rick Olson +// +// See scriptaculous.js for full license. + +/*--------------------------------------------------------------------------*/ + +var Droppables = { + drops: [], + + remove: function(element) { + this.drops = this.drops.reject(function(d) { return d.element==element }); + }, + + add: function(element) { + element = $(element); + var options = Object.extend({ + greedy: true, + hoverclass: null + }, arguments[1] || {}); + + // cache containers + if(options.containment) { + options._containers = []; + var containment = options.containment; + if((typeof containment == 'object') && + (containment.constructor == Array)) { + containment.each( function(c) { options._containers.push($(c)) }); + } else { + options._containers.push($(containment)); + } + } + + Element.makePositioned(element); // fix IE + options.element = element; + + this.drops.push(options); + }, + + isContained: function(element, drop) { + var parentNode = element.parentNode; + return drop._containers.detect(function(c) { return parentNode == c }); + }, + + isAffected: function(pX, pY, element, drop) { + return ( + (drop.element!=element) && + ((!drop._containers) || + this.isContained(element, drop)) && + ((!drop.accept) || + (Element.Class.has_any(element, drop.accept))) && + Position.within(drop.element, pX, pY) ); + }, + + deactivate: function(drop) { + if(drop.hoverclass) + Element.Class.remove(drop.element, drop.hoverclass); + this.last_active = null; + }, + + activate: function(drop) { + if(this.last_active) this.deactivate(this.last_active); + if(drop.hoverclass) + Element.Class.add(drop.element, drop.hoverclass); + this.last_active = drop; + }, + + show: function(event, element) { + if(!this.drops.length) return; + var pX = Event.pointerX(event); + var pY = Event.pointerY(event); + Position.prepare(); + + var i = this.drops.length-1; do { + var drop = this.drops[i]; + if(this.isAffected(pX, pY, element, drop)) { + if(drop.onHover) + drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); + if(drop.greedy) { + this.activate(drop); + return; + } + } + } while (i--); + + if(this.last_active) this.deactivate(this.last_active); + }, + + fire: function(event, element) { + if(!this.last_active) return; + Position.prepare(); + + if (this.isAffected(Event.pointerX(event), Event.pointerY(event), element, this.last_active)) + if (this.last_active.onDrop) + this.last_active.onDrop(element, this.last_active.element, event); + }, + + reset: function() { + if(this.last_active) + this.deactivate(this.last_active); + } +} + +var Draggables = { + observers: [], + addObserver: function(observer) { + this.observers.push(observer); + }, + removeObserver: function(element) { // element instead of obsever fixes mem leaks + this.observers = this.observers.reject( function(o) { return o.element==element }); + }, + notify: function(eventName, draggable) { // 'onStart', 'onEnd' + this.observers.invoke(eventName, draggable); + } +} + +/*--------------------------------------------------------------------------*/ + +var Draggable = Class.create(); +Draggable.prototype = { + initialize: function(element) { + var options = Object.extend({ + handle: false, + starteffect: function(element) { + new Effect.Opacity(element, {duration:0.2, from:1.0, to:0.7}); + }, + reverteffect: function(element, top_offset, left_offset) { + var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02; + new Effect.MoveBy(element, -top_offset, -left_offset, {duration:dur}); + }, + endeffect: function(element) { + new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0}); + }, + zindex: 1000, + revert: false + }, arguments[1] || {}); + + this.element = $(element); + if(options.handle && (typeof options.handle == 'string')) + this.handle = Element.Class.childrenWith(this.element, options.handle)[0]; + + if(!this.handle) this.handle = $(options.handle); + if(!this.handle) this.handle = this.element; + + Element.makePositioned(this.element); // fix IE + + this.offsetX = 0; + this.offsetY = 0; + this.originalLeft = this.currentLeft(); + this.originalTop = this.currentTop(); + this.originalX = this.element.offsetLeft; + this.originalY = this.element.offsetTop; + + this.options = options; + + this.active = false; + this.dragging = false; + + this.eventMouseDown = this.startDrag.bindAsEventListener(this); + this.eventMouseUp = this.endDrag.bindAsEventListener(this); + this.eventMouseMove = this.update.bindAsEventListener(this); + this.eventKeypress = this.keyPress.bindAsEventListener(this); + + this.registerEvents(); + }, + destroy: function() { + Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); + this.unregisterEvents(); + }, + registerEvents: function() { + Event.observe(document, "mouseup", this.eventMouseUp); + Event.observe(document, "mousemove", this.eventMouseMove); + Event.observe(document, "keypress", this.eventKeypress); + Event.observe(this.handle, "mousedown", this.eventMouseDown); + }, + unregisterEvents: function() { + //if(!this.active) return; + //Event.stopObserving(document, "mouseup", this.eventMouseUp); + //Event.stopObserving(document, "mousemove", this.eventMouseMove); + //Event.stopObserving(document, "keypress", this.eventKeypress); + }, + currentLeft: function() { + return parseInt(this.element.style.left || '0'); + }, + currentTop: function() { + return parseInt(this.element.style.top || '0') + }, + startDrag: function(event) { + if(Event.isLeftClick(event)) { + + // abort on form elements, fixes a Firefox issue + var src = Event.element(event); + if(src.tagName && ( + src.tagName=='INPUT' || + src.tagName=='SELECT' || + src.tagName=='BUTTON' || + src.tagName=='TEXTAREA')) return; + + // this.registerEvents(); + this.active = true; + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + var offsets = Position.cumulativeOffset(this.element); + this.offsetX = (pointer[0] - offsets[0]); + this.offsetY = (pointer[1] - offsets[1]); + Event.stop(event); + } + }, + finishDrag: function(event, success) { + // this.unregisterEvents(); + + this.active = false; + this.dragging = false; + + if(this.options.ghosting) { + Position.relativize(this.element); + Element.remove(this._clone); + this._clone = null; + } + + if(success) Droppables.fire(event, this.element); + Draggables.notify('onEnd', this); + + var revert = this.options.revert; + if(revert && typeof revert == 'function') revert = revert(this.element); + + if(revert && this.options.reverteffect) { + this.options.reverteffect(this.element, + this.currentTop()-this.originalTop, + this.currentLeft()-this.originalLeft); + } else { + this.originalLeft = this.currentLeft(); + this.originalTop = this.currentTop(); + } + + if(this.options.zindex) + this.element.style.zIndex = this.originalZ; + + if(this.options.endeffect) + this.options.endeffect(this.element); + + + Droppables.reset(); + }, + keyPress: function(event) { + if(this.active) { + if(event.keyCode==Event.KEY_ESC) { + this.finishDrag(event, false); + Event.stop(event); + } + } + }, + endDrag: function(event) { + if(this.active && this.dragging) { + this.finishDrag(event, true); + Event.stop(event); + } + this.active = false; + this.dragging = false; + }, + draw: function(event) { + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + var offsets = Position.cumulativeOffset(this.element); + offsets[0] -= this.currentLeft(); + offsets[1] -= this.currentTop(); + var style = this.element.style; + if((!this.options.constraint) || (this.options.constraint=='horizontal')) + style.left = (pointer[0] - offsets[0] - this.offsetX) + "px"; + if((!this.options.constraint) || (this.options.constraint=='vertical')) + style.top = (pointer[1] - offsets[1] - this.offsetY) + "px"; + if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering + }, + update: function(event) { + if(this.active) { + if(!this.dragging) { + var style = this.element.style; + this.dragging = true; + + if(Element.getStyle(this.element,'position')=='') + style.position = "relative"; + + if(this.options.zindex) { + this.options.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); + style.zIndex = this.options.zindex; + } + + if(this.options.ghosting) { + this._clone = this.element.cloneNode(true); + Position.absolutize(this.element); + this.element.parentNode.insertBefore(this._clone, this.element); + } + + Draggables.notify('onStart', this); + if(this.options.starteffect) this.options.starteffect(this.element); + } + + Droppables.show(event, this.element); + this.draw(event); + if(this.options.change) this.options.change(this); + + // fix AppleWebKit rendering + if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); + + Event.stop(event); + } + } +} + +/*--------------------------------------------------------------------------*/ + +var SortableObserver = Class.create(); +SortableObserver.prototype = { + initialize: function(element, observer) { + this.element = $(element); + this.observer = observer; + this.lastValue = Sortable.serialize(this.element); + }, + onStart: function() { + this.lastValue = Sortable.serialize(this.element); + }, + onEnd: function() { + Sortable.unmark(); + if(this.lastValue != Sortable.serialize(this.element)) + this.observer(this.element) + } +} + +var Sortable = { + sortables: new Array(), + options: function(element){ + element = $(element); + return this.sortables.detect(function(s) { return s.element == element }); + }, + destroy: function(element){ + element = $(element); + this.sortables.findAll(function(s) { return s.element == element }).each(function(s){ + Draggables.removeObserver(s.element); + s.droppables.each(function(d){ Droppables.remove(d) }); + s.draggables.invoke('destroy'); + }); + this.sortables = this.sortables.reject(function(s) { return s.element == element }); + }, + create: function(element) { + element = $(element); + var options = Object.extend({ + element: element, + tag: 'li', // assumes li children, override with tag: 'tagname' + dropOnEmpty: false, + tree: false, // fixme: unimplemented + overlap: 'vertical', // one of 'vertical', 'horizontal' + constraint: 'vertical', // one of 'vertical', 'horizontal', false + containment: element, // also takes array of elements (or id's); or false + handle: false, // or a CSS class + only: false, + hoverclass: null, + ghosting: false, + format: null, + onChange: function() {}, + onUpdate: function() {} + }, arguments[1] || {}); + + // clear any old sortable with same element + this.destroy(element); + + // build options for the draggables + var options_for_draggable = { + revert: true, + ghosting: options.ghosting, + constraint: options.constraint, + handle: options.handle }; + + if(options.starteffect) + options_for_draggable.starteffect = options.starteffect; + + if(options.reverteffect) + options_for_draggable.reverteffect = options.reverteffect; + else + if(options.ghosting) options_for_draggable.reverteffect = function(element) { + element.style.top = 0; + element.style.left = 0; + }; + + if(options.endeffect) + options_for_draggable.endeffect = options.endeffect; + + if(options.zindex) + options_for_draggable.zindex = options.zindex; + + // build options for the droppables + var options_for_droppable = { + overlap: options.overlap, + containment: options.containment, + hoverclass: options.hoverclass, + onHover: Sortable.onHover, + greedy: !options.dropOnEmpty + } + + // fix for gecko engine + Element.cleanWhitespace(element); + + options.draggables = []; + options.droppables = []; + + // make it so + + // drop on empty handling + if(options.dropOnEmpty) { + Droppables.add(element, + {containment: options.containment, onHover: Sortable.onEmptyHover, greedy: false}); + options.droppables.push(element); + } + + (this.findElements(element, options) || []).each( function(e) { + // handles are per-draggable + var handle = options.handle ? + Element.Class.childrenWith(e, options.handle)[0] : e; + options.draggables.push( + new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); + Droppables.add(e, options_for_droppable); + options.droppables.push(e); + }); + + // keep reference + this.sortables.push(options); + + // for onupdate + Draggables.addObserver(new SortableObserver(element, options.onUpdate)); + + }, + + // return all suitable-for-sortable elements in a guaranteed order + findElements: function(element, options) { + if(!element.hasChildNodes()) return null; + var elements = []; + $A(element.childNodes).each( function(e) { + if(e.tagName && e.tagName==options.tag.toUpperCase() && + (!options.only || (Element.Class.has(e, options.only)))) + elements.push(e); + if(options.tree) { + var grandchildren = this.findElements(e, options); + if(grandchildren) elements.push(grandchildren); + } + }); + + return (elements.length>0 ? elements.flatten() : null); + }, + + onHover: function(element, dropon, overlap) { + if(overlap>0.5) { + Sortable.mark(dropon, 'before'); + if(dropon.previousSibling != element) { + var oldParentNode = element.parentNode; + element.style.visibility = "hidden"; // fix gecko rendering + dropon.parentNode.insertBefore(element, dropon); + if(dropon.parentNode!=oldParentNode) + Sortable.options(oldParentNode).onChange(element); + Sortable.options(dropon.parentNode).onChange(element); + } + } else { + Sortable.mark(dropon, 'after'); + var nextElement = dropon.nextSibling || null; + if(nextElement != element) { + var oldParentNode = element.parentNode; + element.style.visibility = "hidden"; // fix gecko rendering + dropon.parentNode.insertBefore(element, nextElement); + if(dropon.parentNode!=oldParentNode) + Sortable.options(oldParentNode).onChange(element); + Sortable.options(dropon.parentNode).onChange(element); + } + } + }, + + onEmptyHover: function(element, dropon) { + if(element.parentNode!=dropon) { + dropon.appendChild(element); + } + }, + + unmark: function() { + if(Sortable._marker) Element.hide(Sortable._marker); + }, + + mark: function(dropon, position) { + // mark on ghosting only + var sortable = Sortable.options(dropon.parentNode); + if(sortable && !sortable.ghosting) return; + + if(!Sortable._marker) { + Sortable._marker = $('dropmarker') || document.createElement('DIV'); + Element.hide(Sortable._marker); + Element.Class.add(Sortable._marker, 'dropmarker'); + Sortable._marker.style.position = 'absolute'; + document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); + } + var offsets = Position.cumulativeOffset(dropon); + Sortable._marker.style.top = offsets[1] + 'px'; + if(position=='after') Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px'; + Sortable._marker.style.left = offsets[0] + 'px'; + Element.show(Sortable._marker); + }, + + serialize: function(element) { + element = $(element); + var sortableOptions = this.options(element); + var options = Object.extend({ + tag: sortableOptions.tag, + only: sortableOptions.only, + name: element.id, + format: sortableOptions.format || /^[^_]*_(.*)$/ + }, arguments[1] || {}); + return $(this.findElements(element, options) || []).collect( function(item) { + return (encodeURIComponent(options.name) + "[]=" + + encodeURIComponent(item.id.match(options.format) ? item.id.match(options.format)[1] : '')); + }).join("&"); + } +} \ No newline at end of file diff --git a/public/javascripts/effects.js b/public/javascripts/effects.js new file mode 100644 index 0000000..7e65d92 --- /dev/null +++ b/public/javascripts/effects.js @@ -0,0 +1,1101 @@ +// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// Contributors: +// Justin Palmer (http://encytemedia.com/) +// Mark Pilgrim (http://diveintomark.org/) +// Martin Bialasinki +// +// See scriptaculous.js for full license. + +Object.debug = function(obj) { + var info = []; + + if(typeof obj in ["string","number"]) { + return obj; + } else { + for(property in obj) + if(typeof obj[property]!="function") + info.push(property + ' => ' + + (typeof obj[property] == "string" ? + '"' + obj[property] + '"' : + obj[property])); + } + + return ("'" + obj + "' #" + typeof obj + + ": {" + info.join(", ") + "}"); +} + + +/*--------------------------------------------------------------------------*/ + +var Builder = { + NODEMAP: { + AREA: 'map', + CAPTION: 'table', + COL: 'table', + COLGROUP: 'table', + LEGEND: 'fieldset', + OPTGROUP: 'select', + OPTION: 'select', + PARAM: 'object', + TBODY: 'table', + TD: 'table', + TFOOT: 'table', + TH: 'table', + THEAD: 'table', + TR: 'table' + }, + // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken, + // due to a Firefox bug + node: function(elementName) { + elementName = elementName.toUpperCase(); + + // try innerHTML approach + var parentTag = this.NODEMAP[elementName] || 'div'; + var parentElement = document.createElement(parentTag); + parentElement.innerHTML = "<" + elementName + ">"; + var element = parentElement.firstChild || null; + + // see if browser added wrapping tags + if(element && (element.tagName != elementName)) + element = element.getElementsByTagName(elementName)[0]; + + // fallback to createElement approach + if(!element) element = document.createElement(elementName); + + // abort if nothing could be created + if(!element) return; + + // attributes (or text) + if(arguments[1]) + if(this._isStringOrNumber(arguments[1]) || + (arguments[1] instanceof Array)) { + this._children(element, arguments[1]); + } else { + var attrs = this._attributes(arguments[1]); + if(attrs.length) { + parentElement.innerHTML = "<" +elementName + " " + + attrs + ">"; + element = parentElement.firstChild || null; + // workaround firefox 1.0.X bug + if(!element) { + element = document.createElement(elementName); + for(attr in arguments[1]) + element[attr == 'class' ? 'className' : attr] = arguments[1][attr]; + } + if(element.tagName != elementName) + element = parentElement.getElementsByTagName(elementName)[0]; + } + } + + // text, or array of children + if(arguments[2]) + this._children(element, arguments[2]); + + return element; + }, + _text: function(text) { + return document.createTextNode(text); + }, + _attributes: function(attributes) { + var attrs = []; + for(attribute in attributes) + attrs.push((attribute=='className' ? 'class' : attribute) + + '="' + attributes[attribute].toString().escapeHTML() + '"'); + return attrs.join(" "); + }, + _children: function(element, children) { + if(typeof children=='object') { // array can hold nodes and text + children.flatten().each( function(e) { + if(typeof e=='object') + element.appendChild(e) + else + if(Builder._isStringOrNumber(e)) + element.appendChild(Builder._text(e)); + }); + } else + if(Builder._isStringOrNumber(children)) + element.appendChild(Builder._text(children)); + }, + _isStringOrNumber: function(param) { + return(typeof param=='string' || typeof param=='number'); + } +} + +/* ------------- element ext -------------- */ + +// converts rgb() and #xxx to #xxxxxx format, +// returns self (or first argument) if not convertable +String.prototype.parseColor = function() { + color = "#"; + if(this.slice(0,4) == "rgb(") { + var cols = this.slice(4,this.length-1).split(','); + var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); + } else { + if(this.slice(0,1) == '#') { + if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); + if(this.length==7) color = this.toLowerCase(); + } + } + return(color.length==7 ? color : (arguments[0] || this)); +} + +Element.collectTextNodesIgnoreClass = function(element, ignoreclass) { + var children = $(element).childNodes; + var text = ""; + var classtest = new RegExp("^([^ ]+ )*" + ignoreclass+ "( [^ ]+)*$","i"); + + for (var i = 0; i < children.length; i++) { + if(children[i].nodeType==3) { + text+=children[i].nodeValue; + } else { + if((!children[i].className.match(classtest)) && children[i].hasChildNodes()) + text += Element.collectTextNodesIgnoreClass(children[i], ignoreclass); + } + } + + return text; +} + +Element.setContentZoom = function(element, percent) { + element = $(element); + element.style.fontSize = (percent/100) + "em"; + if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); +} + +Element.getOpacity = function(element){ + var opacity; + if (opacity = Element.getStyle(element, "opacity")) + return parseFloat(opacity); + if (opacity = (Element.getStyle(element, "filter") || '').match(/alpha\(opacity=(.*)\)/)) + if(opacity[1]) return parseFloat(opacity[1]) / 100; + return 1.0; +} + +Element.setOpacity = function(element, value){ + element= $(element); + var els = element.style; + if (value == 1){ + els.opacity = '0.999999'; + if(/MSIE/.test(navigator.userAgent)) + els.filter = Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,''); + } else { + if(value < 0.00001) value = 0; + els.opacity = value; + if(/MSIE/.test(navigator.userAgent)) + els.filter = Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') + + "alpha(opacity="+value*100+")"; + } +} + +Element.getInlineOpacity = function(element){ + element= $(element); + var op; + op = element.style.opacity; + if (typeof op != "undefined" && op != "") return op; + return ""; +} + +Element.setInlineOpacity = function(element, value){ + element= $(element); + var els = element.style; + els.opacity = value; +} + +/*--------------------------------------------------------------------------*/ + +Element.Class = { + // Element.toggleClass(element, className) toggles the class being on/off + // Element.toggleClass(element, className1, className2) toggles between both classes, + // defaulting to className1 if neither exist + toggle: function(element, className) { + if(Element.Class.has(element, className)) { + Element.Class.remove(element, className); + if(arguments.length == 3) Element.Class.add(element, arguments[2]); + } else { + Element.Class.add(element, className); + if(arguments.length == 3) Element.Class.remove(element, arguments[2]); + } + }, + + // gets space-delimited classnames of an element as an array + get: function(element) { + return $(element).className.split(' '); + }, + + // functions adapted from original functions by Gavin Kistner + remove: function(element) { + element = $(element); + var removeClasses = arguments; + $R(1,arguments.length-1).each( function(index) { + element.className = + element.className.split(' ').reject( + function(klass) { return (klass == removeClasses[index]) } ).join(' '); + }); + }, + + add: function(element) { + element = $(element); + for(var i = 1; i < arguments.length; i++) { + Element.Class.remove(element, arguments[i]); + element.className += (element.className.length > 0 ? ' ' : '') + arguments[i]; + } + }, + + // returns true if all given classes exist in said element + has: function(element) { + element = $(element); + if(!element || !element.className) return false; + var regEx; + for(var i = 1; i < arguments.length; i++) { + if((typeof arguments[i] == 'object') && + (arguments[i].constructor == Array)) { + for(var j = 0; j < arguments[i].length; j++) { + regEx = new RegExp("(^|\\s)" + arguments[i][j] + "(\\s|$)"); + if(!regEx.test(element.className)) return false; + } + } else { + regEx = new RegExp("(^|\\s)" + arguments[i] + "(\\s|$)"); + if(!regEx.test(element.className)) return false; + } + } + return true; + }, + + // expects arrays of strings and/or strings as optional paramters + // Element.Class.has_any(element, ['classA','classB','classC'], 'classD') + has_any: function(element) { + element = $(element); + if(!element || !element.className) return false; + var regEx; + for(var i = 1; i < arguments.length; i++) { + if((typeof arguments[i] == 'object') && + (arguments[i].constructor == Array)) { + for(var j = 0; j < arguments[i].length; j++) { + regEx = new RegExp("(^|\\s)" + arguments[i][j] + "(\\s|$)"); + if(regEx.test(element.className)) return true; + } + } else { + regEx = new RegExp("(^|\\s)" + arguments[i] + "(\\s|$)"); + if(regEx.test(element.className)) return true; + } + } + return false; + }, + + childrenWith: function(element, className) { + var children = $(element).getElementsByTagName('*'); + var elements = new Array(); + + for (var i = 0; i < children.length; i++) + if (Element.Class.has(children[i], className)) + elements.push(children[i]); + + return elements; + } +} + +/*--------------------------------------------------------------------------*/ + +var Effect = { + tagifyText: function(element) { + var tagifyStyle = "position:relative"; + if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ";zoom:1"; + element = $(element); + $A(element.childNodes).each( function(child) { + if(child.nodeType==3) { + child.nodeValue.toArray().each( function(character) { + element.insertBefore( + Builder.node('span',{style: tagifyStyle}, + character == " " ? String.fromCharCode(160) : character), + child); + }); + Element.remove(child); + } + }); + }, + multiple: function(element, effect) { + var elements; + if(((typeof element == 'object') || + (typeof element == 'function')) && + (element.length)) + elements = element; + else + elements = $(element).childNodes; + + var options = Object.extend({ + speed: 0.1, + delay: 0.0 + }, arguments[2] || {}); + var speed = options.speed; + var delay = options.delay; + + $A(elements).each( function(element, index) { + new effect(element, Object.extend(options, { delay: delay + index * speed })); + }); + } +}; + +var Effect2 = Effect; // deprecated + +/* ------------- transitions ------------- */ + +Effect.Transitions = {} + +Effect.Transitions.linear = function(pos) { + return pos; +} +Effect.Transitions.sinoidal = function(pos) { + return (-Math.cos(pos*Math.PI)/2) + 0.5; +} +Effect.Transitions.reverse = function(pos) { + return 1-pos; +} +Effect.Transitions.flicker = function(pos) { + return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; +} +Effect.Transitions.wobble = function(pos) { + return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5; +} +Effect.Transitions.pulse = function(pos) { + return (Math.floor(pos*10) % 2 == 0 ? + (pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10))); +} +Effect.Transitions.none = function(pos) { + return 0; +} +Effect.Transitions.full = function(pos) { + return 1; +} + +/* ------------- core effects ------------- */ + +Effect.Queue = { + effects: [], + interval: null, + add: function(effect) { + var timestamp = new Date().getTime(); + + switch(effect.options.queue) { + case 'front': + // move unstarted effects after this effect + this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) { + e.startOn += effect.finishOn; + e.finishOn += effect.finishOn; + }); + break; + case 'end': + // start effect after last queued effect has finished + timestamp = this.effects.pluck('finishOn').max() || timestamp; + break; + } + + effect.startOn += timestamp; + effect.finishOn += timestamp; + this.effects.push(effect); + if(!this.interval) + this.interval = setInterval(this.loop.bind(this), 40); + }, + remove: function(effect) { + this.effects = this.effects.reject(function(e) { return e==effect }); + if(this.effects.length == 0) { + clearInterval(this.interval); + this.interval = null; + } + }, + loop: function() { + var timePos = new Date().getTime(); + this.effects.invoke('loop', timePos); + } +} + +Effect.Base = function() {}; +Effect.Base.prototype = { + position: null, + setOptions: function(options) { + this.options = Object.extend({ + transition: Effect.Transitions.sinoidal, + duration: 1.0, // seconds + fps: 25.0, // max. 25fps due to Effect.Queue implementation + sync: false, // true for combining + from: 0.0, + to: 1.0, + delay: 0.0, + queue: 'parallel' + }, options || {}); + }, + start: function(options) { + this.setOptions(options || {}); + this.currentFrame = 0; + this.state = 'idle'; + this.startOn = this.options.delay*1000; + this.finishOn = this.startOn + (this.options.duration*1000); + this.event('beforeStart'); + if(!this.options.sync) Effect.Queue.add(this); + }, + loop: function(timePos) { + if(timePos >= this.startOn) { + if(timePos >= this.finishOn) { + this.render(1.0); + this.cancel(); + this.event('beforeFinish'); + if(this.finish) this.finish(); + this.event('afterFinish'); + return; + } + var pos = (timePos - this.startOn) / (this.finishOn - this.startOn); + var frame = Math.round(pos * this.options.fps * this.options.duration); + if(frame > this.currentFrame) { + this.render(pos); + this.currentFrame = frame; + } + } + }, + render: function(pos) { + if(this.state == 'idle') { + this.state = 'running'; + this.event('beforeSetup'); + if(this.setup) this.setup(); + this.event('afterSetup'); + } + if(this.options.transition) pos = this.options.transition(pos); + pos *= (this.options.to-this.options.from); + pos += this.options.from; + this.position = pos; + this.event('beforeUpdate'); + if(this.update) this.update(pos); + this.event('afterUpdate'); + }, + cancel: function() { + if(!this.options.sync) Effect.Queue.remove(this); + this.state = 'finished'; + }, + event: function(eventName) { + if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this); + if(this.options[eventName]) this.options[eventName](this); + } +} + +Effect.Parallel = Class.create(); +Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), { + initialize: function(effects) { + this.effects = effects || []; + this.start(arguments[1]); + }, + update: function(position) { + this.effects.invoke('render', position); + }, + finish: function(position) { + this.effects.each( function(effect) { + effect.render(1.0); + effect.cancel(); + effect.event('beforeFinish'); + if(effect.finish) effect.finish(position); + effect.event('afterFinish'); + }); + } +}); + +Effect.Opacity = Class.create(); +Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), { + initialize: function(element) { + this.element = $(element); + // make this work on IE on elements without 'layout' + if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout)) + this.element.style.zoom = 1; + var options = Object.extend({ + from: Element.getOpacity(this.element) || 0.0, + to: 1.0 + }, arguments[1] || {}); + this.start(options); + }, + update: function(position) { + Element.setOpacity(this.element, position); + } +}); + +Effect.MoveBy = Class.create(); +Object.extend(Object.extend(Effect.MoveBy.prototype, Effect.Base.prototype), { + initialize: function(element, toTop, toLeft) { + this.element = $(element); + this.toTop = toTop; + this.toLeft = toLeft; + this.start(arguments[3]); + }, + setup: function() { + // Bug in Opera: Opera returns the "real" position of a static element or + // relative element that does not have top/left explicitly set. + // ==> Always set top and left for position relative elements in your stylesheets + // (to 0 if you do not need them) + + Element.makePositioned(this.element); + this.originalTop = parseFloat(Element.getStyle(this.element,'top') || '0'); + this.originalLeft = parseFloat(Element.getStyle(this.element,'left') || '0'); + }, + update: function(position) { + var topd = this.toTop * position + this.originalTop; + var leftd = this.toLeft * position + this.originalLeft; + this.setPosition(topd, leftd); + }, + setPosition: function(topd, leftd) { + this.element.style.top = topd + "px"; + this.element.style.left = leftd + "px"; + } +}); + +Effect.Scale = Class.create(); +Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), { + initialize: function(element, percent) { + this.element = $(element) + var options = Object.extend({ + scaleX: true, + scaleY: true, + scaleContent: true, + scaleFromCenter: false, + scaleMode: 'box', // 'box' or 'contents' or {} with provided values + scaleFrom: 100.0, + scaleTo: percent + }, arguments[2] || {}); + this.start(options); + }, + setup: function() { + var effect = this; + + this.restoreAfterFinish = this.options.restoreAfterFinish || false; + this.elementPositioning = Element.getStyle(this.element,'position'); + + effect.originalStyle = {}; + ['top','left','width','height','fontSize'].each( function(k) { + effect.originalStyle[k] = effect.element.style[k]; + }); + + this.originalTop = this.element.offsetTop; + this.originalLeft = this.element.offsetLeft; + + var fontSize = Element.getStyle(this.element,'font-size') || "100%"; + ['em','px','%'].each( function(fontSizeType) { + if(fontSize.indexOf(fontSizeType)>0) { + effect.fontSize = parseFloat(fontSize); + effect.fontSizeType = fontSizeType; + } + }); + + this.factor = (this.options.scaleTo - this.options.scaleFrom)/100; + + this.dims = null; + if(this.options.scaleMode=='box') + this.dims = [this.element.clientHeight, this.element.clientWidth]; + if(this.options.scaleMode=='content') + this.dims = [this.element.scrollHeight, this.element.scrollWidth]; + if(!this.dims) + this.dims = [this.options.scaleMode.originalHeight, + this.options.scaleMode.originalWidth]; + }, + update: function(position) { + var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position); + if(this.options.scaleContent && this.fontSize) + this.element.style.fontSize = this.fontSize*currentScale + this.fontSizeType; + this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale); + }, + finish: function(position) { + if (this.restoreAfterFinish) { + var effect = this; + ['top','left','width','height','fontSize'].each( function(k) { + effect.element.style[k] = effect.originalStyle[k]; + }); + } + }, + setDimensions: function(height, width) { + var els = this.element.style; + if(this.options.scaleX) els.width = width + 'px'; + if(this.options.scaleY) els.height = height + 'px'; + if(this.options.scaleFromCenter) { + var topd = (height - this.dims[0])/2; + var leftd = (width - this.dims[1])/2; + if(this.elementPositioning == 'absolute') { + if(this.options.scaleY) els.top = this.originalTop-topd + "px"; + if(this.options.scaleX) els.left = this.originalLeft-leftd + "px"; + } else { + if(this.options.scaleY) els.top = -topd + "px"; + if(this.options.scaleX) els.left = -leftd + "px"; + } + } + } +}); + +Effect.Highlight = Class.create(); +Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), { + initialize: function(element) { + this.element = $(element); + var options = Object.extend({ + startcolor: "#ffff99" + }, arguments[1] || {}); + this.start(options); + }, + setup: function() { + // Disable background image during the effect + this.oldBgImage = this.element.style.backgroundImage; + this.element.style.backgroundImage = "none"; + if(!this.options.endcolor) + this.options.endcolor = Element.getStyle(this.element, 'background-color').parseColor('#ffffff'); + if (typeof this.options.restorecolor == "undefined") + this.options.restorecolor = this.element.style.backgroundColor; + // init color calculations + this.colors_base = [ + parseInt(this.options.startcolor.slice(1,3),16), + parseInt(this.options.startcolor.slice(3,5),16), + parseInt(this.options.startcolor.slice(5),16) ]; + this.colors_delta = [ + parseInt(this.options.endcolor.slice(1,3),16)-this.colors_base[0], + parseInt(this.options.endcolor.slice(3,5),16)-this.colors_base[1], + parseInt(this.options.endcolor.slice(5),16)-this.colors_base[2]]; + }, + update: function(position) { + var effect = this; var colors = $R(0,2).map( function(i){ + return Math.round(effect.colors_base[i]+(effect.colors_delta[i]*position)) + }); + this.element.style.backgroundColor = "#" + + colors[0].toColorPart() + colors[1].toColorPart() + colors[2].toColorPart(); + }, + finish: function() { + this.element.style.backgroundColor = this.options.restorecolor; + this.element.style.backgroundImage = this.oldBgImage; + } +}); + +Effect.ScrollTo = Class.create(); +Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), { + initialize: function(element) { + this.element = $(element); + this.start(arguments[1] || {}); + }, + setup: function() { + Position.prepare(); + var offsets = Position.cumulativeOffset(this.element); + var max = window.innerHeight ? + window.height - window.innerHeight : + document.body.scrollHeight - + (document.documentElement.clientHeight ? + document.documentElement.clientHeight : document.body.clientHeight); + this.scrollStart = Position.deltaY; + this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart; + }, + update: function(position) { + Position.prepare(); + window.scrollTo(Position.deltaX, + this.scrollStart + (position*this.delta)); + } +}); + +/* ------------- combination effects ------------- */ + +Effect.Fade = function(element) { + var oldOpacity = Element.getInlineOpacity(element); + var options = Object.extend({ + from: Element.getOpacity(element) || 1.0, + to: 0.0, + afterFinishInternal: function(effect) + { if (effect.options.to == 0) { + Element.hide(effect.element); + Element.setInlineOpacity(effect.element, oldOpacity); + } + } + }, arguments[1] || {}); + return new Effect.Opacity(element,options); +} + +Effect.Appear = function(element) { + var options = Object.extend({ + from: (Element.getStyle(element, "display") == "none" ? 0.0 : Element.getOpacity(element) || 0.0), + to: 1.0, + beforeSetup: function(effect) + { Element.setOpacity(effect.element, effect.options.from); + Element.show(effect.element); } + }, arguments[1] || {}); + return new Effect.Opacity(element,options); +} + +Effect.Puff = function(element) { + element = $(element); + var oldOpacity = Element.getInlineOpacity(element); + var oldPosition = element.style.position; + return new Effect.Parallel( + [ new Effect.Scale(element, 200, + { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), + new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], + Object.extend({ duration: 1.0, + beforeSetupInternal: function(effect) + { effect.effects[0].element.style.position = 'absolute'; }, + afterFinishInternal: function(effect) + { Element.hide(effect.effects[0].element); + effect.effects[0].element.style.position = oldPosition; + Element.setInlineOpacity(effect.effects[0].element, oldOpacity); } + }, arguments[1] || {}) + ); +} + +Effect.BlindUp = function(element) { + element = $(element); + Element.makeClipping(element); + return new Effect.Scale(element, 0, + Object.extend({ scaleContent: false, + scaleX: false, + restoreAfterFinish: true, + afterFinishInternal: function(effect) + { + Element.hide(effect.element); + Element.undoClipping(effect.element); + } + }, arguments[1] || {}) + ); +} + +Effect.BlindDown = function(element) { + element = $(element); + var oldHeight = element.style.height; + var elementDimensions = Element.getDimensions(element); + return new Effect.Scale(element, 100, + Object.extend({ scaleContent: false, + scaleX: false, + scaleFrom: 0, + scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, + restoreAfterFinish: true, + afterSetup: function(effect) { + Element.makeClipping(effect.element); + effect.element.style.height = "0px"; + Element.show(effect.element); + }, + afterFinishInternal: function(effect) { + Element.undoClipping(effect.element); + effect.element.style.height = oldHeight; + } + }, arguments[1] || {}) + ); +} + +Effect.SwitchOff = function(element) { + element = $(element); + var oldOpacity = Element.getInlineOpacity(element); + return new Effect.Appear(element, { + duration: 0.4, + from: 0, + transition: Effect.Transitions.flicker, + afterFinishInternal: function(effect) { + new Effect.Scale(effect.element, 1, { + duration: 0.3, scaleFromCenter: true, + scaleX: false, scaleContent: false, restoreAfterFinish: true, + beforeSetup: function(effect) { + Element.makePositioned(effect.element); + Element.makeClipping(effect.element); + }, + afterFinishInternal: function(effect) { + Element.hide(effect.element); + Element.undoClipping(effect.element); + Element.undoPositioned(effect.element); + Element.setInlineOpacity(effect.element, oldOpacity); + } + }) + } + }); +} + +Effect.DropOut = function(element) { + element = $(element); + var oldTop = element.style.top; + var oldLeft = element.style.left; + var oldOpacity = Element.getInlineOpacity(element); + return new Effect.Parallel( + [ new Effect.MoveBy(element, 100, 0, { sync: true }), + new Effect.Opacity(element, { sync: true, to: 0.0 }) ], + Object.extend( + { duration: 0.5, + beforeSetup: function(effect) { + Element.makePositioned(effect.effects[0].element); }, + afterFinishInternal: function(effect) { + Element.hide(effect.effects[0].element); + Element.undoPositioned(effect.effects[0].element); + effect.effects[0].element.style.left = oldLeft; + effect.effects[0].element.style.top = oldTop; + Element.setInlineOpacity(effect.effects[0].element, oldOpacity); } + }, arguments[1] || {})); +} + +Effect.Shake = function(element) { + element = $(element); + var oldTop = element.style.top; + var oldLeft = element.style.left; + return new Effect.MoveBy(element, 0, 20, + { duration: 0.05, afterFinishInternal: function(effect) { + new Effect.MoveBy(effect.element, 0, -40, + { duration: 0.1, afterFinishInternal: function(effect) { + new Effect.MoveBy(effect.element, 0, 40, + { duration: 0.1, afterFinishInternal: function(effect) { + new Effect.MoveBy(effect.element, 0, -40, + { duration: 0.1, afterFinishInternal: function(effect) { + new Effect.MoveBy(effect.element, 0, 40, + { duration: 0.1, afterFinishInternal: function(effect) { + new Effect.MoveBy(effect.element, 0, -20, + { duration: 0.05, afterFinishInternal: function(effect) { + Element.undoPositioned(effect.element); + effect.element.style.left = oldLeft; + effect.element.style.top = oldTop; + }}) }}) }}) }}) }}) }}); +} + +Effect.SlideDown = function(element) { + element = $(element); + Element.cleanWhitespace(element); + // SlideDown need to have the content of the element wrapped in a container element with fixed height! + var oldInnerBottom = element.firstChild.style.bottom; + var elementDimensions = Element.getDimensions(element); + return new Effect.Scale(element, 100, + Object.extend({ scaleContent: false, + scaleX: false, + scaleFrom: 0, + scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, + restoreAfterFinish: true, + afterSetup: function(effect) { + Element.makePositioned(effect.element.firstChild); + if (window.opera) effect.element.firstChild.style.top = ""; + Element.makeClipping(effect.element); + element.style.height = '0'; + Element.show(element); + }, + afterUpdateInternal: function(effect) { + effect.element.firstChild.style.bottom = + (effect.originalHeight - effect.element.clientHeight) + 'px'; }, + afterFinishInternal: function(effect) { + Element.undoClipping(effect.element); + Element.undoPositioned(effect.element.firstChild); + effect.element.firstChild.style.bottom = oldInnerBottom; } + }, arguments[1] || {}) + ); +} + +Effect.SlideUp = function(element) { + element = $(element); + Element.cleanWhitespace(element); + var oldInnerBottom = element.firstChild.style.bottom; + return new Effect.Scale(element, 0, + Object.extend({ scaleContent: false, + scaleX: false, + scaleMode: 'box', + scaleFrom: 100, + restoreAfterFinish: true, + beforeStartInternal: function(effect) { + Element.makePositioned(effect.element.firstChild); + if (window.opera) effect.element.firstChild.style.top = ""; + Element.makeClipping(effect.element); + Element.show(element); + }, + afterUpdateInternal: function(effect) { + effect.element.firstChild.style.bottom = + (effect.originalHeight - effect.element.clientHeight) + 'px'; }, + afterFinishInternal: function(effect) { + Element.hide(effect.element); + Element.undoClipping(effect.element); + Element.undoPositioned(effect.element.firstChild); + effect.element.firstChild.style.bottom = oldInnerBottom; } + }, arguments[1] || {}) + ); +} + +Effect.Squish = function(element) { + // Bug in opera makes the TD containing this element expand for a instance after finish + return new Effect.Scale(element, window.opera ? 1 : 0, + { restoreAfterFinish: true, + beforeSetup: function(effect) { + Element.makeClipping(effect.element); }, + afterFinishInternal: function(effect) { + Element.hide(effect.element); + Element.undoClipping(effect.element); } + }); +} + +Effect.Grow = function(element) { + element = $(element); + var options = arguments[1] || {}; + + var elementDimensions = Element.getDimensions(element); + var originalWidth = elementDimensions.width; + var originalHeight = elementDimensions.height; + var oldTop = element.style.top; + var oldLeft = element.style.left; + var oldHeight = element.style.height; + var oldWidth = element.style.width; + var oldOpacity = Element.getInlineOpacity(element); + + var direction = options.direction || 'center'; + var moveTransition = options.moveTransition || Effect.Transitions.sinoidal; + var scaleTransition = options.scaleTransition || Effect.Transitions.sinoidal; + var opacityTransition = options.opacityTransition || Effect.Transitions.full; + + var initialMoveX, initialMoveY; + var moveX, moveY; + + switch (direction) { + case 'top-left': + initialMoveX = initialMoveY = moveX = moveY = 0; + break; + case 'top-right': + initialMoveX = originalWidth; + initialMoveY = moveY = 0; + moveX = -originalWidth; + break; + case 'bottom-left': + initialMoveX = moveX = 0; + initialMoveY = originalHeight; + moveY = -originalHeight; + break; + case 'bottom-right': + initialMoveX = originalWidth; + initialMoveY = originalHeight; + moveX = -originalWidth; + moveY = -originalHeight; + break; + case 'center': + initialMoveX = originalWidth / 2; + initialMoveY = originalHeight / 2; + moveX = -originalWidth / 2; + moveY = -originalHeight / 2; + break; + } + + return new Effect.MoveBy(element, initialMoveY, initialMoveX, { + duration: 0.01, + beforeSetup: function(effect) { + Element.hide(effect.element); + Element.makeClipping(effect.element); + Element.makePositioned(effect.element); + }, + afterFinishInternal: function(effect) { + new Effect.Parallel( + [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: opacityTransition }), + new Effect.MoveBy(effect.element, moveY, moveX, { sync: true, transition: moveTransition }), + new Effect.Scale(effect.element, 100, { + scaleMode: { originalHeight: originalHeight, originalWidth: originalWidth }, + sync: true, scaleFrom: window.opera ? 1 : 0, transition: scaleTransition, restoreAfterFinish: true}) + ], Object.extend({ + beforeSetup: function(effect) { + effect.effects[0].element.style.height = 0; + Element.show(effect.effects[0].element); + }, + afterFinishInternal: function(effect) { + var el = effect.effects[0].element; + var els = el.style; + Element.undoClipping(el); + Element.undoPositioned(el); + els.top = oldTop; + els.left = oldLeft; + els.height = oldHeight; + els.width = originalWidth; + Element.setInlineOpacity(el, oldOpacity); + } + }, options) + ) + } + }); +} + +Effect.Shrink = function(element) { + element = $(element); + var options = arguments[1] || {}; + + var originalWidth = element.clientWidth; + var originalHeight = element.clientHeight; + var oldTop = element.style.top; + var oldLeft = element.style.left; + var oldHeight = element.style.height; + var oldWidth = element.style.width; + var oldOpacity = Element.getInlineOpacity(element); + + var direction = options.direction || 'center'; + var moveTransition = options.moveTransition || Effect.Transitions.sinoidal; + var scaleTransition = options.scaleTransition || Effect.Transitions.sinoidal; + var opacityTransition = options.opacityTransition || Effect.Transitions.none; + + var moveX, moveY; + + switch (direction) { + case 'top-left': + moveX = moveY = 0; + break; + case 'top-right': + moveX = originalWidth; + moveY = 0; + break; + case 'bottom-left': + moveX = 0; + moveY = originalHeight; + break; + case 'bottom-right': + moveX = originalWidth; + moveY = originalHeight; + break; + case 'center': + moveX = originalWidth / 2; + moveY = originalHeight / 2; + break; + } + + return new Effect.Parallel( + [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: opacityTransition }), + new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: scaleTransition, restoreAfterFinish: true}), + new Effect.MoveBy(element, moveY, moveX, { sync: true, transition: moveTransition }) + ], Object.extend({ + beforeStartInternal: function(effect) { + Element.makePositioned(effect.effects[0].element); + Element.makeClipping(effect.effects[0].element); + }, + afterFinishInternal: function(effect) { + var el = effect.effects[0].element; + var els = el.style; + Element.hide(el); + Element.undoClipping(el); + Element.undoPositioned(el); + els.top = oldTop; + els.left = oldLeft; + els.height = oldHeight; + els.width = oldWidth; + Element.setInlineOpacity(el, oldOpacity); + } + }, options) + ); +} + +Effect.Pulsate = function(element) { + element = $(element); + var options = arguments[1] || {}; + var oldOpacity = Element.getInlineOpacity(element); + var transition = options.transition || Effect.Transitions.sinoidal; + var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) }; + reverser.bind(transition); + return new Effect.Opacity(element, + Object.extend(Object.extend({ duration: 3.0, from: 0, + afterFinishInternal: function(effect) { Element.setInlineOpacity(effect.element, oldOpacity); } + }, options), {transition: reverser})); +} + +Effect.Fold = function(element) { + element = $(element); + var originalTop = element.style.top; + var originalLeft = element.style.left; + var originalWidth = element.style.width; + var originalHeight = element.style.height; + Element.makeClipping(element); + return new Effect.Scale(element, 5, Object.extend({ + scaleContent: false, + scaleX: false, + afterFinishInternal: function(effect) { + new Effect.Scale(element, 1, { + scaleContent: false, + scaleY: false, + afterFinishInternal: function(effect) { + Element.hide(effect.element); + Element.undoClipping(effect.element); + effect.element.style.top = originalTop; + effect.element.style.left = originalLeft; + effect.element.style.width = originalWidth; + effect.element.style.height = originalHeight; + } }); + }}, arguments[1] || {})); +} diff --git a/public/javascripts/effects2.js b/public/javascripts/effects2.js new file mode 100644 index 0000000..6b73620 --- /dev/null +++ b/public/javascripts/effects2.js @@ -0,0 +1,349 @@ +// Copyright (c) 2005 Thomas Fuchs (http://mir.aculo.us) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + Effect2 = {} + + /* ------------- transitions ------------- */ + + Effect2.Transitions = {} + Effect2.Transitions.linear = function(pos) { + return pos; + } + Effect2.Transitions.sinoidal = function(pos) { + return (-Math.cos(pos*Math.PI)/2) + 0.5; + } + Effect2.Transitions.reverse = function(pos) { + return 1-pos; + } + Effect2.Transitions.flicker = function(pos) { + return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random(0.25); + } + Effect2.Transitions.wobble = function(pos) { + return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5; + } + + /* ------------- core effects ------------- */ + + Effect2.Base = function() {}; + Effect2.Base.prototype = { + setOptions: function(options) { + this.options = { + transition: Effect2.Transitions.sinoidal, + duration: 1.0, // seconds + fps: 25.0, // max. 100fps + sync: false, // true for combining + from: 0.0, + to: 1.0 + }.extend(options || {}); + }, + start: function(options) { + this.setOptions(options || {}); + this.currentFrame = 0; + this.startOn = new Date().getTime(); + this.finishOn = this.startOn + (this.options.duration*1000); + if(this.options.beforeStart) this.options.beforeStart(this); + if(!this.options.sync) this.loop(); + }, + loop: function() { + timePos = new Date().getTime(); + if(timePos >= this.finishOn) { + this.render(this.options.to); + if(this.finish) this.finish(); + if(this.options.afterFinish) this.options.afterFinish(this); + return; + } + pos = (timePos - this.startOn) / (this.finishOn - this.startOn); + frame = Math.round(pos * this.options.fps * this.options.duration); + if(frame > this.currentFrame) { + this.render(pos); + this.currentFrame = frame; + } + this.timeout = setTimeout(this.loop.bind(this), 10); + }, + render: function(pos) { + if(this.options.transition) pos = this.options.transition(pos); + pos = pos * (this.options.to-this.options.from); + pos += this.options.from; + if(this.options.beforeUpdate) this.options.beforeUpdate(this); + if(this.update) this.update(pos); + if(this.options.afterUpdate) this.options.afterUpdate(this); + }, + cancel: function() { + if(this.timeout) clearTimeout(this.timeout); + } + } + + Effect2.Parallel = Class.create(); + Effect2.Parallel.prototype = (new Effect2.Base()).extend({ + initialize: function(effects) { + this.effects = effects || []; + this.start(arguments[1]); + }, + update: function(position) { + for (var i = 0; i < this.effects.length; i++) + this.effects[i].render(position); + }, + finish: function(position) { + for (var i = 0; i < this.effects.length; i++) + if(this.effects[i].finish) this.effects[i].finish(position); + } + }); + + Effect2.Opacity = Class.create(); + Effect2.Opacity.prototype = (new Effect2.Base()).extend({ + initialize: function() { + this.element = $(arguments[0] || document.rootElement); + options = { + from: 0.0, + to: 1.0 + }.extend(arguments[1] || {}); + this.start(options); + }, + update: function(position) { + this.setOpacity(position); + }, + setOpacity: function(opacity) { + opacity = (opacity == 1) ? 0.99999 : opacity; + this.element.style.opacity = opacity; + this.element.style.filter = "alpha(opacity:"+opacity*100+")"; + } + }); + + Effect2.MoveBy = Class.create(); + Effect2.MoveBy.prototype = (new Effect2.Base()).extend({ + initialize: function(element, toTop, toLeft) { + this.element = $(element); + this.originalTop = + this.element.style.top ? parseFloat(this.element.style.top) : 0; + this.originalLeft = + this.element.style.left ? parseFloat(this.element.style.left) : 0; + this.toTop = toTop; + this.toLeft = toLeft; + if(this.element.style.position == "") + this.element.style.position = "relative"; + this.start(arguments[3]); + }, + update: function(position) { + topd = this.toTop * position + this.originalTop; + leftd = this.toLeft * position + this.originalLeft; + this.setPosition(topd, leftd); + }, + setPosition: function(topd, leftd) { + this.element.style.top = topd + "px"; + this.element.style.left = leftd + "px"; + } + }); + + Effect2.Scale = Class.create(); + Effect2.Scale.prototype = (new Effect2.Base()).extend({ + initialize: function(element, percent) { + this.element = $(element) + options = { + scaleX: true, + scaleY: true, + scaleContent: true, + scaleFromCenter: false, + scaleMode: 'box', // 'box' or 'contents' + scaleFrom: 100.0 + }.extend(arguments[2] || {}); + this.originalTop = this.element.offsetTop; + this.originalLeft = this.element.offsetLeft; + if (this.element.style.fontSize=="") this.sizeEm = 1.0; + if (this.element.style.fontSize && this.element.style.fontSize.indexOf("em")>0) + this.sizeEm = parseFloat(this.element.style.fontSize); + this.factor = (percent/100.0) - (options.scaleFrom/100.0); + if(options.scaleMode=='box') { + this.originalHeight = this.element.clientHeight; + this.originalWidth = this.element.clientWidth; + } else + if(options.scaleMode=='contents') { + this.originalHeight = this.element.scrollHeight; + this.originalWidth = this.element.scrollWidth; + } + this.start(options); + }, + + update: function(position) { + currentScale = (this.options.scaleFrom/100.0) + (this.factor * position); + if(this.options.scaleContent && this.sizeEm) + this.element.style.fontSize = this.sizeEm*currentScale + "em"; + this.setDimensions( + this.originalWidth * currentScale, + this.originalHeight * currentScale); + }, + + setDimensions: function(width, height) { + if(this.options.scaleX) this.element.style.width = width + 'px'; + if(this.options.scaleY) this.element.style.height = height + 'px'; + if(this.options.scaleFromCenter) { + topd = (height - this.originalHeight)/2; + leftd = (width - this.originalWidth)/2; + if(this.element.style.position=='absolute') { + if(this.options.scaleY) this.element.style.top = this.originalTop-topd + "px"; + if(this.options.scaleX) this.element.style.left = this.originalLeft-leftd + "px"; + } else { + if(this.options.scaleY) this.element.style.top = -topd + "px"; + if(this.options.scaleX) this.element.style.left = -leftd + "px"; + } + } + } + }); + + /* ------------- prepackaged effects ------------- */ + + Effect2.Fade = function(element) { + options = { + from: 1.0, + to: 0.0, + afterFinish: function(effect) + { Element.hide(effect.element); + effect.setOpacity(1); } + }.extend(arguments[1] || {}); + new Effect2.Opacity(element,options); + } + +Effect2.Appear = function(element) { + options = { + from: 0.0, + to: 1.0, + beforeStart: function(effect) + { effect.setOpacity(0); + Element.show(effect.element); }, + afterUpdate: function(effect) + { Element.show(effect.element); } + }.extend(arguments[1] || {}); + new Effect2.Opacity(element,options); +} + + Effect2.Puff = function(element) { + new Effect2.Parallel( + [ new Effect2.Scale(element, 200, { sync: true, scaleFromCenter: true }), + new Effect2.Opacity(element, { sync: true, to: 0.0, from: 1.0 } ) ], + { duration: 1.0, + afterUpdate: function(effect) + { effect.effects[0].element.style.position = 'absolute'; }, + afterFinish: function(effect) + { Element.hide(effect.effects[0].element); } + } + ); + } + + Effect2.BlindUp = function(element) { + $(element).style.overflow = 'hidden'; + new Effect2.Scale(element, 0, + { scaleContent: false, + scaleX: false, + afterFinish: function(effect) + { Element.hide(effect.element) } + }.extend(arguments[1] || {}) + ); + } + + Effect2.BlindDown = function(element) { + $(element).style.height = '0px'; + $(element).style.overflow = 'hidden'; + Element.show(element); + new Effect2.Scale(element, 100, + { scaleContent: false, + scaleX: false, + scaleMode: 'contents', + scaleFrom: 0 + }.extend(arguments[1] || {}) + ); + } + + Effect2.SwitchOff = function(element) { + new Effect2.Appear(element, + { duration: 0.4, + transition: Effect2.Transitions.flicker, + afterFinish: function(effect) + { effect.element.style.overflow = 'hidden'; + new Effect2.Scale(effect.element, 1, + { duration: 0.3, scaleFromCenter: true, + scaleX: false, scaleContent: false, + afterUpdate: function(effect) { + if(effect.element.style.position=="") + effect.element.style.position = 'relative'; }, + afterFinish: function(effect) { Element.hide(effect.element); } + } ) + } + } ) + } + + Effect2.DropOut = function(element) { + new Effect2.Parallel( + [ new Effect2.MoveBy(element, 100, 0, { sync: true }), + new Effect2.Opacity(element, { sync: true, to: 0.0, from: 1.0 } ) ], + { duration: 0.5, + afterFinish: function(effect) + { Element.hide(effect.effects[0].element); } + }); + } + + Effect2.Shake = function(element) { + new Effect2.MoveBy(element, 0, 20, + { duration: 0.05, afterFinish: function(effect) { + new Effect2.MoveBy(effect.element, 0, -40, + { duration: 0.1, afterFinish: function(effect) { + new Effect2.MoveBy(effect.element, 0, 40, + { duration: 0.1, afterFinish: function(effect) { + new Effect2.MoveBy(effect.element, 0, -40, + { duration: 0.1, afterFinish: function(effect) { + new Effect2.MoveBy(effect.element, 0, 40, + { duration: 0.1, afterFinish: function(effect) { + new Effect2.MoveBy(effect.element, 0, -20, + { duration: 0.05, afterFinish: function(effect) { + }}) }}) }}) }}) }}) }}); + } + + Effect2.SlideDown = function(element) { + $(element).style.height = '0px'; + $(element).style.overflow = 'hidden'; + $(element).firstChild.style.position = 'relative'; + Element.show(element); + new Effect2.Scale(element, 100, + { scaleContent: false, + scaleX: false, + scaleMode: 'contents', + scaleFrom: 0, + afterUpdate: function(effect) + { effect.element.firstChild.style.bottom = + (effect.originalHeight - effect.element.clientHeight) + 'px'; } + }.extend(arguments[1] || {}) + ); + } + + Effect2.SlideUp = function(element) { + $(element).style.overflow = 'hidden'; + $(element).firstChild.style.position = 'relative'; + Element.show(element); + new Effect2.Scale(element, 0, + { scaleContent: false, + scaleX: false, + afterUpdate: function(effect) + { effect.element.firstChild.style.bottom = + (effect.originalHeight - effect.element.clientHeight) + 'px'; }, + afterFinish: function(effect) + { Element.hide(effect.element); } + }.extend(arguments[1] || {}) + ); + } \ No newline at end of file diff --git a/public/javascripts/global.js b/public/javascripts/global.js new file mode 100644 index 0000000..a1367b9 --- /dev/null +++ b/public/javascripts/global.js @@ -0,0 +1 @@ +function changeLoc(loc){window.location=loc}function getCookie(name){var prefix=name+"=";var cStr=document.cookie;var start=cStr.indexOf(prefix);if(start==-1){return null;}var end=cStr.indexOf(";",start+prefix.length);if(end==-1){end=cStr.length;}var value=cStr.substring(start+prefix.length,end);return unescape(value);}function setCookie(name,value,expiration){document.cookie=name+"="+value+"; expires="+expiration;}function toggleCheckbox(checkBox){var element=document.getElementById(checkBox.id);if(element.value=="1"||element.checked){element.checked=false;element.value="0";}else{element.checked=true;element.value="1";}}function toggleChkbox(checkBox){if(checkBox.checked){checkBox.checked=true;}else{checkBox.checked=false;}}function toggle_list(id){ul="ul_"+id;img="img_"+id;hid="h_"+id;ulElement=document.getElementById(ul);imgElement=document.getElementById(img);hiddenElement=document.getElementById(hid);if(ulElement){if(ulElement.className=='closed'){ulElement.className="open";imgElement.src="/images/list_opened.gif";hiddenElement.value="1"}else{ulElement.className="closed";imgElement.src="/images/list_closed.gif";hiddenElement.value="0"}}}function toggle_layer(id){lElement=document.getElementById(id);imgElement=document.getElementById("img_"+id);if(lElement){if(lElement.className=='closed'){lElement.className="open";imgElement.src="/images/list_opened.gif";return true;}else{lElement.className="closed";imgElement.src="/images/list_closed.gif";return false;}}return true;}function toggle_layer_status(id){lElement=document.getElementById(id);if(lElement){if(lElement.className=='closed'){return false;}else{return true;}}return true;}function toggle_text(id){if(document.getElementById)elem=document.getElementById(id);else if(document.all)elem=eval("document.all."+id);else return false;if(!elem)return true;elemStyle=elem.style;if(elemStyle.display!="block"){elemStyle.display="block"}else{elemStyle.display="none"}return true;}function getFF(id){if(document.getElementById)elem=document.getElementById(id);else if(document.all)elem=document.eval("document.all."+id);return elem}function setFF(id,value){if(getFF(id))getFF(id).value=value;}function setCFF(id){if(getFF(id))getFF(id).checked=true;}function updateSUFromC(btnName){var suem=getCookie('_cdf_em');var sueg=getCookie('_cdf_gr');if(suem!=""&&suem!=null&&suem!="undefined"){setFF('sup_email',suem);setFF('signup_submit_button',btnName);}if(sueg&&sueg!=""){if(sueg.indexOf(",")<0&&sueg!=""){gr_id=sueg;setCFF('supgr_'+gr_id);}else while((i=sueg.indexOf(","))>=0){gr_id=sueg.substring(0,i);sueg=sueg.substring(i+1);setCFF('supgr_'+gr_id);}if(sueg.indexOf(",")<0&&sueg!=""){gr_id=sueg;setCFF('supgr_'+gr_id);}}}function updateLUEfC(){var suem=getCookie('_cdf_em');if(suem!=""&&suem!=null&&suem!="undefined"){setFF('login_user_email',suem);}}function replaceHRFST(ifrm){var o=ifrm;var w=null;if(o.contentWindow){w=o.contentWindow;}else if(window.frames&&window.frames[o.id].window){w=window.frames[o.id];}else return;var doc=w.document;if(!doc.getElementsByTagName)return;var anchors=doc.getElementsByTagName("a");for(var i=0;i=12){adds=' PM';h=system_date.getHours()-12;}else{adds=' AM';h=system_date.getHours();}spans[i].innerHTML=h+":"+(system_date.getMinutes()+"").replace(/\b(\d)\b/g,'0$1')+adds;}}function PopupPic(sPicURL,sWidth,sHeight){window.open("/popup.htm?"+sPicURL,"","resizable=1,HEIGHT="+sHeight+",WIDTH="+sWidth+",scrollbars=yes");}function open_link(target,location){if(target=='blank'){window.open(location);}else{window.top.location=location;}} \ No newline at end of file diff --git a/public/javascripts/global_src.js b/public/javascripts/global_src.js new file mode 100644 index 0000000..94e387a --- /dev/null +++ b/public/javascripts/global_src.js @@ -0,0 +1,201 @@ +function changeLoc(loc) { window.location = loc } +function getCookie(name) { + var prefix = name + "="; + var cStr = document.cookie; + var start = cStr.indexOf(prefix); + if (start==-1) { + return null; + } + + var end = cStr.indexOf(";", start+prefix.length); + if (end==-1) { end=cStr.length; } + + var value=cStr.substring(start+prefix.length, end); + return unescape(value); +} +function setCookie(name, value, expiration) { + document.cookie = name+"="+value+"; expires="+expiration; +} +function toggleCheckbox(checkBox) { + var element = document.getElementById(checkBox.id); + if (element.value == "1" || element.checked) { + element.checked = false; + element.value = "0"; + } else { + element.checked = true; + element.value = "1"; + } +} +function toggleChkbox(checkBox) { + if (checkBox.checked) { + checkBox.checked = true; + } else { + checkBox.checked = false; + } +} +function toggle_list(id){ + ul = "ul_" + id; + img = "img_" + id; + hid = "h_" + id; + ulElement = document.getElementById(ul); + imgElement = document.getElementById(img); + hiddenElement = document.getElementById(hid); + if (ulElement){ + if (ulElement.className == 'closed'){ + ulElement.className = "open"; + imgElement.src = "/images/list_opened.gif"; + hiddenElement.value = "1" + }else{ + ulElement.className = "closed"; + imgElement.src = "/images/list_closed.gif"; + hiddenElement.value = "0" + } + } +} +function toggle_layer(id) { + lElement = document.getElementById(id); + imgElement = document.getElementById("img_" + id); + if (lElement){ + if (lElement.className == 'closed'){ + lElement.className = "open"; + imgElement.src = "/images/list_opened.gif"; + return true; + }else{ + lElement.className = "closed"; + imgElement.src = "/images/list_closed.gif"; + return false; + } + } + return true; +} +function toggle_layer_status(id) { + lElement = document.getElementById(id); + if (lElement){ + if (lElement.className == 'closed'){ + return false; + }else{ + return true; + } + } + return true; +} +function toggle_text(id){ + if ( document.getElementById ) + elem = document.getElementById( id ); + else if ( document.all ) + elem = eval( "document.all." + id ); + else + return false; + + if(!elem) return true; + + elemStyle = elem.style; + if ( elemStyle.display != "block" ) { + elemStyle.display = "block" + } else { + elemStyle.display = "none" + } + return true; +} +function getFF(id) { + if ( document.getElementById ) elem = document.getElementById( id ); + else if ( document.all ) elem = document.eval( "document.all." + id ); + return elem +} +function setFF(id, value) {if(getFF(id))getFF(id).value=value;} +function setCFF(id) {if(getFF(id))getFF(id).checked=true;} +function updateSUFromC(btnName) { + var suem = getCookie('_cdf_em');var sueg = getCookie('_cdf_gr'); + if (suem != "" && suem != null && suem != "undefined") { setFF('sup_email', suem); setFF('signup_submit_button',btnName); } + + if (sueg && sueg != "") { + if (sueg.indexOf(",") < 0 && sueg != "") { gr_id = sueg; setCFF('supgr_'+gr_id); + } else while ((i = sueg.indexOf(",")) >= 0) { gr_id = sueg.substring(0,i); sueg = sueg.substring(i+1); setCFF('supgr_'+gr_id); } + if (sueg.indexOf(",") < 0 && sueg != "") { gr_id = sueg; setCFF('supgr_'+gr_id);} + } +} +function updateLUEfC() { + var suem = getCookie('_cdf_em'); + if (suem != "" && suem != null && suem != "undefined") { setFF('login_user_email', suem); } +} +function replaceHRFST(ifrm) { + var o = ifrm; + var w = null; + if (o.contentWindow) { + // For IE5.5 and IE6 + w = o.contentWindow; + } else if (window.frames && window.frames[o.id].window) { + w = window.frames[o.id]; + } else return; + var doc = w.document; + if (!doc.getElementsByTagName) return; + var anchors = doc.getElementsByTagName("a"); + for (var i=0; i= 12) { adds = ' PM'; h = system_date.getHours() - 12; } + else { adds = ' AM'; h = system_date.getHours(); } + spans[i].innerHTML = h + ":" + (system_date.getMinutes()+"").replace(/\b(\d)\b/g, '0$1') + adds; + } +} +function PopupPic(sPicURL,sWidth,sHeight) { + window.open( "/popup.htm?"+sPicURL, "", "resizable=1,HEIGHT="+sHeight+",WIDTH="+sWidth+",scrollbars=yes"); +} + +function open_link(target, location){ + if (target == 'blank'){ + window.open(location); + } else { + window.top.location = location; + } +} \ No newline at end of file diff --git a/public/javascripts/htmlstyle.js b/public/javascripts/htmlstyle.js new file mode 100755 index 0000000..ece3392 --- /dev/null +++ b/public/javascripts/htmlstyle.js @@ -0,0 +1,21 @@ +var config = new HTMLArea.Config(); // create a new configuration object + // having all the default values +config.width = '520px'; +config.pageStyle = + 'body { font-family: verdana,sans-serif; font-size: 12px } '; + +config.toolbar = [ +[ "fontname", "fontsize","formatblock","bold", "italic", "underline", "separator", "insertimage", "createlink"], +["justifyleft", "justifycenter", "justifyright", "justifyfull", "separator", "forecolor", "hilitecolor", "separator", "popupeditor", "htmlmode"] +]; +config.statusBar = false; + +var configView = new HTMLArea.Config(); // create a new configuration object + // having all the default values +configView.width = '670px'; +configView.pageStyle = + 'body { font-family: verdana,sans-serif; font-size: 12px } '; + +configView.toolbar = []; +configView.statusBar = false; +configView.readonly = true; \ No newline at end of file diff --git a/public/javascripts/jstrim.pl b/public/javascripts/jstrim.pl new file mode 100755 index 0000000..7829efc --- /dev/null +++ b/public/javascripts/jstrim.pl @@ -0,0 +1,76 @@ +#! /usr/bin/perl -w + +jsTrim("prototype_src.js", "prototype.js"); +jsTrim("global_src.js", "global.js"); +#jsTrim("jscripts/tiny_mce/themes/simple/editor_template_src.js", "jscripts/tiny_mce/themes/simple/editor_template.js"); +#jsTrim("jscripts/tiny_mce/themes/default/editor_template_src.js", "jscripts/tiny_mce/themes/default/editor_template.js"); +#jsTrim("jscripts/tiny_mce/themes/advanced/editor_template_src.js", "jscripts/tiny_mce/themes/advanced/editor_template.js"); +#jsTrim("jscripts/tiny_mce/plugins/advhr/editor_plugin_src.js", "jscripts/tiny_mce/plugins/advhr/editor_plugin.js"); +#jsTrim("jscripts/tiny_mce/plugins/advimage/editor_plugin_src.js", "jscripts/tiny_mce/plugins/advimage/editor_plugin.js"); +#jsTrim("jscripts/tiny_mce/plugins/advlink/editor_plugin_src.js", "jscripts/tiny_mce/plugins/advlink/editor_plugin.js"); +#jsTrim("jscripts/tiny_mce/plugins/emotions/editor_plugin_src.js", "jscripts/tiny_mce/plugins/emotions/editor_plugin.js"); +#jsTrim("jscripts/tiny_mce/plugins/flash/editor_plugin_src.js", "jscripts/tiny_mce/plugins/flash/editor_plugin.js"); +#jsTrim("jscripts/tiny_mce/plugins/iespell/editor_plugin_src.js", "jscripts/tiny_mce/plugins/iespell/editor_plugin.js"); +#jsTrim("jscripts/tiny_mce/plugins/insertdatetime/editor_plugin_src.js", "jscripts/tiny_mce/plugins/insertdatetime/editor_plugin.js"); +#jsTrim("jscripts/tiny_mce/plugins/preview/editor_plugin_src.js", "jscripts/tiny_mce/plugins/preview/editor_plugin.js"); +#jsTrim("jscripts/tiny_mce/plugins/print/editor_plugin_src.js", "jscripts/tiny_mce/plugins/print/editor_plugin.js"); +#jsTrim("jscripts/tiny_mce/plugins/save/editor_plugin_src.js", "jscripts/tiny_mce/plugins/save/editor_plugin.js"); +#jsTrim("jscripts/tiny_mce/plugins/searchreplace/editor_plugin_src.js", "jscripts/tiny_mce/plugins/searchreplace/editor_plugin.js"); +#jsTrim("jscripts/tiny_mce/plugins/zoom/editor_plugin_src.js", "jscripts/tiny_mce/plugins/zoom/editor_plugin.js"); +#jsTrim("jscripts/tiny_mce/plugins/table/editor_plugin_src.js", "jscripts/tiny_mce/plugins/table/editor_plugin.js"); +#jsTrim("jscripts/tiny_mce/plugins/contextmenu/editor_plugin_src.js", "jscripts/tiny_mce/plugins/contextmenu/editor_plugin.js"); +#jsTrim("jscripts/tiny_mce/plugins/paste/editor_plugin_src.js", "jscripts/tiny_mce/plugins/paste/editor_plugin.js"); +#jsTrim("jscripts/tiny_mce/plugins/fullscreen/editor_plugin_src.js", "jscripts/tiny_mce/plugins/fullscreen/editor_plugin.js"); +#jsTrim("jscripts/tiny_mce/plugins/directionality/editor_plugin_src.js", "jscripts/tiny_mce/plugins/directionality/editor_plugin.js"); + +sub jsTrim { + my $inFile = $_[0]; + my $outFile = $_[1]; + my $comment = ''; + my $content = ''; + + # Load input file + open(FILE, "<$inFile"); + undef $/; + $content = ; + close(FILE); + + if ($content =~ s#^\s*(/\*.*?\*/)##s or $content =~ s#^\s*(//.*?)\n\s*[^/]##s) { + $comment = "$1\n"; + } + + local $^W; + + # removing C/C++ - style comments: + $content =~ s#/\*[^*]*\*+([^/*][^*]*\*+)*/|//[^\n]*|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#$2#gs; + + # save string literals + my @strings = (); + $content =~ s/("(\\.|[^"\\])*"|'(\\.|[^'\\])*')/push(@strings, "$1");'__CMPRSTR_'.$#strings.'__';/egs; + + # remove C-style comments + $content =~ s#/\*.*?\*/##gs; + # remove C++-style comments + $content =~ s#//.*?\n##gs; + # removing leading/trailing whitespace: + #$content =~ s#(?:(?:^|\n)\s+|\s+(?:$|\n))##gs; + # removing newlines: + #$content =~ s#\r?\n##gs; + + # removing other whitespace (between operators, etc.) (regexp-s stolen from Mike Hall's JS Crunchinator) + $content =~ s/\s+/ /gs; # condensing whitespace + #$content =~ s/^\s(.*)/$1/gs; # condensing whitespace + #$content =~ s/(.*)\s$/$1/gs; # condensing whitespace + $content =~ s/\s([\x21\x25\x26\x28\x29\x2a\x2b\x2c\x2d\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x5b\x5d\x5c\x7b\x7c\x7d\x7e])/$1/gs; + $content =~ s/([\x21\x25\x26\x28\x29\x2a\x2b\x2c\x2d\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x5b\x5d\x5c\x7b\x7c\x7d\x7e])\s/$1/gs; + + # restore string literals + $content =~ s/__CMPRSTR_([0-9]+)__/$strings[$1]/egs; + + # Write to ouput file + open(FILE, ">$outFile"); + flock(FILE, 2); + seek(FILE, 0, 2); + print FILE $comment, $content; + close(FILE); +} diff --git a/public/javascripts/prototype.js b/public/javascripts/prototype.js new file mode 100644 index 0000000..120f4cb --- /dev/null +++ b/public/javascripts/prototype.js @@ -0,0 +1,1724 @@ +/* Prototype JavaScript framework, version 1.4.0_rc0 + * (c) 2005 Sam Stephenson + * + * THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff + * against the source tree, available from the Prototype darcs repository. + * + * Prototype is freely distributable under the terms of an MIT-style license. + * + * For details, see the Prototype web site: http://prototype.conio.net/ + * +/*--------------------------------------------------------------------------*/ + +var Prototype = { + Version: '1.4.0_rc0', + + emptyFunction: function() {}, + K: function(x) {return x} +} + +var Class = { + create: function() { + return function() { + this.initialize.apply(this, arguments); + } + } +} + +var Abstract = new Object(); + +Object.extend = function(destination, source) { + for (property in source) { + destination[property] = source[property]; + } + return destination; +} + +Object.inspect = function(object) { + try { + if (object == undefined) return 'undefined'; + if (object == null) return 'null'; + return object.inspect ? object.inspect() : object.toString(); + } catch (e) { + if (e instanceof RangeError) return '...'; + throw e; + } +} + +Function.prototype.bind = function(object) { + var __method = this; + return function() { + return __method.apply(object, arguments); + } +} + +Function.prototype.bindAsEventListener = function(object) { + var __method = this; + return function(event) { + return __method.call(object, event || window.event); + } +} + +Object.extend(Number.prototype, { + toColorPart: function() { + var digits = this.toString(16); + if (this < 16) return '0' + digits; + return digits; + }, + + succ: function() { + return this + 1; + }, + + times: function(iterator) { + $R(0, this, true).each(iterator); + return this; + } +}); + +var Try = { + these: function() { + var returnValue; + + for (var i = 0; i < arguments.length; i++) { + var lambda = arguments[i]; + try { + returnValue = lambda(); + break; + } catch (e) {} + } + + return returnValue; + } +} + +/*--------------------------------------------------------------------------*/ + +var PeriodicalExecuter = Class.create(); +PeriodicalExecuter.prototype = { + initialize: function(callback, frequency) { + this.callback = callback; + this.frequency = frequency; + this.currentlyExecuting = false; + + this.registerCallback(); + }, + + registerCallback: function() { + setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + if (!this.currentlyExecuting) { + try { + this.currentlyExecuting = true; + this.callback(); + } finally { + this.currentlyExecuting = false; + } + } + } +} + +/*--------------------------------------------------------------------------*/ + +function $() { + var elements = new Array(); + + for (var i = 0; i < arguments.length; i++) { + var element = arguments[i]; + if (typeof element == 'string') + element = document.getElementById(element); + + if (arguments.length == 1) + return element; + + elements.push(element); + } + + return elements; +} +Object.extend(String.prototype, { + stripTags: function() { + return this.replace(/<\/?[^>]+>/gi, ''); + }, + + escapeHTML: function() { + var div = document.createElement('div'); + var text = document.createTextNode(this); + div.appendChild(text); + return div.innerHTML; + }, + + unescapeHTML: function() { + var div = document.createElement('div'); + div.innerHTML = this.stripTags(); + return div.childNodes[0] ? div.childNodes[0].nodeValue : ''; + }, + + toQueryParams: function() { + var pairs = this.match(/^\??(.*)$/)[1].split('&'); + return pairs.inject({}, function(params, pairString) { + var pair = pairString.split('='); + params[pair[0]] = pair[1]; + return params; + }); + }, + + toArray: function() { + return this.split(''); + }, + + camelize: function() { + var oStringList = this.split('-'); + if (oStringList.length == 1) return oStringList[0]; + + var camelizedString = this.indexOf('-') == 0 + ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) + : oStringList[0]; + + for (var i = 1, len = oStringList.length; i < len; i++) { + var s = oStringList[i]; + camelizedString += s.charAt(0).toUpperCase() + s.substring(1); + } + + return camelizedString; + }, + + inspect: function() { + return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'"; + } +}); + +String.prototype.parseQuery = String.prototype.toQueryParams; + +var $break = new Object(); +var $continue = new Object(); + +var Enumerable = { + each: function(iterator) { + var index = 0; + try { + this._each(function(value) { + try { + iterator(value, index++); + } catch (e) { + if (e != $continue) throw e; + } + }); + } catch (e) { + if (e != $break) throw e; + } + }, + + all: function(iterator) { + var result = true; + this.each(function(value, index) { + if (!(result &= (iterator || Prototype.K)(value, index))) + throw $break; + }); + return result; + }, + + any: function(iterator) { + var result = true; + this.each(function(value, index) { + if (result &= (iterator || Prototype.K)(value, index)) + throw $break; + }); + return result; + }, + + collect: function(iterator) { + var results = []; + this.each(function(value, index) { + results.push(iterator(value, index)); + }); + return results; + }, + + detect: function (iterator) { + var result; + this.each(function(value, index) { + if (iterator(value, index)) { + result = value; + throw $break; + } + }); + return result; + }, + + findAll: function(iterator) { + var results = []; + this.each(function(value, index) { + if (iterator(value, index)) + results.push(value); + }); + return results; + }, + + grep: function(pattern, iterator) { + var results = []; + this.each(function(value, index) { + var stringValue = value.toString(); + if (stringValue.match(pattern)) + results.push((iterator || Prototype.K)(value, index)); + }) + return results; + }, + + include: function(object) { + var found = false; + this.each(function(value) { + if (value == object) { + found = true; + throw $break; + } + }); + return found; + }, + + inject: function(memo, iterator) { + this.each(function(value, index) { + memo = iterator(memo, value, index); + }); + return memo; + }, + + invoke: function(method) { + var args = $A(arguments).slice(1); + return this.collect(function(value) { + return value[method].apply(value, args); + }); + }, + + max: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (value >= (result || value)) + result = value; + }); + return result; + }, + + min: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (value <= (result || value)) + result = value; + }); + return result; + }, + + partition: function(iterator) { + var trues = [], falses = []; + this.each(function(value, index) { + ((iterator || Prototype.K)(value, index) ? + trues : falses).push(value); + }); + return [trues, falses]; + }, + + pluck: function(property) { + var results = []; + this.each(function(value, index) { + results.push(value[property]); + }); + return results; + }, + + reject: function(iterator) { + var results = []; + this.each(function(value, index) { + if (!iterator(value, index)) + results.push(value); + }); + return results; + }, + + sortBy: function(iterator) { + return this.collect(function(value, index) { + return {value: value, criteria: iterator(value, index)}; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }).pluck('value'); + }, + + toArray: function() { + return this.collect(Prototype.K); + }, + + zip: function() { + var iterator = Prototype.K, args = $A(arguments); + if (typeof args.last() == 'function') + iterator = args.pop(); + + var collections = [this].concat(args).map($A); + return this.map(function(value, index) { + iterator(value = collections.pluck(index)); + return value; + }); + }, + + inspect: function() { + return '#'; + } +} + +Object.extend(Enumerable, { + map: Enumerable.collect, + find: Enumerable.detect, + select: Enumerable.findAll, + member: Enumerable.include, + entries: Enumerable.toArray +}); +var $A = Array.from = function(iterable) { + if (iterable.toArray) { + return iterable.toArray(); + } else { + var results = []; + for (var i = 0; i < iterable.length; i++) + results.push(iterable[i]); + return results; + } +} + +Object.extend(Array.prototype, Enumerable); + +Object.extend(Array.prototype, { + _each: function(iterator) { + for (var i = 0; i < this.length; i++) + iterator(this[i]); + }, + + first: function() { + return this[0]; + }, + + last: function() { + return this[this.length - 1]; + }, + + compact: function() { + return this.select(function(value) { + return value != undefined || value != null; + }); + }, + + flatten: function() { + return this.inject([], function(array, value) { + return array.concat(value.constructor == Array ? + value.flatten() : [value]); + }); + }, + + without: function() { + var values = $A(arguments); + return this.select(function(value) { + return !values.include(value); + }); + }, + + indexOf: function(object) { + for (var i = 0; i < this.length; i++) + if (this[i] == object) return i; + return false; + }, + + reverse: function() { + var result = []; + for (var i = this.length; i > 0; i--) + result.push(this[i-1]); + return result; + }, + + inspect: function() { + return '[' + this.map(Object.inspect).join(', ') + ']'; + } +}); +var Hash = { + _each: function(iterator) { + for (key in this) { + var value = this[key]; + if (typeof value == 'function') continue; + + var pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } + }, + + keys: function() { + return this.pluck('key'); + }, + + values: function() { + return this.pluck('value'); + }, + + merge: function(hash) { + return $H(hash).inject($H(this), function(mergedHash, pair) { + mergedHash[pair.key] = pair.value; + return mergedHash; + }); + }, + + toQueryString: function() { + return this.map(function(pair) { + return pair.map(encodeURIComponent).join('='); + }).join('&'); + }, + + inspect: function() { + return '#'; + } +} + +function $H(object) { + var hash = Object.extend({}, object || {}); + Object.extend(hash, Enumerable); + Object.extend(hash, Hash); + return hash; +} +var Range = Class.create(); +Object.extend(Range.prototype, Enumerable); +Object.extend(Range.prototype, { + initialize: function(start, end, exclusive) { + this.start = start; + this.end = end; + this.exclusive = exclusive; + }, + + _each: function(iterator) { + var value = this.start; + do { + iterator(value); + value = value.succ(); + } while (this.include(value)); + }, + + include: function(value) { + if (value < this.start) + return false; + if (this.exclusive) + return value < this.end; + return value <= this.end; + } +}); + +var $R = function(start, end, exclusive) { + return new Range(start, end, exclusive); +} + +var Ajax = { + getTransport: function() { + return Try.these( + function() {return new ActiveXObject('Msxml2.XMLHTTP')}, + function() {return new ActiveXObject('Microsoft.XMLHTTP')}, + function() {return new XMLHttpRequest()} + ) || false; + }, + + activeRequestCount: 0 +} + +Ajax.Responders = { + responders: [], + + _each: function(iterator) { + this.responders._each(iterator); + }, + + register: function(responderToAdd) { + if (!this.include(responderToAdd)) + this.responders.push(responderToAdd); + }, + + unregister: function(responderToRemove) { + this.responders = this.responders.without(responderToRemove); + }, + + dispatch: function(callback, request, transport, json) { + this.each(function(responder) { + if (responder[callback] && typeof responder[callback] == 'function') { + try { + responder[callback].apply(responder, [request, transport, json]); + } catch (e) { + } + } + }); + } +}; + +Object.extend(Ajax.Responders, Enumerable); + +Ajax.Responders.register({ + onCreate: function() { + Ajax.activeRequestCount++; + }, + + onComplete: function() { + Ajax.activeRequestCount--; + } +}); + +Ajax.Base = function() {}; +Ajax.Base.prototype = { + setOptions: function(options) { + this.options = { + method: 'post', + asynchronous: true, + parameters: '' + } + Object.extend(this.options, options || {}); + }, + + responseIsSuccess: function() { + return this.transport.status == undefined + || this.transport.status == 0 + || (this.transport.status >= 200 && this.transport.status < 300); + }, + + responseIsFailure: function() { + return !this.responseIsSuccess(); + } +} + +Ajax.Request = Class.create(); +Ajax.Request.Events = + ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; + +Ajax.Request.prototype = Object.extend(new Ajax.Base(), { + initialize: function(url, options) { + this.transport = Ajax.getTransport(); + this.setOptions(options); + this.request(url); + }, + + request: function(url) { + var parameters = this.options.parameters || ''; + if (parameters.length > 0) parameters += '&_='; + + try { + this.url = url; + if (this.options.method == 'get') + this.url += '?' + parameters; + + Ajax.Responders.dispatch('onCreate', this, this.transport); + + this.transport.open(this.options.method, this.url, + this.options.asynchronous); + + if (this.options.asynchronous) { + this.transport.onreadystatechange = this.onStateChange.bind(this); + setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10); + } + + this.setRequestHeaders(); + + var body = this.options.postBody ? this.options.postBody : parameters; + this.transport.send(this.options.method == 'post' ? body : null); + + } catch (e) { + } + }, + + setRequestHeaders: function() { + var requestHeaders = + ['X-Requested-With', 'XMLHttpRequest', + 'X-Prototype-Version', Prototype.Version]; + + if (this.options.method == 'post') { + requestHeaders.push('Content-type', + 'application/x-www-form-urlencoded'); + + /* Force "Connection: close" for Mozilla browsers to work around + * a bug where XMLHttpReqeuest sends an incorrect Content-length + * header. See Mozilla Bugzilla #246651. + */ + if (this.transport.overrideMimeType) + requestHeaders.push('Connection', 'close'); + } + + if (this.options.requestHeaders) + requestHeaders.push.apply(requestHeaders, this.options.requestHeaders); + + for (var i = 0; i < requestHeaders.length; i += 2) + this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]); + }, + + onStateChange: function() { + var readyState = this.transport.readyState; + if (readyState != 1) + this.respondToReadyState(this.transport.readyState); + }, + + evalJSON: function() { + try { + var json = this.transport.getResponseHeader('X-JSON'), object; + object = eval(json); + return object; + } catch (e) { + } + }, + + respondToReadyState: function(readyState) { + var event = Ajax.Request.Events[readyState]; + var transport = this.transport, json = this.evalJSON(); + + if (event == 'Complete') + (this.options['on' + this.transport.status] + || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')] + || Prototype.emptyFunction)(transport, json); + + (this.options['on' + event] || Prototype.emptyFunction)(transport, json); + Ajax.Responders.dispatch('on' + event, this, transport, json); + + /* Avoid memory leak in MSIE: clean up the oncomplete event handler */ + if (event == 'Complete') + this.transport.onreadystatechange = Prototype.emptyFunction; + } +}); + +Ajax.Updater = Class.create(); +Ajax.Updater.ScriptFragment = '(?:)((\n|.)*?)(?:<\/script>)'; + +Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { + initialize: function(container, url, options) { + this.containers = { + success: container.success ? $(container.success) : $(container), + failure: container.failure ? $(container.failure) : + (container.success ? null : $(container)) + } + + this.transport = Ajax.getTransport(); + this.setOptions(options); + + var onComplete = this.options.onComplete || Prototype.emptyFunction; + this.options.onComplete = (function(transport, object) { + this.updateContent(); + onComplete(transport, object); + }).bind(this); + + this.request(url); + }, + + updateContent: function() { + var receiver = this.responseIsSuccess() ? + this.containers.success : this.containers.failure; + + var match = new RegExp(Ajax.Updater.ScriptFragment, 'img'); + var response = this.transport.responseText.replace(match, ''); + var scripts = this.transport.responseText.match(match); + + if (receiver) { + if (this.options.insertion) { + new this.options.insertion(receiver, response); + } else { + receiver.innerHTML = response; + } + } + + if (this.responseIsSuccess()) { + if (this.onComplete) + setTimeout(this.onComplete.bind(this), 10); + } + + if (this.options.evalScripts && scripts) { + match = new RegExp(Ajax.Updater.ScriptFragment, 'im'); + setTimeout((function() { + for (var i = 0; i < scripts.length; i++) + eval(scripts[i].match(match)[1]); + }).bind(this), 10); + } + } +}); + +Ajax.PeriodicalUpdater = Class.create(); +Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { + initialize: function(container, url, options) { + this.setOptions(options); + this.onComplete = this.options.onComplete; + + this.frequency = (this.options.frequency || 2); + this.decay = (this.options.decay || 1); + + this.updater = {}; + this.container = container; + this.url = url; + + this.start(); + }, + + start: function() { + this.options.onComplete = this.updateComplete.bind(this); + this.onTimerEvent(); + }, + + stop: function() { + this.updater.onComplete = undefined; + clearTimeout(this.timer); + (this.onComplete || Prototype.emptyFunction).apply(this, arguments); + }, + + updateComplete: function(request) { + if (this.options.decay) { + this.decay = (request.responseText == this.lastText ? + this.decay * this.options.decay : 1); + + this.lastText = request.responseText; + } + this.timer = setTimeout(this.onTimerEvent.bind(this), + this.decay * this.frequency * 1000); + }, + + onTimerEvent: function() { + this.updater = new Ajax.Updater(this.container, this.url, this.options); + } +}); +document.getElementsByClassName = function(className, parentElement) { + var children = (document.body || $(parentElement)).getElementsByTagName('*'); + return $A(children).inject([], function(elements, child) { + if (Element.hasClassName(child, className)) + elements.push(child); + return elements; + }); +} + +/*--------------------------------------------------------------------------*/ + +if (!window.Element) { + var Element = new Object(); +} + +Object.extend(Element, { + visible: function(element) { + return $(element).style.display != 'none'; + }, + + toggle: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + Element[Element.visible(element) ? 'hide' : 'show'](element); + } + }, + + hide: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = 'none'; + } + }, + + show: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = ''; + } + }, + + remove: function(element) { + element = $(element); + element.parentNode.removeChild(element); + }, + + getHeight: function(element) { + element = $(element); + return element.offsetHeight; + }, + + classNames: function(element) { + return new Element.ClassNames(element); + }, + + hasClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).include(className); + }, + + addClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).add(className); + }, + + removeClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).remove(className); + }, + + // removes whitespace-only text node children + cleanWhitespace: function(element) { + element = $(element); + for (var i = 0; i < element.childNodes.length; i++) { + var node = element.childNodes[i]; + if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) + Element.remove(node); + } + }, + + empty: function(element) { + return $(element).innerHTML.match(/^\s*$/); + }, + + scrollTo: function(element) { + element = $(element); + var x = element.x ? element.x : element.offsetLeft, + y = element.y ? element.y : element.offsetTop; + window.scrollTo(x, y); + }, + + getStyle: function(element, style) { + element = $(element); + var value = element.style[style.camelize()]; + if (!value) { + if (document.defaultView && document.defaultView.getComputedStyle) { + var css = document.defaultView.getComputedStyle(element, null); + value = css ? css.getPropertyValue(style) : null; + } else if (element.currentStyle) { + value = element.currentStyle[style.camelize()]; + } + } + + if (window.opera && ['left', 'top', 'right', 'bottom'].include(style)) + if (Element.getStyle(element, 'position') == 'static') value = 'auto'; + + return value == 'auto' ? null : value; + }, + + getDimensions: function(element) { + element = $(element); + if (Element.getStyle(element, 'display') != 'none') + return {width: element.offsetWidth, height: element.offsetHeight}; + + // All *Width and *Height properties give 0 on elements with display none, + // so enable the element temporarily + var els = element.style; + var originalVisibility = els.visibility; + var originalPosition = els.position; + els.visibility = 'hidden'; + els.position = 'absolute'; + els.display = ''; + var originalWidth = element.clientWidth; + var originalHeight = element.clientHeight; + els.display = 'none'; + els.position = originalPosition; + els.visibility = originalVisibility; + return {width: originalWidth, height: originalHeight}; + }, + + makePositioned: function(element) { + element = $(element); + var pos = Element.getStyle(element, 'position'); + if (pos == 'static' || !pos) { + element._madePositioned = true; + element.style.position = 'relative'; + // Opera returns the offset relative to the positioning context, when an + // element is position relative but top and left have not been defined + if (window.opera) { + element.style.top = 0; + element.style.left = 0; + } + } + }, + + undoPositioned: function(element) { + element = $(element); + if (element._madePositioned) { + element._madePositioned = undefined; + element.style.position = + element.style.top = + element.style.left = + element.style.bottom = + element.style.right = ''; + } + }, + + makeClipping: function(element) { + element = $(element); + if (element._overflow) return; + element._overflow = element.style.overflow; + if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') + element.style.overflow = 'hidden'; + }, + + undoClipping: function(element) { + element = $(element); + if (element._overflow) return; + element.style.overflow = element._overflow; + element._overflow = undefined; + } +}); + +var Toggle = new Object(); +Toggle.display = Element.toggle; + +/*--------------------------------------------------------------------------*/ + +Abstract.Insertion = function(adjacency) { + this.adjacency = adjacency; +} + +Abstract.Insertion.prototype = { + initialize: function(element, content) { + this.element = $(element); + this.content = content; + + if (this.adjacency && this.element.insertAdjacentHTML) { + try { + this.element.insertAdjacentHTML(this.adjacency, this.content); + } catch (e) { + if (this.element.tagName.toLowerCase() == 'tbody') { + this.insertContent(this.contentFromAnonymousTable()); + } else { + throw e; + } + } + } else { + this.range = this.element.ownerDocument.createRange(); + if (this.initializeRange) this.initializeRange(); + this.insertContent([this.range.createContextualFragment(this.content)]); + } + }, + + contentFromAnonymousTable: function() { + var div = document.createElement('div'); + div.innerHTML = '' + this.content + '
    '; + return $A(div.childNodes[0].childNodes[0].childNodes); + } +} + +var Insertion = new Object(); + +Insertion.Before = Class.create(); +Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), { + initializeRange: function() { + this.range.setStartBefore(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, this.element); + }).bind(this)); + } +}); + +Insertion.Top = Class.create(); +Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(true); + }, + + insertContent: function(fragments) { + fragments.reverse().each((function(fragment) { + this.element.insertBefore(fragment, this.element.firstChild); + }).bind(this)); + } +}); + +Insertion.Bottom = Class.create(); +Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.appendChild(fragment); + }).bind(this)); + } +}); + +Insertion.After = Class.create(); +Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { + initializeRange: function() { + this.range.setStartAfter(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, + this.element.nextSibling); + }).bind(this)); + } +}); + +/*--------------------------------------------------------------------------*/ + +Element.ClassNames = Class.create(); +Element.ClassNames.prototype = { + initialize: function(element) { + this.element = $(element); + }, + + _each: function(iterator) { + this.element.className.split(/\s+/).select(function(name) { + return name.length > 0; + })._each(iterator); + }, + + set: function(className) { + this.element.className = className; + }, + + add: function(classNameToAdd) { + if (this.include(classNameToAdd)) return; + this.set(this.toArray().concat(classNameToAdd).join(' ')); + }, + + remove: function(classNameToRemove) { + if (!this.include(classNameToRemove)) return; + this.set(this.select(function(className) { + return className != classNameToRemove; + })); + }, + + toString: function() { + return this.toArray().join(' '); + } +} + +Object.extend(Element.ClassNames.prototype, Enumerable); +var Field = { + clear: function() { + for (var i = 0; i < arguments.length; i++) + $(arguments[i]).value = ''; + }, + + focus: function(element) { + $(element).focus(); + }, + + present: function() { + for (var i = 0; i < arguments.length; i++) + if ($(arguments[i]).value == '') return false; + return true; + }, + + select: function(element) { + $(element).select(); + }, + + activate: function(element) { + $(element).focus(); + $(element).select(); + } +} + +/*--------------------------------------------------------------------------*/ + +var Form = { + serialize: function(form) { + var elements = Form.getElements($(form)); + var queryComponents = new Array(); + + for (var i = 0; i < elements.length; i++) { + var queryComponent = Form.Element.serialize(elements[i]); + if (queryComponent) + queryComponents.push(queryComponent); + } + + return queryComponents.join('&'); + }, + + getElements: function(form) { + var form = $(form); + var elements = new Array(); + + for (tagName in Form.Element.Serializers) { + var tagElements = form.getElementsByTagName(tagName); + for (var j = 0; j < tagElements.length; j++) + elements.push(tagElements[j]); + } + return elements; + }, + + getInputs: function(form, typeName, name) { + var form = $(form); + var inputs = form.getElementsByTagName('input'); + + if (!typeName && !name) + return inputs; + + var matchingInputs = new Array(); + for (var i = 0; i < inputs.length; i++) { + var input = inputs[i]; + if ((typeName && input.type != typeName) || + (name && input.name != name)) + continue; + matchingInputs.push(input); + } + + return matchingInputs; + }, + + disable: function(form) { + var elements = Form.getElements(form); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + element.blur(); + element.disabled = 'true'; + } + }, + + enable: function(form) { + var elements = Form.getElements(form); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + element.disabled = ''; + } + }, + + focusFirstElement: function(form) { + var form = $(form); + var elements = Form.getElements(form); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + if (element.type != 'hidden' && !element.disabled) { + Field.activate(element); + break; + } + } + }, + + reset: function(form) { + $(form).reset(); + } +} + +Form.Element = { + serialize: function(element) { + var element = $(element); + var method = element.tagName.toLowerCase(); + var parameter = Form.Element.Serializers[method](element); + + if (parameter) + return encodeURIComponent(parameter[0]) + '=' + + encodeURIComponent(parameter[1]); + }, + + getValue: function(element) { + var element = $(element); + var method = element.tagName.toLowerCase(); + var parameter = Form.Element.Serializers[method](element); + + if (parameter) + return parameter[1]; + } +} + +Form.Element.Serializers = { + input: function(element) { + switch (element.type.toLowerCase()) { + case 'submit': + case 'hidden': + case 'password': + case 'text': + return Form.Element.Serializers.textarea(element); + case 'checkbox': + case 'radio': + return Form.Element.Serializers.inputSelector(element); + } + return false; + }, + + inputSelector: function(element) { + if (element.checked) + return [element.name, element.value]; + }, + + textarea: function(element) { + return [element.name, element.value]; + }, + + select: function(element) { + return Form.Element.Serializers[element.type == 'select-one' ? + 'selectOne' : 'selectMany'](element); + }, + + selectOne: function(element) { + var value = '', opt, index = element.selectedIndex; + if (index >= 0) { + opt = element.options[index]; + value = opt.value; + if (!value && !('value' in opt)) + value = opt.text; + } + return [element.name, value]; + }, + + selectMany: function(element) { + var value = new Array(); + for (var i = 0; i < element.length; i++) { + var opt = element.options[i]; + if (opt.selected) { + var optValue = opt.value; + if (!optValue && !('value' in opt)) + optValue = opt.text; + value.push(optValue); + } + } + return [element.name, value]; + } +} + +/*--------------------------------------------------------------------------*/ + +var $F = Form.Element.getValue; + +/*--------------------------------------------------------------------------*/ + +Abstract.TimedObserver = function() {} +Abstract.TimedObserver.prototype = { + initialize: function(element, frequency, callback) { + this.frequency = frequency; + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + this.registerCallback(); + }, + + registerCallback: function() { + setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + var value = this.getValue(); + if (this.lastValue != value) { + this.callback(this.element, value); + this.lastValue = value; + } + } +} + +Form.Element.Observer = Class.create(); +Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.Observer = Class.create(); +Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); + +/*--------------------------------------------------------------------------*/ + +Abstract.EventObserver = function() {} +Abstract.EventObserver.prototype = { + initialize: function(element, callback) { + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + if (this.element.tagName.toLowerCase() == 'form') + this.registerFormCallbacks(); + else + this.registerCallback(this.element); + }, + + onElementEvent: function() { + var value = this.getValue(); + if (this.lastValue != value) { + this.callback(this.element, value); + this.lastValue = value; + } + }, + + registerFormCallbacks: function() { + var elements = Form.getElements(this.element); + for (var i = 0; i < elements.length; i++) + this.registerCallback(elements[i]); + }, + + registerCallback: function(element) { + if (element.type) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + element.target = this; + element.prev_onclick = element.onclick || Prototype.emptyFunction; + element.onclick = function() { + this.prev_onclick(); + this.target.onElementEvent(); + } + break; + case 'password': + case 'text': + case 'textarea': + case 'select-one': + case 'select-multiple': + element.target = this; + element.prev_onchange = element.onchange || Prototype.emptyFunction; + element.onchange = function() { + this.prev_onchange(); + this.target.onElementEvent(); + } + break; + } + } + } +} + +Form.Element.EventObserver = Class.create(); +Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.EventObserver = Class.create(); +Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); +if (!window.Event) { + var Event = new Object(); +} + +Object.extend(Event, { + KEY_BACKSPACE: 8, + KEY_TAB: 9, + KEY_RETURN: 13, + KEY_ESC: 27, + KEY_LEFT: 37, + KEY_UP: 38, + KEY_RIGHT: 39, + KEY_DOWN: 40, + KEY_DELETE: 46, + + element: function(event) { + return event.target || event.srcElement; + }, + + isLeftClick: function(event) { + return (((event.which) && (event.which == 1)) || + ((event.button) && (event.button == 1))); + }, + + pointerX: function(event) { + return event.pageX || (event.clientX + + (document.documentElement.scrollLeft || document.body.scrollLeft)); + }, + + pointerY: function(event) { + return event.pageY || (event.clientY + + (document.documentElement.scrollTop || document.body.scrollTop)); + }, + + stop: function(event) { + if (event.preventDefault) { + event.preventDefault(); + event.stopPropagation(); + } else { + event.returnValue = false; + event.cancelBubble = true; + } + }, + + // find the first node with the given tagName, starting from the + // node the event was triggered on; traverses the DOM upwards + findElement: function(event, tagName) { + var element = Event.element(event); + while (element.parentNode && (!element.tagName || + (element.tagName.toUpperCase() != tagName.toUpperCase()))) + element = element.parentNode; + return element; + }, + + observers: false, + + _observeAndCache: function(element, name, observer, useCapture) { + if (!this.observers) this.observers = []; + if (element.addEventListener) { + this.observers.push([element, name, observer, useCapture]); + element.addEventListener(name, observer, useCapture); + } else if (element.attachEvent) { + this.observers.push([element, name, observer, useCapture]); + element.attachEvent('on' + name, observer); + } + }, + + unloadCache: function() { + if (!Event.observers) return; + for (var i = 0; i < Event.observers.length; i++) { + Event.stopObserving.apply(this, Event.observers[i]); + Event.observers[i][0] = null; + } + Event.observers = false; + }, + + observe: function(element, name, observer, useCapture) { + var element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (navigator.appVersion.match(/Konqueror|Safari|KHTML/) + || element.attachEvent)) + name = 'keydown'; + + this._observeAndCache(element, name, observer, useCapture); + }, + + stopObserving: function(element, name, observer, useCapture) { + var element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (navigator.appVersion.match(/Konqueror|Safari|KHTML/) + || element.detachEvent)) + name = 'keydown'; + + if (element.removeEventListener) { + element.removeEventListener(name, observer, useCapture); + } else if (element.detachEvent) { + element.detachEvent('on' + name, observer); + } + } +}); + +/* prevent memory leaks in IE */ +Event.observe(window, 'unload', Event.unloadCache, false); +var Position = { + // set to true if needed, warning: firefox performance problems + // NOT neeeded for page scrolling, only if draggable contained in + // scrollable elements + includeScrollOffsets: false, + + // must be called before calling withinIncludingScrolloffset, every time the + // page is scrolled + prepare: function() { + this.deltaX = window.pageXOffset + || document.documentElement.scrollLeft + || document.body.scrollLeft + || 0; + this.deltaY = window.pageYOffset + || document.documentElement.scrollTop + || document.body.scrollTop + || 0; + }, + + realOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.scrollTop || 0; + valueL += element.scrollLeft || 0; + element = element.parentNode; + } while (element); + return [valueL, valueT]; + }, + + cumulativeOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + } while (element); + return [valueL, valueT]; + }, + + positionedOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + if (element) { + p = Element.getStyle(element, 'position'); + if (p == 'relative' || p == 'absolute') break; + } + } while (element); + return [valueL, valueT]; + }, + + offsetParent: function(element) { + if (element.offsetParent) return element.offsetParent; + if (element == document.body) return element; + + while ((element = element.parentNode) && element != document.body) + if (Element.getStyle(element, 'position') != 'static') + return element; + + return document.body; + }, + + // caches x/y coordinate pair to use with overlap + within: function(element, x, y) { + if (this.includeScrollOffsets) + return this.withinIncludingScrolloffsets(element, x, y); + this.xcomp = x; + this.ycomp = y; + this.offset = this.cumulativeOffset(element); + + return (y >= this.offset[1] && + y < this.offset[1] + element.offsetHeight && + x >= this.offset[0] && + x < this.offset[0] + element.offsetWidth); + }, + + withinIncludingScrolloffsets: function(element, x, y) { + var offsetcache = this.realOffset(element); + + this.xcomp = x + offsetcache[0] - this.deltaX; + this.ycomp = y + offsetcache[1] - this.deltaY; + this.offset = this.cumulativeOffset(element); + + return (this.ycomp >= this.offset[1] && + this.ycomp < this.offset[1] + element.offsetHeight && + this.xcomp >= this.offset[0] && + this.xcomp < this.offset[0] + element.offsetWidth); + }, + + // within must be called directly before + overlap: function(mode, element) { + if (!mode) return 0; + if (mode == 'vertical') + return ((this.offset[1] + element.offsetHeight) - this.ycomp) / + element.offsetHeight; + if (mode == 'horizontal') + return ((this.offset[0] + element.offsetWidth) - this.xcomp) / + element.offsetWidth; + }, + + clone: function(source, target) { + source = $(source); + target = $(target); + target.style.position = 'absolute'; + var offsets = this.cumulativeOffset(source); + target.style.top = offsets[1] + 'px'; + target.style.left = offsets[0] + 'px'; + target.style.width = source.offsetWidth + 'px'; + target.style.height = source.offsetHeight + 'px'; + }, + + page: function(forElement) { + var valueT = 0, valueL = 0; + + var element = forElement; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + + // Safari fix + if (element.offsetParent==document.body) + if (Element.getStyle(element,'position')=='absolute') break; + + } while (element = element.offsetParent); + + element = forElement; + do { + valueT -= element.scrollTop || 0; + valueL -= element.scrollLeft || 0; + } while (element = element.parentNode); + + return [valueL, valueT]; + }, + + clone: function(source, target) { + var options = Object.extend({ + setLeft: true, + setTop: true, + setWidth: true, + setHeight: true, + offsetTop: 0, + offsetLeft: 0 + }, arguments[2] || {}) + + // find page position of source + source = $(source); + var p = Position.page(source); + + // find coordinate system to use + target = $(target); + var delta = [0, 0]; + var parent = null; + // delta [0,0] will do fine with position: fixed elements, + // position:absolute needs offsetParent deltas + if (Element.getStyle(target,'position') == 'absolute') { + parent = Position.offsetParent(target); + delta = Position.page(parent); + } + + // correct by body offsets (fixes Safari) + if (parent == document.body) { + delta[0] -= document.body.offsetLeft; + delta[1] -= document.body.offsetTop; + } + + // set position + if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; + if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; + if(options.setWidth) target.style.width = source.offsetWidth + 'px'; + if(options.setHeight) target.style.height = source.offsetHeight + 'px'; + }, + + absolutize: function(element) { + element = $(element); + if (element.style.position == 'absolute') return; + Position.prepare(); + + var offsets = Position.positionedOffset(element); + var top = offsets[1]; + var left = offsets[0]; + var width = element.clientWidth; + var height = element.clientHeight; + + element._originalLeft = left - parseFloat(element.style.left || 0); + element._originalTop = top - parseFloat(element.style.top || 0); + element._originalWidth = element.style.width; + element._originalHeight = element.style.height; + + element.style.position = 'absolute'; + element.style.top = top + 'px';; + element.style.left = left + 'px';; + element.style.width = width + 'px';; + element.style.height = height + 'px';; + }, + + relativize: function(element) { + element = $(element); + if (element.style.position == 'relative') return; + Position.prepare(); + + element.style.position = 'relative'; + var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); + var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); + + element.style.top = top + 'px'; + element.style.left = left + 'px'; + element.style.height = element._originalHeight; + element.style.width = element._originalWidth; + } +} + +// Safari returns margins on body which is incorrect if the child is absolutely +// positioned. For performance reasons, redefine Position.cumulativeOffset for +// KHTML/WebKit only. +if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { + Position.cumulativeOffset = function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + if (element.offsetParent == document.body) + if (Element.getStyle(element, 'position') == 'absolute') break; + + element = element.offsetParent; + } while (element); + + return [valueL, valueT]; + } +} \ No newline at end of file diff --git a/public/javascripts/prototype_src.js b/public/javascripts/prototype_src.js new file mode 100644 index 0000000..87aa729 --- /dev/null +++ b/public/javascripts/prototype_src.js @@ -0,0 +1,521 @@ +var Prototype = { + Version: '1.2.1' +}; + +var Class = { + create: function() { + return function() { + this.initialize.apply(this, arguments); + } + } +}; + +var Abstract = new Object(); +Object.prototype.extend = function(object) { + for (property in object) { + this[property] = object[property]; + } + return this; +}; +Function.prototype.bind = function(object) { + var method = this; + return function() { + method.apply(object, arguments); + } +}; + +Function.prototype.bindAsEventListener = function(object) { + var method = this; + return function(event) { + method.call(object, event || window.event); + } +}; + +Number.prototype.toColorPart = function() { + var digits = this.toString(16); + if (this < 16) return '0' + digits; + return digits; +}; + +var Try = { + these: function() { + var returnValue; + + for (var i = 0; i < arguments.length; i++) { + var lambda = arguments[i]; + try { + returnValue = lambda(); + break; + } catch (e) {} + } + + return returnValue; + } +}; + +var PeriodicalExecuter = Class.create(); +PeriodicalExecuter.prototype = { + initialize: function(callback, frequency) { + this.callback = callback; + this.frequency = frequency; + this.currentlyExecuting = false; + + this.registerCallback(); + }, + + registerCallback: function() { + setTimeout(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + if (!this.currentlyExecuting) { + try { + this.currentlyExecuting = true; + this.callback(); + } finally { + this.currentlyExecuting = false; + } + } + + this.registerCallback(); + } +}; +function $() { + var elements = new Array(); + + for (var i = 0; i < arguments.length; i++) { + var element = arguments[i]; + if (typeof element == 'string') + element = document.getElementById(element); + + if (arguments.length == 1) + return element; + + elements.push(element); + } + + return elements; +}; +if (!Array.prototype.push) { + Array.prototype.push = function() { + var startLength = this.length; + for (var i = 0; i < arguments.length; i++) + this[startLength + i] = arguments[i]; + return this.length; + }; +}; + +if (!Function.prototype.apply) { + // Based on code from http://www.youngpup.net/ + Function.prototype.apply = function(object, parameters) { + var parameterStrings = new Array(); + if (!object) object = window; + if (!parameters) parameters = new Array(); + + for (var i = 0; i < parameters.length; i++) + parameterStrings[i] = 'x[' + i + ']'; + + object.__apply__ = this; + var result = eval('obj.__apply__(' + + parameterStrings[i].join(', ') + ')'); + object.__apply__ = null; + + return result; + }; +}; + +var Ajax = { + getTransport: function() { + return Try.these( + function() {return new ActiveXObject('Msxml2.XMLHTTP')}, + function() {return new ActiveXObject('Microsoft.XMLHTTP')}, + function() {return new XMLHttpRequest()} + ) || false; + }, + + emptyFunction: function() {} +}; + +Ajax.Base = function() {}; +Ajax.Base.prototype = { + setOptions: function(options) { + this.options = { + method: 'post', + asynchronous: true, + parameters: '' + }.extend(options || {}); + } +}; + +Ajax.Request = Class.create(); +Ajax.Request.Events = + ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; + +Ajax.Request.prototype = (new Ajax.Base()).extend({ + initialize: function(url, options) { + this.transport = Ajax.getTransport(); + this.setOptions(options); + + try { + if (this.options.method == 'get') + url += '?' + this.options.parameters + '&_='; + + this.transport.open(this.options.method, url, + this.options.asynchronous); + + if (this.options.asynchronous) { + this.transport.onreadystatechange = this.onStateChange.bind(this); + setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10); + } + + this.transport.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); + this.transport.setRequestHeader('X-Prototype-Version', Prototype.Version); + + if (this.options.method == 'post') { + this.transport.setRequestHeader('Connection', 'close'); + this.transport.setRequestHeader('Content-type', + 'application/x-www-form-urlencoded'); + } + + this.transport.send(this.options.method == 'post' ? + this.options.parameters + '&_=' : null); + + } catch (e) { + } + }, + + onStateChange: function() { + var readyState = this.transport.readyState; + if (readyState != 1) + this.respondToReadyState(this.transport.readyState); + }, + + respondToReadyState: function(readyState) { + var event = Ajax.Request.Events[readyState]; + (this.options['on' + event] || Ajax.emptyFunction)(this.transport); + } +}); + +Ajax.Updater = Class.create(); +Ajax.Updater.prototype = (new Ajax.Base()).extend({ + initialize: function(container, url, options) { + this.container = $(container); + this.setOptions(options); + + if (this.options.asynchronous) { + this.onComplete = this.options.onComplete; + this.options.onComplete = this.updateContent.bind(this); + } + + this.request = new Ajax.Request(url, this.options); + + if (!this.options.asynchronous) + this.updateContent(); + }, + + updateContent: function() { + if (this.options.insertion) { + new this.options.insertion(this.container, + this.request.transport.responseText); + } else { + this.container.innerHTML = this.request.transport.responseText; + } + + if (this.onComplete) { + setTimeout((function() {this.onComplete(this.request)}).bind(this), 10); + } + } +}); +var Field = { + clear: function() { + for (var i = 0; i < arguments.length; i++) + $(arguments[i]).value = ''; + }, + + focus: function(element) { + $(element).focus(); + }, + + present: function() { + for (var i = 0; i < arguments.length; i++) + if ($(arguments[i]).value == '') return false; + return true; + }, + + select: function(element) { + $(element).select(); + }, + + activate: function(element) { + $(element).focus(); + $(element).select(); + } +}; +var Form = { + serialize: function(form) { + var elements = Form.getElements($(form)); + var queryComponents = new Array(); + + for (var i = 0; i < elements.length; i++) { + var queryComponent = Form.Element.serialize(elements[i]); + if (queryComponent) + queryComponents.push(queryComponent); + } + + return queryComponents.join('&'); + }, + + getElements: function(form) { + form = $(form); + var elements = new Array(); + + for (tagName in Form.Element.Serializers) { + var tagElements = form.getElementsByTagName(tagName); + for (var j = 0; j < tagElements.length; j++) + elements.push(tagElements[j]); + } + return elements; + }, + + disable: function(form) { + var elements = Form.getElements(form); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + element.blur(); + element.disable = 'true'; + } + }, + + focusFirstElement: function(form) { + form = $(form); + var elements = Form.getElements(form); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + if (element.type != 'hidden' && !element.disabled) { + Field.activate(element); + break; + } + } + }, + + reset: function(form) { + $(form).reset(); + } +}; + +Form.Element = { + serialize: function(element) { + element = $(element); + var method = element.tagName.toLowerCase(); + var parameter = Form.Element.Serializers[method](element); + + if (parameter) + return encodeURIComponent(parameter[0]) + '=' + + encodeURIComponent(parameter[1]); + }, + + getValue: function(element) { + element = $(element); + var method = element.tagName.toLowerCase(); + var parameter = Form.Element.Serializers[method](element); + + if (parameter) + return parameter[1]; + } +}; + +Form.Element.Serializers = { + input: function(element) { + switch (element.type.toLowerCase()) { + case 'hidden': + case 'password': + case 'text': + return Form.Element.Serializers.textarea(element); + case 'checkbox': + case 'radio': + return Form.Element.Serializers.inputSelector(element); + } + return false; + }, + + inputSelector: function(element) { + if (element.checked) + return [element.name, element.value]; + }, + + textarea: function(element) { + return [element.name, element.value]; + }, + + select: function(element) { + var index = element.selectedIndex; + var value = element.options[index].value || element.options[index].text; + return [element.name, (index >= 0) ? value : '']; + } +}; + +var $F = Form.Element.getValue; + +Abstract.TimedObserver = function() {}; +Abstract.TimedObserver.prototype = { + initialize: function(element, frequency, callback) { + this.frequency = frequency; + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + this.registerCallback(); + }, + + registerCallback: function() { + setTimeout(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + var value = this.getValue(); + if (this.lastValue != value) { + this.callback(this.element, value); + this.lastValue = value; + } + + this.registerCallback(); + } +}; + +Form.Element.Observer = Class.create(); +Form.Element.Observer.prototype = (new Abstract.TimedObserver()).extend({ + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.Observer = Class.create(); +Form.Observer.prototype = (new Abstract.TimedObserver()).extend({ + getValue: function() { + return Form.serialize(this.element); + } +}); + +document.getElementsByClassName = function(className) { + var children = document.getElementsByTagName('*') || document.all; + var elements = new Array(); + + for (var i = 0; i < children.length; i++) { + var child = children[i]; + var classNames = child.className.split(' '); + for (var j = 0; j < classNames.length; j++) { + if (classNames[j] == className) { + elements.push(child); + break; + } + } + } + + return elements; +}; + +var Element = { + toggle: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = + (element.style.display == 'none' ? '' : 'none'); + } + }, + + hide: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = 'none'; + } + }, + + show: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = ''; + } + }, + + remove: function(element) { + element = $(element); + element.parentNode.removeChild(element); + }, + + getHeight: function(element) { + element = $(element); + return element.offsetHeight; + } +}; + +var Toggle = new Object(); +Toggle.display = Element.toggle; + +Abstract.Insertion = function(adjacency) { + this.adjacency = adjacency; +}; + +Abstract.Insertion.prototype = { + initialize: function(element, content) { + this.element = $(element); + this.content = content; + + if (this.adjacency && this.element.insertAdjacentHTML) { + this.element.insertAdjacentHTML(this.adjacency, this.content); + } else { + this.range = this.element.ownerDocument.createRange(); + if (this.initializeRange) this.initializeRange(); + this.fragment = this.range.createContextualFragment(this.content); + this.insertContent(); + } + } +}; + +var Insertion = new Object(); + +Insertion.Before = Class.create(); +Insertion.Before.prototype = (new Abstract.Insertion('beforeBegin')).extend({ + initializeRange: function() { + this.range.setStartBefore(this.element); + }, + + insertContent: function() { + this.element.parentNode.insertBefore(this.fragment, this.element); + } +}); + +Insertion.Top = Class.create(); +Insertion.Top.prototype = (new Abstract.Insertion('afterBegin')).extend({ + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(true); + }, + + insertContent: function() { + this.element.insertBefore(this.fragment, this.element.firstChild); + } +}); + +Insertion.Bottom = Class.create(); +Insertion.Bottom.prototype = (new Abstract.Insertion('beforeEnd')).extend({ + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(this.element); + }, + + insertContent: function() { + this.element.appendChild(this.fragment); + } +}); + +Insertion.After = Class.create(); +Insertion.After.prototype = (new Abstract.Insertion('afterEnd')).extend({ + initializeRange: function() { + this.range.setStartAfter(this.element); + }, + + insertContent: function() { + this.element.parentNode.insertBefore(this.fragment, + this.element.nextSibling); + } +}); \ No newline at end of file diff --git a/public/javascripts/scriptaculous.js b/public/javascripts/scriptaculous.js new file mode 100644 index 0000000..cd0e341 --- /dev/null +++ b/public/javascripts/scriptaculous.js @@ -0,0 +1,47 @@ +// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +var Scriptaculous = { + Version: '1.5_rc3', + require: function(libraryName) { + // inserting via DOM fails in Safari 2.0, so brute force approach + document.write(''); + }, + load: function() { + if((typeof Prototype=='undefined') || + parseFloat(Prototype.Version.split(".")[0] + "." + + Prototype.Version.split(".")[1]) < 1.4) + throw("script.aculo.us requires the Prototype JavaScript framework >= 1.4.0"); + var scriptTags = document.getElementsByTagName("script"); + for(var i=0;i this.maximum) sliderValue = this.maximum; + if(sliderValue < this.minimum) sliderValue = this.minimum; + var offsetDiff = (sliderValue - (this.value||this.minimum)) * this.increment; + + if(this.isVertical()){ + this.setCurrentTop(offsetDiff + this.currentTop()); + } else { + this.setCurrentLeft(offsetDiff + this.currentLeft()); + } + this.value = sliderValue; + this.updateFinished(); + }, + minimumOffset: function(){ + return(this.isVertical() ? + this.trackTop() + this.alignY : + this.trackLeft() + this.alignX); + }, + maximumOffset: function(){ + return(this.isVertical() ? + this.trackTop() + this.alignY + (this.maximum - this.minimum) * this.increment : + this.trackLeft() + this.alignX + (this.maximum - this.minimum) * this.increment); + }, + isVertical: function(){ + return (this.axis == 'vertical'); + }, + startDrag: function(event) { + if(Event.isLeftClick(event)) { + if(!this.disabled){ + this.active = true; + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + var offsets = Position.cumulativeOffset(this.handle); + this.offsetX = (pointer[0] - offsets[0]); + this.offsetY = (pointer[1] - offsets[1]); + this.originalLeft = this.currentLeft(); + this.originalTop = this.currentTop(); + } + Event.stop(event); + } + }, + update: function(event) { + if(this.active) { + if(!this.dragging) { + var style = this.handle.style; + this.dragging = true; + if(style.position=="") style.position = "relative"; + style.zIndex = this.options.zindex; + } + this.draw(event); + // fix AppleWebKit rendering + if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); + Event.stop(event); + } + }, + draw: function(event) { + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + var offsets = Position.cumulativeOffset(this.handle); + + offsets[0] -= this.currentLeft(); + offsets[1] -= this.currentTop(); + + // Adjust for the pointer's position on the handle + pointer[0] -= this.offsetX; + pointer[1] -= this.offsetY; + var style = this.handle.style; + + if(this.isVertical()){ + if(pointer[1] > this.maximumOffset()) + pointer[1] = this.maximumOffset(); + if(pointer[1] < this.minimumOffset()) + pointer[1] = this.minimumOffset(); + + // Increment by values + if(this.values){ + this.value = this.getNearestValue(Math.round((pointer[1] - this.minimumOffset()) / this.increment) + this.minimum); + pointer[1] = this.trackTop() + this.alignY + (this.value - this.minimum) * this.increment; + } else { + this.value = Math.round((pointer[1] - this.minimumOffset()) / this.increment) + this.minimum; + } + style.top = pointer[1] - offsets[1] + "px"; + } else { + if(pointer[0] > this.maximumOffset()) pointer[0] = this.maximumOffset(); + if(pointer[0] < this.minimumOffset()) pointer[0] = this.minimumOffset(); + // Increment by values + if(this.values){ + this.value = this.getNearestValue(Math.round((pointer[0] - this.minimumOffset()) / this.increment) + this.minimum); + pointer[0] = this.trackLeft() + this.alignX + (this.value - this.minimum) * this.increment; + } else { + this.value = Math.round((pointer[0] - this.minimumOffset()) / this.increment) + this.minimum; + } + style.left = (pointer[0] - offsets[0]) + "px"; + } + if(this.options.onSlide) this.options.onSlide(this.value); + }, + endDrag: function(event) { + if(this.active && this.dragging) { + this.finishDrag(event, true); + Event.stop(event); + } + this.active = false; + this.dragging = false; + }, + finishDrag: function(event, success) { + this.active = false; + this.dragging = false; + this.handle.style.zIndex = this.originalZ; + this.originalLeft = this.currentLeft(); + this.originalTop = this.currentTop(); + this.updateFinished(); + }, + updateFinished: function() { + if(this.options.onChange) this.options.onChange(this.value); + }, + keyPress: function(event) { + if(this.active && !this.disabled) { + switch(event.keyCode) { + case Event.KEY_ESC: + this.finishDrag(event, false); + Event.stop(event); + break; + } + if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); + } + } +} diff --git a/public/javascripts/webmail.js b/public/javascripts/webmail.js new file mode 100755 index 0000000..698ed65 --- /dev/null +++ b/public/javascripts/webmail.js @@ -0,0 +1,35 @@ +function chooseContacts() { + rs('', '/contacts/contact/list?mode=choose',550,480,0); +} + +function setBulk() { + if (getFormField("mail_bulk").checked) getFormField("set_bulk").value = "set_bulk" + document.forms['composeMail'].submit(); +} + +function getFormField(id) { + if ( document.getElementById ) elem = document.getElementById( id ); + else if ( document.all ) elem = document.eval( "document.all." + id ); + return elem; +} + +function toggle_msg_operations(setc) { + var isOpened = toggle_layer('msgops'); + if (setc) setCookie("_wmlmo", ( isOpened ? "opened" : "closed"), 1000000); +} + +function toggle_msg_search(setc) { + var isOpened = toggle_layer('msg_search'); + if (setc) setCookie("_wmlms", (isOpened ? "opened" : "closed"), 1000000); +} + +function checkAll(theForm) { // check all the checkboxes in the list + for (var i=0;i + + +blank_page + + + + + + diff --git a/public/tiny_mce/jstrim.pl b/public/tiny_mce/jstrim.pl new file mode 100755 index 0000000..43fbf09 --- /dev/null +++ b/public/tiny_mce/jstrim.pl @@ -0,0 +1,75 @@ +#! /usr/bin/perl -w + +jsTrim("tiny_mce_src.js", "tiny_mce.js"); +jsTrim("themes/simple/editor_template_src.js", "themes/simple/editor_template.js"); +jsTrim("themes/default/editor_template_src.js", "themes/default/editor_template.js"); +jsTrim("themes/advanced/editor_template_src.js", "themes/advanced/editor_template.js"); +jsTrim("plugins/advhr/editor_plugin_src.js", "plugins/advhr/editor_plugin.js"); +jsTrim("plugins/advimage/editor_plugin_src.js", "plugins/advimage/editor_plugin.js"); +jsTrim("plugins/advlink/editor_plugin_src.js", "plugins/advlink/editor_plugin.js"); +jsTrim("plugins/linkattach/editor_plugin_src.js", "plugins/linkattach/editor_plugin.js"); +jsTrim("plugins/emotions/editor_plugin_src.js", "plugins/emotions/editor_plugin.js"); +jsTrim("plugins/flash/editor_plugin_src.js", "plugins/flash/editor_plugin.js"); +jsTrim("plugins/iespell/editor_plugin_src.js", "plugins/iespell/editor_plugin.js"); +jsTrim("plugins/insertdatetime/editor_plugin_src.js", "plugins/insertdatetime/editor_plugin.js"); +jsTrim("plugins/preview/editor_plugin_src.js", "plugins/preview/editor_plugin.js"); +jsTrim("plugins/print/editor_plugin_src.js", "plugins/print/editor_plugin.js"); +jsTrim("plugins/save/editor_plugin_src.js", "plugins/save/editor_plugin.js"); +jsTrim("plugins/searchreplace/editor_plugin_src.js", "plugins/searchreplace/editor_plugin.js"); +jsTrim("plugins/zoom/editor_plugin_src.js", "plugins/zoom/editor_plugin.js"); +jsTrim("plugins/table/editor_plugin_src.js", "plugins/table/editor_plugin.js"); +jsTrim("plugins/contextmenu/editor_plugin_src.js", "plugins/contextmenu/editor_plugin.js"); +jsTrim("plugins/paste/editor_plugin_src.js", "plugins/paste/editor_plugin.js"); +jsTrim("plugins/fullscreen/editor_plugin_src.js", "plugins/fullscreen/editor_plugin.js"); +jsTrim("plugins/directionality/editor_plugin_src.js", "plugins/directionality/editor_plugin.js"); +sub jsTrim { + my $inFile = $_[0]; + my $outFile = $_[1]; + my $comment = ''; + my $content = ''; + + # Load input file + open(FILE, "<$inFile"); + undef $/; + $content = ; + close(FILE); + + if ($content =~ s#^\s*(/\*.*?\*/)##s or $content =~ s#^\s*(//.*?)\n\s*[^/]##s) { + $comment = "$1\n"; + } + + local $^W; + + # removing C/C++ - style comments: + $content =~ s#/\*[^*]*\*+([^/*][^*]*\*+)*/|//[^\n]*|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#$2#gs; + + # save string literals + my @strings = (); + $content =~ s/("(\\.|[^"\\])*"|'(\\.|[^'\\])*')/push(@strings, "$1");'__CMPRSTR_'.$#strings.'__';/egs; + + # remove C-style comments + $content =~ s#/\*.*?\*/##gs; + # remove C++-style comments + $content =~ s#//.*?\n##gs; + # removing leading/trailing whitespace: + #$content =~ s#(?:(?:^|\n)\s+|\s+(?:$|\n))##gs; + # removing newlines: + #$content =~ s#\r?\n##gs; + + # removing other whitespace (between operators, etc.) (regexp-s stolen from Mike Hall's JS Crunchinator) + $content =~ s/\s+/ /gs; # condensing whitespace + #$content =~ s/^\s(.*)/$1/gs; # condensing whitespace + #$content =~ s/(.*)\s$/$1/gs; # condensing whitespace + $content =~ s/\s([\x21\x25\x26\x28\x29\x2a\x2b\x2c\x2d\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x5b\x5d\x5c\x7b\x7c\x7d\x7e])/$1/gs; + $content =~ s/([\x21\x25\x26\x28\x29\x2a\x2b\x2c\x2d\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x5b\x5d\x5c\x7b\x7c\x7d\x7e])\s/$1/gs; + + # restore string literals + $content =~ s/__CMPRSTR_([0-9]+)__/$strings[$1]/egs; + + # Write to ouput file + open(FILE, ">$outFile"); + flock(FILE, 2); + seek(FILE, 0, 2); + print FILE $comment, $content; + close(FILE); +} diff --git a/public/tiny_mce/langs/ar.js b/public/tiny_mce/langs/ar.js new file mode 100644 index 0000000..be4cf7a --- /dev/null +++ b/public/tiny_mce/langs/ar.js @@ -0,0 +1,39 @@ +// arabic lang variables +// Toolbar Items and Context Menu +tinyMCELang['lang_dir'] = 'rtl'; +tinyMCELang['lang_bold_desc'] = 'غامق'; +tinyMCELang['lang_italic_desc'] = 'مائل'; +tinyMCELang['lang_underline_desc'] = 'تسطير'; +tinyMCELang['lang_striketrough_desc'] = 'يتوسطه خط'; +tinyMCELang['lang_justifyleft_desc'] = 'محاذاة إلى اليسار'; +tinyMCELang['lang_justifycenter_desc'] = 'توسيط'; +tinyMCELang['lang_justifyright_desc'] = 'محاذاة إلى اليمين'; +tinyMCELang['lang_justifyfull_desc'] = 'ضبط'; +tinyMCELang['lang_bullist_desc'] = 'تعداد نقطي'; +tinyMCELang['lang_numlist_desc'] = 'تعداد رقمي'; +tinyMCELang['lang_outdent_desc'] = 'إنقاص المسافة البادئة'; +tinyMCELang['lang_indent_desc'] = 'زيادة المسافة البادئة'; +tinyMCELang['lang_undo_desc'] = 'تراجع'; +tinyMCELang['lang_redo_desc'] = 'إعادة'; +tinyMCELang['lang_link_desc'] = 'إدراج/تحرير رابط'; +tinyMCELang['lang_unlink_desc'] = 'إزالة رابط'; +tinyMCELang['lang_image_desc'] = 'إدراج/تحرير صورة'; +tinyMCELang['lang_cleanup_desc'] = 'Cleanup messy code'; +tinyMCELang['lang_focus_alert'] = 'A editor instance must be focused before using this command.'; +tinyMCELang['lang_edit_confirm'] = 'Do you want to use the WYSIWYG mode for this textarea?'; +tinyMCELang['lang_insert_link_title'] = 'إدراج/تحرير رابط'; +tinyMCELang['lang_insert'] = 'إدراج'; +tinyMCELang['lang_update'] = 'إدراج'; +tinyMCELang['lang_cancel'] = 'ألغي'; +tinyMCELang['lang_insert_link_url'] = 'رابط URL'; +tinyMCELang['lang_insert_link_target'] = 'الهدف'; +tinyMCELang['lang_insert_link_target_same'] = 'نفس الإطار'; +tinyMCELang['lang_insert_link_target_blank'] = 'إطار جديد (_blank)'; +tinyMCELang['lang_insert_image_title'] = 'إدراج/تحرير صورة'; +tinyMCELang['lang_insert_image_src'] = 'صورة URL'; +tinyMCELang['lang_insert_image_alt'] = 'الوصف'; +tinyMCELang['lang_help_desc'] = 'المساعدة'; +tinyMCELang['lang_bold_img'] = 'bold.gif'; +tinyMCELang['lang_italic_img'] = 'italic.gif'; +tinyMCELang['lang_underline_img'] = "underline.gif"; +tinyMCELang['lang_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?'; diff --git a/public/tiny_mce/langs/ca.js b/public/tiny_mce/langs/ca.js new file mode 100644 index 0000000..32f8f1b --- /dev/null +++ b/public/tiny_mce/langs/ca.js @@ -0,0 +1,38 @@ +// CA lang variables by Marc Bria + +tinyMCELang['lang_bold_desc'] = 'Negreta'; +tinyMCELang['lang_italic_desc'] = 'Cursiva'; +tinyMCELang['lang_underline_desc'] = 'Subratllat'; +tinyMCELang['lang_striketrough_desc'] = 'Tatxat'; +tinyMCELang['lang_justifyleft_desc'] = 'Alinear a lesquerra'; +tinyMCELang['lang_justifycenter_desc'] = 'Alinear al centre'; +tinyMCELang['lang_justifyright_desc'] = 'Alinear a la dreta'; +tinyMCELang['lang_justifyfull_desc'] = 'Alinear justificat'; +tinyMCELang['lang_bullist_desc'] = 'Llista sense ordenar'; +tinyMCELang['lang_numlist_desc'] = 'Llista ordenada'; +tinyMCELang['lang_outdent_desc'] = 'Disminueix sangria'; +tinyMCELang['lang_indent_desc'] = 'Augmentar sangria'; +tinyMCELang['lang_undo_desc'] = 'Desfer'; +tinyMCELang['lang_redo_desc'] = 'Refer'; +tinyMCELang['lang_link_desc'] = 'Insertar enlla'; +tinyMCELang['lang_unlink_desc'] = 'Treure enlla'; +tinyMCELang['lang_image_desc'] = 'Insertar imatge'; +tinyMCELang['lang_cleanup_desc'] = 'Netejar codi'; +tinyMCELang['lang_focus_alert'] = 'Lrea de leditor ha de ser enfocada abans dexecutar aquesta comanda.'; +tinyMCELang['lang_edit_confirm'] = 'Vols utilitzar el modus WYSIWYG per a aquesta rea de text?'; +tinyMCELang['lang_insert_link_title'] = 'Insertar/editar enlla'; +tinyMCELang['lang_insert'] = 'Insertar'; +tinyMCELang['lang_update'] = 'Insertar'; +tinyMCELang['lang_cancel'] = 'Cancellar'; +tinyMCELang['lang_insert_link_url'] = 'Adrea de lenlla'; +tinyMCELang['lang_insert_link_target'] = 'Dest'; +tinyMCELang['lang_insert_link_target_same'] = 'Obrir enlla a la mateixa finestra'; +tinyMCELang['lang_insert_link_target_blank'] = 'Obrir enlla en una finestra nova'; +tinyMCELang['lang_insert_image_title'] = 'Insertar/editar imatge'; +tinyMCELang['lang_insert_image_src'] = 'URL de limatge'; +tinyMCELang['lang_insert_image_alt'] = 'Descripci de la imatge'; +tinyMCELang['lang_help_desc'] = 'Ajut'; +tinyMCELang['lang_bold_img'] = "bold.gif"; +tinyMCELang['lang_italic_img'] = "italic.gif"; +tinyMCELang['lang_underline_img'] = "underline.gif"; +tinyMCELang['lang_clipboard_msg'] = 'Copiar/Tallar/Enganxar no s possible amb Mozilla i Firefox.\nVols ms informaci sobre aquest problema de seguretat?'; diff --git a/public/tiny_mce/langs/cs.js b/public/tiny_mce/langs/cs.js new file mode 100644 index 0000000..b504680 --- /dev/null +++ b/public/tiny_mce/langs/cs.js @@ -0,0 +1,38 @@ +// CZ lang variables thanks to "Pavel Novk" - repaired by Josef Klimosz + +tinyMCELang['lang_bold_desc'] = 'Tun'; +tinyMCELang['lang_italic_desc'] = 'Kurzva'; +tinyMCELang['lang_underline_desc'] = 'Podtren'; +tinyMCELang['lang_striketrough_desc'] = 'Pekrtnut'; +tinyMCELang['lang_justifyleft_desc'] = 'Zarovnn vlevo'; +tinyMCELang['lang_justifycenter_desc'] = 'Zarovnn na sted'; +tinyMCELang['lang_justifyright_desc'] = 'Zarovnn vpravo'; +tinyMCELang['lang_justifyfull_desc'] = 'Zarovnn do bloku'; +tinyMCELang['lang_bullist_desc'] = 'Seznam s odrkami'; +tinyMCELang['lang_numlist_desc'] = 'slovan seznam'; +tinyMCELang['lang_outdent_desc'] = 'Snit odsazen'; +tinyMCELang['lang_indent_desc'] = 'Zvit odsazen'; +tinyMCELang['lang_undo_desc'] = 'Zpt'; +tinyMCELang['lang_redo_desc'] = 'Znovu'; +tinyMCELang['lang_link_desc'] = 'Vloit odkaz'; +tinyMCELang['lang_unlink_desc'] = 'Zruit odkaz'; +tinyMCELang['lang_image_desc'] = 'Vloit obrzek'; +tinyMCELang['lang_cleanup_desc'] = 'Vyistit kd'; +tinyMCELang['lang_focus_alert'] = 'Ped pouitm tohoto pkazu mus bt kurzor v okn editoru.'; +tinyMCELang['lang_edit_confirm'] = 'Chcete pout WYSIWYG editaci pro tento text?'; +tinyMCELang['lang_insert_link_title'] = 'Vloit/upravit odkaz'; +tinyMCELang['lang_insert'] = 'Vloit'; +tinyMCELang['lang_update'] = 'Zmnit'; +tinyMCELang['lang_cancel'] = 'Zruit'; +tinyMCELang['lang_insert_link_url'] = 'URL odkazu'; +tinyMCELang['lang_insert_link_target'] = 'Cl'; +tinyMCELang['lang_insert_link_target_same'] = 'Otevt odkaz ve stejnm okn'; +tinyMCELang['lang_insert_link_target_blank'] = 'Otevt odkaz v novm okn'; +tinyMCELang['lang_insert_image_title'] = 'Vloit/upravit obrzek'; +tinyMCELang['lang_insert_image_src'] = 'URL obrzku'; +tinyMCELang['lang_insert_image_alt'] = 'Popis obrzku'; +tinyMCELang['lang_help_desc'] = 'Npovda'; +tinyMCELang['lang_bold_img'] = 'bold.gif'; +tinyMCELang['lang_italic_img'] = 'italic.gif'; +tinyMCELang['lang_underline_img'] = "underline.gif"; +tinyMCELang['lang_clipboard_msg'] = 'Copy/Cut/Paste nen pouiteln v Mozille a Firefoxu.\nChcete vce informac o tomto problmu?'; \ No newline at end of file diff --git a/public/tiny_mce/langs/da.js b/public/tiny_mce/langs/da.js new file mode 100644 index 0000000..4dfa696 --- /dev/null +++ b/public/tiny_mce/langs/da.js @@ -0,0 +1,38 @@ +// DK lang variables contributed by Jan Moelgaard + +tinyMCELang['lang_bold_desc'] = 'Fed'; +tinyMCELang['lang_italic_desc'] = 'Kursiv'; +tinyMCELang['lang_underline_desc'] = 'Understreg'; +tinyMCELang['lang_striketrough_desc'] = 'Gennemstreg'; +tinyMCELang['lang_justifyleft_desc'] = 'Venstrestil'; +tinyMCELang['lang_justifycenter_desc'] = 'Centrer'; +tinyMCELang['lang_justifyright_desc'] = 'Højrestil'; +tinyMCELang['lang_justifyfull_desc'] = 'Lige margin'; +tinyMCELang['lang_bullist_desc'] = 'Bulletliste'; +tinyMCELang['lang_numlist_desc'] = 'Nummerliste'; +tinyMCELang['lang_outdent_desc'] = 'Ryk til venstre'; +tinyMCELang['lang_indent_desc'] = 'Ryk til højre'; +tinyMCELang['lang_undo_desc'] = 'Fortryd'; +tinyMCELang['lang_redo_desc'] = 'Gør igen'; +tinyMCELang['lang_link_desc'] = 'Indsæt link'; +tinyMCELang['lang_unlink_desc'] = 'Fjern link'; +tinyMCELang['lang_image_desc'] = 'Indsæt billede'; +tinyMCELang['lang_cleanup_desc'] = 'Ryd op i koden'; +tinyMCELang['lang_focus_alert'] = 'Der skal sættes fokus på sessionen, før man kan bruge denne kommando'; +tinyMCELang['lang_edit_confirm'] = 'Vil du bruge WYSIWYG mode til dette textområde?'; +tinyMCELang['lang_insert_link_title'] = 'Indsæt eller rediger link'; +tinyMCELang['lang_insert'] = 'Indsæt'; +tinyMCELang['lang_update'] = 'Opdater'; +tinyMCELang['lang_cancel'] = 'Fortryd'; +tinyMCELang['lang_insert_link_url'] = 'Linkadresse'; +tinyMCELang['lang_insert_link_target'] = 'Target'; +tinyMCELang['lang_insert_link_target_same'] = 'Luk linket op i samme vindue'; +tinyMCELang['lang_insert_link_target_blank'] = 'Luk linket op i et nyt vindue'; +tinyMCELang['lang_insert_image_title'] = 'Indsæt / rediger billede'; +tinyMCELang['lang_insert_image_src'] = 'Billedets adresse'; +tinyMCELang['lang_insert_image_alt'] = 'Alternativ tekst'; +tinyMCELang['lang_help_desc'] = 'Hjælp'; +tinyMCELang['lang_bold_img'] = "bold.gif"; +tinyMCELang['lang_italic_img'] = "italic.gif"; +tinyMCELang['lang_underline_img'] = "underline.gif"; +tinyMCELang['lang_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?'; diff --git a/public/tiny_mce/langs/de.js b/public/tiny_mce/langs/de.js new file mode 100644 index 0000000..c75a307 --- /dev/null +++ b/public/tiny_mce/langs/de.js @@ -0,0 +1,38 @@ +// DE lang variables + +tinyMCELang['lang_bold_desc'] = 'Fett'; +tinyMCELang['lang_italic_desc'] = 'Kursiv'; +tinyMCELang['lang_underline_desc'] = 'Unterstrichen'; +tinyMCELang['lang_striketrough_desc'] = 'Durchgestrichen'; +tinyMCELang['lang_justifyleft_desc'] = 'Linksbündig'; +tinyMCELang['lang_justifycenter_desc'] = 'Zentriert'; +tinyMCELang['lang_justifyright_desc'] = 'Rechtsbündig'; +tinyMCELang['lang_justifyfull_desc'] = 'Blocksatz'; +tinyMCELang['lang_bullist_desc'] = 'Aufzählungszeichen'; +tinyMCELang['lang_numlist_desc'] = 'Nummerierung'; +tinyMCELang['lang_outdent_desc'] = 'Einzug verkleinern'; +tinyMCELang['lang_indent_desc'] = 'Einzug vergrössern'; +tinyMCELang['lang_undo_desc'] = 'Rückgängig'; +tinyMCELang['lang_redo_desc'] = 'Wiederholen'; +tinyMCELang['lang_link_desc'] = 'Link einfügen/bearbeiten'; +tinyMCELang['lang_unlink_desc'] = 'Link entfernen'; +tinyMCELang['lang_image_desc'] = 'Bild einfügen/bearbeiten'; +tinyMCELang['lang_cleanup_desc'] = 'unsauberen Code aufräumen'; +tinyMCELang['lang_focus_alert'] = 'Eine Bearbeitungsinstanz muss für diesen Befehl hervorgehoben.'; +tinyMCELang['lang_edit_confirm'] = 'Wollen Sie den WYSIWYG Modus für dieses Textfeld benutzen?'; +tinyMCELang['lang_insert_link_title'] = 'Link einfügen/bearbeiten'; +tinyMCELang['lang_insert'] = 'Einfügen'; +tinyMCELang['lang_update'] = 'Aktualisieren'; +tinyMCELang['lang_cancel'] = 'Abbrechen'; +tinyMCELang['lang_insert_link_url'] = 'Link URL'; +tinyMCELang['lang_insert_link_target'] = 'Ziel'; +tinyMCELang['lang_insert_link_target_same'] = 'Link in gleichen Fester öffnen'; +tinyMCELang['lang_insert_link_target_blank'] = 'Link in neuen Fenster öffnen'; +tinyMCELang['lang_insert_image_title'] = 'Bild einfügen/bearbeiten'; +tinyMCELang['lang_insert_image_src'] = 'Bild URL'; +tinyMCELang['lang_insert_image_alt'] = 'Bild Beschreibung'; +tinyMCELang['lang_help_desc'] = 'Hilfe'; +tinyMCELang['lang_bold_img'] = "bold_de_se.gif"; +tinyMCELang['lang_italic_img'] = "italic_de_se.gif"; +tinyMCELang['lang_underline_img'] = "underline.gif"; +tinyMCELang['lang_clipboard_msg'] = 'Kopieren/Ausschneiten/Einfügen ist mit Mozilla und Firefox nicht verfügbar.\nWollen Sie mehr Informationen darüber erhalten?'; diff --git a/public/tiny_mce/langs/el.js b/public/tiny_mce/langs/el.js new file mode 100644 index 0000000..41ae3a0 --- /dev/null +++ b/public/tiny_mce/langs/el.js @@ -0,0 +1,38 @@ +// Greek lang variables by Jacaranda Bill + +tinyMCELang['lang_bold_desc'] = ' '; +tinyMCELang['lang_italic_desc'] = ' '; +tinyMCELang['lang_underline_desc'] = ''; +tinyMCELang['lang_striketrough_desc'] = ' '; +tinyMCELang['lang_justifyleft_desc'] = ' '; +tinyMCELang['lang_justifycenter_desc'] = ' '; +tinyMCELang['lang_justifyright_desc'] = ' '; +tinyMCELang['lang_justifyfull_desc'] = ' '; +tinyMCELang['lang_bullist_desc'] = ''; +tinyMCELang['lang_numlist_desc'] = ''; +tinyMCELang['lang_outdent_desc'] = ' '; +tinyMCELang['lang_indent_desc'] = ' '; +tinyMCELang['lang_undo_desc'] = ''; +tinyMCELang['lang_redo_desc'] = ' '; +tinyMCELang['lang_link_desc'] = '/ -'; +tinyMCELang['lang_unlink_desc'] = ' -'; +tinyMCELang['lang_image_desc'] = '/ '; +tinyMCELang['lang_cleanup_desc'] = ' '; +tinyMCELang['lang_focus_alert'] = ' .'; +tinyMCELang['lang_edit_confirm'] = ' WYSIWYG ;'; +tinyMCELang['lang_insert_link_title'] = '/ -'; +tinyMCELang['lang_insert'] = ''; +tinyMCELang['lang_update'] = ''; +tinyMCELang['lang_cancel'] = ''; +tinyMCELang['lang_insert_link_url'] = ''; +tinyMCELang['lang_insert_link_target'] = ''; +tinyMCELang['lang_insert_link_target_same'] = ' '; +tinyMCELang['lang_insert_link_target_blank'] = ' '; +tinyMCELang['lang_insert_image_title'] = '/ '; +tinyMCELang['lang_insert_image_src'] = ''; +tinyMCELang['lang_insert_image_alt'] = ''; +tinyMCELang['lang_help_desc'] = ''; +tinyMCELang['lang_bold_img'] = "bold.gif"; +tinyMCELang['lang_italic_img'] = "italic.gif"; +tinyMCELang['lang_underline_img'] = "underline.gif"; +tinyMCELang['lang_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?'; diff --git a/public/tiny_mce/langs/en.js b/public/tiny_mce/langs/en.js new file mode 100644 index 0000000..a27a3db --- /dev/null +++ b/public/tiny_mce/langs/en.js @@ -0,0 +1,44 @@ +// UK lang variables + +tinyMCELang['lang_bold_desc'] = 'Bold'; +tinyMCELang['lang_italic_desc'] = 'Italic'; +tinyMCELang['lang_underline_desc'] = 'Underline'; +tinyMCELang['lang_striketrough_desc'] = 'Striketrough'; +tinyMCELang['lang_justifyleft_desc'] = 'Align left'; +tinyMCELang['lang_justifycenter_desc'] = 'Align center'; +tinyMCELang['lang_justifyright_desc'] = 'Align right'; +tinyMCELang['lang_justifyfull_desc'] = 'Align full'; +tinyMCELang['lang_bullist_desc'] = 'Unordered list'; +tinyMCELang['lang_numlist_desc'] = 'Ordered list'; +tinyMCELang['lang_outdent_desc'] = 'Outdent'; +tinyMCELang['lang_indent_desc'] = 'Indent'; +tinyMCELang['lang_undo_desc'] = 'Undo'; +tinyMCELang['lang_redo_desc'] = 'Redo'; +tinyMCELang['lang_link_desc'] = 'Insert/edit link'; +tinyMCELang['lang_attachment_desc'] = 'Insert/edit Attachment link'; +tinyMCELang['lang_unlink_desc'] = 'Unlink'; +tinyMCELang['lang_image_desc'] = 'Insert/edit image'; +tinyMCELang['lang_cleanup_desc'] = 'Cleanup messy code'; +tinyMCELang['lang_focus_alert'] = 'A editor instance must be focused before using this command.'; +tinyMCELang['lang_edit_confirm'] = 'Do you want to use the WYSIWYG mode for this textarea?'; +tinyMCELang['lang_insert_link_title'] = 'Insert/edit link'; +tinyMCELang['lang_insert_attachment_title'] = 'Insert/edit attachment link'; +tinyMCELang['lang_insert'] = 'Insert'; +tinyMCELang['lang_update'] = 'Update'; +tinyMCELang['lang_cancel'] = 'Cancel'; +tinyMCELang['lang_insert_link_url'] = 'Link URL'; +tinyMCELang['lang_insert_link_target'] = 'Target'; +tinyMCELang['lang_insert_link_target_same'] = 'Open link in the same window'; +tinyMCELang['lang_insert_link_target_blank'] = 'Open link in a new window'; +tinyMCELang['lang_insert_attachment_url'] = 'Attachment Link URL'; +tinyMCELang['lang_insert_attachment_target'] = 'Target'; +tinyMCELang['lang_insert_attachment_target_same'] = 'Open attachment link in the same window'; +tinyMCELang['lang_insert_attachment_target_blank'] = 'Open attachment linl in a new window'; +tinyMCELang['lang_insert_image_title'] = 'Insert/edit image'; +tinyMCELang['lang_insert_image_src'] = 'Image URL'; +tinyMCELang['lang_insert_image_alt'] = 'Image description'; +tinyMCELang['lang_help_desc'] = 'Help'; +tinyMCELang['lang_bold_img'] = "bold.gif"; +tinyMCELang['lang_italic_img'] = "italic.gif"; +tinyMCELang['lang_underline_img'] = "underline.gif"; +tinyMCELang['lang_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?'; diff --git a/public/tiny_mce/langs/es.js b/public/tiny_mce/langs/es.js new file mode 100644 index 0000000..3fd59c1 --- /dev/null +++ b/public/tiny_mce/langs/es.js @@ -0,0 +1,38 @@ +// ES lang variables by Alvaro Velasco + +tinyMCELang['lang_bold_desc'] = 'Negrita'; +tinyMCELang['lang_italic_desc'] = 'Cursiva'; +tinyMCELang['lang_underline_desc'] = 'Subrayado'; +tinyMCELang['lang_striketrough_desc'] = 'Tachado'; +tinyMCELang['lang_justifyleft_desc'] = 'Alinear a la izquierda'; +tinyMCELang['lang_justifycenter_desc'] = 'Alinear al centro'; +tinyMCELang['lang_justifyright_desc'] = 'Alinear a la derecha'; +tinyMCELang['lang_justifyfull_desc'] = 'Alinear justificado'; +tinyMCELang['lang_bullist_desc'] = 'Lista sin ordenar'; +tinyMCELang['lang_numlist_desc'] = 'Lista ordenada'; +tinyMCELang['lang_outdent_desc'] = 'Disminuye sangria'; +tinyMCELang['lang_indent_desc'] = 'Aumentar sangria'; +tinyMCELang['lang_undo_desc'] = 'Deshacer'; +tinyMCELang['lang_redo_desc'] = 'Rehacer'; +tinyMCELang['lang_link_desc'] = 'Insertar enlace'; +tinyMCELang['lang_unlink_desc'] = 'Quitar enlace'; +tinyMCELang['lang_image_desc'] = 'Insertar imagen'; +tinyMCELang['lang_cleanup_desc'] = 'Limpiar codigo'; +tinyMCELang['lang_focus_alert'] = 'Una instanacia del editor debe ser enfocada antes de usar este comando.'; +tinyMCELang['lang_edit_confirm'] = 'Quieres usar el modo WYSIWYG para esta area de texto?'; +tinyMCELang['lang_insert_link_title'] = 'Insertar/editar enlace'; +tinyMCELang['lang_insert'] = 'Insertar'; +tinyMCELang['lang_update'] = 'Insertar'; +tinyMCELang['lang_cancel'] = 'Cancelar'; +tinyMCELang['lang_insert_link_url'] = 'Direccion del enlace'; +tinyMCELang['lang_insert_link_target'] = 'Destino'; +tinyMCELang['lang_insert_link_target_same'] = 'Abrir enlace en la misma ventana'; +tinyMCELang['lang_insert_link_target_blank'] = 'Abrir enlace en una ventana nueva'; +tinyMCELang['lang_insert_image_title'] = 'Insertar/editar imagen'; +tinyMCELang['lang_insert_image_src'] = 'URL de la imagen'; +tinyMCELang['lang_insert_image_alt'] = 'Descripcion de la imagen'; +tinyMCELang['lang_help_desc'] = 'Ayuda'; +tinyMCELang['lang_bold_img'] = "bold.gif"; +tinyMCELang['lang_italic_img'] = "italic.gif"; +tinyMCELang['lang_underline_img'] = "underline.gif"; +tinyMCELang['lang_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?'; diff --git a/public/tiny_mce/langs/fa.js b/public/tiny_mce/langs/fa.js new file mode 100644 index 0000000..c6db94a --- /dev/null +++ b/public/tiny_mce/langs/fa.js @@ -0,0 +1,43 @@ +// IR lang variables +// Persian (Farsi) language pack (for IRAN) +// By: Morteza Zafari +// Lost@LostLord.com +// http://www.LostLord.com + +tinyMCELang['lang_dir'] = 'rtl'; +tinyMCELang['lang_bold_desc'] = 'ضخيم'; +tinyMCELang['lang_italic_desc'] = 'کجکي'; +tinyMCELang['lang_underline_desc'] = 'زير خط دار'; +tinyMCELang['lang_striketrough_desc'] = 'خط خورده'; +tinyMCELang['lang_justifyleft_desc'] = 'چپ چين'; +tinyMCELang['lang_justifycenter_desc'] = 'وسط چين'; +tinyMCELang['lang_justifyright_desc'] = 'راست چين'; +tinyMCELang['lang_justifyfull_desc'] = 'کشيده چين'; +tinyMCELang['lang_bullist_desc'] = 'ليست'; +tinyMCELang['lang_numlist_desc'] = 'ليست عددي'; +tinyMCELang['lang_outdent_desc'] = 'کاهش زبانه'; +tinyMCELang['lang_indent_desc'] = 'افزايش زبانه'; +tinyMCELang['lang_undo_desc'] = 'برگردونک'; +tinyMCELang['lang_redo_desc'] = 'سرگردونک'; +tinyMCELang['lang_link_desc'] = 'درج و ويرايش لينک'; +tinyMCELang['lang_unlink_desc'] = 'حذف لينک'; +tinyMCELang['lang_image_desc'] = 'درج و ويرايش عکس'; +tinyMCELang['lang_cleanup_desc'] = 'پاکسازي کد'; +tinyMCELang['lang_focus_alert'] = 'A editor instance must be focused before using this command.'; +tinyMCELang['lang_edit_confirm'] = 'Do you want to use the WYSIWYG mode for this textarea?'; +tinyMCELang['lang_insert_link_title'] = 'درج و ويرايش لينک'; +tinyMCELang['lang_insert'] = ' تاييد '; +tinyMCELang['lang_update'] = ' تاييد '; +tinyMCELang['lang_cancel'] = ' انصراف '; +tinyMCELang['lang_insert_link_url'] = 'URL لينک'; +tinyMCELang['lang_insert_link_target'] = 'مقصد'; +tinyMCELang['lang_insert_link_target_same'] = 'لينک را در همان صفحه باز کن'; +tinyMCELang['lang_insert_link_target_blank'] = 'لينک را در صفحه جديد باز کن'; +tinyMCELang['lang_insert_image_title'] = 'درج و ويرايش عکس'; +tinyMCELang['lang_insert_image_src'] = 'URL عکس'; +tinyMCELang['lang_insert_image_alt'] = 'توضيح'; +tinyMCELang['lang_help_desc'] = 'راهنما'; +tinyMCELang['lang_bold_img'] = "bold.gif"; +tinyMCELang['lang_italic_img'] = "italic.gif"; +tinyMCELang['lang_underline_img'] = "underline.gif"; +tinyMCELang['lang_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?'; diff --git a/public/tiny_mce/langs/fi.js b/public/tiny_mce/langs/fi.js new file mode 100644 index 0000000..a3d0685 --- /dev/null +++ b/public/tiny_mce/langs/fi.js @@ -0,0 +1,38 @@ +// FI lang variables by Urho Konttori from Absolutions + +tinyMCELang['lang_bold_desc'] = 'Lihavoi'; +tinyMCELang['lang_italic_desc'] = 'Kursivoi'; +tinyMCELang['lang_underline_desc'] = 'Alleviivaa'; +tinyMCELang['lang_striketrough_desc'] = 'Yliviivaa'; +tinyMCELang['lang_justifyleft_desc'] = 'Vasen tasaus'; +tinyMCELang['lang_justifycenter_desc'] = 'Keskitys'; +tinyMCELang['lang_justifyright_desc'] = 'Oikea tasaus'; +tinyMCELang['lang_justifyfull_desc'] = 'Pakotettu tasaus'; +tinyMCELang['lang_bullist_desc'] = 'Numeroimaton lista'; +tinyMCELang['lang_numlist_desc'] = 'Numeroitu lista'; +tinyMCELang['lang_outdent_desc'] = 'Poista sisennyt'; +tinyMCELang['lang_indent_desc'] = 'Sisennys'; +tinyMCELang['lang_undo_desc'] = 'Peruuta'; +tinyMCELang['lang_redo_desc'] = 'Suorita uudelleen'; +tinyMCELang['lang_link_desc'] = 'Lis linkki'; +tinyMCELang['lang_unlink_desc'] = 'Poista linkki'; +tinyMCELang['lang_image_desc'] = 'Lis kuva'; +tinyMCELang['lang_cleanup_desc'] = 'Siisti koodi'; +tinyMCELang['lang_focus_alert'] = 'Teksinksittelyalueella tytyy olla fokus ennen tmn komennon suorittamista.'; +tinyMCELang['lang_edit_confirm'] = 'Haluatko kytt WYSIWYG moodia thn tekstialueeseen?'; +tinyMCELang['lang_insert_link_title'] = 'Lis/muokkaa linkki'; +tinyMCELang['lang_insert'] = 'Lis'; +tinyMCELang['lang_update'] = 'Lis'; +tinyMCELang['lang_cancel'] = 'Peruuta'; +tinyMCELang['lang_insert_link_url'] = 'Linkin URL'; +tinyMCELang['lang_insert_link_target'] = 'Kohde'; +tinyMCELang['lang_insert_link_target_same'] = 'Avaa linkki samassa ikkunassa'; +tinyMCELang['lang_insert_link_target_blank'] = 'Avaa linkki uudessa ikkunassa'; +tinyMCELang['lang_insert_image_title'] = 'Lis/muokkaa kuvaa'; +tinyMCELang['lang_insert_image_src'] = 'Kuvan URL'; +tinyMCELang['lang_insert_image_alt'] = 'Kuvan selite'; +tinyMCELang['lang_help_desc'] = 'Apua'; +tinyMCELang['lang_bold_img'] = "bold.gif"; +tinyMCELang['lang_italic_img'] = "italic.gif"; +tinyMCELang['lang_underline_img'] = "underline.gif"; +tinyMCELang['lang_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?'; diff --git a/public/tiny_mce/langs/fr.js b/public/tiny_mce/langs/fr.js new file mode 100644 index 0000000..b9f3af0 --- /dev/null +++ b/public/tiny_mce/langs/fr.js @@ -0,0 +1,38 @@ +// FR lang variables by Pat Boens +// Modify by Laurent Dran +tinyMCELang['lang_bold_desc'] = 'Gras'; +tinyMCELang['lang_italic_desc'] = 'Italique'; +tinyMCELang['lang_underline_desc'] = 'Souligné'; +tinyMCELang['lang_striketrough_desc'] = 'Barr'; +tinyMCELang['lang_justifyleft_desc'] = 'Aligner à gauche'; +tinyMCELang['lang_justifycenter_desc'] = 'Aligner au centre'; +tinyMCELang['lang_justifyright_desc'] = 'Aligner à droite'; +tinyMCELang['lang_justifyfull_desc'] = 'Justifier'; +tinyMCELang['lang_bullist_desc'] = 'Liste dsordonnée (puces)'; +tinyMCELang['lang_numlist_desc'] = 'Liste ordonnée (numéros)'; +tinyMCELang['lang_outdent_desc'] = 'Diminuer le retrait'; +tinyMCELang['lang_indent_desc'] = 'Augmenter le retrait'; +tinyMCELang['lang_undo_desc'] = 'Défaire'; +tinyMCELang['lang_redo_desc'] = 'Refaire'; +tinyMCELang['lang_link_desc'] = 'Insérer/diter le lien'; +tinyMCELang['lang_unlink_desc'] = 'Enlever le lien'; +tinyMCELang['lang_image_desc'] = 'Insérer/diter une image'; +tinyMCELang['lang_cleanup_desc'] = 'Nettoyer le code'; +tinyMCELang['lang_focus_alert'] = 'Une instance de l\éditeur doit avoir le focus avant d\'utiliser cette commande.'; +tinyMCELang['lang_edit_confirm'] = 'Voulez-vous utiliser le mode WYSIWYG pour cette zone de texte (textarea) ?'; +tinyMCELang['lang_insert_link_title'] = 'Insertion/édition lien'; +tinyMCELang['lang_insert'] = 'Insertion'; +tinyMCELang['lang_update'] = 'Insertion'; +tinyMCELang['lang_cancel'] = 'Annuler'; +tinyMCELang['lang_insert_link_url'] = 'Lien URL'; +tinyMCELang['lang_insert_link_target'] = 'Cible'; +tinyMCELang['lang_insert_link_target_same'] = 'Ouvrir le lien dans la mme fenêtre'; +tinyMCELang['lang_insert_link_target_blank'] = 'Ouvrir le lien dans une nouvelle fenêtre'; +tinyMCELang['lang_insert_image_title'] = 'Insertion/édition d\'une image'; +tinyMCELang['lang_insert_image_src'] = 'URL de l\'image'; +tinyMCELang['lang_insert_image_alt'] = 'Description de l\'image'; +tinyMCELang['lang_help_desc'] = 'Aide'; +tinyMCELang['lang_bold_img'] = "bold.gif"; +tinyMCELang['lang_italic_img'] = "italic.gif"; +tinyMCELang['lang_underline_img'] = "underline.gif"; +tinyMCELang['lang_clipboard_msg'] = 'Copier/Couper/Coller ne sont pas disponibles pour Mozilla et Firefox.\nVoulez vous plus d\'informatios ce sujet?'; diff --git a/public/tiny_mce/langs/fr_ca.js b/public/tiny_mce/langs/fr_ca.js new file mode 100644 index 0000000..fe862a5 --- /dev/null +++ b/public/tiny_mce/langs/fr_ca.js @@ -0,0 +1,38 @@ +// Canadian French lang variables by Virtuelcom + +tinyMCELang['lang_bold_desc'] = 'Gras'; +tinyMCELang['lang_italic_desc'] = 'Italique'; +tinyMCELang['lang_underline_desc'] = 'Souligner'; +tinyMCELang['lang_striketrough_desc'] = 'Barrer'; +tinyMCELang['lang_justifyleft_desc'] = 'Aligner gauche'; +tinyMCELang['lang_justifycenter_desc'] = 'Aligner au centre'; +tinyMCELang['lang_justifyright_desc'] = 'Aligner droite'; +tinyMCELang['lang_justifyfull_desc'] = 'Justifier'; +tinyMCELang['lang_bullist_desc'] = 'Puces'; +tinyMCELang['lang_numlist_desc'] = 'Numrotation'; +tinyMCELang['lang_outdent_desc'] = 'Rduire le retrait'; +tinyMCELang['lang_indent_desc'] = 'Augmenter le retrait'; +tinyMCELang['lang_undo_desc'] = 'Annuler la dernire action'; +tinyMCELang['lang_redo_desc'] = 'Refaire la dernire action annule'; +tinyMCELang['lang_link_desc'] = 'Insrer un hyperlien'; +tinyMCELang['lang_unlink_desc'] = 'Supprimer un hyperlien'; +tinyMCELang['lang_image_desc'] = 'Insrer une image'; +tinyMCELang['lang_cleanup_desc'] = 'Nettoyer le code'; +tinyMCELang['lang_focus_alert'] = 'Un diteur doit tre slectionn pour utiliser cette fonction.'; +tinyMCELang['lang_edit_confirm'] = 'Dsirez-vous utiliser l\'diteur pour modifier cette zone?'; +tinyMCELang['lang_insert_link_title'] = 'Insrer / Modifier un hyperlien'; +tinyMCELang['lang_insert'] = 'Insrer'; +tinyMCELang['lang_update'] = 'Insrer'; +tinyMCELang['lang_cancel'] = 'Annuler'; +tinyMCELang['lang_insert_link_url'] = 'Adresse URL'; +tinyMCELang['lang_insert_link_target'] = 'Destination'; +tinyMCELang['lang_insert_link_target_same'] = 'Ouvrir dans la mme fentre'; +tinyMCELang['lang_insert_link_target_blank'] = 'Ouvrir dans une nouvelle fentre'; +tinyMCELang['lang_insert_image_title'] = 'Insrer / Modifier une image'; +tinyMCELang['lang_insert_image_src'] = 'Adresse de l\'image'; +tinyMCELang['lang_insert_image_alt'] = 'Description de l\'image'; +tinyMCELang['lang_help_desc'] = 'Aide'; +tinyMCELang['lang_bold_img'] = "bold_fr.gif"; +tinyMCELang['lang_italic_img'] = "italic.gif"; +tinyMCELang['lang_underline_img'] = "underline_fr.gif"; +tinyMCELang['lang_clipboard_msg'] = 'Copier/Couper/Coller ne sont pas disponibles dans Mozilla et FireFox.\nDsirez-vous consulter de plus amples informations ce sujet?'; diff --git a/public/tiny_mce/langs/hu.js b/public/tiny_mce/langs/hu.js new file mode 100644 index 0000000..be057b9 --- /dev/null +++ b/public/tiny_mce/langs/hu.js @@ -0,0 +1,39 @@ +// HU lang variables +// Edited by 2XP (2xp@dino.hu) + +tinyMCELang['lang_bold_desc'] = 'Félkövér'; +tinyMCELang['lang_italic_desc'] = 'Dõlt'; +tinyMCELang['lang_underline_desc'] = 'Aláhúzott'; +tinyMCELang['lang_striketrough_desc'] = 'Áthúzott'; +tinyMCELang['lang_justifyleft_desc'] = 'Balra igazítás'; +tinyMCELang['lang_justifycenter_desc'] = 'Középre igazítás'; +tinyMCELang['lang_justifyright_desc'] = 'Jobbra igazítás'; +tinyMCELang['lang_justifyfull_desc'] = 'Sorkizárt'; +tinyMCELang['lang_bullist_desc'] = 'Felsorolás'; +tinyMCELang['lang_numlist_desc'] = 'Számozott lista'; +tinyMCELang['lang_outdent_desc'] = 'Behúzás balra'; +tinyMCELang['lang_indent_desc'] = 'Behúzás jobbra'; +tinyMCELang['lang_undo_desc'] = 'Visszavonás'; +tinyMCELang['lang_redo_desc'] = 'Ismétlés'; +tinyMCELang['lang_link_desc'] = 'Link felvétele'; +tinyMCELang['lang_unlink_desc'] = 'Link törlése'; +tinyMCELang['lang_image_desc'] = 'Kép beillesztése'; +tinyMCELang['lang_cleanup_desc'] = 'Kód tisztítása'; +tinyMCELang['lang_focus_alert'] = 'Miel\u00F5tt haszn\u00E1lja ezt a funkci\u00F3t, ki kell jel\u00F6lnie a szerkeszteni k\u00EDv\u00E1nt ter\u00FCletet.'; +tinyMCELang['lang_edit_confirm'] = 'K\u00EDv\u00E1nja a WYSIWYG m\u00F3dot erre a sz\u00F6vegter\u00FCletre alkalmazni??'; +tinyMCELang['lang_insert_link_title'] = 'Link beillesztése/szerkesztése'; +tinyMCELang['lang_insert'] = 'Beillesztés'; +tinyMCELang['lang_update'] = 'Beillesztés'; +tinyMCELang['lang_cancel'] = 'Mégsem'; +tinyMCELang['lang_insert_link_url'] = 'Link URL'; +tinyMCELang['lang_insert_link_target'] = 'Cél'; +tinyMCELang['lang_insert_link_target_same'] = 'Link megnyitása azonos ablakban'; +tinyMCELang['lang_insert_link_target_blank'] = 'Link megnyitása új ablakban'; +tinyMCELang['lang_insert_image_title'] = 'Kép beillesztése/szerkesztése'; +tinyMCELang['lang_insert_image_src'] = 'Kép URL'; +tinyMCELang['lang_insert_image_alt'] = 'Képleírás'; +tinyMCELang['lang_help_desc'] = 'Segítég'; +tinyMCELang['lang_bold_img'] = 'bold.gif'; +tinyMCELang['lang_italic_img'] = 'italic.gif'; +tinyMCELang['lang_underline_img'] = "underline.gif"; +tinyMCELang['lang_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?'; diff --git a/public/tiny_mce/langs/it.js b/public/tiny_mce/langs/it.js new file mode 100644 index 0000000..62a2f0c --- /dev/null +++ b/public/tiny_mce/langs/it.js @@ -0,0 +1,38 @@ +// Variabili lingua IT - fabrix.xm@lombardiacom.it + +tinyMCELang['lang_bold_desc'] = 'Grassetto'; +tinyMCELang['lang_italic_desc'] = 'Corsivo'; +tinyMCELang['lang_underline_desc'] = 'Sottolineato'; +tinyMCELang['lang_striketrough_desc'] = 'Barrato'; +tinyMCELang['lang_justifyleft_desc'] = 'Allinea a sinistra'; +tinyMCELang['lang_justifycenter_desc'] = 'Allinea centrato'; +tinyMCELang['lang_justifyright_desc'] = 'Allinea a destra'; +tinyMCELang['lang_justifyfull_desc'] = 'Giustifica'; +tinyMCELang['lang_bullist_desc'] = 'Lista non ordinata'; +tinyMCELang['lang_numlist_desc'] = 'Lista ordinata'; +tinyMCELang['lang_outdent_desc'] = 'Rientra'; +tinyMCELang['lang_indent_desc'] = 'Indenta'; +tinyMCELang['lang_undo_desc'] = 'Annulla'; +tinyMCELang['lang_redo_desc'] = 'Ripeti'; +tinyMCELang['lang_link_desc'] = 'Inserisci link'; +tinyMCELang['lang_unlink_desc'] = 'Elimina link'; +tinyMCELang['lang_image_desc'] = 'Inserisci immagine'; +tinyMCELang['lang_cleanup_desc'] = 'Pulisci il codice'; +tinyMCELang['lang_focus_alert'] = 'Una istanza dell\' editor deve essere selezionata prima di usare questo comando.'; +tinyMCELang['lang_edit_confirm'] = 'Vuoi usare la modalit\u00E0 WYSIWYG per questa textarea?'; +tinyMCELang['lang_insert_link_title'] = 'Inserisci/modifica link'; +tinyMCELang['lang_insert'] = 'Inserisci'; +tinyMCELang['lang_update'] = 'Inserisci'; +tinyMCELang['lang_cancel'] = 'Cancella'; +tinyMCELang['lang_insert_link_url'] = 'Link URL'; +tinyMCELang['lang_insert_link_target'] = 'Target'; +tinyMCELang['lang_insert_link_target_same'] = 'Apri il link nella stessa finestra'; +tinyMCELang['lang_insert_link_target_blank'] = 'Apri il link in una nuova finestra'; +tinyMCELang['lang_insert_image_title'] = 'Inserisci/modifica immagine'; +tinyMCELang['lang_insert_image_src'] = 'URL immagine'; +tinyMCELang['lang_insert_image_alt'] = 'Descrizione dell\'immagine'; +tinyMCELang['lang_help_desc'] = 'Guida'; +tinyMCELang['lang_bold_img'] = "bold.gif"; +tinyMCELang['lang_italic_img'] = "italic.gif"; +tinyMCELang['lang_underline_img'] = "underline.gif"; +tinyMCELang['lang_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?'; diff --git a/public/tiny_mce/langs/ja.js b/public/tiny_mce/langs/ja.js new file mode 100644 index 0000000..3795c5b --- /dev/null +++ b/public/tiny_mce/langs/ja.js @@ -0,0 +1,38 @@ +// JP lang variables + +tinyMCELang['lang_bold_desc'] = '$BB@;z(B'; +tinyMCELang['lang_italic_desc'] = '$B'; + } + + return ""; +} + +/** + * Gets executed when a command is called. + */ +function TinyMCE_template_execCommand(editor_id, element, command, user_interface, value) { + // Handle commands + switch (command) { + // Remember to have the "mce" prefix for commands so they don't intersect with built in ones in the browser. + case "mceTemplate": + // Show UI/Popup + if (user_interface) { + // Open a popup window and send in some custom data in a window argument + var template = new Array(); + + template['file'] = '../../plugins/template/popup.htm'; // Relative to theme + template['width'] = 150; + template['height'] = 180; + + tinyMCE.openWindow(template, {editor_id : editor_id, some_custom_arg : "somecustomdata"}); + + // Let TinyMCE know that something was modified + tinyMCE.triggerNodeChange(false); + } else { + // Do a command this gets called from the template popup + alert("execCommand: mceTemplate gets called from popup."); + } + + return true; + } + + // Pass to next handler in chain + return false; +} + +/** + * Gets executed when the selection/cursor position was changed. + */ +function TinyMCE_template_handleNodeChange(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) { + // Deselect template button + tinyMCE.switchClassSticky(editor_id + '_template', 'mceButtonNormal'); + + // Select template button if parent node is a strong or b + if (node.parentNode.nodeName == "STRONG" || node.parentNode.nodeName == "B") + tinyMCE.switchClassSticky(editor_id + '_template', 'mceButtonSelected'); + + return true; +} + +/** + * Gets executed when contents is inserted / retrived. + */ +function TinyMCE_template_cleanup(type, content) { + switch (type) { + case "get_from_editor": + alert("[FROM] Value HTML string: " + content); + + // Do custom cleanup code here + + break; + + case "insert_to_editor": + alert("[TO] Value HTML string: " + content); + + // Do custom cleanup code here + + break; + + case "get_from_editor_dom": + alert("[FROM] Value DOM Element " + content.innerHTML); + + // Do custom cleanup code here + + break; + + case "insert_to_editor_dom": + alert("[TO] Value DOM Element: " + content.innerHTML); + + // Do custom cleanup code here + + break; + } + + return content; +} diff --git a/public/tiny_mce/plugins/_template/images/template.gif b/public/tiny_mce/plugins/_template/images/template.gif new file mode 100644 index 0000000..321a134 Binary files /dev/null and b/public/tiny_mce/plugins/_template/images/template.gif differ diff --git a/public/tiny_mce/plugins/_template/langs/en.js b/public/tiny_mce/plugins/_template/langs/en.js new file mode 100644 index 0000000..2d3358d --- /dev/null +++ b/public/tiny_mce/plugins/_template/langs/en.js @@ -0,0 +1,6 @@ +// UK lang variables + +/* Remember to namespace the language parameters lang__ */ + +tinyMCELang['lang_template_title'] = 'This is just a template popup'; +tinyMCELang['lang_template_desc'] = 'This is just a template button'; diff --git a/public/tiny_mce/plugins/_template/langs/zh_cn.js b/public/tiny_mce/plugins/_template/langs/zh_cn.js new file mode 100644 index 0000000..10c9439 --- /dev/null +++ b/public/tiny_mce/plugins/_template/langs/zh_cn.js @@ -0,0 +1,7 @@ +// Simplified Chinese lang variables contributed by cube316 (cube316@gmail.com) +// http://www.cube316.net/ ԻȡTinyMCE֧ + +/* Remember to namespace the language parameters lang__ */ + +tinyMCELang['lang_template_title'] = 'ģĵ'; +tinyMCELang['lang_template_desc'] = 'ģİť'; \ No newline at end of file diff --git a/public/tiny_mce/plugins/_template/popup.htm b/public/tiny_mce/plugins/_template/popup.htm new file mode 100644 index 0000000..4acf0d8 --- /dev/null +++ b/public/tiny_mce/plugins/_template/popup.htm @@ -0,0 +1,31 @@ + + +{$lang_template_title} + + + + +

    {$lang_template_title}

    + +
    + + +
    + +
    + + diff --git a/public/tiny_mce/plugins/_template/readme.txt b/public/tiny_mce/plugins/_template/readme.txt new file mode 100644 index 0000000..2ee1505 --- /dev/null +++ b/public/tiny_mce/plugins/_template/readme.txt @@ -0,0 +1 @@ +This is a template/tutorial plugin that where created to help you in the development of own plugins for TinyMCE. \ No newline at end of file diff --git a/public/tiny_mce/plugins/advhr/editor_plugin.js b/public/tiny_mce/plugins/advhr/editor_plugin.js new file mode 100644 index 0000000..ef74430 --- /dev/null +++ b/public/tiny_mce/plugins/advhr/editor_plugin.js @@ -0,0 +1,2 @@ +/* Import plugin specific language pack */ + tinyMCE.importPluginLanguagePack('advhr','en,de,sv,zh_cn,cs,fa,fr_ca,fr,pl,pt_br');function TinyMCE_advhr_getControlHTML(control_name){switch(control_name){case "advhr":return '';}return "";}function TinyMCE_advhr_execCommand(editor_id,element,command,user_interface,value){switch(command){case "mceAdvancedHr":var template=new Array();template['file']='../../plugins/advhr/rule.htm';template['width']=270;template['height']=180;var size="",width="",noshade="";if(tinyMCE.selectedElement!=null&&tinyMCE.selectedElement.nodeName.toLowerCase()=="hr"){tinyMCE.hrElement=tinyMCE.selectedElement;if(tinyMCE.hrElement){size=tinyMCE.hrElement.getAttribute('size')?tinyMCE.hrElement.getAttribute('size'):"";width=tinyMCE.hrElement.getAttribute('width')?tinyMCE.hrElement.getAttribute('width'):"";noshade=tinyMCE.hrElement.getAttribute('noshade')?tinyMCE.hrElement.getAttribute('noshade'):"";}tinyMCE.openWindow(template,{editor_id:editor_id,size:size,width:width,noshade:noshade,mceDo:'update'});}else{if(tinyMCE.isMSIE){tinyMCE.execInstanceCommand(editor_id,'mceInsertContent',false,'
    ');}else{tinyMCE.openWindow(template,{editor_id:editor_id,size:size,width:width,noshade:noshade,mceDo:'insert'});}}return true;}return false;}function TinyMCE_advhr_handleNodeChange(editor_id,node,undo_index,undo_levels,visual_aid,any_selection){tinyMCE.switchClassSticky(editor_id+'_advhr','mceButtonNormal');if(node==null)return;do{if(node.nodeName.toLowerCase()=="hr")tinyMCE.switchClassSticky(editor_id+'_advhr','mceButtonSelected');}while((node=node.parentNode));return true;} \ No newline at end of file diff --git a/public/tiny_mce/plugins/advhr/editor_plugin_src.js b/public/tiny_mce/plugins/advhr/editor_plugin_src.js new file mode 100644 index 0000000..44e021c --- /dev/null +++ b/public/tiny_mce/plugins/advhr/editor_plugin_src.js @@ -0,0 +1,58 @@ +/* Import plugin specific language pack */ +tinyMCE.importPluginLanguagePack('advhr', 'en,de,sv,zh_cn,cs,fa,fr_ca,fr,pl,pt_br'); + +function TinyMCE_advhr_getControlHTML(control_name) { + switch (control_name) { + case "advhr": + return ''; + } + return ""; +} + +/** + * Executes the mceAdvanceHr command. + */ +function TinyMCE_advhr_execCommand(editor_id, element, command, user_interface, value) { + // Handle commands + switch (command) { + case "mceAdvancedHr": + var template = new Array(); + template['file'] = '../../plugins/advhr/rule.htm'; // Relative to theme + template['width'] = 270; + template['height'] = 180; + var size = "", width = "", noshade = ""; + if (tinyMCE.selectedElement != null && tinyMCE.selectedElement.nodeName.toLowerCase() == "hr"){ + tinyMCE.hrElement = tinyMCE.selectedElement; + if (tinyMCE.hrElement) { + size = tinyMCE.hrElement.getAttribute('size') ? tinyMCE.hrElement.getAttribute('size') : ""; + width = tinyMCE.hrElement.getAttribute('width') ? tinyMCE.hrElement.getAttribute('width') : ""; + noshade = tinyMCE.hrElement.getAttribute('noshade') ? tinyMCE.hrElement.getAttribute('noshade') : ""; + } + tinyMCE.openWindow(template, {editor_id : editor_id, size : size, width : width, noshade : noshade, mceDo : 'update'}); + } else { + if (tinyMCE.isMSIE) { + tinyMCE.execInstanceCommand(editor_id, 'mceInsertContent', false,'
    '); + } else { + tinyMCE.openWindow(template, {editor_id : editor_id, size : size, width : width, noshade : noshade, mceDo : 'insert'}); + } + } + + return true; + } + // Pass to next handler in chain + return false; +} + +function TinyMCE_advhr_handleNodeChange(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) { + tinyMCE.switchClassSticky(editor_id + '_advhr', 'mceButtonNormal'); + + if (node == null) + return; + + do { + if (node.nodeName.toLowerCase() == "hr") + tinyMCE.switchClassSticky(editor_id + '_advhr', 'mceButtonSelected'); + } while ((node = node.parentNode)); + + return true; +} \ No newline at end of file diff --git a/public/tiny_mce/plugins/advhr/images/advhr.gif b/public/tiny_mce/plugins/advhr/images/advhr.gif new file mode 100644 index 0000000..e18bfc2 Binary files /dev/null and b/public/tiny_mce/plugins/advhr/images/advhr.gif differ diff --git a/public/tiny_mce/plugins/advhr/langs/cs.js b/public/tiny_mce/plugins/advhr/langs/cs.js new file mode 100644 index 0000000..7e000e9 --- /dev/null +++ b/public/tiny_mce/plugins/advhr/langs/cs.js @@ -0,0 +1,6 @@ +// UK lang variables + +tinyMCELang['lang_insert_advhr_desc'] = 'Vloit/editovat vodorovn oddlova' +tinyMCELang['lang_insert_advhr_width'] = 'ka'; +tinyMCELang['lang_insert_advhr_size'] = 'Vka'; +tinyMCELang['lang_insert_advhr_noshade'] = 'Nestnovat'; \ No newline at end of file diff --git a/public/tiny_mce/plugins/advhr/langs/de.js b/public/tiny_mce/plugins/advhr/langs/de.js new file mode 100644 index 0000000..beefec8 --- /dev/null +++ b/public/tiny_mce/plugins/advhr/langs/de.js @@ -0,0 +1,6 @@ +// DE lang variables + +tinyMCELang['lang_insert_advhr_desc'] = 'Horizontale Linie einfügen / bearbeiten' +tinyMCELang['lang_insert_advhr_width'] = 'Breite'; +tinyMCELang['lang_insert_advhr_size'] = 'Höhe'; +tinyMCELang['lang_insert_advhr_noshade'] = 'Keinen Schatten'; diff --git a/public/tiny_mce/plugins/advhr/langs/en.js b/public/tiny_mce/plugins/advhr/langs/en.js new file mode 100644 index 0000000..8daf26e --- /dev/null +++ b/public/tiny_mce/plugins/advhr/langs/en.js @@ -0,0 +1,6 @@ +// UK lang variables + +tinyMCELang['lang_insert_advhr_desc'] = 'Insert / edit Horizontale Rule' +tinyMCELang['lang_insert_advhr_width'] = 'Width'; +tinyMCELang['lang_insert_advhr_size'] = 'Height'; +tinyMCELang['lang_insert_advhr_noshade'] = 'No shadow'; diff --git a/public/tiny_mce/plugins/advhr/langs/fa.js b/public/tiny_mce/plugins/advhr/langs/fa.js new file mode 100644 index 0000000..934c8ba --- /dev/null +++ b/public/tiny_mce/plugins/advhr/langs/fa.js @@ -0,0 +1,11 @@ +// IR lang variables +// Persian (Farsi) language pack (for IRAN) +// By: Morteza Zafari +// Lost@LostLord.com +// http://www.LostLord.com + +tinyMCELang['lang_dir'] = 'rtl'; +tinyMCELang['lang_insert_advhr_desc'] = 'درج و ویرایش خط افقی' +tinyMCELang['lang_insert_advhr_width'] = 'عرض'; +tinyMCELang['lang_insert_advhr_size'] = 'ارتفاع'; +tinyMCELang['lang_insert_advhr_noshade'] = 'بدون سایه'; diff --git a/public/tiny_mce/plugins/advhr/langs/fr.js b/public/tiny_mce/plugins/advhr/langs/fr.js new file mode 100644 index 0000000..ae30fe3 --- /dev/null +++ b/public/tiny_mce/plugins/advhr/langs/fr.js @@ -0,0 +1,6 @@ +// French lang variables by Laurent Dran + +tinyMCELang['lang_insert_advhr_desc'] = 'Insérer / éditer une Rčgle Horizontale' +tinyMCELang['lang_insert_advhr_width'] = 'Largeur'; +tinyMCELang['lang_insert_advhr_size'] = 'Hauteur'; +tinyMCELang['lang_insert_advhr_noshade'] = 'Sans ombre'; diff --git a/public/tiny_mce/plugins/advhr/langs/fr_ca.js b/public/tiny_mce/plugins/advhr/langs/fr_ca.js new file mode 100644 index 0000000..77e74ad --- /dev/null +++ b/public/tiny_mce/plugins/advhr/langs/fr_ca.js @@ -0,0 +1,6 @@ +// CA_FR lang variables + +tinyMCELang['lang_insert_advhr_desc'] = 'Insrer / Modifier Sparateur Horizontal'; +tinyMCELang['lang_insert_advhr_width'] = 'Largeur'; +tinyMCELang['lang_insert_advhr_size'] = 'Hauteur'; +tinyMCELang['lang_insert_advhr_noshade'] = 'Sans ombrage'; diff --git a/public/tiny_mce/plugins/advhr/langs/pl.js b/public/tiny_mce/plugins/advhr/langs/pl.js new file mode 100644 index 0000000..da2d829 --- /dev/null +++ b/public/tiny_mce/plugins/advhr/langs/pl.js @@ -0,0 +1,6 @@ +// PL lang variables + +tinyMCELang['lang_insert_advhr_desc'] = 'Wstaw/Edytuj poziomą linię' +tinyMCELang['lang_insert_advhr_width'] = 'Szerokość'; +tinyMCELang['lang_insert_advhr_size'] = 'Wysokość'; +tinyMCELang['lang_insert_advhr_noshade'] = 'Brak cienia'; \ No newline at end of file diff --git a/public/tiny_mce/plugins/advhr/langs/pt_br.js b/public/tiny_mce/plugins/advhr/langs/pt_br.js new file mode 100644 index 0000000..e38f3b7 --- /dev/null +++ b/public/tiny_mce/plugins/advhr/langs/pt_br.js @@ -0,0 +1,6 @@ +// pt_BR lang variables + +tinyMCELang['lang_insert_advhr_desc'] = 'Inserir / editar Linha Horizontal' +tinyMCELang['lang_insert_advhr_width'] = 'Largura'; +tinyMCELang['lang_insert_advhr_size'] = 'Altura'; +tinyMCELang['lang_insert_advhr_noshade'] = 'Sem Sombra'; diff --git a/public/tiny_mce/plugins/advhr/langs/sv.js b/public/tiny_mce/plugins/advhr/langs/sv.js new file mode 100644 index 0000000..7066716 --- /dev/null +++ b/public/tiny_mce/plugins/advhr/langs/sv.js @@ -0,0 +1,6 @@ +// SE lang variables + +tinyMCELang['lang_insert_advhr_desc'] = 'Skapa/Redigera horisontell linje' +tinyMCELang['lang_insert_advhr_width'] = 'Bredd'; +tinyMCELang['lang_insert_advhr_size'] = 'Hjd'; +tinyMCELang['lang_insert_advhr_noshade'] = 'Ingen skugga'; diff --git a/public/tiny_mce/plugins/advhr/langs/zh_cn.js b/public/tiny_mce/plugins/advhr/langs/zh_cn.js new file mode 100644 index 0000000..656ea52 --- /dev/null +++ b/public/tiny_mce/plugins/advhr/langs/zh_cn.js @@ -0,0 +1,7 @@ +// Simplified Chinese lang variables contributed by cube316 (cube316@gmail.com) +// http://www.cube316.net/ ԻȡTinyMCE֧ + +tinyMCELang['lang_insert_advhr_desc'] = '/༭ ˮƽ' +tinyMCELang['lang_insert_advhr_width'] = ''; +tinyMCELang['lang_insert_advhr_size'] = '߶'; +tinyMCELang['lang_insert_advhr_noshade'] = 'Ӱ'; diff --git a/public/tiny_mce/plugins/advhr/readme.txt b/public/tiny_mce/plugins/advhr/readme.txt new file mode 100644 index 0000000..f39e3b4 --- /dev/null +++ b/public/tiny_mce/plugins/advhr/readme.txt @@ -0,0 +1,20 @@ + Advhr plugin for TinyMCE +----------------------------- + +About: + This is a more advanced hr dialog contributed by Michael Keck. + This one supports noshade, width and size. + +Installation instructions: + * Copy the advhr directory to the plugins directory of TinyMCE (/jscripts/tiny_mce/plugins). + * Add plugin to TinyMCE plugin option list example: plugins : "advhr". + * Add this "hr[class|width|size|noshade]" to extended_valid_elements option. + +Initialization example: + tinyMCE.init({ + theme : "advanced", + mode : "textareas", + plugins : "advhr", + theme_advanced_buttons1_add : "advhr", + extended_valid_elements : "hr[class|width|size|noshade]" + }); diff --git a/public/tiny_mce/plugins/advhr/rule.htm b/public/tiny_mce/plugins/advhr/rule.htm new file mode 100644 index 0000000..b47d75f --- /dev/null +++ b/public/tiny_mce/plugins/advhr/rule.htm @@ -0,0 +1,107 @@ + + +{$lang_insert_link_title} + + + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + +
    {$lang_insert_advhr_desc}
    {$lang_insert_advhr_width}: + + +
    {$lang_insert_advhr_size}:
    +
    + + diff --git a/public/tiny_mce/plugins/advimage/editor_plugin.js b/public/tiny_mce/plugins/advimage/editor_plugin.js new file mode 100644 index 0000000..652a3b8 --- /dev/null +++ b/public/tiny_mce/plugins/advimage/editor_plugin.js @@ -0,0 +1,2 @@ +/* Import plugin specific language pack */ + tinyMCE.importPluginLanguagePack('advimage','en,de,sv,zh_cn,cs,fa,fr_ca,fr,pl,pt_br');function TinyMCE_advimage_getInsertImageTemplate(){var template=new Array();template['file']='../../plugins/advimage/image.htm';template['width']=430;template['height']=380;template['width']+=tinyMCE.getLang('lang_insert_image_delta_width',0);template['height']+=tinyMCE.getLang('lang_insert_image_delta_height',0);return template;}function TinyMCE_advimage_cleanup(type,content){switch(type){case "insert_to_editor_dom":var imgs=content.getElementsByTagName("img");for(var i=0;i + +{$lang_insert_image_title} + + + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$lang_insert_image_title}
    {$lang_insert_image_src}: + + + + +
    {$lang_insert_image_alt}:
    {$lang_insert_image_alt2}:
    {$lang_insert_image_dimensions}: + x + px +
    {$lang_insert_image_border}:
    {$lang_insert_image_align}: +
    {$lang_insert_image_vspace}:
    {$lang_insert_image_hspace}:
    {$lang_insert_image_mouseover}: + + + + +
    {$lang_insert_image_mouseout}: + + + + +
     
    +
    + + diff --git a/public/tiny_mce/plugins/advimage/langs/cs.js b/public/tiny_mce/plugins/advimage/langs/cs.js new file mode 100644 index 0000000..dde44c6 --- /dev/null +++ b/public/tiny_mce/plugins/advimage/langs/cs.js @@ -0,0 +1,6 @@ +// UK lang variables + +tinyMCELang['lang_insert_image_alt2'] = 'Nzev obrzku'; +tinyMCELang['lang_insert_image_onmousemove'] = 'Alternativn obrzek' +tinyMCELang['lang_insert_image_mouseover'] = 'pi najet myi'; +tinyMCELang['lang_insert_image_mouseout'] = 'pi odjet myi'; \ No newline at end of file diff --git a/public/tiny_mce/plugins/advimage/langs/de.js b/public/tiny_mce/plugins/advimage/langs/de.js new file mode 100644 index 0000000..c5a6d22 --- /dev/null +++ b/public/tiny_mce/plugins/advimage/langs/de.js @@ -0,0 +1,6 @@ +// DE lang variables + +tinyMCELang['lang_insert_image_alt2'] = 'Titel des Bildes'; +tinyMCELang['lang_insert_image_onmousemove'] = 'Alternatives Bild' +tinyMCELang['lang_insert_image_mouseover'] = 'für Maus darüber'; +tinyMCELang['lang_insert_image_mouseout'] = 'für Maus ausserhalb'; diff --git a/public/tiny_mce/plugins/advimage/langs/en.js b/public/tiny_mce/plugins/advimage/langs/en.js new file mode 100644 index 0000000..c4098af --- /dev/null +++ b/public/tiny_mce/plugins/advimage/langs/en.js @@ -0,0 +1,6 @@ +// UK lang variables + +tinyMCELang['lang_insert_image_alt2'] = 'Image title'; +tinyMCELang['lang_insert_image_onmousemove'] = 'Alternative image' +tinyMCELang['lang_insert_image_mouseover'] = 'for mouse over'; +tinyMCELang['lang_insert_image_mouseout'] = 'for mouse out'; diff --git a/public/tiny_mce/plugins/advimage/langs/fa.js b/public/tiny_mce/plugins/advimage/langs/fa.js new file mode 100644 index 0000000..685a49f --- /dev/null +++ b/public/tiny_mce/plugins/advimage/langs/fa.js @@ -0,0 +1,11 @@ +// IR lang variables +// Persian (Farsi) language pack (for IRAN) +// By: Morteza Zafari +// Lost@LostLord.com +// http://www.LostLord.com + +tinyMCELang['lang_dir'] = 'rtl'; +tinyMCELang['lang_insert_image_alt2'] = 'عنوان عکس'; +tinyMCELang['lang_insert_image_onmousemove'] = 'عکس جایگزین' +tinyMCELang['lang_insert_image_mouseover'] = 'عکس جایگزین هنگام ورود نشانگر ماوس'; +tinyMCELang['lang_insert_image_mouseout'] = 'عکس جایگزین هنگام خروج نشانگر ماوس'; diff --git a/public/tiny_mce/plugins/advimage/langs/fr.js b/public/tiny_mce/plugins/advimage/langs/fr.js new file mode 100644 index 0000000..588ab3c --- /dev/null +++ b/public/tiny_mce/plugins/advimage/langs/fr.js @@ -0,0 +1,6 @@ +// French lang variables by Laurent Dran + +tinyMCELang['lang_insert_image_alt2'] = 'Titre de l\'image'; +tinyMCELang['lang_insert_image_onmousemove'] = 'Image alternative' +tinyMCELang['lang_insert_image_mouseover'] = 'Pour la souris au dessus'; +tinyMCELang['lang_insert_image_mouseout'] = 'Pour la souris en dehors'; diff --git a/public/tiny_mce/plugins/advimage/langs/fr_ca.js b/public/tiny_mce/plugins/advimage/langs/fr_ca.js new file mode 100644 index 0000000..32e8af7 --- /dev/null +++ b/public/tiny_mce/plugins/advimage/langs/fr_ca.js @@ -0,0 +1,6 @@ +// CA_FR lang variables + +tinyMCELang['lang_insert_image_alt2'] = 'Titre de l\'image'; +tinyMCELang['lang_insert_image_onmousemove'] = 'Image alternative'; +tinyMCELang['lang_insert_image_mouseover'] = 'pour le mouse over'; +tinyMCELang['lang_insert_image_mouseout'] = 'pour le mouse out'; diff --git a/public/tiny_mce/plugins/advimage/langs/ko.js b/public/tiny_mce/plugins/advimage/langs/ko.js new file mode 100644 index 0000000..68fe45a --- /dev/null +++ b/public/tiny_mce/plugins/advimage/langs/ko.js @@ -0,0 +1,6 @@ +// KO lang variables + +tinyMCELang['lang_insert_image_alt2'] = '׸ '; +tinyMCELang['lang_insert_image_onmousemove'] = 'ü ̹' +tinyMCELang['lang_insert_image_mouseover'] = '콺 ÷ '; +tinyMCELang['lang_insert_image_mouseout'] = '콺 '; diff --git a/public/tiny_mce/plugins/advimage/langs/pl.js b/public/tiny_mce/plugins/advimage/langs/pl.js new file mode 100644 index 0000000..fffba25 --- /dev/null +++ b/public/tiny_mce/plugins/advimage/langs/pl.js @@ -0,0 +1,6 @@ +// PL lang variables + +tinyMCELang['lang_insert_image_alt2'] = 'Tytuł obrazka'; +tinyMCELang['lang_insert_image_onmousemove'] = 'Obrazek zastępczy' +tinyMCELang['lang_insert_image_mouseover'] = 'po najechaniu myszy'; +tinyMCELang['lang_insert_image_mouseout'] = 'po odjechaniu myszy'; \ No newline at end of file diff --git a/public/tiny_mce/plugins/advimage/langs/pt_br.js b/public/tiny_mce/plugins/advimage/langs/pt_br.js new file mode 100644 index 0000000..91f2278 --- /dev/null +++ b/public/tiny_mce/plugins/advimage/langs/pt_br.js @@ -0,0 +1,6 @@ +// pt_BR lang variables + +tinyMCELang['lang_insert_image_alt2'] = 'Ttulo da Imagem'; +tinyMCELang['lang_insert_image_onmousemove'] = 'Imagem Alternativa' +tinyMCELang['lang_insert_image_mouseover'] = 'para quando mouse sobre'; +tinyMCELang['lang_insert_image_mouseout'] = 'para quando mouse fora'; diff --git a/public/tiny_mce/plugins/advimage/langs/sv.js b/public/tiny_mce/plugins/advimage/langs/sv.js new file mode 100644 index 0000000..f901dbd --- /dev/null +++ b/public/tiny_mce/plugins/advimage/langs/sv.js @@ -0,0 +1,6 @@ +// SE lang variables + +tinyMCELang['lang_insert_image_alt2'] = 'Bildentitel'; +tinyMCELang['lang_insert_image_onmousemove'] = 'Alternativ bild' +tinyMCELang['lang_insert_image_mouseover'] = 'när pekaren är över'; +tinyMCELang['lang_insert_image_mouseout'] = 'när pekaren är utanför'; diff --git a/public/tiny_mce/plugins/advimage/langs/zh_cn.js b/public/tiny_mce/plugins/advimage/langs/zh_cn.js new file mode 100644 index 0000000..e418581 --- /dev/null +++ b/public/tiny_mce/plugins/advimage/langs/zh_cn.js @@ -0,0 +1,7 @@ +// Simplified Chinese lang variables contributed by cube316 (cube316@gmail.com) +// http://www.cube316.net/ ԻȡTinyMCE֧ + +tinyMCELang['lang_insert_image_alt2'] = 'ͼƬ'; +tinyMCELang['lang_insert_image_onmousemove'] = 'ͼ' +tinyMCELang['lang_insert_image_mouseover'] = 'ʱ'; +tinyMCELang['lang_insert_image_mouseout'] = 'ƿʱ'; diff --git a/public/tiny_mce/plugins/advimage/readme.txt b/public/tiny_mce/plugins/advimage/readme.txt new file mode 100644 index 0000000..b88835b --- /dev/null +++ b/public/tiny_mce/plugins/advimage/readme.txt @@ -0,0 +1,19 @@ + Advimage plugin for TinyMCE +----------------------------- + +About: + This is a more advanced image dialog mostly based on code contributed by Michael Keck. + This one supports mouseover/out image swapping. + +Installation instructions: + * Copy the advimage directory to the plugins directory of TinyMCE (/jscripts/tiny_mce/plugins). + * Add plugin to TinyMCE plugin option list example: plugins : "advimage". + * Add this "a[name|href|target|title|onclick]" to extended_valid_elements option. + +Initialization example: + tinyMCE.init({ + theme : "advanced", + mode : "textareas", + plugins : "preview", + extended_valid_elements : "a[name|href|target|title|onclick]" + }); diff --git a/public/tiny_mce/plugins/advlink/editor_plugin.js b/public/tiny_mce/plugins/advlink/editor_plugin.js new file mode 100644 index 0000000..826d7bb --- /dev/null +++ b/public/tiny_mce/plugins/advlink/editor_plugin.js @@ -0,0 +1,2 @@ +/* Import plugin specific language pack */ + tinyMCE.importPluginLanguagePack('advlink','en,de,sv,zh_cn,cs,fa,fr_ca,fr,pl,pt_br');function TinyMCE_advlink_getInsertLinkTemplate(){var template=new Array();template['file']='../../plugins/advlink/link.htm';template['width']=400;template['height']=420;template['width']+=tinyMCE.getLang('lang_insert_link_delta_width',0);template['height']+=tinyMCE.getLang('lang_insert_link_delta_height',0);return template;} \ No newline at end of file diff --git a/public/tiny_mce/plugins/advlink/editor_plugin_src.js b/public/tiny_mce/plugins/advlink/editor_plugin_src.js new file mode 100644 index 0000000..6d9daea --- /dev/null +++ b/public/tiny_mce/plugins/advlink/editor_plugin_src.js @@ -0,0 +1,18 @@ +/* Import plugin specific language pack */ +tinyMCE.importPluginLanguagePack('advlink', 'en,de,sv,zh_cn,cs,fa,fr_ca,fr,pl,pt_br'); + +/** + * Insert link template function. + */ +function TinyMCE_advlink_getInsertLinkTemplate() { + var template = new Array(); + template['file'] = '../../plugins/advlink/link.htm'; + template['width'] = 400; + template['height'] = 420; + + // Language specific width and height addons + template['width'] += tinyMCE.getLang('lang_insert_link_delta_width', 0); + template['height'] += tinyMCE.getLang('lang_insert_link_delta_height', 0); + + return template; +} \ No newline at end of file diff --git a/public/tiny_mce/plugins/advlink/langs/cs.js b/public/tiny_mce/plugins/advlink/langs/cs.js new file mode 100644 index 0000000..fb758ca --- /dev/null +++ b/public/tiny_mce/plugins/advlink/langs/cs.js @@ -0,0 +1,20 @@ +// CZ lang variables + +tinyMCELang['lang_insert_link_target_same'] = 'Otevt ve stejnm okn/rmu'; +tinyMCELang['lang_insert_link_target_parent'] = 'Otevt v rodiovskm okn/rmu'; +tinyMCELang['lang_insert_link_target_top'] = 'Otevt v nejvym rmu (pepe vechny rmy)'; +tinyMCELang['lang_insert_link_target_blank'] = 'Otevt v novm okn'; +tinyMCELang['lang_insert_link_target_named'] = 'Otevt v okn'; +tinyMCELang['lang_insert_link_popup'] = 'JS-Popup'; +tinyMCELang['lang_insert_link_popup_url'] = 'Popup URL'; +tinyMCELang['lang_insert_link_popup_name'] = 'Nzev okna'; +tinyMCELang['lang_insert_link_popup_return'] = 'insert \'return false\''; +tinyMCELang['lang_insert_link_popup_scrollbars'] = 'Ukzat posuvnky'; +tinyMCELang['lang_insert_link_popup_statusbar'] = 'Ukzat stavov dek'; +tinyMCELang['lang_insert_link_popup_toolbar'] = 'Ukzat ovl. litu'; +tinyMCELang['lang_insert_link_popup_menubar'] = 'Ukzat menu'; +tinyMCELang['lang_insert_link_popup_location'] = 'Ukzat litu umstn'; +tinyMCELang['lang_insert_link_popup_resizable'] = 'Promnn velikost okna'; +tinyMCELang['lang_insert_link_popup_size'] = 'Velikost'; +tinyMCELang['lang_insert_link_popup_position'] = 'Umstn (X/Y)'; +tinyMCELang['lang_insert_link_popup_missingtarget'] = 'Vlote nzev cle nebo vyberte jinou volbu.'; \ No newline at end of file diff --git a/public/tiny_mce/plugins/advlink/langs/de.js b/public/tiny_mce/plugins/advlink/langs/de.js new file mode 100644 index 0000000..14af22a --- /dev/null +++ b/public/tiny_mce/plugins/advlink/langs/de.js @@ -0,0 +1,20 @@ +// DE lang variables + +tinyMCELang['lang_insert_link_target_same'] = 'Im selben Frame öffnen'; +tinyMCELang['lang_insert_link_target_parent'] = 'Im darüber liegenden Frame öffnen'; +tinyMCELang['lang_insert_link_target_top']= 'Im obersten Frame öffnen'; +tinyMCELang['lang_insert_link_target_blank']= 'In einem neuen Fenster öffnen'; +tinyMCELang['lang_insert_link_target_named']= 'Öffnen im Fenster/Frame'; +tinyMCELang['lang_insert_link_popup'] = 'JS-Popup'; +tinyMCELang['lang_insert_link_popup_url'] = 'Popup URL'; +tinyMCELang['lang_insert_link_popup_name']= 'Fenstername'; +tinyMCELang['lang_insert_link_popup_return']= 'mit \'return false\''; +tinyMCELang['lang_insert_link_popup_scrollbars']= 'Scrollbars anzeigen'; +tinyMCELang['lang_insert_link_popup_statusbar'] = 'Statusbar anzeigen'; +tinyMCELang['lang_insert_link_popup_toolbar'] = 'Toolbars anzeigen'; +tinyMCELang['lang_insert_link_popup_menubar'] = 'Menu anzeigen'; +tinyMCELang['lang_insert_link_popup_location']= 'Adresszeile anzeigen'; +tinyMCELang['lang_insert_link_popup_resizable'] = 'Größe änderbar'; +tinyMCELang['lang_insert_link_popup_size']= 'Größe'; +tinyMCELang['lang_insert_link_popup_position']= 'Position (X/Y)'; +tinyMCELang['lang_insert_link_popup_missingtarget'] = 'Bitte geben Sie einen Namen für das Ziel an oder wählen Sie eine andere Option.'; diff --git a/public/tiny_mce/plugins/advlink/langs/en.js b/public/tiny_mce/plugins/advlink/langs/en.js new file mode 100644 index 0000000..9384f39 --- /dev/null +++ b/public/tiny_mce/plugins/advlink/langs/en.js @@ -0,0 +1,20 @@ +// UK lang variables + +tinyMCELang['lang_insert_link_target_same'] = 'Open in this window / frame'; +tinyMCELang['lang_insert_link_target_parent'] = 'Open in parent window / frame'; +tinyMCELang['lang_insert_link_target_top'] = 'Open in top frame (replaces all frames)'; +tinyMCELang['lang_insert_link_target_blank'] = 'Open in new window'; +tinyMCELang['lang_insert_link_target_named'] = 'Open in the window'; +tinyMCELang['lang_insert_link_popup'] = 'JS-Popup'; +tinyMCELang['lang_insert_link_popup_url'] = 'Popup URL'; +tinyMCELang['lang_insert_link_popup_name'] = 'Window name'; +tinyMCELang['lang_insert_link_popup_return'] = 'insert \'return false\''; +tinyMCELang['lang_insert_link_popup_scrollbars'] = 'Show scrollbars'; +tinyMCELang['lang_insert_link_popup_statusbar'] = 'Show statusbar'; +tinyMCELang['lang_insert_link_popup_toolbar'] = 'Show toolbars'; +tinyMCELang['lang_insert_link_popup_menubar'] = 'Show menubar'; +tinyMCELang['lang_insert_link_popup_location'] = 'Show locationbar'; +tinyMCELang['lang_insert_link_popup_resizable'] = 'Make window resizable'; +tinyMCELang['lang_insert_link_popup_size'] = 'Size'; +tinyMCELang['lang_insert_link_popup_position'] = 'Position (X/Y)'; +tinyMCELang['lang_insert_link_popup_missingtarget'] = 'Please insert a name for the target or choose another option.'; diff --git a/public/tiny_mce/plugins/advlink/langs/fa.js b/public/tiny_mce/plugins/advlink/langs/fa.js new file mode 100644 index 0000000..f126461 --- /dev/null +++ b/public/tiny_mce/plugins/advlink/langs/fa.js @@ -0,0 +1,25 @@ +// IR lang variables +// Persian (Farsi) language pack (for IRAN) +// By: Morteza Zafari +// Lost@LostLord.com +// http://www.LostLord.com + +tinyMCELang['lang_dir'] = 'rtl'; +tinyMCELang['lang_insert_link_target_same'] = 'در همین صفحه / فریم باز کن'; +tinyMCELang['lang_insert_link_target_parent'] = 'در صفحه / فریم اصلی باز کن'; +tinyMCELang['lang_insert_link_target_top'] = 'در فریم اصلی باز کن (همه فریمها نادیده گرفته میشود)'; +tinyMCELang['lang_insert_link_target_blank'] = 'در صفحه جدید باز کن'; +tinyMCELang['lang_insert_link_target_named'] = 'در پنجره باز کن'; +tinyMCELang['lang_insert_link_popup'] = 'JS-Popup'; +tinyMCELang['lang_insert_link_popup_url'] = 'URL پنجره'; +tinyMCELang['lang_insert_link_popup_name'] = 'نام پنجره'; +tinyMCELang['lang_insert_link_popup_return'] = 'افزودن \'return false\''; +tinyMCELang['lang_insert_link_popup_scrollbars'] = 'نمایش scrollbars'; +tinyMCELang['lang_insert_link_popup_statusbar'] = 'نمایش statusbar'; +tinyMCELang['lang_insert_link_popup_toolbar'] = 'نمایش toolbars'; +tinyMCELang['lang_insert_link_popup_menubar'] = 'نمایش menubar'; +tinyMCELang['lang_insert_link_popup_location'] = 'نمایش locationbar'; +tinyMCELang['lang_insert_link_popup_resizable'] = 'قابل تغییر اندازه باشد'; +tinyMCELang['lang_insert_link_popup_size'] = 'اندازه'; +tinyMCELang['lang_insert_link_popup_position'] = 'موقعیت (X/Y)'; +tinyMCELang['lang_insert_link_popup_missingtarget'] = 'لطفا یک نام برای مقصد انتخاب کنید در غیر این صورت گزینه دیگری را انتخاب نمایید.'; diff --git a/public/tiny_mce/plugins/advlink/langs/fr.js b/public/tiny_mce/plugins/advlink/langs/fr.js new file mode 100644 index 0000000..b0ddca8 --- /dev/null +++ b/public/tiny_mce/plugins/advlink/langs/fr.js @@ -0,0 +1,20 @@ +// French lang variables by Laurent Dran + +tinyMCELang['lang_insert_link_target_same'] = 'Ouvre dans la fenętre / Cadre(frame)'; +tinyMCELang['lang_insert_link_target_parent'] = 'Ouvre dans fenętre parente / Cadres(frame)'; +tinyMCELang['lang_insert_link_target_top'] = 'Ouvre dans le Top frame (remplace toutes les cadres(frames))'; +tinyMCELang['lang_insert_link_target_blank'] = 'Ouvre dans la fenętre'; +tinyMCELang['lang_insert_link_target_named'] = 'Ouvre dans la fenętre'; +tinyMCELang['lang_insert_link_popup'] = 'JS-Popup'; +tinyMCELang['lang_insert_link_popup_url'] = 'URL de la Popup'; +tinyMCELang['lang_insert_link_popup_name'] = 'Nom de la fenętre'; +tinyMCELang['lang_insert_link_popup_return'] = 'Insert \'return false\''; +tinyMCELang['lang_insert_link_popup_scrollbars'] = 'Montrer la barre de défilement '; +tinyMCELang['lang_insert_link_popup_statusbar'] = 'Montrer la barre d\'état'; +tinyMCELang['lang_insert_link_popup_toolbar'] = 'Montrer la barre d\'outils'; +tinyMCELang['lang_insert_link_popup_menubar'] = 'Montrer la barre du menu'; +tinyMCELang['lang_insert_link_popup_location'] = 'Montre la barre d\'adresse'; +tinyMCELang['lang_insert_link_popup_resizable'] = 'Fabriquer une fenętre redimensionnable'; +tinyMCELang['lang_insert_link_popup_size'] = 'Taille'; +tinyMCELang['lang_insert_link_popup_position'] = 'Position (X/Y)'; +tinyMCELang['lang_insert_link_popup_missingtarget'] = 'Veuillez insérer un nom pour la cible ou choisissez une autre option.'; diff --git a/public/tiny_mce/plugins/advlink/langs/fr_ca.js b/public/tiny_mce/plugins/advlink/langs/fr_ca.js new file mode 100644 index 0000000..b40dfbc --- /dev/null +++ b/public/tiny_mce/plugins/advlink/langs/fr_ca.js @@ -0,0 +1,20 @@ +// CA_FR lang variables + +tinyMCELang['lang_insert_link_target_same'] = 'Ouvrir dans la mme fentre'; +tinyMCELang['lang_insert_link_target_parent'] = 'Ouvrir dans la fentre parent'; +tinyMCELang['lang_insert_link_target_top'] = 'Ouvrir dans le cadre suprieur'; +tinyMCELang['lang_insert_link_target_blank'] = 'Ouvrir dans une nouvelle fentre'; +tinyMCELang['lang_insert_link_target_named'] = 'Ouvrir la destination'; +tinyMCELang['lang_insert_link_popup'] = 'JS-Popup'; +tinyMCELang['lang_insert_link_popup_url'] = 'URL du popup'; +tinyMCELang['lang_insert_link_popup_name'] = 'Nom de la fentre'; +tinyMCELang['lang_insert_link_popup_return'] = 'Insrer le script \'return false\''; +tinyMCELang['lang_insert_link_popup_scrollbars'] = 'Barres de dfilement'; +tinyMCELang['lang_insert_link_popup_statusbar'] = 'Barre de statut'; +tinyMCELang['lang_insert_link_popup_toolbar'] = 'Barres d\'outils'; +tinyMCELang['lang_insert_link_popup_menubar'] = 'Barre de menu'; +tinyMCELang['lang_insert_link_popup_location'] = 'Barre d\'adresse'; +tinyMCELang['lang_insert_link_popup_resizable'] = 'Fentre redimensionnable'; +tinyMCELang['lang_insert_link_popup_size'] = 'Dimensions'; +tinyMCELang['lang_insert_link_popup_position'] = 'Position (X/Y)'; +tinyMCELang['lang_insert_link_popup_missingtarget'] = 'S.v.p., entrer un nom de destination ou choisir une autre option.'; diff --git a/public/tiny_mce/plugins/advlink/langs/ko.js b/public/tiny_mce/plugins/advlink/langs/ko.js new file mode 100644 index 0000000..06a34eb --- /dev/null +++ b/public/tiny_mce/plugins/advlink/langs/ko.js @@ -0,0 +1,19 @@ +// KO lang variables + +tinyMCELang['lang_insert_link_target_same'] = ' â ũ/ '; +tinyMCELang['lang_insert_link_target_parent'] = 'θ â ũ/ '; +tinyMCELang['lang_insert_link_target_top'] = 'TOP ӿ ( ü)'; +tinyMCELang['lang_insert_link_target_blank'] = ' â '; +tinyMCELang['lang_insert_link_target_named'] = ' â '; +tinyMCELang['lang_insert_link_popup'] = 'JS-Popup'; +tinyMCELang['lang_insert_link_popup_url'] = '˾ URL'; +tinyMCELang['lang_insert_link_popup_name'] = 'â ̸'; +tinyMCELang['lang_insert_link_popup_return'] = '\'return false\' ֱ'; +tinyMCELang['lang_insert_link_popup_scrollbars'] = 'ũѹٸ '; +tinyMCELang['lang_insert_link_popup_statusbar'] = 'â '; +tinyMCELang['lang_insert_link_popup_toolbar'] = 'ٸ '; +tinyMCELang['lang_insert_link_popup_menubar'] = '޴ٸ '; +tinyMCELang['lang_insert_link_popup_location'] = 'ġ ǥ '; +tinyMCELang['lang_insert_link_popup_resizable'] = 'ũ '; +tinyMCELang['lang_insert_link_popup_size'] = 'ũ'; +tinyMCELang['lang_insert_link_popup_position'] = 'ġ (X/Y)'; diff --git a/public/tiny_mce/plugins/advlink/langs/pl.js b/public/tiny_mce/plugins/advlink/langs/pl.js new file mode 100644 index 0000000..d801bcb --- /dev/null +++ b/public/tiny_mce/plugins/advlink/langs/pl.js @@ -0,0 +1,23 @@ +// PL lang variables + +tinyMCELang['lang_insert_link_target_same'] = 'Otwórz w tym samym oknie'; +tinyMCELang['lang_insert_link_target_parent'] = 'Open in parent window / frame'; +tinyMCELang['lang_insert_link_target_top'] = 'Open in top frame (replaces all frames)'; +tinyMCELang['lang_insert_link_target_blank'] = 'Otwórz w nowym oknie'; +tinyMCELang['lang_insert_link_target_named'] = 'Open in the window'; +tinyMCELang['lang_insert_link_popup'] = 'JS-Popup'; +tinyMCELang['lang_insert_link_popup_url'] = 'Popup URL'; +tinyMCELang['lang_insert_link_popup_name'] = 'Window name'; +tinyMCELang['lang_insert_link_popup_return'] = 'insert \'return false\''; +tinyMCELang['lang_insert_link_popup_scrollbars'] = 'Show scrollbars'; +tinyMCELang['lang_insert_link_popup_statusbar'] = 'Show statusbar'; +tinyMCELang['lang_insert_link_popup_toolbar'] = 'Show toolbars'; +tinyMCELang['lang_insert_link_popup_menubar'] = 'Show menubar'; +tinyMCELang['lang_insert_link_popup_location'] = 'Show locationbar'; +tinyMCELang['lang_insert_link_popup_resizable'] = 'Make window resizable'; +tinyMCELang['lang_insert_link_popup_size'] = 'Size'; +tinyMCELang['lang_insert_link_popup_position'] = 'Position (X/Y)'; +tinyMCELang['lang_insert_link_popup_missingtarget'] = 'Please insert a name for the target or choose another option.'; +tinyMCELang['lang_insert_link_url'] = 'Adres URL'; +tinyMCELang['lang_insert_link_target'] = 'Cel'; + diff --git a/public/tiny_mce/plugins/advlink/langs/pt_br.js b/public/tiny_mce/plugins/advlink/langs/pt_br.js new file mode 100644 index 0000000..7cf01e0 --- /dev/null +++ b/public/tiny_mce/plugins/advlink/langs/pt_br.js @@ -0,0 +1,20 @@ +// pt_BR lang variables + +tinyMCELang['lang_insert_link_target_same'] = 'Abrir nesta mesma janela / frame'; +tinyMCELang['lang_insert_link_target_parent'] = 'Abrir na janela / frame prvia'; +tinyMCELang['lang_insert_link_target_top'] = 'Abrir no frame superior (substitui todos os frames)'; +tinyMCELang['lang_insert_link_target_blank'] = 'Abrir em nova janela'; +tinyMCELang['lang_insert_link_target_named'] = 'Abrir na janela'; +tinyMCELang['lang_insert_link_popup'] = 'JS-Popup'; +tinyMCELang['lang_insert_link_popup_url'] = 'Popup URL endereo'; +tinyMCELang['lang_insert_link_popup_name'] = 'Nome da janela'; +tinyMCELang['lang_insert_link_popup_return'] = 'inserir \'retorna falso\''; +tinyMCELang['lang_insert_link_popup_scrollbars'] = 'Mostra barras de rolagem'; +tinyMCELang['lang_insert_link_popup_statusbar'] = 'Mostra barra de status'; +tinyMCELang['lang_insert_link_popup_toolbar'] = 'Mostra barras de ferramentas'; +tinyMCELang['lang_insert_link_popup_menubar'] = 'Mostra barra de menu'; +tinyMCELang['lang_insert_link_popup_location'] = 'Mostra barra de endereo'; +tinyMCELang['lang_insert_link_popup_resizable'] = 'Permite redimensionamento da janela'; +tinyMCELang['lang_insert_link_popup_size'] = 'Tamanho'; +tinyMCELang['lang_insert_link_popup_position'] = 'Posio (X/Y)'; +tinyMCELang['lang_insert_link_popup_missingtarget'] = 'Por Favor insira um nome para o alvo ou escolha outra opo.'; diff --git a/public/tiny_mce/plugins/advlink/langs/sv.js b/public/tiny_mce/plugins/advlink/langs/sv.js new file mode 100644 index 0000000..d029a1c --- /dev/null +++ b/public/tiny_mce/plugins/advlink/langs/sv.js @@ -0,0 +1,20 @@ +// SE lang variables + +tinyMCELang['lang_insert_link_target_same'] = 'Öppna i samma fönster / ram'; +tinyMCELang['lang_insert_link_target_parent'] = 'Öppna i underliggande fönster / ram'; +tinyMCELang['lang_insert_link_target_top'] = 'Öppna i toppramen (ersätter alla ramar)'; +tinyMCELang['lang_insert_link_target_blank'] = 'Öppna i ett nytt fönster'; +tinyMCELang['lang_insert_link_target_named'] = 'Öppna i ett specifikt fönster'; +tinyMCELang['lang_insert_link_popup'] = 'JS-Popup'; +tinyMCELang['lang_insert_link_popup_url'] = 'Popup URL'; +tinyMCELang['lang_insert_link_popup_name'] = 'Fönstrets namn'; +tinyMCELang['lang_insert_link_popup_return'] = 'Sätt in \'return false\''; +tinyMCELang['lang_insert_link_popup_scrollbars'] = 'Visa scrollbars'; +tinyMCELang['lang_insert_link_popup_statusbar'] = 'Visa statusbar'; +tinyMCELang['lang_insert_link_popup_toolbar'] = 'Visa toolbars'; +tinyMCELang['lang_insert_link_popup_menubar'] = 'Visa menubar'; +tinyMCELang['lang_insert_link_popup_location'] = 'Visa locationbar'; +tinyMCELang['lang_insert_link_popup_resizable'] = 'Gör fönstret skalbart'; +tinyMCELang['lang_insert_link_popup_size'] = 'Storlek'; +tinyMCELang['lang_insert_link_popup_position'] = 'Position (X/Y)'; +tinyMCELang['lang_insert_link_popup_missingtarget'] = 'Var god skriv ett namn fr fnstret eller vlj ett annat val.'; diff --git a/public/tiny_mce/plugins/advlink/langs/zh_cn.js b/public/tiny_mce/plugins/advlink/langs/zh_cn.js new file mode 100644 index 0000000..4cb524b --- /dev/null +++ b/public/tiny_mce/plugins/advlink/langs/zh_cn.js @@ -0,0 +1,21 @@ +// Simplified Chinese lang variables contributed by cube316 (cube316@gmail.com) +// http://www.cube316.net/ ԻȡTinyMCE֧ + +tinyMCELang['lang_insert_link_target_same'] = 'ڱ/д'; +tinyMCELang['lang_insert_link_target_parent'] = 'ڸ/д'; +tinyMCELang['lang_insert_link_target_top'] = 'ڸд򿪣滻пܣ'; +tinyMCELang['lang_insert_link_target_blank'] = '´д'; +tinyMCELang['lang_insert_link_target_named'] = 'ڴ˴д'; +tinyMCELang['lang_insert_link_popup'] = 'JavaScript'; +tinyMCELang['lang_insert_link_popup_url'] = 'ڵַ'; +tinyMCELang['lang_insert_link_popup_name'] = ''; +tinyMCELang['lang_insert_link_popup_return'] = ' \'return false\''; +tinyMCELang['lang_insert_link_popup_scrollbars'] = 'ʾ'; +tinyMCELang['lang_insert_link_popup_statusbar'] = 'ʾ״̬'; +tinyMCELang['lang_insert_link_popup_toolbar'] = 'ʾ'; +tinyMCELang['lang_insert_link_popup_menubar'] = 'ʾ˵'; +tinyMCELang['lang_insert_link_popup_location'] = 'ʾַ'; +tinyMCELang['lang_insert_link_popup_resizable'] = 'ض崰ڴС'; +tinyMCELang['lang_insert_link_popup_size'] = 'ߴ'; +tinyMCELang['lang_insert_link_popup_position'] = 'λ(X/Y)'; +tinyMCELang['lang_insert_link_popup_missingtarget'] = 'Ŀƻѡѡ'; diff --git a/public/tiny_mce/plugins/advlink/link.htm b/public/tiny_mce/plugins/advlink/link.htm new file mode 100644 index 0000000..d04b1d9 --- /dev/null +++ b/public/tiny_mce/plugins/advlink/link.htm @@ -0,0 +1,444 @@ + + +{$lang_insert_link_title} + + + + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$lang_insert_link_title}
    {$lang_insert_link_url}: + + + + +
    {$lang_theme_insert_link_titlefield}:
    {$lang_insert_link_target}: + + + + + + + + + + + + + + + + + + + + + +
     ({$lang_insert_link_target_same})
     ({$lang_insert_link_target_parent})
     ({$lang_insert_link_target_top})
     ({$lang_insert_link_target_blank})
    + + + + + + +
     
    +
    + + + + + + + + + + + + + + + + + +
    {$lang_insert_link_popup_url}:  + + + + +
    {$lang_insert_link_popup_name}: 
    {$lang_insert_link_popup_size}:  + x + px +
    {$lang_insert_link_popup_position}:  + / + (c /c = center) +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      
     
       
     
    +
    +
    + + diff --git a/public/tiny_mce/plugins/advlink/readme.txt b/public/tiny_mce/plugins/advlink/readme.txt new file mode 100644 index 0000000..6e9ac10 --- /dev/null +++ b/public/tiny_mce/plugins/advlink/readme.txt @@ -0,0 +1,19 @@ + Advlink plugin for TinyMCE +----------------------------- + +About: + This is a more advanced link dialog mostly based on code contributed by Michael Keck. + This one supports popup windows and targets. + +Installation instructions: + * Copy the advlink directory to the plugins directory of TinyMCE (/jscripts/tiny_mce/plugins). + * Add plugin to TinyMCE plugin option list example: plugins : "advlink". + * Add this "a[name|href|target|title|onclick]" to extended_valid_elements option. + +Initialization example: + tinyMCE.init({ + theme : "advanced", + mode : "textareas", + plugins : "advlink", + extended_valid_elements : "a[name|href|target|title|onclick]" + }); diff --git a/public/tiny_mce/plugins/contextmenu/contextmenu.css b/public/tiny_mce/plugins/contextmenu/contextmenu.css new file mode 100644 index 0000000..58bb337 --- /dev/null +++ b/public/tiny_mce/plugins/contextmenu/contextmenu.css @@ -0,0 +1,60 @@ +.contextMenuIEPopup { + padding: 0px; + margin: 0px; + border: 0px; + overflow: hidden; +} + +.contextMenu { + position: absolute; + cursor: default; + z-index: 1000; + border: 1px solid #D4D0C8; + background-color: #FFFFFF; +} + +.contextMenuItem, .contextMenuItemOver { +} + +.contextMenuItemOver { + background-color: #B6BDD2; +} + +.contextMenuSeparator { + width: 100%; + background-color: #D4D0C8; + border: 0px; +} + +.contextMenuImage, .contextMenuItemDisabled { + border: 0px; +} + +.contextMenuIcon { + background-color: #F0F0EE; +} + +.contextMenuItemOver .contextMenuIcon { + background-color: #B6BDD2; +} + +.contextMenuIcon { + background-color: #F0F0EE; +} + +.contextMenuItemDisabled img { + filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); + -moz-opacity:0.3; + opacity: 0.3; +} + +.contextMenuText { + font-family: Tahoma, Verdana, Arial, Helvetica; + font-size: 11px; + margin-left: 5px; + margin-right: 10px; +} + +.contextMenuItemDisabled { + color: #AAAAAA; +} diff --git a/public/tiny_mce/plugins/contextmenu/editor_plugin.js b/public/tiny_mce/plugins/contextmenu/editor_plugin.js new file mode 100644 index 0000000..899ad2b --- /dev/null +++ b/public/tiny_mce/plugins/contextmenu/editor_plugin.js @@ -0,0 +1,2 @@ +/* Import plugin specific language pack */ + if(!tinyMCE.settings['contextmenu_skip_plugin_css'])tinyMCE.loadCSS(tinyMCE.baseURL+"/plugins/contextmenu/contextmenu.css");var TinyMCE_contextmenu_contextMenu=null;function TinyMCE_contextmenu_initInstance(inst){if(tinyMCE.isMSIE5_0)return;tinyMCE.addEvent(inst.getDoc(),"click",TinyMCE_contextmenu_hideContextMenu);tinyMCE.addEvent(inst.getDoc(),"keypress",TinyMCE_contextmenu_hideContextMenu);tinyMCE.addEvent(inst.getDoc(),"keydown",TinyMCE_contextmenu_hideContextMenu);tinyMCE.addEvent(document,"click",TinyMCE_contextmenu_hideContextMenu);tinyMCE.addEvent(document,"keypress",TinyMCE_contextmenu_hideContextMenu);tinyMCE.addEvent(document,"keydown",TinyMCE_contextmenu_hideContextMenu);var contextMenu=new ContextMenu({commandhandler:"TinyMCE_contextmenu_commandHandler",spacer_image:tinyMCE.baseURL+"/plugins/contextmenu/images/spacer.gif"});TinyMCE_contextmenu_contextMenu=contextMenu;if(tinyMCE.isGecko){tinyMCE.addEvent(inst.getDoc(),"contextmenu",function(e){TinyMCE_contextmenu_showContextMenu(tinyMCE.isMSIE?inst.contentWindow.event:e,inst);});}else tinyMCE.addEvent(inst.getDoc(),"contextmenu",TinyMCE_contextmenu_onContextMenu);}function TinyMCE_contextmenu_onContextMenu(e){var elm=tinyMCE.isMSIE?e.srcElement:e.target;var targetInst,body;if((body=tinyMCE.getParentElement(elm,"body"))!=null){for(var n in tinyMCE.instances){var inst=tinyMCE.instances[n];if(body==inst.getBody()){targetInst=inst;break;}}return TinyMCE_contextmenu_showContextMenu(tinyMCE.isMSIE?targetInst.contentWindow.event:e,targetInst);}}function TinyMCE_contextmenu_showContextMenu(e,inst){function getAttrib(elm,name){return elm.getAttribute(name)?elm.getAttribute(name):"";}var x,y,elm,contextMenu;var pos=tinyMCE.getAbsPosition(inst.iframeElement);x=tinyMCE.isMSIE?e.screenX:pos.absLeft+(e.pageX-inst.getBody().scrollLeft);y=tinyMCE.isMSIE?e.screenY:pos.absTop+(e.pageY-inst.getBody().scrollTop);elm=tinyMCE.isMSIE?e.srcElement:e.target;contextMenu=TinyMCE_contextmenu_contextMenu;contextMenu.inst=inst;window.setTimeout(function(){var theme=tinyMCE.getParam("theme");contextMenu.clearAll();var sel=inst.getSelectedText().length!=0||elm.nodeName=="IMG";contextMenu.addItem(tinyMCE.baseURL+"/themes/"+theme+"/images/cut.gif","$lang_cut_desc","Cut","",!sel);contextMenu.addItem(tinyMCE.baseURL+"/themes/"+theme+"/images/copy.gif","$lang_copy_desc","Copy","",!sel);contextMenu.addItem(tinyMCE.baseURL+"/themes/"+theme+"/images/paste.gif","$lang_paste_desc","Paste","",false);elm=tinyMCE.getParentElement(elm,"img,table,td");if(elm){switch(elm.nodeName){case "IMG":contextMenu.addSeparator();if(tinyMCE.getAttrib(elm,'name','').indexOf('mce_plugin_flash')==0)contextMenu.addItem(tinyMCE.baseURL+"/plugins/flash/images/flash.gif","$lang_flash_props","mceFlash");else contextMenu.addItem(tinyMCE.baseURL+"/themes/"+theme+"/images/image.gif","$lang_image_props_desc","mceImage");break;case "TABLE":case "TD":if(typeof(TinyMCE_table_getControlHTML)!="undefined"){var colspan=(elm.nodeName=="TABLE")?"":getAttrib(elm,"colspan");var rowspan=(elm.nodeName=="TABLE")?"":getAttrib(elm,"rowspan");colspan=colspan==""?"1":colspan;rowspan=rowspan==""?"1":rowspan;contextMenu.addSeparator();contextMenu.addItem(tinyMCE.baseURL+"/themes/"+theme+"/images/cut.gif","$lang_table_cut_row_desc","mceTableCutRow");contextMenu.addItem(tinyMCE.baseURL+"/themes/"+theme+"/images/copy.gif","$lang_table_copy_row_desc","mceTableCopyRow");contextMenu.addItem(tinyMCE.baseURL+"/themes/"+theme+"/images/paste.gif","$lang_table_paste_row_before_desc","mceTablePasteRowBefore","",inst.tableRowClipboard==null);contextMenu.addItem(tinyMCE.baseURL+"/themes/"+theme+"/images/paste.gif","$lang_table_paste_row_after_desc","mceTablePasteRowAfter","",inst.tableRowClipboard==null);contextMenu.addSeparator();contextMenu.addItem(tinyMCE.baseURL+"/plugins/table/images/table.gif","$lang_table_insert_desc","mceInsertTable","insert");contextMenu.addItem(tinyMCE.baseURL+"/plugins/table/images/table.gif","$lang_table_props_desc","mceInsertTable");contextMenu.addItem(tinyMCE.baseURL+"/plugins/table/images/table_cell_props.gif","$lang_table_cell_desc","mceTableCellProps");contextMenu.addSeparator();contextMenu.addItem(tinyMCE.baseURL+"/plugins/table/images/table_row_props.gif","$lang_table_row_desc","mceTableRowProps");contextMenu.addItem(tinyMCE.baseURL+"/plugins/table/images/table_insert_row_before.gif","$lang_table_insert_row_before_desc","mceTableInsertRowBefore");contextMenu.addItem(tinyMCE.baseURL+"/plugins/table/images/table_insert_row_after.gif","$lang_table_insert_row_after_desc","mceTableInsertRowAfter");contextMenu.addItem(tinyMCE.baseURL+"/plugins/table/images/table_delete_row.gif","$lang_table_delete_row_desc","mceTableDeleteRow");contextMenu.addSeparator();contextMenu.addItem(tinyMCE.baseURL+"/plugins/table/images/table_insert_col_before.gif","$lang_table_insert_col_before_desc","mceTableInsertColBefore");contextMenu.addItem(tinyMCE.baseURL+"/plugins/table/images/table_insert_col_after.gif","$lang_table_insert_col_after_desc","mceTableInsertColAfter");contextMenu.addItem(tinyMCE.baseURL+"/plugins/table/images/table_delete_col.gif","$lang_table_delete_col_desc","mceTableDeleteCol");contextMenu.addSeparator();contextMenu.addItem(tinyMCE.baseURL+"/plugins/table/images/table_split_cells.gif","$lang_table_split_cells_desc","mceTableSplitCells","",(colspan=="1"&&rowspan=="1"));contextMenu.addItem(tinyMCE.baseURL+"/plugins/table/images/table_merge_cells.gif","$lang_table_merge_cells_desc","mceTableMergeCells","",false);}break;}}contextMenu.show(x,y);},10);tinyMCE.cancelEvent(e);return false;}function TinyMCE_contextmenu_hideContextMenu(){TinyMCE_contextmenu_contextMenu.hide();return true;}function TinyMCE_contextmenu_commandHandler(command,value){TinyMCE_contextmenu_contextMenu.hide();var ui=false;if(command=="mceInsertTable"||command=="mceTableCellProps"||command=="mceTableRowProps"||command=="mceTableMergeCells")ui=true;TinyMCE_contextmenu_contextMenu.inst.execCommand(command,ui,value);}function ContextMenu(settings){function defParam(key,def_val){settings[key]=typeof(settings[key])!="undefined"?settings[key]:def_val;}var self=this;this.isMSIE=(navigator.appName=="Microsoft Internet Explorer");this.contextMenuDiv=document.createElement("div");this.contextMenuDiv.className="contextMenu";this.contextMenuDiv.setAttribute("class","contextMenu");this.contextMenuDiv.style.display="none";this.contextMenuDiv.style.position='absolute';this.contextMenuDiv.style.zindex=1000;this.contextMenuDiv.style.left='0px';this.contextMenuDiv.style.top='0px';this.contextMenuDiv.unselectable="on";document.body.appendChild(this.contextMenuDiv);defParam("commandhandler","");defParam("spacer_image","images/spacer.gif");this.items=new Array();this.settings=settings;this.html="";if(tinyMCE.isMSIE&&!tinyMCE.isMSIE5_0){this.pop=window.createPopup();doc=this.pop.document;doc.open();doc.write('');doc.close();}};ContextMenu.prototype.clearAll=function(){this.html="";this.contextMenuDiv.innerHTML="";};ContextMenu.prototype.addSeparator=function(){this.html+='';};ContextMenu.prototype.addItem=function(icon,title,command,value,disabled){if(title.charAt(0)=='$')title=tinyMCE.getLang(title.substring(1));var onMouseDown='';var html='';if(tinyMCE.isMSIE&&!tinyMCE.isMSIE5_0)onMouseDown='contextMenu.execCommand(\''+command+'\', \''+value+'\');return false;';else onMouseDown=this.settings['commandhandler']+'(\''+command+'\', \''+value+'\');return false;';if(icon=="")icon=this.settings['spacer_image'];if(!disabled)html+='';else html+='';html+='';html+='
    ';html+=title;html+='
    ';html+='';this.html+=html;};ContextMenu.prototype.show=function(x,y){if(this.html=="")return;var html='';html+='';html+=this.html;html+='
    ';this.contextMenuDiv.innerHTML=html;if(tinyMCE.isMSIE&&!tinyMCE.isMSIE5_0){var width,height;this.contextMenuDiv.style.display="block";width=this.contextMenuDiv.offsetWidth;height=this.contextMenuDiv.offsetHeight;this.contextMenuDiv.style.display="none";this.pop.document.body.innerHTML='
    '+html+"
    ";this.pop.document.tinyMCE=tinyMCE;this.pop.document.contextMenu=this;this.pop.show(x,y,width,height);}else{this.contextMenuDiv.style.left=x+'px';this.contextMenuDiv.style.top=y+'px';this.contextMenuDiv.style.display="block";}};ContextMenu.prototype.hide=function(){if(tinyMCE.isMSIE&&!tinyMCE.isMSIE5_0)this.pop.hide();else this.contextMenuDiv.style.display="none";};ContextMenu.prototype.execCommand=function(command,value){eval(this.settings['commandhandler']+"(command, value);");}; \ No newline at end of file diff --git a/public/tiny_mce/plugins/contextmenu/editor_plugin_src.js b/public/tiny_mce/plugins/contextmenu/editor_plugin_src.js new file mode 100644 index 0000000..2f07c64 --- /dev/null +++ b/public/tiny_mce/plugins/contextmenu/editor_plugin_src.js @@ -0,0 +1,289 @@ +/* Import plugin specific language pack */ +//tinyMCE.importPluginLanguagePack('contextmenu', 'en,zh_cn,cs,fa,fr_ca,fr,de'); +if (!tinyMCE.settings['contextmenu_skip_plugin_css']) + tinyMCE.loadCSS(tinyMCE.baseURL + "/plugins/contextmenu/contextmenu.css"); + +// Global contextmenu class instance +var TinyMCE_contextmenu_contextMenu = null; + +function TinyMCE_contextmenu_initInstance(inst) { + // Is not working on MSIE 5.0 + if (tinyMCE.isMSIE5_0) + return; + + // Add hide event handles + tinyMCE.addEvent(inst.getDoc(), "click", TinyMCE_contextmenu_hideContextMenu); + tinyMCE.addEvent(inst.getDoc(), "keypress", TinyMCE_contextmenu_hideContextMenu); + tinyMCE.addEvent(inst.getDoc(), "keydown", TinyMCE_contextmenu_hideContextMenu); + tinyMCE.addEvent(document, "click", TinyMCE_contextmenu_hideContextMenu); + tinyMCE.addEvent(document, "keypress", TinyMCE_contextmenu_hideContextMenu); + tinyMCE.addEvent(document, "keydown", TinyMCE_contextmenu_hideContextMenu); + + var contextMenu = new ContextMenu({ + commandhandler : "TinyMCE_contextmenu_commandHandler", + spacer_image : tinyMCE.baseURL + "/plugins/contextmenu/images/spacer.gif" + }); + + // Register global reference + TinyMCE_contextmenu_contextMenu = contextMenu; + + // Attach contextmenu event + if (tinyMCE.isGecko) { + tinyMCE.addEvent(inst.getDoc(), "contextmenu", function(e) {TinyMCE_contextmenu_showContextMenu(tinyMCE.isMSIE ? inst.contentWindow.event : e, inst);}); + } else + tinyMCE.addEvent(inst.getDoc(), "contextmenu", TinyMCE_contextmenu_onContextMenu); +} + +function TinyMCE_contextmenu_onContextMenu(e) { + var elm = tinyMCE.isMSIE ? e.srcElement : e.target; + var targetInst, body; + + // Find instance + if ((body = tinyMCE.getParentElement(elm, "body")) != null) { + for (var n in tinyMCE.instances) { + var inst = tinyMCE.instances[n]; + + if (body == inst.getBody()) { + targetInst = inst; + break; + } + } + + return TinyMCE_contextmenu_showContextMenu(tinyMCE.isMSIE ? targetInst.contentWindow.event : e, targetInst); + } +} + +function TinyMCE_contextmenu_showContextMenu(e, inst) { + function getAttrib(elm, name) { + return elm.getAttribute(name) ? elm.getAttribute(name) : ""; + } + + var x, y, elm, contextMenu; + var pos = tinyMCE.getAbsPosition(inst.iframeElement); + + x = tinyMCE.isMSIE ? e.screenX : pos.absLeft + (e.pageX - inst.getBody().scrollLeft); + y = tinyMCE.isMSIE ? e.screenY : pos.absTop + (e.pageY - inst.getBody().scrollTop); + elm = tinyMCE.isMSIE ? e.srcElement : e.target; + contextMenu = TinyMCE_contextmenu_contextMenu; + contextMenu.inst = inst; + + // Mozilla needs some time + window.setTimeout(function () { + var theme = tinyMCE.getParam("theme"); + + contextMenu.clearAll(); + var sel = inst.getSelectedText().length != 0 || elm.nodeName == "IMG"; + + // Default items + contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/cut.gif", "$lang_cut_desc", "Cut", "", !sel); + contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/copy.gif", "$lang_copy_desc", "Copy", "", !sel); + contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/paste.gif", "$lang_paste_desc", "Paste", "", false); + + // Get element + elm = tinyMCE.getParentElement(elm, "img,table,td"); + if (elm) { + switch (elm.nodeName) { + case "IMG": + contextMenu.addSeparator(); + + // If flash + if (tinyMCE.getAttrib(elm, 'name', '').indexOf('mce_plugin_flash') == 0) + contextMenu.addItem(tinyMCE.baseURL + "/plugins/flash/images/flash.gif", "$lang_flash_props", "mceFlash"); + else + contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/image.gif", "$lang_image_props_desc", "mceImage"); + break; + + case "TABLE": + case "TD": + // Is table plugin loaded + if (typeof(TinyMCE_table_getControlHTML) != "undefined") { + var colspan = (elm.nodeName == "TABLE") ? "" : getAttrib(elm, "colspan"); + var rowspan = (elm.nodeName == "TABLE") ? "" : getAttrib(elm, "rowspan"); + + colspan = colspan == "" ? "1" : colspan; + rowspan = rowspan == "" ? "1" : rowspan; + + contextMenu.addSeparator(); + contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/cut.gif", "$lang_table_cut_row_desc", "mceTableCutRow"); + contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/copy.gif", "$lang_table_copy_row_desc", "mceTableCopyRow"); + contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/paste.gif", "$lang_table_paste_row_before_desc", "mceTablePasteRowBefore", "", inst.tableRowClipboard == null); + contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/paste.gif", "$lang_table_paste_row_after_desc", "mceTablePasteRowAfter", "", inst.tableRowClipboard == null); + +/* contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/left.gif", "$lang_justifyleft_desc", "JustifyLeft", "", false); + contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/center.gif", "$lang_justifycenter_desc", "JustifyCenter", "", false); + contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/right.gif", "$lang_justifyright_desc", "JustifyRight", "", false); + contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/full.gif", "$lang_justifyfull_desc", "JustifyFull", "", false);*/ + contextMenu.addSeparator(); + contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table.gif", "$lang_table_insert_desc", "mceInsertTable", "insert"); + contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table.gif", "$lang_table_props_desc", "mceInsertTable"); + contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_cell_props.gif", "$lang_table_cell_desc", "mceTableCellProps"); + contextMenu.addSeparator(); + contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_row_props.gif", "$lang_table_row_desc", "mceTableRowProps"); + contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_insert_row_before.gif", "$lang_table_insert_row_before_desc", "mceTableInsertRowBefore"); + contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_insert_row_after.gif", "$lang_table_insert_row_after_desc", "mceTableInsertRowAfter"); + contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_delete_row.gif", "$lang_table_delete_row_desc", "mceTableDeleteRow"); + contextMenu.addSeparator(); + contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_insert_col_before.gif", "$lang_table_insert_col_before_desc", "mceTableInsertColBefore"); + contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_insert_col_after.gif", "$lang_table_insert_col_after_desc", "mceTableInsertColAfter"); + contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_delete_col.gif", "$lang_table_delete_col_desc", "mceTableDeleteCol"); + contextMenu.addSeparator(); + contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_split_cells.gif", "$lang_table_split_cells_desc", "mceTableSplitCells", "", (colspan == "1" && rowspan == "1")); + contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_merge_cells.gif", "$lang_table_merge_cells_desc", "mceTableMergeCells", "", false); + } + break; + } + } + + contextMenu.show(x, y); + }, 10); + + // Cancel default handeling + tinyMCE.cancelEvent(e); + return false; +} + +function TinyMCE_contextmenu_hideContextMenu() { + TinyMCE_contextmenu_contextMenu.hide(); + + return true; +} + +function TinyMCE_contextmenu_commandHandler(command, value) { + TinyMCE_contextmenu_contextMenu.hide(); + + // UI must be true on these + var ui = false; + if (command == "mceInsertTable" || command == "mceTableCellProps" || command == "mceTableRowProps" || command == "mceTableMergeCells") + ui = true; + + TinyMCE_contextmenu_contextMenu.inst.execCommand(command, ui, value); +} + +// Context menu class + +function ContextMenu(settings) { + // Default value function + function defParam(key, def_val) { + settings[key] = typeof(settings[key]) != "undefined" ? settings[key] : def_val; + } + + var self = this; + + this.isMSIE = (navigator.appName == "Microsoft Internet Explorer"); + + // Setup contextmenu div + this.contextMenuDiv = document.createElement("div"); + this.contextMenuDiv.className = "contextMenu"; + this.contextMenuDiv.setAttribute("class", "contextMenu"); + this.contextMenuDiv.style.display = "none"; + this.contextMenuDiv.style.position = 'absolute'; + this.contextMenuDiv.style.zindex = 1000; + this.contextMenuDiv.style.left = '0px'; + this.contextMenuDiv.style.top = '0px'; + this.contextMenuDiv.unselectable = "on"; + + document.body.appendChild(this.contextMenuDiv); + + // Setup default values + defParam("commandhandler", ""); + defParam("spacer_image", "images/spacer.gif"); + + this.items = new Array(); + this.settings = settings; + this.html = ""; + + // IE Popup + if (tinyMCE.isMSIE && !tinyMCE.isMSIE5_0) { + this.pop = window.createPopup(); + doc = this.pop.document; + doc.open(); + doc.write(''); + doc.close(); + } +}; + +ContextMenu.prototype.clearAll = function() { + this.html = ""; + this.contextMenuDiv.innerHTML = ""; +}; + +ContextMenu.prototype.addSeparator = function() { + this.html += ''; +}; + +ContextMenu.prototype.addItem = function(icon, title, command, value, disabled) { + if (title.charAt(0) == '$') + title = tinyMCE.getLang(title.substring(1)); + + var onMouseDown = ''; + var html = ''; + + if (tinyMCE.isMSIE && !tinyMCE.isMSIE5_0) + onMouseDown = 'contextMenu.execCommand(\'' + command + '\', \'' + value + '\');return false;'; + else + onMouseDown = this.settings['commandhandler'] + '(\'' + command + '\', \'' + value + '\');return false;'; + + if (icon == "") + icon = this.settings['spacer_image']; + + if (!disabled) + html += ''; + else + html += ''; + + html += ''; + html += '
    '; + + // Add text + html += title; + + html += '
    '; + html += ''; + + // Add to main + this.html += html; +}; + +ContextMenu.prototype.show = function(x, y) { + if (this.html == "") + return; + + var html = ''; + + html += ''; + html += this.html; + html += '
    '; + + this.contextMenuDiv.innerHTML = html; + + if (tinyMCE.isMSIE && !tinyMCE.isMSIE5_0) { + var width, height; + + // Get dimensions + this.contextMenuDiv.style.display = "block"; + width = this.contextMenuDiv.offsetWidth; + height = this.contextMenuDiv.offsetHeight; + this.contextMenuDiv.style.display = "none"; + + // Setup popup and show + this.pop.document.body.innerHTML = '
    ' + html + "
    "; + this.pop.document.tinyMCE = tinyMCE; + this.pop.document.contextMenu = this; + this.pop.show(x, y, width, height); + } else { + this.contextMenuDiv.style.left = x + 'px'; + this.contextMenuDiv.style.top = y + 'px'; + this.contextMenuDiv.style.display = "block"; + } +}; + +ContextMenu.prototype.hide = function() { + if (tinyMCE.isMSIE && !tinyMCE.isMSIE5_0) + this.pop.hide(); + else + this.contextMenuDiv.style.display = "none"; +}; + +ContextMenu.prototype.execCommand = function(command, value) { + eval(this.settings['commandhandler'] + "(command, value);"); +}; diff --git a/public/tiny_mce/plugins/contextmenu/images/spacer.gif b/public/tiny_mce/plugins/contextmenu/images/spacer.gif new file mode 100644 index 0000000..fc25609 Binary files /dev/null and b/public/tiny_mce/plugins/contextmenu/images/spacer.gif differ diff --git a/public/tiny_mce/plugins/directionality/editor_plugin.js b/public/tiny_mce/plugins/directionality/editor_plugin.js new file mode 100644 index 0000000..fb26cdb --- /dev/null +++ b/public/tiny_mce/plugins/directionality/editor_plugin.js @@ -0,0 +1,2 @@ +/* Import plugin specific language pack */ + tinyMCE.importPluginLanguagePack('directionality','en,sv');function TinyMCE_directionality_getControlHTML(control_name){var safariPatch='" onclick="';if(tinyMCE.isSafari)safariPatch="";switch(control_name){case "ltr":return '';case "rtl":return '';}return "";}function TinyMCE_directionality_execCommand(editor_id,element,command,user_interface,value){switch(command){case "mceDirectionLTR":var inst=tinyMCE.getInstanceById(editor_id);var elm=tinyMCE.getParentElement(inst.getFocusElement(),"p,div,td,h1,h2,h3,h4,h5,h6,pre,address");if(elm)elm.setAttribute("dir","ltr");tinyMCE.triggerNodeChange(false);return true;case "mceDirectionRTL":var inst=tinyMCE.getInstanceById(editor_id);var elm=tinyMCE.getParentElement(inst.getFocusElement(),"p,div,td,h1,h2,h3,h4,h5,h6,pre,address");if(elm)elm.setAttribute("dir","rtl");tinyMCE.triggerNodeChange(false);return true;}return false;}function TinyMCE_directionality_handleNodeChange(editor_id,node,undo_index,undo_levels,visual_aid,any_selection){function getAttrib(elm,name){return elm.getAttribute(name)?elm.getAttribute(name):"";}tinyMCE.switchClassSticky(editor_id+'_ltr','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_rtl','mceButtonNormal');if(node==null)return;var elm=tinyMCE.getParentElement(node,"p,div,td,h1,h2,h3,h4,h5,h6,pre,address");if(!elm)return;var dir=getAttrib(elm,"dir");if(dir=="ltr"||dir=="")tinyMCE.switchClassSticky(editor_id+'_ltr','mceButtonSelected');else tinyMCE.switchClassSticky(editor_id+'_rtl','mceButtonSelected');return true;} \ No newline at end of file diff --git a/public/tiny_mce/plugins/directionality/editor_plugin_src.js b/public/tiny_mce/plugins/directionality/editor_plugin_src.js new file mode 100644 index 0000000..de183fe --- /dev/null +++ b/public/tiny_mce/plugins/directionality/editor_plugin_src.js @@ -0,0 +1,71 @@ +/* Import plugin specific language pack */ +tinyMCE.importPluginLanguagePack('directionality', 'en,sv'); + +function TinyMCE_directionality_getControlHTML(control_name) { + var safariPatch = '" onclick="'; + + if (tinyMCE.isSafari) + safariPatch = ""; + + switch (control_name) { + case "ltr": + return ''; + + case "rtl": + return ''; + } + + return ""; +} + +function TinyMCE_directionality_execCommand(editor_id, element, command, user_interface, value) { + // Handle commands + switch (command) { + case "mceDirectionLTR": + var inst = tinyMCE.getInstanceById(editor_id); + var elm = tinyMCE.getParentElement(inst.getFocusElement(), "p,div,td,h1,h2,h3,h4,h5,h6,pre,address"); + + if (elm) + elm.setAttribute("dir", "ltr"); + + tinyMCE.triggerNodeChange(false); + return true; + + case "mceDirectionRTL": + var inst = tinyMCE.getInstanceById(editor_id); + var elm = tinyMCE.getParentElement(inst.getFocusElement(), "p,div,td,h1,h2,h3,h4,h5,h6,pre,address"); + + if (elm) + elm.setAttribute("dir", "rtl"); + + tinyMCE.triggerNodeChange(false); + return true; + } + + // Pass to next handler in chain + return false; +} + +function TinyMCE_directionality_handleNodeChange(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) { + function getAttrib(elm, name) { + return elm.getAttribute(name) ? elm.getAttribute(name) : ""; + } + + tinyMCE.switchClassSticky(editor_id + '_ltr', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_rtl', 'mceButtonNormal'); + + if (node == null) + return; + + var elm = tinyMCE.getParentElement(node, "p,div,td,h1,h2,h3,h4,h5,h6,pre,address"); + if (!elm) + return; + + var dir = getAttrib(elm, "dir"); + if (dir == "ltr" || dir == "") + tinyMCE.switchClassSticky(editor_id + '_ltr', 'mceButtonSelected'); + else + tinyMCE.switchClassSticky(editor_id + '_rtl', 'mceButtonSelected'); + + return true; +} diff --git a/public/tiny_mce/plugins/directionality/images/ltr.gif b/public/tiny_mce/plugins/directionality/images/ltr.gif new file mode 100644 index 0000000..1f8e046 Binary files /dev/null and b/public/tiny_mce/plugins/directionality/images/ltr.gif differ diff --git a/public/tiny_mce/plugins/directionality/images/rtl.gif b/public/tiny_mce/plugins/directionality/images/rtl.gif new file mode 100644 index 0000000..40ec613 Binary files /dev/null and b/public/tiny_mce/plugins/directionality/images/rtl.gif differ diff --git a/public/tiny_mce/plugins/directionality/langs/en.js b/public/tiny_mce/plugins/directionality/langs/en.js new file mode 100644 index 0000000..2f5ad45 --- /dev/null +++ b/public/tiny_mce/plugins/directionality/langs/en.js @@ -0,0 +1,4 @@ +// UK lang variables + +tinyMCELang['lang_directionality_ltr_desc'] = 'Direction left to right' +tinyMCELang['lang_directionality_rtl_desc'] = 'Direction right to left'; diff --git a/public/tiny_mce/plugins/directionality/langs/sv.js b/public/tiny_mce/plugins/directionality/langs/sv.js new file mode 100644 index 0000000..7639836 --- /dev/null +++ b/public/tiny_mce/plugins/directionality/langs/sv.js @@ -0,0 +1,4 @@ +// SV lang variables + +tinyMCELang['lang_directionality_ltr_desc'] = 'Riktning från vänster till höger' +tinyMCELang['lang_directionality_rtl_desc'] = 'Riktning från höger till vänster'; diff --git a/public/tiny_mce/plugins/directionality/langs/zh_cn.js b/public/tiny_mce/plugins/directionality/langs/zh_cn.js new file mode 100644 index 0000000..9dfe94a --- /dev/null +++ b/public/tiny_mce/plugins/directionality/langs/zh_cn.js @@ -0,0 +1,5 @@ +// Simplified Chinese lang variables contributed by cube316 (cube316@gmail.com) +// http://www.cube316.net/ ԻȡTinyMCE֧ + +tinyMCELang['lang_directionality_ltr_desc'] = 'ҵķ' +tinyMCELang['lang_directionality_rtl_desc'] = 'ķ'; diff --git a/public/tiny_mce/plugins/directionality/readme.txt b/public/tiny_mce/plugins/directionality/readme.txt new file mode 100644 index 0000000..c1cae7e --- /dev/null +++ b/public/tiny_mce/plugins/directionality/readme.txt @@ -0,0 +1,16 @@ + Directionality plugin for TinyMCE +------------------------------ + +This plugin adds directionality icons to TinyMCE that enables TinyMCE to better handle languages that is written from right to left. + +Installation instructions: + * Add plugin to TinyMCE plugin option list example: plugins : "directionality". + * Add the ltr, rtl button names to button list, example: theme_advanced_buttons3_add : "ltr,rtl". + +Initialization example: + tinyMCE.init({ + theme : "advanced", + mode : "textareas", + plugins : "directionality", + theme_advanced_buttons3_add : "ltr,rtl" + }); diff --git a/public/tiny_mce/plugins/emotions/editor_plugin.js b/public/tiny_mce/plugins/emotions/editor_plugin.js new file mode 100644 index 0000000..84d0edc --- /dev/null +++ b/public/tiny_mce/plugins/emotions/editor_plugin.js @@ -0,0 +1,2 @@ +/* Import plugin specific language pack */ + tinyMCE.importPluginLanguagePack('emotions','en,sv,zh_cn,cs,fa,fr_ca,fr,de,pl,pt_br');function TinyMCE_emotions_getControlHTML(control_name){switch(control_name){case "emotions":return '';}return "";}function TinyMCE_emotions_execCommand(editor_id,element,command,user_interface,value){switch(command){case "mceEmotion":var template=new Array();template['file']='../../plugins/emotions/emotions.htm';template['width']=150;template['height']=180;tinyMCE.openWindow(template,{editor_id:editor_id});return true;}return false;} \ No newline at end of file diff --git a/public/tiny_mce/plugins/emotions/editor_plugin_src.js b/public/tiny_mce/plugins/emotions/editor_plugin_src.js new file mode 100644 index 0000000..69f5129 --- /dev/null +++ b/public/tiny_mce/plugins/emotions/editor_plugin_src.js @@ -0,0 +1,36 @@ +/* Import plugin specific language pack */ +tinyMCE.importPluginLanguagePack('emotions', 'en,sv,zh_cn,cs,fa,fr_ca,fr,de,pl,pt_br'); + +/** + * Returns the HTML contents of the emotions control. + */ +function TinyMCE_emotions_getControlHTML(control_name) { + switch (control_name) { + case "emotions": + return ''; + } + + return ""; +} + +/** + * Executes the mceEmotion command. + */ +function TinyMCE_emotions_execCommand(editor_id, element, command, user_interface, value) { + // Handle commands + switch (command) { + case "mceEmotion": + var template = new Array(); + + template['file'] = '../../plugins/emotions/emotions.htm'; // Relative to theme + template['width'] = 150; + template['height'] = 180; + + tinyMCE.openWindow(template, {editor_id : editor_id}); + + return true; + } + + // Pass to next handler in chain + return false; +} diff --git a/public/tiny_mce/plugins/emotions/emotions.htm b/public/tiny_mce/plugins/emotions/emotions.htm new file mode 100644 index 0000000..5466dba --- /dev/null +++ b/public/tiny_mce/plugins/emotions/emotions.htm @@ -0,0 +1,45 @@ + + +{$lang_insert_emotions_title} + + + + +
    +
    {$lang_insert_emotions_title}:

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + diff --git a/public/tiny_mce/plugins/emotions/images/emotions.gif b/public/tiny_mce/plugins/emotions/images/emotions.gif new file mode 100644 index 0000000..d34f0e0 Binary files /dev/null and b/public/tiny_mce/plugins/emotions/images/emotions.gif differ diff --git a/public/tiny_mce/plugins/emotions/images/readme.txt b/public/tiny_mce/plugins/emotions/images/readme.txt new file mode 100644 index 0000000..a3cea1b --- /dev/null +++ b/public/tiny_mce/plugins/emotions/images/readme.txt @@ -0,0 +1,2 @@ +These emotions where taken from Mozilla Thunderbird. +I hope they don't get angry if I use them here after all this is a open source project aswell. diff --git a/public/tiny_mce/plugins/emotions/images/smiley-cool.gif b/public/tiny_mce/plugins/emotions/images/smiley-cool.gif new file mode 100644 index 0000000..1e2c1d6 Binary files /dev/null and b/public/tiny_mce/plugins/emotions/images/smiley-cool.gif differ diff --git a/public/tiny_mce/plugins/emotions/images/smiley-cry.gif b/public/tiny_mce/plugins/emotions/images/smiley-cry.gif new file mode 100644 index 0000000..e0dcf8a Binary files /dev/null and b/public/tiny_mce/plugins/emotions/images/smiley-cry.gif differ diff --git a/public/tiny_mce/plugins/emotions/images/smiley-embarassed.gif b/public/tiny_mce/plugins/emotions/images/smiley-embarassed.gif new file mode 100644 index 0000000..8e3f07a Binary files /dev/null and b/public/tiny_mce/plugins/emotions/images/smiley-embarassed.gif differ diff --git a/public/tiny_mce/plugins/emotions/images/smiley-foot-in-mouth.gif b/public/tiny_mce/plugins/emotions/images/smiley-foot-in-mouth.gif new file mode 100644 index 0000000..b3e47cc Binary files /dev/null and b/public/tiny_mce/plugins/emotions/images/smiley-foot-in-mouth.gif differ diff --git a/public/tiny_mce/plugins/emotions/images/smiley-frown.gif b/public/tiny_mce/plugins/emotions/images/smiley-frown.gif new file mode 100644 index 0000000..9335e99 Binary files /dev/null and b/public/tiny_mce/plugins/emotions/images/smiley-frown.gif differ diff --git a/public/tiny_mce/plugins/emotions/images/smiley-innocent.gif b/public/tiny_mce/plugins/emotions/images/smiley-innocent.gif new file mode 100644 index 0000000..cdb7256 Binary files /dev/null and b/public/tiny_mce/plugins/emotions/images/smiley-innocent.gif differ diff --git a/public/tiny_mce/plugins/emotions/images/smiley-kiss.gif b/public/tiny_mce/plugins/emotions/images/smiley-kiss.gif new file mode 100644 index 0000000..242c38c Binary files /dev/null and b/public/tiny_mce/plugins/emotions/images/smiley-kiss.gif differ diff --git a/public/tiny_mce/plugins/emotions/images/smiley-laughing.gif b/public/tiny_mce/plugins/emotions/images/smiley-laughing.gif new file mode 100644 index 0000000..09a9ec7 Binary files /dev/null and b/public/tiny_mce/plugins/emotions/images/smiley-laughing.gif differ diff --git a/public/tiny_mce/plugins/emotions/images/smiley-money-mouth.gif b/public/tiny_mce/plugins/emotions/images/smiley-money-mouth.gif new file mode 100644 index 0000000..12b1138 Binary files /dev/null and b/public/tiny_mce/plugins/emotions/images/smiley-money-mouth.gif differ diff --git a/public/tiny_mce/plugins/emotions/images/smiley-sealed.gif b/public/tiny_mce/plugins/emotions/images/smiley-sealed.gif new file mode 100644 index 0000000..76002b2 Binary files /dev/null and b/public/tiny_mce/plugins/emotions/images/smiley-sealed.gif differ diff --git a/public/tiny_mce/plugins/emotions/images/smiley-smile.gif b/public/tiny_mce/plugins/emotions/images/smiley-smile.gif new file mode 100644 index 0000000..8cf2b5d Binary files /dev/null and b/public/tiny_mce/plugins/emotions/images/smiley-smile.gif differ diff --git a/public/tiny_mce/plugins/emotions/images/smiley-surprised.gif b/public/tiny_mce/plugins/emotions/images/smiley-surprised.gif new file mode 100644 index 0000000..ece78a3 Binary files /dev/null and b/public/tiny_mce/plugins/emotions/images/smiley-surprised.gif differ diff --git a/public/tiny_mce/plugins/emotions/images/smiley-tongue-out.gif b/public/tiny_mce/plugins/emotions/images/smiley-tongue-out.gif new file mode 100644 index 0000000..16b13a5 Binary files /dev/null and b/public/tiny_mce/plugins/emotions/images/smiley-tongue-out.gif differ diff --git a/public/tiny_mce/plugins/emotions/images/smiley-undecided.gif b/public/tiny_mce/plugins/emotions/images/smiley-undecided.gif new file mode 100644 index 0000000..2aec732 Binary files /dev/null and b/public/tiny_mce/plugins/emotions/images/smiley-undecided.gif differ diff --git a/public/tiny_mce/plugins/emotions/images/smiley-wink.gif b/public/tiny_mce/plugins/emotions/images/smiley-wink.gif new file mode 100644 index 0000000..5d975f6 Binary files /dev/null and b/public/tiny_mce/plugins/emotions/images/smiley-wink.gif differ diff --git a/public/tiny_mce/plugins/emotions/images/smiley-yell.gif b/public/tiny_mce/plugins/emotions/images/smiley-yell.gif new file mode 100644 index 0000000..7719bc4 Binary files /dev/null and b/public/tiny_mce/plugins/emotions/images/smiley-yell.gif differ diff --git a/public/tiny_mce/plugins/emotions/langs/cs.js b/public/tiny_mce/plugins/emotions/langs/cs.js new file mode 100644 index 0000000..90d1c8b --- /dev/null +++ b/public/tiny_mce/plugins/emotions/langs/cs.js @@ -0,0 +1,4 @@ +// UK lang variables + +tinyMCELang['lang_insert_emotions_title'] = 'Vloit emotikon'; +tinyMCELang['lang_emotions_desc'] = 'Emotikony'; diff --git a/public/tiny_mce/plugins/emotions/langs/de.js b/public/tiny_mce/plugins/emotions/langs/de.js new file mode 100644 index 0000000..e828c76 --- /dev/null +++ b/public/tiny_mce/plugins/emotions/langs/de.js @@ -0,0 +1,6 @@ +// DE lang variables + + +tinyMCELang['lang_insert_emotions_title'] = 'Emotion einfügen'; +tinyMCELang['lang_emotions_desc'] = 'Emotion'; + diff --git a/public/tiny_mce/plugins/emotions/langs/el.js b/public/tiny_mce/plugins/emotions/langs/el.js new file mode 100644 index 0000000..607433f --- /dev/null +++ b/public/tiny_mce/plugins/emotions/langs/el.js @@ -0,0 +1,5 @@ +// Greek lang variables by Jacaranda Bill + +tinyMCELang['lang_insert_emotions_title'] = ' emoticon'; +tinyMCELang['lang_emotions_desc'] = ' emoticons'; + diff --git a/public/tiny_mce/plugins/emotions/langs/en.js b/public/tiny_mce/plugins/emotions/langs/en.js new file mode 100644 index 0000000..37f549f --- /dev/null +++ b/public/tiny_mce/plugins/emotions/langs/en.js @@ -0,0 +1,5 @@ +// UK lang variables + +tinyMCELang['lang_insert_emotions_title'] = 'Insert emotion'; +tinyMCELang['lang_emotions_desc'] = 'Emotions'; + diff --git a/public/tiny_mce/plugins/emotions/langs/fa.js b/public/tiny_mce/plugins/emotions/langs/fa.js new file mode 100644 index 0000000..fe7db9e --- /dev/null +++ b/public/tiny_mce/plugins/emotions/langs/fa.js @@ -0,0 +1,10 @@ +// IR lang variables +// Persian (Farsi) language pack (for IRAN) +// By: Morteza Zafari +// Lost@LostLord.com +// http://www.LostLord.com + +tinyMCELang['lang_dir'] = 'rtl'; +tinyMCELang['lang_insert_emotions_title'] = 'افزودن شکلک'; +tinyMCELang['lang_emotions_desc'] = 'شکلکها'; + diff --git a/public/tiny_mce/plugins/emotions/langs/fr.js b/public/tiny_mce/plugins/emotions/langs/fr.js new file mode 100644 index 0000000..b2dbedb --- /dev/null +++ b/public/tiny_mce/plugins/emotions/langs/fr.js @@ -0,0 +1,5 @@ +// French lang variables by Laurent Dran + +tinyMCELang['lang_insert_emotions_title'] = 'Insèrer un émoticon'; +tinyMCELang['lang_emotions_desc'] = 'Émoticons'; + diff --git a/public/tiny_mce/plugins/emotions/langs/fr_ca.js b/public/tiny_mce/plugins/emotions/langs/fr_ca.js new file mode 100644 index 0000000..1e8d362 --- /dev/null +++ b/public/tiny_mce/plugins/emotions/langs/fr_ca.js @@ -0,0 +1,5 @@ +// CAN_FR lang variables + +tinyMCELang['lang_insert_emotions_title'] = 'Insrer un moticon'; +tinyMCELang['lang_emotions_desc'] = 'moticons'; + diff --git a/public/tiny_mce/plugins/emotions/langs/it.js b/public/tiny_mce/plugins/emotions/langs/it.js new file mode 100644 index 0000000..fa93e6b --- /dev/null +++ b/public/tiny_mce/plugins/emotions/langs/it.js @@ -0,0 +1,5 @@ +//IT lang variables + +tinyMCELang['lang_insert_emotions_title'] = 'Inserisci una emoticon'; +tinyMCELang['lang_emotions_desc'] = 'Emoticon'; + diff --git a/public/tiny_mce/plugins/emotions/langs/ko.js b/public/tiny_mce/plugins/emotions/langs/ko.js new file mode 100644 index 0000000..654193f --- /dev/null +++ b/public/tiny_mce/plugins/emotions/langs/ko.js @@ -0,0 +1,5 @@ +// KO lang variables + +tinyMCELang['lang_insert_emotions_title'] = '̸Ƽ ֱ'; +tinyMCELang['lang_emotions_desc'] = '̸Ƽ'; + diff --git a/public/tiny_mce/plugins/emotions/langs/pl.js b/public/tiny_mce/plugins/emotions/langs/pl.js new file mode 100644 index 0000000..63996c9 --- /dev/null +++ b/public/tiny_mce/plugins/emotions/langs/pl.js @@ -0,0 +1,4 @@ +// PL lang variables + +tinyMCELang['lang_insert_emotions_title'] = 'Wstaw emtoiconę'; +tinyMCELang['lang_emotions_desc'] = 'Emtoicony'; \ No newline at end of file diff --git a/public/tiny_mce/plugins/emotions/langs/pt_br.js b/public/tiny_mce/plugins/emotions/langs/pt_br.js new file mode 100644 index 0000000..a9fc32e --- /dev/null +++ b/public/tiny_mce/plugins/emotions/langs/pt_br.js @@ -0,0 +1,5 @@ +// pt_BR lang variables + +tinyMCELang['lang_insert_emotions_title'] = 'Inserir Emoticon'; +tinyMCELang['lang_emotions_desc'] = 'Emoticons'; + diff --git a/public/tiny_mce/plugins/emotions/langs/sv.js b/public/tiny_mce/plugins/emotions/langs/sv.js new file mode 100644 index 0000000..82e1ba3 --- /dev/null +++ b/public/tiny_mce/plugins/emotions/langs/sv.js @@ -0,0 +1,4 @@ +// SE lang variables + +tinyMCELang['lang_insert_emotions_title'] = 'Klistra in knsla'; +tinyMCELang['lang_emotions_desc'] = 'Knslor'; diff --git a/public/tiny_mce/plugins/emotions/langs/zh_cn.js b/public/tiny_mce/plugins/emotions/langs/zh_cn.js new file mode 100644 index 0000000..cdd4896 --- /dev/null +++ b/public/tiny_mce/plugins/emotions/langs/zh_cn.js @@ -0,0 +1,6 @@ +// Simplified Chinese lang variables contributed by cube316 (cube316@gmail.com) +// http://www.cube316.net/ ԻȡTinyMCE֧ + +tinyMCELang['lang_insert_emotions_title'] = ''; +tinyMCELang['lang_emotions_desc'] = ''; + diff --git a/public/tiny_mce/plugins/emotions/readme.txt b/public/tiny_mce/plugins/emotions/readme.txt new file mode 100644 index 0000000..e2fdeb5 --- /dev/null +++ b/public/tiny_mce/plugins/emotions/readme.txt @@ -0,0 +1,20 @@ + Emotions plugin for TinyMCE +------------------------------ + +Installation instructions: + * Copy the emotions directory to the plugins directory of TinyMCE (/jscripts/tiny_mce/plugins). + * Add plugin to TinyMCE plugin option list example: plugins : "emotions". + * Add the emotions button name to button list, example: theme_advanced_buttons3_add : "emotions". + +Initialization example: + tinyMCE.init({ + theme : "advanced", + mode : "textareas", + plugins : "emotions", + theme_advanced_buttons3_add : "emotions" + }); + +Copyright notice: + These emotions where taken from Mozilla Thunderbird. + I hope they don't get angry if I use them here after all this is a open source project + aswell and I realy love their product. diff --git a/public/tiny_mce/plugins/flash/editor_plugin.js b/public/tiny_mce/plugins/flash/editor_plugin.js new file mode 100644 index 0000000..82ec648 --- /dev/null +++ b/public/tiny_mce/plugins/flash/editor_plugin.js @@ -0,0 +1,2 @@ +/* Import plugin specific language pack */ + tinyMCE.importPluginLanguagePack('flash','en,de,sv,zh_cn,cs,fa,fr_ca,fr,pl,pt_br');function TinyMCE_flash_initInstance(inst){if(!tinyMCE.settings['flash_skip_plugin_css'])tinyMCE.importCSS(inst.getDoc(),tinyMCE.baseURL+"/plugins/flash/flash.css");}function TinyMCE_flash_getControlHTML(control_name){switch(control_name){case "flash":return '';}return "";}function TinyMCE_flash_parseAttributes(attribute_string){var attributeName="";var attributeValue="";var withInName;var withInValue;var attributes=new Array();var whiteSpaceRegExp=new RegExp('^[ \n\r\t]+','g');if(attribute_string==null||attribute_string.length<2)return null;withInName=withInValue=false;for(var i=0;i','gi'),'');content=content.replace(new RegExp('<[ ]*object','gi'),'','gi'),'');while((startPos=content.indexOf('',startPos);var attribs=TinyMCE_flash_parseAttributes(content.substring(startPos+6,endPos));embedList[embedList.length]=attribs;}var index=0;while((startPos=content.indexOf('=embedList.length)break;var attribs=embedList[index];endPos=content.indexOf('',startPos);endPos+=9;var contentAfter=content.substring(endPos);content=content.substring(0,startPos);content+=''+content.substring(endPos);content+=contentAfter;index++;startPos++;}break;case "get_from_editor":var startPos=-1;while((startPos=content.indexOf('',startPos);var attribs=TinyMCE_flash_parseAttributes(content.substring(startPos+4,endPos));if(attribs['name']!="mce_plugin_flash")continue;endPos+=2;var embedHTML='';embedHTML+='';embedHTML+='';embedHTML+='';embedHTML+='';embedHTML+='';chunkBefore=content.substring(0,startPos);chunkAfter=content.substring(endPos);content=chunkBefore+embedHTML+chunkAfter;}break;}return content;}function TinyMCE_flash_handleNodeChange(editor_id,node,undo_index,undo_levels,visual_aid,any_selection){function getAttrib(elm,name){return elm.getAttribute(name)?elm.getAttribute(name):"";}tinyMCE.switchClassSticky(editor_id+'_flash','mceButtonNormal');if(node==null)return;do{if(node.nodeName.toLowerCase()=="img"&&getAttrib(node,'name').indexOf('mce_plugin_flash')==0)tinyMCE.switchClassSticky(editor_id+'_flash','mceButtonSelected');}while((node=node.parentNode));return true;} \ No newline at end of file diff --git a/public/tiny_mce/plugins/flash/editor_plugin_src.js b/public/tiny_mce/plugins/flash/editor_plugin_src.js new file mode 100644 index 0000000..3de1762 --- /dev/null +++ b/public/tiny_mce/plugins/flash/editor_plugin_src.js @@ -0,0 +1,225 @@ +/* Import plugin specific language pack */ +tinyMCE.importPluginLanguagePack('flash', 'en,de,sv,zh_cn,cs,fa,fr_ca,fr,pl,pt_br'); + +function TinyMCE_flash_initInstance(inst) { + if (!tinyMCE.settings['flash_skip_plugin_css']) + tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/plugins/flash/flash.css"); +} + +function TinyMCE_flash_getControlHTML(control_name) { + switch (control_name) { + case "flash": + return ''; + } + + return ""; +} + +function TinyMCE_flash_parseAttributes(attribute_string) { + var attributeName = ""; + var attributeValue = ""; + var withInName; + var withInValue; + var attributes = new Array(); + var whiteSpaceRegExp = new RegExp('^[ \n\r\t]+', 'g'); + + if (attribute_string == null || attribute_string.length < 2) + return null; + + withInName = withInValue = false; + + for (var i=0; i','gi'),''); + content = content.replace(new RegExp('<[ ]*object','gi'),'','gi'),''); + + // Parse all embed tags + while ((startPos = content.indexOf('', startPos); + var attribs = TinyMCE_flash_parseAttributes(content.substring(startPos + 6, endPos)); + embedList[embedList.length] = attribs; + } + + // Parse all object tags and replace them with images from the embed data + var index = 0; + while ((startPos = content.indexOf('= embedList.length) + break; + + var attribs = embedList[index]; + + // Find end of object + endPos = content.indexOf('', startPos); + endPos += 9; + + // Insert image + var contentAfter = content.substring(endPos); + content = content.substring(0, startPos); + content += '' + content.substring(endPos); + content += contentAfter; + index++; + + startPos++; + } + break; + + case "get_from_editor": + // Parse all img tags and replace them with object+embed + var startPos = -1; + while ((startPos = content.indexOf('', startPos); + var attribs = TinyMCE_flash_parseAttributes(content.substring(startPos + 4, endPos)); + + // Is not flash, skip it + if (attribs['name'] != "mce_plugin_flash") + continue; + + endPos += 2; + + var embedHTML = ''; + + // Insert object + embed + embedHTML += ''; + embedHTML += ''; + embedHTML += ''; + embedHTML += ''; + embedHTML += ''; + + // Insert embed/object chunk + chunkBefore = content.substring(0, startPos); + chunkAfter = content.substring(endPos); + content = chunkBefore + embedHTML + chunkAfter; + } + break; + } + + // Pass through to next handler in chain + return content; +} + +function TinyMCE_flash_handleNodeChange(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) { + function getAttrib(elm, name) { + return elm.getAttribute(name) ? elm.getAttribute(name) : ""; + } + + tinyMCE.switchClassSticky(editor_id + '_flash', 'mceButtonNormal'); + + if (node == null) + return; + + do { + if (node.nodeName.toLowerCase() == "img" && getAttrib(node, 'name').indexOf('mce_plugin_flash') == 0) + tinyMCE.switchClassSticky(editor_id + '_flash', 'mceButtonSelected'); + } while ((node = node.parentNode)); + + return true; +} diff --git a/public/tiny_mce/plugins/flash/flash.css b/public/tiny_mce/plugins/flash/flash.css new file mode 100644 index 0000000..a05f373 --- /dev/null +++ b/public/tiny_mce/plugins/flash/flash.css @@ -0,0 +1,7 @@ +.mce_plugin_flash { + border: 1px dotted #cc0000; + background-image: url(images/flash.gif); + background-position: center; + background-repeat: no-repeat; + background-color: #ffffcc; +} diff --git a/public/tiny_mce/plugins/flash/flash.htm b/public/tiny_mce/plugins/flash/flash.htm new file mode 100644 index 0000000..139c9ca --- /dev/null +++ b/public/tiny_mce/plugins/flash/flash.htm @@ -0,0 +1,182 @@ + + +{$lang_insert_flash} + + + + + + +
    + + + + + + + + + + + + + + + +
    {$lang_insert_flash}

    + + + + + + + + + + + +
    {$lang_insert_flash_file}: + + + + + +
    +
    {$lang_insert_flash_size}: + +  x  + +

    + +
    +
    + + diff --git a/public/tiny_mce/plugins/flash/images/flash.gif b/public/tiny_mce/plugins/flash/images/flash.gif new file mode 100644 index 0000000..4950e67 Binary files /dev/null and b/public/tiny_mce/plugins/flash/images/flash.gif differ diff --git a/public/tiny_mce/plugins/flash/langs/cs.js b/public/tiny_mce/plugins/flash/langs/cs.js new file mode 100644 index 0000000..29e46f3 --- /dev/null +++ b/public/tiny_mce/plugins/flash/langs/cs.js @@ -0,0 +1,7 @@ +// CS lang variables + +tinyMCELang['lang_insert_flash'] = 'Vloit/editovat Flash Movie'; +tinyMCELang['lang_insert_flash_file'] = 'Flash soubor (.swf)'; +tinyMCELang['lang_insert_flash_size'] = 'Velikost'; +tinyMCELang['lang_insert_flash_list'] = 'Seznam'; +tinyMCELang['lang_flash_props'] = 'Vlastnosti Flash'; diff --git a/public/tiny_mce/plugins/flash/langs/de.js b/public/tiny_mce/plugins/flash/langs/de.js new file mode 100644 index 0000000..e20613e --- /dev/null +++ b/public/tiny_mce/plugins/flash/langs/de.js @@ -0,0 +1,7 @@ +// DE lang variables + +tinyMCELang['lang_insert_flash'] = 'Flash Movie einfügen / bearbeiten'; +tinyMCELang['lang_insert_flash_file'] = 'Flash-Datei'; +tinyMCELang['lang_insert_flash_size'] = 'Größe'; +tinyMCELang['lang_insert_flash_list'] = 'Flash Dateien'; +tinyMCELang['lang_flash_props'] = 'Flash properties'; diff --git a/public/tiny_mce/plugins/flash/langs/en.js b/public/tiny_mce/plugins/flash/langs/en.js new file mode 100644 index 0000000..91befcd --- /dev/null +++ b/public/tiny_mce/plugins/flash/langs/en.js @@ -0,0 +1,7 @@ +// UK lang variables + +tinyMCELang['lang_insert_flash'] = 'Insert / edit Flash Movie'; +tinyMCELang['lang_insert_flash_file'] = 'Flash-File (.swf)'; +tinyMCELang['lang_insert_flash_size'] = 'Size'; +tinyMCELang['lang_insert_flash_list'] = 'Flash files'; +tinyMCELang['lang_flash_props'] = 'Flash properties'; diff --git a/public/tiny_mce/plugins/flash/langs/fa.js b/public/tiny_mce/plugins/flash/langs/fa.js new file mode 100644 index 0000000..d146add --- /dev/null +++ b/public/tiny_mce/plugins/flash/langs/fa.js @@ -0,0 +1,11 @@ +// IR lang variables +// Persian (Farsi) language pack (for IRAN) +// By: Morteza Zafari +// Lost@LostLord.com +// http://www.LostLord.com + +tinyMCELang['lang_dir'] = 'rtl'; +tinyMCELang['lang_insert_flash'] = '?????? ? ?????? ???? ???'; +tinyMCELang['lang_insert_flash_file'] = '???? ??? (.swf)'; +tinyMCELang['lang_insert_flash_size'] = '?????'; +tinyMCELang['lang_flash_props'] = 'Flash properties'; diff --git a/public/tiny_mce/plugins/flash/langs/fr.js b/public/tiny_mce/plugins/flash/langs/fr.js new file mode 100644 index 0000000..afeede5 --- /dev/null +++ b/public/tiny_mce/plugins/flash/langs/fr.js @@ -0,0 +1,7 @@ +// French lang variables by Laurent Dran + +tinyMCELang['lang_insert_flash'] = 'Insérer / éditer une animation Flash'; +tinyMCELang['lang_insert_flash_file'] = 'Fichier-Flash (.swf)'; +tinyMCELang['lang_insert_flash_size'] = 'Taille'; +tinyMCELang['lang_insert_flash_list'] = 'Fichiers Flash'; +tinyMCELang['lang_flash_props'] = 'Flash properties'; diff --git a/public/tiny_mce/plugins/flash/langs/fr_ca.js b/public/tiny_mce/plugins/flash/langs/fr_ca.js new file mode 100644 index 0000000..a4e2c6e --- /dev/null +++ b/public/tiny_mce/plugins/flash/langs/fr_ca.js @@ -0,0 +1,6 @@ +// CA_FR lang variables + +tinyMCELang['lang_insert_flash'] = 'Insrer / Modifier une animation Flash'; +tinyMCELang['lang_insert_flash_file'] = 'Fichier Flash (.swf)'; +tinyMCELang['lang_insert_flash_size'] = 'Dimension'; +tinyMCELang['lang_flash_props'] = 'Flash properties'; diff --git a/public/tiny_mce/plugins/flash/langs/pl.js b/public/tiny_mce/plugins/flash/langs/pl.js new file mode 100644 index 0000000..7965baa --- /dev/null +++ b/public/tiny_mce/plugins/flash/langs/pl.js @@ -0,0 +1,7 @@ +// PL lang variables + +tinyMCELang['lang_insert_flash'] = 'Wstaw/Edytuj animację Flash'; +tinyMCELang['lang_insert_flash_file'] = 'Plik Flash (.swf)'; +tinyMCELang['lang_insert_flash_size'] = 'Rozmiar'; +tinyMCELang['lang_insert_flash_list'] = 'Pliki Flash'; +tinyMCELang['lang_flash_props'] = 'Właściwości animacji Flash'; \ No newline at end of file diff --git a/public/tiny_mce/plugins/flash/langs/pt_br.js b/public/tiny_mce/plugins/flash/langs/pt_br.js new file mode 100644 index 0000000..b7ed73d --- /dev/null +++ b/public/tiny_mce/plugins/flash/langs/pt_br.js @@ -0,0 +1,7 @@ +// pt_BR lang variables + +tinyMCELang['lang_insert_flash'] = 'Inserir / editar Arquivo Flash'; +tinyMCELang['lang_insert_flash_file'] = 'Arquivo Flash (.swf)'; +tinyMCELang['lang_insert_flash_size'] = 'Tamanho'; +tinyMCELang['lang_insert_flash_list'] = 'Lista de arquivos Flash'; +tinyMCELang['lang_flash_props'] = 'Propriedades Flash'; diff --git a/public/tiny_mce/plugins/flash/langs/sv.js b/public/tiny_mce/plugins/flash/langs/sv.js new file mode 100644 index 0000000..44b5b30 --- /dev/null +++ b/public/tiny_mce/plugins/flash/langs/sv.js @@ -0,0 +1,7 @@ +// SE lang variables + +tinyMCELang['lang_insert_flash'] = 'Skapa/uppdatera flash-film'; +tinyMCELang['lang_insert_flash_file'] = 'Flash-film (.swf)'; +tinyMCELang['lang_insert_flash_size'] = 'Storlek'; +tinyMCELang['lang_insert_flash_list'] = 'Flash-filer'; +tinyMCELang['lang_flash_props'] = 'Flash egenskaper'; diff --git a/public/tiny_mce/plugins/flash/langs/zh_cn.js b/public/tiny_mce/plugins/flash/langs/zh_cn.js new file mode 100644 index 0000000..4b5a270 --- /dev/null +++ b/public/tiny_mce/plugins/flash/langs/zh_cn.js @@ -0,0 +1,8 @@ +// Simplified Chinese lang variables contributed by cube316 (cube316@gmail.com) +// http://www.cube316.net/ ԻȡTinyMCE֧ + +tinyMCELang['lang_insert_flash'] = '/༭ FlashӰ'; +tinyMCELang['lang_insert_flash_file'] = 'Flashļ(.swf)'; +tinyMCELang['lang_insert_flash_size'] = 'ߴ'; +tinyMCELang['lang_insert_flash_list'] = 'Flashļб'; +tinyMCELang['lang_flash_props'] = 'Flash'; diff --git a/public/tiny_mce/plugins/flash/readme.txt b/public/tiny_mce/plugins/flash/readme.txt new file mode 100644 index 0000000..b868a9f --- /dev/null +++ b/public/tiny_mce/plugins/flash/readme.txt @@ -0,0 +1,48 @@ + FLASH plugin for TinyMCE +----------------------------- + +About: + This is the INSERT FLASH Dialog contributed by Michael Keck. + This one supports popup windows and targets. + +Note: + The placeholder for Flash is called 'mce_plugin_flash' and needs a class 'mce_plugin_flash' in the 'css_-style'. + Do not name another image 'name="mce_plugin_flash"! + +Installation instructions: + * Copy the flash directory to the plugins directory of TinyMCE (/jscripts/tiny_mce/plugins). + * Add plugin to TinyMCE plugin option list example: plugins : "flash". + * Add this "img[class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name]" to extended_valid_elements option. + +Initialization example: + tinyMCE.init({ + theme : "advanced", + mode : "textareas", + plugins : "flash", + extended_valid_elements : "img[class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name]" + flash_external_list_url : "example_flash_list.js" // Optional URL to a list of Flash movies + }); + + +---------------------------------------------------------------- +ADDITIONAL NOTE: + +The flash plugin has been heavily modified (the original is editor_plugin_original.js) since the original did not play nicely with html content that +already contained existing flash tags and in fact stripped out the object +tags for existing flash html. The rewrite corrects this as well attempts +to preserve the existing flash tags where possible. The tinyMCE.init call +should be be something like: + +Initialization example: + tinyMCE.init({ + theme : "advanced", + mode : "textareas", + plugins : "flash", + extended_valid_elements : "img[class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name|obj|param|embed]" + }); + +Note the extra obj,param,embed attributes for the img tag. These attributes +are used to serialize data from existing flash tags so that they can be +properly restored. Editing a flash tag with the plugin will cause this +information to be lost (sorry !) but still produces a working flash nevertheless. + diff --git a/public/tiny_mce/plugins/fullscreen/editor_plugin.js b/public/tiny_mce/plugins/fullscreen/editor_plugin.js new file mode 100644 index 0000000..8cb83d3 --- /dev/null +++ b/public/tiny_mce/plugins/fullscreen/editor_plugin.js @@ -0,0 +1,2 @@ +/* Import plugin specific language pack */ + tinyMCE.importPluginLanguagePack('fullscreen','en,sv,cs');function TinyMCE_fullscreen_getControlHTML(control_name){switch(control_name){case "fullscreen":return '';}return "";}function TinyMCE_fullscreen_execCommand(editor_id,element,command,user_interface,value){switch(command){case "mceFullScreen":if(tinyMCE.getParam('fullscreen_is_enabled')){window.opener.tinyMCE.execInstanceCommand(tinyMCE.getParam('fullscreen_editor_id'),'mceSetContent',false,tinyMCE.getContent(editor_id));top.close();}else{tinyMCE.setWindowArg('editor_id',editor_id);var win=window.open(tinyMCE.baseURL+"/plugins/fullscreen/fullscreen.htm","mceFullScreenPopup","fullscreen=yes,menubar=no,toolbar=no,scrollbars=no,resizable=yes,left=0,top=0,width="+screen.availWidth+",height="+screen.availHeight);}return true;}return false;} \ No newline at end of file diff --git a/public/tiny_mce/plugins/fullscreen/editor_plugin_src.js b/public/tiny_mce/plugins/fullscreen/editor_plugin_src.js new file mode 100644 index 0000000..de9bcba --- /dev/null +++ b/public/tiny_mce/plugins/fullscreen/editor_plugin_src.js @@ -0,0 +1,34 @@ +/* Import plugin specific language pack */ +tinyMCE.importPluginLanguagePack('fullscreen', 'en,sv,cs'); + +function TinyMCE_fullscreen_getControlHTML(control_name) { + switch (control_name) { + case "fullscreen": + return ''; + } + + return ""; +} + +function TinyMCE_fullscreen_execCommand(editor_id, element, command, user_interface, value) { + // Handle commands + switch (command) { + case "mceFullScreen": + if (tinyMCE.getParam('fullscreen_is_enabled')) { + // In fullscreen mode + window.opener.tinyMCE.execInstanceCommand(tinyMCE.getParam('fullscreen_editor_id'), 'mceSetContent', false, tinyMCE.getContent(editor_id)); + top.close(); + } else { + tinyMCE.setWindowArg('editor_id', editor_id); + + var win = window.open(tinyMCE.baseURL + "/plugins/fullscreen/fullscreen.htm", "mceFullScreenPopup", "fullscreen=yes,menubar=no,toolbar=no,scrollbars=no,resizable=yes,left=0,top=0,width=" + screen.availWidth + ",height=" + screen.availHeight); + } + + return true; + } + + // Pass to next handler in chain + return false; +} + + diff --git a/public/tiny_mce/plugins/fullscreen/fullscreen.htm b/public/tiny_mce/plugins/fullscreen/fullscreen.htm new file mode 100644 index 0000000..30644e6 --- /dev/null +++ b/public/tiny_mce/plugins/fullscreen/fullscreen.htm @@ -0,0 +1,72 @@ + + + + + + + + + + + + + diff --git a/public/tiny_mce/plugins/fullscreen/images/fullscreen.gif b/public/tiny_mce/plugins/fullscreen/images/fullscreen.gif new file mode 100644 index 0000000..850ff8d Binary files /dev/null and b/public/tiny_mce/plugins/fullscreen/images/fullscreen.gif differ diff --git a/public/tiny_mce/plugins/fullscreen/langs/cs.js b/public/tiny_mce/plugins/fullscreen/langs/cs.js new file mode 100644 index 0000000..04b8b2d --- /dev/null +++ b/public/tiny_mce/plugins/fullscreen/langs/cs.js @@ -0,0 +1,4 @@ +// CS lang variables + +tinyMCELang['lang_fullscreen_title'] = 'Fullscreen'; +tinyMCELang['lang_fullscreen_desc'] = 'Pr(epnout na fullscreen'; diff --git a/public/tiny_mce/plugins/fullscreen/langs/en.js b/public/tiny_mce/plugins/fullscreen/langs/en.js new file mode 100644 index 0000000..7cfe92d --- /dev/null +++ b/public/tiny_mce/plugins/fullscreen/langs/en.js @@ -0,0 +1,4 @@ +// UK lang variables + +tinyMCELang['lang_fullscreen_title'] = 'Fullscreen mode' +tinyMCELang['lang_fullscreen_desc'] = 'Toggle fullscreen mode' diff --git a/public/tiny_mce/plugins/fullscreen/langs/sv.js b/public/tiny_mce/plugins/fullscreen/langs/sv.js new file mode 100644 index 0000000..9215295 --- /dev/null +++ b/public/tiny_mce/plugins/fullscreen/langs/sv.js @@ -0,0 +1,4 @@ +// SV lang variables + +tinyMCELang['lang_fullscreen_title'] = 'Fullskärmsläge' +tinyMCELang['lang_fullscreen_desc'] = 'Hoppa från/till fullskärmsläge' diff --git a/public/tiny_mce/plugins/fullscreen/langs/zh_cn.js b/public/tiny_mce/plugins/fullscreen/langs/zh_cn.js new file mode 100644 index 0000000..6572603 --- /dev/null +++ b/public/tiny_mce/plugins/fullscreen/langs/zh_cn.js @@ -0,0 +1,5 @@ +// Simplified Chinese lang variables contributed by cube316 (cube316@gmail.com) +// http://www.cube316.net/ ԻȡTinyMCE֧ + +tinyMCELang['lang_fullscreen_title'] = 'ȫģʽ' +tinyMCELang['lang_fullscreen_desc'] = 'лȫģʽ' diff --git a/public/tiny_mce/plugins/fullscreen/readme.txt b/public/tiny_mce/plugins/fullscreen/readme.txt new file mode 100644 index 0000000..1be5b27 --- /dev/null +++ b/public/tiny_mce/plugins/fullscreen/readme.txt @@ -0,0 +1,17 @@ + Fullscreen plugin for TinyMCE +------------------------------ + +This plugin adds fullscreen mode to TinyMCE. + +Installation instructions: + * Add plugin to TinyMCE plugin option list example: plugins : "fullscreen". + * Add the fullscreen button name to button list, example: theme_advanced_buttons3_add : "fullscreen". + +Initialization example: + tinyMCE.init({ + theme : "advanced", + mode : "textareas", + plugins : "fullscreen", + theme_advanced_buttons3_add : "fullscreen", + plaintext_create_paragraphs : false + }); diff --git a/public/tiny_mce/plugins/iespell/editor_plugin.js b/public/tiny_mce/plugins/iespell/editor_plugin.js new file mode 100644 index 0000000..2d6c817 --- /dev/null +++ b/public/tiny_mce/plugins/iespell/editor_plugin.js @@ -0,0 +1,2 @@ +/* Import plugin specific language pack */ + tinyMCE.importPluginLanguagePack('iespell','cs,el,en,fr_ca,it,ko,sv,zh_cn,fr,de,pl,pt_br');function TinyMCE_iespell_getControlHTML(control_name){if(control_name=="iespell"&&tinyMCE.isMSIE)return '';return "";}function TinyMCE_iespell_execCommand(editor_id,element,command,user_interface,value){if(command=="mceIESpell"){try{var ieSpell=new ActiveXObject("ieSpell.ieSpellExtension");ieSpell.CheckDocumentNode(tinyMCE.getInstanceById(editor_id).contentDocument.documentElement);}catch(e){if(e.number==-2146827859){if(confirm(tinyMCE.getLang("lang_iespell_download","",true)))window.open('http://www.iespell.com/download.php','ieSpellDownload','');}else alert("Error Loading ieSpell: Exception "+e.number);}return true;}return false;} \ No newline at end of file diff --git a/public/tiny_mce/plugins/iespell/editor_plugin_src.js b/public/tiny_mce/plugins/iespell/editor_plugin_src.js new file mode 100644 index 0000000..b85ea9f --- /dev/null +++ b/public/tiny_mce/plugins/iespell/editor_plugin_src.js @@ -0,0 +1,37 @@ +/* Import plugin specific language pack */ +tinyMCE.importPluginLanguagePack('iespell', 'cs,el,en,fr_ca,it,ko,sv,zh_cn,fr,de,pl,pt_br'); + +/** + * Returns the HTML contents of the iespell control. + */ +function TinyMCE_iespell_getControlHTML(control_name) { + // Is it the iespell control and is the brower MSIE. + if (control_name == "iespell" && tinyMCE.isMSIE) + return ''; + + return ""; +} + +/** + * Executes the mceIESpell command. + */ +function TinyMCE_iespell_execCommand(editor_id, element, command, user_interface, value) { + // Handle ieSpellCommand + if (command == "mceIESpell") { + try { + var ieSpell = new ActiveXObject("ieSpell.ieSpellExtension"); + ieSpell.CheckDocumentNode(tinyMCE.getInstanceById(editor_id).contentDocument.documentElement); + } catch (e) { + if (e.number == -2146827859) { + if (confirm(tinyMCE.getLang("lang_iespell_download", "", true))) + window.open('http://www.iespell.com/download.php', 'ieSpellDownload', ''); + } else + alert("Error Loading ieSpell: Exception " + e.number); + } + + return true; + } + + // Pass to next handler in chain + return false; +} \ No newline at end of file diff --git a/public/tiny_mce/plugins/iespell/images/iespell.gif b/public/tiny_mce/plugins/iespell/images/iespell.gif new file mode 100644 index 0000000..46c0c4a Binary files /dev/null and b/public/tiny_mce/plugins/iespell/images/iespell.gif differ diff --git a/public/tiny_mce/plugins/iespell/langs/cs.js b/public/tiny_mce/plugins/iespell/langs/cs.js new file mode 100644 index 0000000..c38a480 --- /dev/null +++ b/public/tiny_mce/plugins/iespell/langs/cs.js @@ -0,0 +1,4 @@ +// UK lang variables + +tinyMCELang['lang_iespell_desc'] = 'Spustit kontrolu pravopisu'; +tinyMCELang['lang_iespell_download'] = "ieSpell nedetekovn. Kliknte na OK a otevete stahovac strnku." \ No newline at end of file diff --git a/public/tiny_mce/plugins/iespell/langs/de.js b/public/tiny_mce/plugins/iespell/langs/de.js new file mode 100644 index 0000000..80a3b02 --- /dev/null +++ b/public/tiny_mce/plugins/iespell/langs/de.js @@ -0,0 +1,4 @@ +// DE lang variables by Tobias Heer + +tinyMCELang['lang_iespell_desc'] = 'Rechtschreibprüfung'; +tinyMCELang['lang_iespell_download'] = "ieSpell nicht gefunden. Klicken Sie OK um auf die Download Seite zu gelangen." diff --git a/public/tiny_mce/plugins/iespell/langs/el.js b/public/tiny_mce/plugins/iespell/langs/el.js new file mode 100644 index 0000000..7925947 --- /dev/null +++ b/public/tiny_mce/plugins/iespell/langs/el.js @@ -0,0 +1,4 @@ +// Greek lang variables by Jacaranda Bill + +tinyMCELang['lang_iespell_desc'] = ' '; +tinyMCELang['lang_iespell_download'] = " ieSpell . OK ." diff --git a/public/tiny_mce/plugins/iespell/langs/en.js b/public/tiny_mce/plugins/iespell/langs/en.js new file mode 100644 index 0000000..b7cc3a4 --- /dev/null +++ b/public/tiny_mce/plugins/iespell/langs/en.js @@ -0,0 +1,4 @@ +// UK lang variables + +tinyMCELang['lang_iespell_desc'] = 'Run spell checking'; +tinyMCELang['lang_iespell_download'] = "ieSpell not detected. Click OK to go to download page." diff --git a/public/tiny_mce/plugins/iespell/langs/fr.js b/public/tiny_mce/plugins/iespell/langs/fr.js new file mode 100644 index 0000000..de66fb0 --- /dev/null +++ b/public/tiny_mce/plugins/iespell/langs/fr.js @@ -0,0 +1,4 @@ +// French lang variables by Laurent Dran + +tinyMCELang['lang_iespell_desc'] = 'Executer le vérificateur d\'orthographe'; +tinyMCELang['lang_iespell_download'] = "ieSpell n\'a pas été trouvé. Cliquez sur OK pour aller au site de téléchargement." diff --git a/public/tiny_mce/plugins/iespell/langs/fr_ca.js b/public/tiny_mce/plugins/iespell/langs/fr_ca.js new file mode 100644 index 0000000..9c172b0 --- /dev/null +++ b/public/tiny_mce/plugins/iespell/langs/fr_ca.js @@ -0,0 +1,4 @@ +// CAN_FR lang variables + +tinyMCELang['lang_iespell_desc'] = 'Executer le vrificateur d\'orthographe'; +tinyMCELang['lang_iespell_download'] = "ieSpell n\'a pas t trouv. Cliquez sur OK pour aller au site de tlchargement."; diff --git a/public/tiny_mce/plugins/iespell/langs/it.js b/public/tiny_mce/plugins/iespell/langs/it.js new file mode 100644 index 0000000..5f6e2f0 --- /dev/null +++ b/public/tiny_mce/plugins/iespell/langs/it.js @@ -0,0 +1,4 @@ +// IT lang variables + +tinyMCELang['lang_iespell_desc'] = 'Avvia il controllo ortografico'; +tinyMCELang['lang_iespell_download'] = "ieSpell non trovato. Clicca OK per andare alla pagina di download." diff --git a/public/tiny_mce/plugins/iespell/langs/ko.js b/public/tiny_mce/plugins/iespell/langs/ko.js new file mode 100644 index 0000000..a5bbfe4 --- /dev/null +++ b/public/tiny_mce/plugins/iespell/langs/ko.js @@ -0,0 +1,4 @@ +// KO lang variables + +tinyMCELang['lang_iespell_desc'] = ' ˻ '; +tinyMCELang['lang_iespell_download'] = "ieSpell ã ϴ. OK ٿε ̵մϴ." diff --git a/public/tiny_mce/plugins/iespell/langs/pl.js b/public/tiny_mce/plugins/iespell/langs/pl.js new file mode 100644 index 0000000..9fcb4e3 --- /dev/null +++ b/public/tiny_mce/plugins/iespell/langs/pl.js @@ -0,0 +1,4 @@ +// PL lang variables + +tinyMCELang['lang_iespell_desc'] = 'Uruchom sprawdzanie pisowni'; +tinyMCELang['lang_iespell_download'] = "Nie wykryto pluginu, kliknij aby przejść do strony z pluginami." \ No newline at end of file diff --git a/public/tiny_mce/plugins/iespell/langs/pt_br.js b/public/tiny_mce/plugins/iespell/langs/pt_br.js new file mode 100644 index 0000000..dba6e82 --- /dev/null +++ b/public/tiny_mce/plugins/iespell/langs/pt_br.js @@ -0,0 +1,4 @@ +// pt_BR lang variables + +tinyMCELang['lang_iespell_desc'] = 'Executar verificao ortogrfica'; +tinyMCELang['lang_iespell_download'] = "Verificador ieSpell no detectado. Click OK para ir pgina de download." diff --git a/public/tiny_mce/plugins/iespell/langs/sv.js b/public/tiny_mce/plugins/iespell/langs/sv.js new file mode 100644 index 0000000..2230c1c --- /dev/null +++ b/public/tiny_mce/plugins/iespell/langs/sv.js @@ -0,0 +1,4 @@ +// SE lang variables + +tinyMCELang['lang_iespell_desc'] = 'Kr rttstavningskontroll'; +tinyMCELang['lang_iespell_download'] = "ieSpell verkar inte vara installerad. Klicka OK för att ladda hem." diff --git a/public/tiny_mce/plugins/iespell/langs/zh_cn.js b/public/tiny_mce/plugins/iespell/langs/zh_cn.js new file mode 100644 index 0000000..35aeba1 --- /dev/null +++ b/public/tiny_mce/plugins/iespell/langs/zh_cn.js @@ -0,0 +1,5 @@ +// Simplified Chinese lang variables contributed by cube316 (cube316@gmail.com) +// http://www.cube316.net/ ԻȡTinyMCE֧ + +tinyMCELang['lang_iespell_desc'] = 'ƴд'; +tinyMCELang['lang_iespell_download'] = "δ⵽ieSpellƴд飬 OK ǰҳ档" diff --git a/public/tiny_mce/plugins/iespell/readme.txt b/public/tiny_mce/plugins/iespell/readme.txt new file mode 100644 index 0000000..0371a2a --- /dev/null +++ b/public/tiny_mce/plugins/iespell/readme.txt @@ -0,0 +1,20 @@ + ieSpell plugin for TinyMCE +---------------------------- + +Installation instructions: + * Copy the iespell directory to the plugins directory of TinyMCE (/jscripts/tiny_mce/plugins). + * Add plugin to TinyMCE plugin option list example: plugins : "iespell". + * Add the iespell button name to button list, example: theme_advanced_buttons3_add : "iespell". + +Initialization example: + tinyMCE.init({ + theme : "advanced", + mode : "textareas", + plugins : "iespell", + theme_advanced_buttons3_add : "iespell" + }); + +Requirements: + The end user will need MSIE on Windows with the ieSpell installed. This can be downloaded + from http://www.iespell.com/download.php. Notice on other browsers than MSIE the spellchecking + button will not be visible. diff --git a/public/tiny_mce/plugins/insertdatetime/editor_plugin.js b/public/tiny_mce/plugins/insertdatetime/editor_plugin.js new file mode 100644 index 0000000..0d4b26b --- /dev/null +++ b/public/tiny_mce/plugins/insertdatetime/editor_plugin.js @@ -0,0 +1,2 @@ +/* Import plugin specific language pack */ + tinyMCE.importPluginLanguagePack('insertdatetime','cs,el,en,fr_ca,it,ko,sv,zh_cn,fa,fr,de,pl,pt_br');function TinyMCE_insertdatetime_getControlHTML(control_name){var safariPatch='" onclick="';if(tinyMCE.isSafari)safariPatch="";switch(control_name){case "insertdate":return '';case "inserttime":return '';}return "";}function TinyMCE_insertdatetime_execCommand(editor_id,element,command,user_interface,value){function addZeros(value,len){value=""+value;if(value.length'; + + case "inserttime": + return ''; + } + + return ""; +} + +/** + * Executes the mceInsertDate command. + */ +function TinyMCE_insertdatetime_execCommand(editor_id, element, command, user_interface, value) { + /* Adds zeros infront of value */ + function addZeros(value, len) { + value = "" + value; + + if (value.length < len) { + for (var i=0; i<(len-value.length); i++) + value = "0" + value; + } + + return value; + } + + /* Returns the date object in the specified format */ + function getDateTime(date, format) { + format = tinyMCE.regexpReplace(format, "%D", "%m/%d/%y"); + format = tinyMCE.regexpReplace(format, "%r", "%I:%M:%S %p"); + format = tinyMCE.regexpReplace(format, "%Y", "" + date.getFullYear()); + format = tinyMCE.regexpReplace(format, "%y", "" + date.getYear()); + format = tinyMCE.regexpReplace(format, "%m", addZeros(date.getMonth()+1, 2)); + format = tinyMCE.regexpReplace(format, "%d", addZeros(date.getDate(), 2)); + format = tinyMCE.regexpReplace(format, "%H", "" + addZeros(date.getHours(), 2)); + format = tinyMCE.regexpReplace(format, "%M", "" + addZeros(date.getMinutes(), 2)); + format = tinyMCE.regexpReplace(format, "%S", "" + addZeros(date.getSeconds(), 2)); + format = tinyMCE.regexpReplace(format, "%I", "" + (date.getHours() < 12 ? (date.getHours()+1) : 24-date.getHours())); + format = tinyMCE.regexpReplace(format, "%p", "" + (date.getHours() < 12 ? "AM" : "PM")); + format = tinyMCE.regexpReplace(format, "%B", "" + tinyMCE.getLang("lang_inserttime_months_long")[date.getMonth()]); + format = tinyMCE.regexpReplace(format, "%b", "" + tinyMCE.getLang("lang_inserttime_months_short")[date.getMonth()]); + format = tinyMCE.regexpReplace(format, "%A", "" + tinyMCE.getLang("lang_inserttime_day_long")[date.getDay()]); + format = tinyMCE.regexpReplace(format, "%a", "" + tinyMCE.getLang("lang_inserttime_day_short")[date.getDay()]); + format = tinyMCE.regexpReplace(format, "%%", "%"); + + return format; + } + + // Handle commands + switch (command) { + case "mceInsertDate": + tinyMCE.execInstanceCommand(editor_id, 'mceInsertContent', false, getDateTime(new Date(), tinyMCE.getParam("plugin_insertdate_dateFormat", "%Y-%m-%d"))); + return true; + + case "mceInsertTime": + tinyMCE.execInstanceCommand(editor_id, 'mceInsertContent', false, getDateTime(new Date(), tinyMCE.getParam("plugin_insertdate_timeFormat", "%H:%M:%S"))); + return true; + } + + // Pass to next handler in chain + return false; +} diff --git a/public/tiny_mce/plugins/insertdatetime/images/insertdate.gif b/public/tiny_mce/plugins/insertdatetime/images/insertdate.gif new file mode 100644 index 0000000..5002f87 Binary files /dev/null and b/public/tiny_mce/plugins/insertdatetime/images/insertdate.gif differ diff --git a/public/tiny_mce/plugins/insertdatetime/images/inserttime.gif b/public/tiny_mce/plugins/insertdatetime/images/inserttime.gif new file mode 100644 index 0000000..eb76a83 Binary files /dev/null and b/public/tiny_mce/plugins/insertdatetime/images/inserttime.gif differ diff --git a/public/tiny_mce/plugins/insertdatetime/langs/cs.js b/public/tiny_mce/plugins/insertdatetime/langs/cs.js new file mode 100644 index 0000000..4b674eb --- /dev/null +++ b/public/tiny_mce/plugins/insertdatetime/langs/cs.js @@ -0,0 +1,8 @@ +// CS lang variables + +tinyMCELang['lang_insertdate_desc'] = 'Vloit datum'; +tinyMCELang['lang_inserttime_desc'] = 'Vloit as'; +tinyMCELang['lang_inserttime_months_long'] = new Array('Leden','nor','Bezen','Duben','Kvten','erven','ervenec','Srpen','Z','jen','Listopad','Prosinec'); +tinyMCELang['lang_inserttime_months_short'] = new Array('Led','no','Be','Dub','Kv','rv','vc','Srp','Z','j','Lis','Pro'); +tinyMCELang['lang_inserttime_day_long'] = new Array('Nedle','Pondl','ter','Steda','tvrtek','Ptek','Sobota','Nedle'); +tinyMCELang['lang_inserttime_day_short'] = new Array('Ne','Po','t','St','t','P','So','Ne'); diff --git a/public/tiny_mce/plugins/insertdatetime/langs/de.js b/public/tiny_mce/plugins/insertdatetime/langs/de.js new file mode 100644 index 0000000..7df43c5 --- /dev/null +++ b/public/tiny_mce/plugins/insertdatetime/langs/de.js @@ -0,0 +1,8 @@ +// DE lang variables + +tinyMCELang['lang_insertdate_desc'] = 'Datum einfügen'; +tinyMCELang['lang_inserttime_desc'] = 'Zeit einfügen'; +tinyMCELang['lang_inserttime_months_long'] = new Array("Januar", "Februar", "M\u00e4rz", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"); +tinyMCELang['lang_inserttime_months_short'] = new Array("Jan", "Feb", "M\u00e4r", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"); +tinyMCELang['lang_inserttime_day_long'] = new Array("Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"); +tinyMCELang['lang_inserttime_day_short'] = new Array("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"); diff --git a/public/tiny_mce/plugins/insertdatetime/langs/el.js b/public/tiny_mce/plugins/insertdatetime/langs/el.js new file mode 100644 index 0000000..07addfc --- /dev/null +++ b/public/tiny_mce/plugins/insertdatetime/langs/el.js @@ -0,0 +1,8 @@ +// Greek lang variables by Jacaranda Bill + +tinyMCELang['lang_insertdate_desc'] = ' '; +tinyMCELang['lang_inserttime_desc'] = ' '; +tinyMCELang['lang_inserttime_months_long'] = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"); +tinyMCELang['lang_inserttime_months_short'] = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); +tinyMCELang['lang_inserttime_day_long'] = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"); +tinyMCELang['lang_inserttime_day_short'] = new Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"); diff --git a/public/tiny_mce/plugins/insertdatetime/langs/en.js b/public/tiny_mce/plugins/insertdatetime/langs/en.js new file mode 100644 index 0000000..e203265 --- /dev/null +++ b/public/tiny_mce/plugins/insertdatetime/langs/en.js @@ -0,0 +1,8 @@ +// UK lang variables + +tinyMCELang['lang_insertdate_desc'] = 'Insert date'; +tinyMCELang['lang_inserttime_desc'] = 'Insert time'; +tinyMCELang['lang_inserttime_months_long'] = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"); +tinyMCELang['lang_inserttime_months_short'] = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); +tinyMCELang['lang_inserttime_day_long'] = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"); +tinyMCELang['lang_inserttime_day_short'] = new Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"); diff --git a/public/tiny_mce/plugins/insertdatetime/langs/fa.js b/public/tiny_mce/plugins/insertdatetime/langs/fa.js new file mode 100644 index 0000000..9a707bb --- /dev/null +++ b/public/tiny_mce/plugins/insertdatetime/langs/fa.js @@ -0,0 +1,9 @@ +// IR lang variables +// Persian (Farsi) language pack (for IRAN) +// By: Morteza Zafari +// Lost@LostLord.com +// http://www.LostLord.com + +tinyMCELang['lang_dir'] = 'rtl'; +tinyMCELang['lang_insertdate_desc'] = 'افزودن تاریخ'; +tinyMCELang['lang_inserttime_desc'] = 'افزودن زمان'; diff --git a/public/tiny_mce/plugins/insertdatetime/langs/fr.js b/public/tiny_mce/plugins/insertdatetime/langs/fr.js new file mode 100644 index 0000000..e583a73 --- /dev/null +++ b/public/tiny_mce/plugins/insertdatetime/langs/fr.js @@ -0,0 +1,8 @@ +// French lang variables by Laurent Dran + +tinyMCELang['lang_insertdate_desc'] = 'Insèrer la date'; +tinyMCELang['lang_inserttime_desc'] = 'Insèrer l\'heure'; +tinyMCELang['lang_inserttime_months_long'] = new Array("Janvier", "Fvrier", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aot", "Septembre", "Octobre", "Novembre", "Dcembre"); +tinyMCELang['lang_inserttime_months_short'] = new Array("Jan", "Fev", "Mar", "Avr", "Mai", "Juin", "Juil", "Aout", "Sep", "Oct", "Nov", "Dec"); +tinyMCELang['lang_inserttime_day_long'] = new Array("Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"); +tinyMCELang['lang_inserttime_day_short'] = new Array("Lun", "Mar", "Mer", "Jeu", "Thu", "Ven", "Sam", "Dim"); diff --git a/public/tiny_mce/plugins/insertdatetime/langs/fr_ca.js b/public/tiny_mce/plugins/insertdatetime/langs/fr_ca.js new file mode 100644 index 0000000..235b25b --- /dev/null +++ b/public/tiny_mce/plugins/insertdatetime/langs/fr_ca.js @@ -0,0 +1,8 @@ +// CAN_FR lang variables + +tinyMCELang['lang_insertdate_desc'] = 'Insrer la date'; +tinyMCELang['lang_inserttime_desc'] = 'Insrer l\'heure'; +tinyMCELang['lang_inserttime_months_long'] = new Array("Janvier", "Fvrier", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aot", "Septembre", "Octobre", "Novembre", "Dcembre"); +tinyMCELang['lang_inserttime_months_short'] = new Array("Jan", "Fev", "Mar", "Avr", "Mai", "Juin", "Juil", "Aout", "Sep", "Oct", "Nov", "Dec"); +tinyMCELang['lang_inserttime_day_long'] = new Array("Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"); +tinyMCELang['lang_inserttime_day_short'] = new Array("Lun", "Mar", "Mer", "Jeu", "Thu", "Ven", "Sam", "Dim"); diff --git a/public/tiny_mce/plugins/insertdatetime/langs/it.js b/public/tiny_mce/plugins/insertdatetime/langs/it.js new file mode 100644 index 0000000..a96b2cb --- /dev/null +++ b/public/tiny_mce/plugins/insertdatetime/langs/it.js @@ -0,0 +1,8 @@ +// IT lang variables + +tinyMCELang['lang_insertdate_desc'] = 'Inserisci data'; +tinyMCELang['lang_inserttime_desc'] = 'Inserisci ora'; +tinyMCELang['lang_inserttime_months_long'] = new Array("Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"); +tinyMCELang['lang_inserttime_months_short'] = new Array("Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"); +tinyMCELang['lang_inserttime_day_long'] = new Array("Domenica", "Luned", "Marted", "Mercoled", "Gioved", "Venerd", "Sabato", "Domenica"); +tinyMCELang['lang_inserttime_day_short'] = new Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"); diff --git a/public/tiny_mce/plugins/insertdatetime/langs/ko.js b/public/tiny_mce/plugins/insertdatetime/langs/ko.js new file mode 100644 index 0000000..a2ea29d --- /dev/null +++ b/public/tiny_mce/plugins/insertdatetime/langs/ko.js @@ -0,0 +1,8 @@ +// KO lang variables + +tinyMCELang['lang_insertdate_desc'] = '¥ ֱ'; +tinyMCELang['lang_inserttime_desc'] = 'ð ֱ'; +tinyMCELang['lang_inserttime_months_long'] = new Array("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"); +tinyMCELang['lang_inserttime_months_short'] = new Array("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"); +tinyMCELang['lang_inserttime_day_long'] = new Array("Ͽ", "", "ȭ", "", "", "ݿ", "", "Ͽ"); +tinyMCELang['lang_inserttime_day_short'] = new Array("", "", "ȭ", "", "", "", "", ""); diff --git a/public/tiny_mce/plugins/insertdatetime/langs/pl.js b/public/tiny_mce/plugins/insertdatetime/langs/pl.js new file mode 100644 index 0000000..1d7d497 --- /dev/null +++ b/public/tiny_mce/plugins/insertdatetime/langs/pl.js @@ -0,0 +1,9 @@ +// PL lang variables + + +tinyMCELang['lang_insertdate_desc'] = 'Wstaw aktualną datę'; +tinyMCELang['lang_inserttime_desc'] = 'Wstaw aktualny czas'; +tinyMCELang['lang_inserttime_months_long'] = new Array("Styczeń", "Luty", "Marzec", "Kwiecień", "Maj", "Czerwiec", "Lipiec", "Sierpień", "Wrzesień", "Październik", "Listopad", "Grudzień"); +tinyMCELang['lang_inserttime_months_short'] = new Array("Stcz", "Lut", "Mar", "Kwi", "Maj", "Czer", "Lip", "Sier", "Wrze", "Paź", "List", "Grudz"); +tinyMCELang['lang_inserttime_day_long'] = new Array("Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota", "Niedziela"); +tinyMCELang['lang_inserttime_day_short'] = new Array("Nie", "Pon", "Wto", "Śro", "Czw", "Pia", "Sob", "Nie"); \ No newline at end of file diff --git a/public/tiny_mce/plugins/insertdatetime/langs/pt_br.js b/public/tiny_mce/plugins/insertdatetime/langs/pt_br.js new file mode 100644 index 0000000..5138c21 --- /dev/null +++ b/public/tiny_mce/plugins/insertdatetime/langs/pt_br.js @@ -0,0 +1,8 @@ +// pt_BR lang variables + +tinyMCELang['lang_insertdate_desc'] = 'Inserir data'; +tinyMCELang['lang_inserttime_desc'] = 'Inserir hora'; +tinyMCELang['lang_inserttime_months_long'] = new Array("Janeiro", "Fevereiro", "Maro", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"); +tinyMCELang['lang_inserttime_months_short'] = new Array("Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"); +tinyMCELang['lang_inserttime_day_long'] = new Array("Domindo", "Segunda-Feira", "Tera-Feira", "Quarta-Feira", "Quinta-Feira", "Sexta-Feira", "Sbado", "Domingo"); +tinyMCELang['lang_inserttime_day_short'] = new Array("Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab", "Dom"); diff --git a/public/tiny_mce/plugins/insertdatetime/langs/sv.js b/public/tiny_mce/plugins/insertdatetime/langs/sv.js new file mode 100644 index 0000000..d128dd0 --- /dev/null +++ b/public/tiny_mce/plugins/insertdatetime/langs/sv.js @@ -0,0 +1,8 @@ +// SE lang variables + +tinyMCELang['lang_insertdate_desc'] = 'Klistra in datum'; +tinyMCELang['lang_inserttime_desc'] = 'Klistra in tid'; +tinyMCELang['lang_inserttime_months_long'] = new Array("Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"); +tinyMCELang['lang_inserttime_months_short'] = new Array("Jan","Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"); +tinyMCELang['lang_inserttime_day_long'] = new Array("Sndag", "Mndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lrdag", "Sndag"); +tinyMCELang['lang_inserttime_day_short'] = new Array("Sn", "Mn", "Tis", "Ons", "Tor", "Fre", "Lr", "Sn"); diff --git a/public/tiny_mce/plugins/insertdatetime/langs/zh_cn.js b/public/tiny_mce/plugins/insertdatetime/langs/zh_cn.js new file mode 100644 index 0000000..172c099 --- /dev/null +++ b/public/tiny_mce/plugins/insertdatetime/langs/zh_cn.js @@ -0,0 +1,9 @@ +// Simplified Chinese lang variables contributed by cube316 (cube316@gmail.com) +// http://www.cube316.net/ ԻȡTinyMCE֧ + +tinyMCELang['lang_insertdate_desc'] = '뵱ǰ'; +tinyMCELang['lang_inserttime_desc'] = '뵱ǰʱ'; +tinyMCELang['lang_inserttime_months_long'] = new Array("һ·", "·", "·", "·", "·", "·", "·", "·", "·", "ʮ·", "ʮһ·", "ʮ·"); +tinyMCELang['lang_inserttime_months_short'] = new Array("һ", "", "", "", "", "", "", "", "", "ʮ", "ʮһ", "ʮ"); +tinyMCELang['lang_inserttime_day_long'] = new Array("", "һ", "ڶ", "", "", "", "", ""); +tinyMCELang['lang_inserttime_day_short'] = new Array("", "һ", "ܶ", "", "", "", "", ""); diff --git a/public/tiny_mce/plugins/insertdatetime/readme.txt b/public/tiny_mce/plugins/insertdatetime/readme.txt new file mode 100644 index 0000000..6399d9e --- /dev/null +++ b/public/tiny_mce/plugins/insertdatetime/readme.txt @@ -0,0 +1,35 @@ + InsertDateTime plugin for TinyMCE +----------------------------------- + +Installation instructions: + * Copy the insertdatetime directory to the plugins directory of TinyMCE (/jscripts/tiny_mce/plugins). + * Add plugin to TinyMCE plugin option list example: plugins : "insertdatetime". + * Add the insertdate or inserttime button name to button list, example: theme_advanced_buttons3_add : "insertdate,inserttime". + +Initialization example: + tinyMCE.init({ + theme : "advanced", + mode : "textareas", + plugins : "insertdatetime", + theme_advanced_buttons3_add : "insertdate,inserttime", + plugin_insertdate_dateFormat : "%Y-%m-%d", + plugin_insertdate_timeFormat : "%H:%M:%S" + }); + +Configuration: + plugin_insertdate_dateFormat - Format that the date is output as. Defaults to: "%Y-%m-%d". + Replacement variables: + %y - year as a decimal number without a century (range 00 to 99) + %Y - year as a decimal number including the century + %d - day of the month as a decimal number (range 01 to 31) + %m - month as a decimal number (range 01 to 12) + %D - same as %m/%d/%y + %r - time in a.m. and p.m. notation + %H - hour as a decimal number using a 24-hour clock (range 00 to 23) + %I - hour as a decimal number using a 12-hour clock (range 01 to 12) + %M - minute as a decimal number (range 00-59) + %S - second as a decimal number (range 00-59) + %p - either `am' or `pm' according to the given time value + %% - a literal `%' character + + plugin_insertdate_timeFormat - Format that the time is output as. Defaults to: "%H:%M:%S". diff --git a/public/tiny_mce/plugins/linkattach/attachment.htm b/public/tiny_mce/plugins/linkattach/attachment.htm new file mode 100644 index 0000000..673377d --- /dev/null +++ b/public/tiny_mce/plugins/linkattach/attachment.htm @@ -0,0 +1,448 @@ + + +{$lang_insert_attachment_title} + + + + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$lang_insert_attachment_title}
    {$lang_insert_attachment_url}: + + + + +
    {$lang_theme_insert_link_titlefield}:
    {$lang_insert_attachment_target}: + + + + + + + + + + + + + + + + + + + + + +
     ({$lang_insert_attachment_target_same})
     ({$lang_insert_attachment_target_parent})
     ({$lang_insert_attachment_target_top})
     ({$lang_insert_attachment_target_blank})
    + + + + + + +
     
    +
    + + + + + + + + + + + + + + + + + +
    {$lang_insert_attachment_popup_url}:  + + + + +
    {$lang_insert_attachment_popup_name}: 
    {$lang_insert_attachment_popup_size}:  + x + px +
    {$lang_insert_attachment_popup_position}:  + / + (c /c = center) +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      
     
       
     
    +
    +
    + + diff --git a/public/tiny_mce/plugins/linkattach/editor_plugin.js b/public/tiny_mce/plugins/linkattach/editor_plugin.js new file mode 100644 index 0000000..1b2fd17 --- /dev/null +++ b/public/tiny_mce/plugins/linkattach/editor_plugin.js @@ -0,0 +1,2 @@ +/* Import plugin specific language pack */ + tinyMCE.importPluginLanguagePack('linkattach','en,de,sv,zh_cn,cs,fa,fr_ca,fr,pl');function TinyMCE_linkattach_getInsertAttachmentTemplate(){var template=new Array();template['file']='../../plugins/linkattach/attachment.htm';template['width']=400;template['height']=420;template['width']+=tinyMCE.getLang('lang_insert_attachment_delta_width',0);template['height']+=tinyMCE.getLang('lang_insert_attachment_delta_height',0);return template;} \ No newline at end of file diff --git a/public/tiny_mce/plugins/linkattach/editor_plugin_src.js b/public/tiny_mce/plugins/linkattach/editor_plugin_src.js new file mode 100644 index 0000000..89e2028 --- /dev/null +++ b/public/tiny_mce/plugins/linkattach/editor_plugin_src.js @@ -0,0 +1,18 @@ +/* Import plugin specific language pack */ +tinyMCE.importPluginLanguagePack('linkattach', 'en,de,sv,zh_cn,cs,fa,fr_ca,fr,pl'); + +/** + * Insert link template function. + */ +function TinyMCE_linkattach_getInsertAttachmentTemplate() { + var template = new Array(); + template['file'] = '../../plugins/linkattach/attachment.htm'; + template['width'] = 400; + template['height'] = 420; + + // Language specific width and height addons + template['width'] += tinyMCE.getLang('lang_insert_attachment_delta_width', 0); + template['height'] += tinyMCE.getLang('lang_insert_attachment_delta_height', 0); + + return template; +} \ No newline at end of file diff --git a/public/tiny_mce/plugins/linkattach/langs/en.js b/public/tiny_mce/plugins/linkattach/langs/en.js new file mode 100644 index 0000000..cc6441c --- /dev/null +++ b/public/tiny_mce/plugins/linkattach/langs/en.js @@ -0,0 +1,20 @@ +// UK lang variables + +tinyMCELang['lang_insert_attachment_target_same'] = 'Open in this window / frame'; +tinyMCELang['lang_insert_attachment_target_parent'] = 'Open in parent window / frame'; +tinyMCELang['lang_insert_attachment_target_top'] = 'Open in top frame (replaces all frames)'; +tinyMCELang['lang_insert_attachment_target_blank'] = 'Open in new window'; +tinyMCELang['lang_insert_attachment_target_named'] = 'Open in the window'; +tinyMCELang['lang_insert_attachment_popup'] = 'JS-Popup'; +tinyMCELang['lang_insert_attachment_popup_url'] = 'Popup URL'; +tinyMCELang['lang_insert_attachment_popup_name'] = 'Window name'; +tinyMCELang['lang_insert_attachment_popup_return'] = 'insert \'return false\''; +tinyMCELang['lang_insert_attachment_popup_scrollbars'] = 'Show scrollbars'; +tinyMCELang['lang_insert_attachment_popup_statusbar'] = 'Show statusbar'; +tinyMCELang['lang_insert_attachment_popup_toolbar'] = 'Show toolbars'; +tinyMCELang['lang_insert_attachment_popup_menubar'] = 'Show menubar'; +tinyMCELang['lang_insert_attachment_popup_location'] = 'Show locationbar'; +tinyMCELang['lang_insert_attachment_popup_resizable'] = 'Make window resizable'; +tinyMCELang['lang_insert_attachment_popup_size'] = 'Size'; +tinyMCELang['lang_insert_attachment_popup_position'] = 'Position (X/Y)'; +tinyMCELang['lang_insert_attachment_popup_missingtarget'] = 'Please insert a name for the target or choose another option.'; diff --git a/public/tiny_mce/plugins/paste/blank.htm b/public/tiny_mce/plugins/paste/blank.htm new file mode 100644 index 0000000..104b550 --- /dev/null +++ b/public/tiny_mce/plugins/paste/blank.htm @@ -0,0 +1,15 @@ + + + +blank_page + + + + + + + diff --git a/public/tiny_mce/plugins/paste/editor_plugin.js b/public/tiny_mce/plugins/paste/editor_plugin.js new file mode 100644 index 0000000..5aa44cb --- /dev/null +++ b/public/tiny_mce/plugins/paste/editor_plugin.js @@ -0,0 +1,25 @@ +// Tiny MCE Paste Plugin +// Updated by speednet 25 May 2005 - IE converts and pastes without opening popup window + tinyMCE.importPluginLanguagePack('paste','en,sv,cs');function TinyMCE_paste_getControlHTML(control_name){switch(control_name){case "pastetext":return '';case "pasteword":return '';case "selectall":return '';}return '';}function TinyMCE_paste_execCommand(editor_id,element,command,user_interface,value){switch(command){case "mcePasteText":if(tinyMCE.isMSIE&&!tinyMCE.getParam('paste_use_dialog',false))TinyMCE_paste__insertText(clipboardData.getData("Text"),true);else{var template=new Array();template['file']='../../plugins/paste/pastetext.htm';template['width']=450;template['height']=400;var plain_text="";tinyMCE.openWindow(template,{editor_id:editor_id,plain_text:plain_text,resizable:"yes",scrollbars:"no",mceDo:'insert'});}return true;case "mcePasteWord":if(tinyMCE.isMSIE&&!tinyMCE.getParam('paste_use_dialog',false)){var html=TinyMCE_paste__clipboardHTML();if(html&&html.length>0)TinyMCE_paste__insertWordContent(html);}else{var template=new Array();template['file']='../../plugins/paste/pasteword.htm';template['width']=450;template['height']=400;var plain_text="";tinyMCE.openWindow(template,{editor_id:editor_id,plain_text:plain_text,resizable:"yes",scrollbars:"no",mceDo:'insert'});}return true;case "mceSelectAll":tinyMCE.execInstanceCommand(editor_id,'selectall');return true;}return false;}function TinyMCE_paste__insertText(content,bLinebreaks){if(content&&content.length>0){if(bLinebreaks){if(tinyMCE.getParam("plaintext_create_paragraphs",true)){content=tinyMCE.regexpReplace(content,"\r\n\r\n","

    ","gi");content=tinyMCE.regexpReplace(content,"\r\r","

    ","gi");content=tinyMCE.regexpReplace(content,"\n\n","

    ","gi");if((pos=content.indexOf('

    '))!=-1){tinyMCE.execCommand("Delete");var node=tinyMCE.selectedInstance.getFocusElement();var breakElms=new Array();do{if(node.nodeType==1){if(node.nodeName=="TD"||node.nodeName=="BODY")break;breakElms[breakElms.length]=node;}}while(node=node.parentNode);var before="",after="

    ";before+=content.substring(0,pos);for(var i=0;i";after+="<"+breakElms[(breakElms.length-1)-i].nodeName+">";}before+="

    ";content=before+content.substring(pos+7)+after;}}content=tinyMCE.regexpReplace(content,"\r\n","
    ","gi");content=tinyMCE.regexpReplace(content,"\r","
    ","gi");content=tinyMCE.regexpReplace(content,"\n","
    ","gi");}tinyMCE.execCommand("mceInsertRawHTML",false,content);}}function TinyMCE_paste__insertWordContent(content){if(content&&content.length>0){content=content.replace(new RegExp('<(!--)([^>]*)(--)>','g'),"");content=content.replace(/<\/?span[^>]*>/gi,"");content=content.replace(/<(\w[^>]*)style="([^"]*)"([^>]*)/gi, "<$1$3"); + content = content.replace(/<\/?font[^>]*>/gi, ""); + content = content.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3"); + content = content.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3"); + content = content.replace(/<\\?\?xml[^>]*>/gi, ""); + content = content.replace(/<\/?\w+:[^>]*>/gi, ""); + content = content.replace(/\/? */gi, ""); + content = content.replace('

     

    ', '' ,'g'); + + if (!tinyMCE.settings['force_p_newlines']) { + content = content.replace('', '' ,'gi'); + content = content.replace('

    ', '

    ' ,'gi'); + } + + if (!tinyMCE.isMSIE && !tinyMCE.settings['force_p_newlines']) { + content = content.replace(/<\/?p[^>]*>/gi, ""); + } + + content = content.replace(/<\/?div[^>]*>/gi, ""); + + // Insert cleaned content + tinyMCE.execCommand("mceAddUndoLevel"); + tinyMCE.execCommand("mceInsertContent",false,content);}}function TinyMCE_paste__clipboardHTML(){var div=document.getElementById('_TinyMCE_clipboardHTML');if(!div){var div=document.createElement('DIV');div.id='_TinyMCE_clipboardHTML';with(div.style){visibility='hidden';overflow='hidden';position='absolute';width=1;height=1;}document.body.appendChild(div);}div.innerHTML='';var rng=document.body.createTextRange();rng.moveToElementText(div);rng.execCommand('Paste');var html=div.innerHTML;div.innerHTML='';return html;} \ No newline at end of file diff --git a/public/tiny_mce/plugins/paste/editor_plugin_src.js b/public/tiny_mce/plugins/paste/editor_plugin_src.js new file mode 100644 index 0000000..96f00bb --- /dev/null +++ b/public/tiny_mce/plugins/paste/editor_plugin_src.js @@ -0,0 +1,174 @@ +// Tiny MCE Paste Plugin +// Updated by speednet 25 May 2005 - IE converts and pastes without opening popup window + +/* Import plugin specific language pack */ +tinyMCE.importPluginLanguagePack('paste', 'en,sv,cs'); + +function TinyMCE_paste_getControlHTML(control_name) { + switch (control_name) { + case "pastetext": + return ''; + + case "pasteword": + return ''; + + case "selectall": + return ''; + } + + return ''; +} + +function TinyMCE_paste_execCommand(editor_id, element, command, user_interface, value) { + switch (command) { + case "mcePasteText": + if (tinyMCE.isMSIE && !tinyMCE.getParam('paste_use_dialog', false)) + TinyMCE_paste__insertText(clipboardData.getData("Text"), true); + else { + var template = new Array(); + template['file'] = '../../plugins/paste/pastetext.htm'; // Relative to theme + template['width'] = 450; + template['height'] = 400; + var plain_text = ""; + tinyMCE.openWindow(template, {editor_id : editor_id, plain_text: plain_text, resizable : "yes", scrollbars : "no", mceDo : 'insert'}); + } + + return true; + + case "mcePasteWord": + if (tinyMCE.isMSIE && !tinyMCE.getParam('paste_use_dialog', false)) { + var html = TinyMCE_paste__clipboardHTML(); + + if (html && html.length > 0) + TinyMCE_paste__insertWordContent(html); + } else { + var template = new Array(); + template['file'] = '../../plugins/paste/pasteword.htm'; // Relative to theme + template['width'] = 450; + template['height'] = 400; + var plain_text = ""; + tinyMCE.openWindow(template, {editor_id : editor_id, plain_text: plain_text, resizable : "yes", scrollbars : "no", mceDo : 'insert'}); + } + + return true; + + case "mceSelectAll": + tinyMCE.execInstanceCommand(editor_id, 'selectall'); + return true; + + } + + // Pass to next handler in chain + return false; +} + +function TinyMCE_paste__insertText(content, bLinebreaks) { + + if (content && content.length > 0) { + if (bLinebreaks) { + // Special paragraph treatment + if (tinyMCE.getParam("plaintext_create_paragraphs", true)) { + content = tinyMCE.regexpReplace(content, "\r\n\r\n", "

    ", "gi"); + content = tinyMCE.regexpReplace(content, "\r\r", "

    ", "gi"); + content = tinyMCE.regexpReplace(content, "\n\n", "

    ", "gi"); + + // Has paragraphs + if ((pos = content.indexOf('

    ')) != -1) { + tinyMCE.execCommand("Delete"); + + var node = tinyMCE.selectedInstance.getFocusElement(); + + // Get list of elements to break + var breakElms = new Array(); + + do { + if (node.nodeType == 1) { + // Don't break tables and break at body + if (node.nodeName == "TD" || node.nodeName == "BODY") + break; + + breakElms[breakElms.length] = node; + } + } while(node = node.parentNode); + + var before = "", after = "

    "; + before += content.substring(0, pos); + + for (var i=0; i"; + after += "<" + breakElms[(breakElms.length-1)-i].nodeName + ">"; + } + + before += "

    "; + content = before + content.substring(pos+7) + after; + } + } + + content = tinyMCE.regexpReplace(content, "\r\n", "
    ", "gi"); + content = tinyMCE.regexpReplace(content, "\r", "
    ", "gi"); + content = tinyMCE.regexpReplace(content, "\n", "
    ", "gi"); + } + + tinyMCE.execCommand("mceInsertRawHTML", false, content); + } +} + +function TinyMCE_paste__insertWordContent(content) { + + if (content && content.length > 0) { + // Cleanup Word content + content = content.replace(new RegExp('<(!--)([^>]*)(--)>', 'g'), ""); // Word comments + content = content.replace(/<\/?span[^>]*>/gi, ""); + content = content.replace(/<(\w[^>]*) style="([^"]*)"([^>]*)/gi, "<$1$3"); + content = content.replace(/<\/?font[^>]*>/gi, ""); + content = content.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3"); + content = content.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3"); + content = content.replace(/<\\?\?xml[^>]*>/gi, ""); + content = content.replace(/<\/?\w+:[^>]*>/gi, ""); + content = content.replace(/\/? */gi, ""); + content = content.replace('

     

    ', '' ,'g'); + + if (!tinyMCE.settings['force_p_newlines']) { + content = content.replace('', '' ,'gi'); + content = content.replace('

    ', '

    ' ,'gi'); + } + + if (!tinyMCE.isMSIE && !tinyMCE.settings['force_p_newlines']) { + content = content.replace(/<\/?p[^>]*>/gi, ""); + } + + content = content.replace(/<\/?div[^>]*>/gi, ""); + + // Insert cleaned content + tinyMCE.execCommand("mceAddUndoLevel"); + tinyMCE.execCommand("mceInsertContent", false, content); + } +} + +function TinyMCE_paste__clipboardHTML() { + var div = document.getElementById('_TinyMCE_clipboardHTML'); + + if (!div) { + var div = document.createElement('DIV'); + div.id = '_TinyMCE_clipboardHTML'; + + with (div.style) { + visibility = 'hidden'; + overflow = 'hidden'; + position = 'absolute'; + width = 1; + height = 1; + } + + document.body.appendChild(div); + } + + div.innerHTML = ''; + var rng = document.body.createTextRange(); + rng.moveToElementText(div); + rng.execCommand('Paste'); + var html = div.innerHTML; + div.innerHTML = ''; + return html; +} + diff --git a/public/tiny_mce/plugins/paste/images/pastetext.gif b/public/tiny_mce/plugins/paste/images/pastetext.gif new file mode 100644 index 0000000..6b9f93f Binary files /dev/null and b/public/tiny_mce/plugins/paste/images/pastetext.gif differ diff --git a/public/tiny_mce/plugins/paste/images/pasteword.gif b/public/tiny_mce/plugins/paste/images/pasteword.gif new file mode 100644 index 0000000..55c1d24 Binary files /dev/null and b/public/tiny_mce/plugins/paste/images/pasteword.gif differ diff --git a/public/tiny_mce/plugins/paste/images/selectall.gif b/public/tiny_mce/plugins/paste/images/selectall.gif new file mode 100644 index 0000000..943f575 Binary files /dev/null and b/public/tiny_mce/plugins/paste/images/selectall.gif differ diff --git a/public/tiny_mce/plugins/paste/langs/cs.js b/public/tiny_mce/plugins/paste/langs/cs.js new file mode 100644 index 0000000..bbe0996 --- /dev/null +++ b/public/tiny_mce/plugins/paste/langs/cs.js @@ -0,0 +1,8 @@ +// CS lang variables + +tinyMCELang['lang_paste_text_desc'] = 'Vloit neformtovan text'; +tinyMCELang['lang_paste_text_title'] = 'Poui CTRL+V na klvesnici pro vloen textu do okna.'; +tinyMCELang['lang_paste_text_linebreaks'] = 'Nechej pr(eruen r(dku*'; +tinyMCELang['lang_paste_word_desc'] = 'Vloit text z aplikace Word'; +tinyMCELang['lang_paste_word_title'] = 'Poui CTRL+V na klvesnici pro vloen textu do okna.'; +tinyMCELang['lang_selectall_desc'] = 'Oznac(it ve'; diff --git a/public/tiny_mce/plugins/paste/langs/en.js b/public/tiny_mce/plugins/paste/langs/en.js new file mode 100644 index 0000000..e575d5f --- /dev/null +++ b/public/tiny_mce/plugins/paste/langs/en.js @@ -0,0 +1,8 @@ +// UK lang variables + +tinyMCELang['lang_paste_text_desc'] = 'Paste as Plain Text'; +tinyMCELang['lang_paste_text_title'] = 'Use CTRL+V on your keyboard to paste the text into the window.'; +tinyMCELang['lang_paste_text_linebreaks'] = 'Keep linebreaks'; +tinyMCELang['lang_paste_word_desc'] = 'Paste from Word'; +tinyMCELang['lang_paste_word_title'] = 'Use CTRL+V on your keyboard to paste the text into the window.'; +tinyMCELang['lang_selectall_desc'] = 'Select All'; diff --git a/public/tiny_mce/plugins/paste/langs/sv.js b/public/tiny_mce/plugins/paste/langs/sv.js new file mode 100644 index 0000000..b7a7746 --- /dev/null +++ b/public/tiny_mce/plugins/paste/langs/sv.js @@ -0,0 +1,8 @@ +// SV lang variables + +tinyMCELang['lang_paste_text_desc'] = 'Klistra in som vanlig text' +tinyMCELang['lang_paste_text_title'] = 'Använd CTRL+V på ditt tangentbord för att klistra in i detta fönster.'; +tinyMCELang['lang_paste_text_linebreaks'] = 'Spara radbrytningar'; +tinyMCELang['lang_paste_word_desc'] = 'Klistra in från Word' +tinyMCELang['lang_paste_word_title'] = 'Använd CTRL+V på ditt tangentbord för att klistra in i detta fönster.'; +tinyMCELang['lang_selectall_desc'] = 'Select All'; diff --git a/public/tiny_mce/plugins/paste/langs/zh_cn.js b/public/tiny_mce/plugins/paste/langs/zh_cn.js new file mode 100644 index 0000000..e4fc2cd --- /dev/null +++ b/public/tiny_mce/plugins/paste/langs/zh_cn.js @@ -0,0 +1,9 @@ +// Simplified Chinese lang variables contributed by cube316 (cube316@gmail.com) +// http://www.cube316.net/ ԻȡTinyMCE֧ + +tinyMCELang['lang_paste_text_desc'] = 'Ϊıճ'; +tinyMCELang['lang_paste_text_title'] = 'ʹÿݼ CTRL+V ıճ´.'; +tinyMCELang['lang_paste_text_linebreaks'] = 'з'; +tinyMCELang['lang_paste_word_desc'] = 'Wordճ'; +tinyMCELang['lang_paste_word_title'] = 'ʹÿݼ CTRL+V ıճ´.'; +tinyMCELang['lang_selectall_desc'] = 'ȫѡ'; diff --git a/public/tiny_mce/plugins/paste/pastetext.htm b/public/tiny_mce/plugins/paste/pastetext.htm new file mode 100644 index 0000000..a651b21 --- /dev/null +++ b/public/tiny_mce/plugins/paste/pastetext.htm @@ -0,0 +1,76 @@ + + +{$lang_paste_text_desc} + + + + + + + + +
    + + + + + + + + + + + + + + + +
    {$lang_paste_text_desc} + +
    {$lang_paste_text_title}
    + +
    +
    + + \ No newline at end of file diff --git a/public/tiny_mce/plugins/paste/pasteword.htm b/public/tiny_mce/plugins/paste/pasteword.htm new file mode 100644 index 0000000..0e1e811 --- /dev/null +++ b/public/tiny_mce/plugins/paste/pasteword.htm @@ -0,0 +1,111 @@ + + +{$lang_paste_word_desc} + + + + + + + + + +
    + + + + + + + + + + + + + + +
    {$lang_paste_word_desc}
    {$lang_paste_word_title}
    + +
    +
    + + \ No newline at end of file diff --git a/public/tiny_mce/plugins/paste/readme.txt b/public/tiny_mce/plugins/paste/readme.txt new file mode 100644 index 0000000..d261ff3 --- /dev/null +++ b/public/tiny_mce/plugins/paste/readme.txt @@ -0,0 +1,28 @@ + Paste plugin for TinyMCE +------------------------------ + +This plugin adds paste as plain text and paste from Word icons to TinyMCE. This plugin was developed by Ryan Demmer and modified by +the TinyMCE crew to be more general and some extra features where added. + +On 25 May 2005, this plugin was modified by speednet: IE now pastes directly into the editor, bypassing the extra steps of opening the Insert box, selecting options, and clicking Insert. Speednet also added the Select All command, which highlights all the content in the editor when the user clicks the toolbar button. (Other miscellaneous cleanup also.) + + +Installation instructions: + * Add plugin to TinyMCE plugin option list example: plugins : "paste". + * Add the plaintext button name to button list, example: theme_advanced_buttons3_add : "pastetext,pasteword,selectall". + +Initialization example: + tinyMCE.init({ + theme : "advanced", + mode : "textareas", + plugins : "paste", + theme_advanced_buttons3_add : "pastetext,pasteword,selectall", + paste_create_paragraphs : false, + paste_use_dialog : true + }); + +Options: + [paste_create_paragraphs] - If enabled double linefeeds are converted to paragraph + elements when using the plain text dialog. This is enabled by default. + [paste_use_dialog] - MSIE specific option, if you set this to true both Mozilla and MSIE will present a paste dialog. + if you set it to false pasting in MSIE will be done directly. This option is set to false by default. diff --git a/public/tiny_mce/plugins/preview/editor_plugin.js b/public/tiny_mce/plugins/preview/editor_plugin.js new file mode 100644 index 0000000..6815de6 --- /dev/null +++ b/public/tiny_mce/plugins/preview/editor_plugin.js @@ -0,0 +1,2 @@ +/* Import plugin specific language pack */ + tinyMCE.importPluginLanguagePack('preview','cs,de,el,en,fr_ca,it,ko,pt,sv,zh_cn,fa,fr,pl,pt_br');function TinyMCE_preview_getControlHTML(control_name){switch(control_name){case "preview":return '';}return "";}function TinyMCE_preview_execCommand(editor_id,element,command,user_interface,value){switch(command){case "mcePreview":var previewPage=tinyMCE.getParam("plugin_preview_pageurl",null);var previewWidth=tinyMCE.getParam("plugin_preview_width","550");var previewHeight=tinyMCE.getParam("plugin_preview_height","600");if(previewPage){var template=new Array();template['file']=previewPage;template['width']=previewWidth;template['height']=previewHeight;tinyMCE.openWindow(template,{editor_id:editor_id,resizable:"yes",scrollbars:"yes",content:tinyMCE.getContent(),content_css:tinyMCE.getParam("content_css")});}else{var win=window.open("","mcePreview","menubar=no,toolbar=no,scrollbars=yes,resizable=yes,left=20,top=20,width="+previewWidth+",height="+previewHeight);var html="";html+='';html+='';html+='';html+=''+tinyMCE.getLang('lang_preview_desc')+'';html+='';html+='';html+='';html+='';html+=tinyMCE.getContent();html+='';html+='';win.document.write(html);win.document.close();}return true;}return false;} \ No newline at end of file diff --git a/public/tiny_mce/plugins/preview/editor_plugin_src.js b/public/tiny_mce/plugins/preview/editor_plugin_src.js new file mode 100644 index 0000000..156a226 --- /dev/null +++ b/public/tiny_mce/plugins/preview/editor_plugin_src.js @@ -0,0 +1,61 @@ +/* Import plugin specific language pack */ +tinyMCE.importPluginLanguagePack('preview', 'cs,de,el,en,fr_ca,it,ko,pt,sv,zh_cn,fa,fr,pl,pt_br'); + +/** + * Returns the HTML contents of the preview control. + */ +function TinyMCE_preview_getControlHTML(control_name) { + switch (control_name) { + case "preview": + return ''; + } + + return ""; +} + +/** + * Executes the mcePreview command. + */ +function TinyMCE_preview_execCommand(editor_id, element, command, user_interface, value) { + // Handle commands + switch (command) { + case "mcePreview": + var previewPage = tinyMCE.getParam("plugin_preview_pageurl", null); + var previewWidth = tinyMCE.getParam("plugin_preview_width", "550"); + var previewHeight = tinyMCE.getParam("plugin_preview_height", "600"); + + // Use a custom preview page + if (previewPage) { + var template = new Array(); + + template['file'] = previewPage; + template['width'] = previewWidth; + template['height'] = previewHeight; + + tinyMCE.openWindow(template, {editor_id : editor_id, resizable : "yes", scrollbars : "yes", content : tinyMCE.getContent(), content_css : tinyMCE.getParam("content_css")}); + } else { + var win = window.open("", "mcePreview", "menubar=no,toolbar=no,scrollbars=yes,resizable=yes,left=20,top=20,width=" + previewWidth + ",height=" + previewHeight); + var html = ""; + + html += ''; + html += ''; + html += ''; + html += '' + tinyMCE.getLang('lang_preview_desc') + ''; + html += ''; + html += ''; + html += ''; + html += ''; + html += tinyMCE.getContent(); + html += ''; + html += ''; + + win.document.write(html); + win.document.close(); + } + + return true; + } + + // Pass to next handler in chain + return false; +} diff --git a/public/tiny_mce/plugins/preview/example.html b/public/tiny_mce/plugins/preview/example.html new file mode 100644 index 0000000..c6f1dfb --- /dev/null +++ b/public/tiny_mce/plugins/preview/example.html @@ -0,0 +1,14 @@ + + + + +Example of a custom preview page + + + + +Editor contents:
    +{$content} + + + diff --git a/public/tiny_mce/plugins/preview/images/preview.gif b/public/tiny_mce/plugins/preview/images/preview.gif new file mode 100644 index 0000000..4e7900c Binary files /dev/null and b/public/tiny_mce/plugins/preview/images/preview.gif differ diff --git a/public/tiny_mce/plugins/preview/langs/cs.js b/public/tiny_mce/plugins/preview/langs/cs.js new file mode 100644 index 0000000..27502b4 --- /dev/null +++ b/public/tiny_mce/plugins/preview/langs/cs.js @@ -0,0 +1,3 @@ +// UK lang variables + +tinyMCELang['lang_preview_desc'] = 'Nhled'; \ No newline at end of file diff --git a/public/tiny_mce/plugins/preview/langs/de.js b/public/tiny_mce/plugins/preview/langs/de.js new file mode 100644 index 0000000..e24e9c4 --- /dev/null +++ b/public/tiny_mce/plugins/preview/langs/de.js @@ -0,0 +1,3 @@ +// DE lang variables by Tobias Heer + +tinyMCELang['lang_preview_desc'] = 'Vorschau'; diff --git a/public/tiny_mce/plugins/preview/langs/el.js b/public/tiny_mce/plugins/preview/langs/el.js new file mode 100644 index 0000000..d63358e --- /dev/null +++ b/public/tiny_mce/plugins/preview/langs/el.js @@ -0,0 +1,3 @@ +// Greek lang variables by Jacaranda Bill + +tinyMCELang['lang_preview_desc'] = ' '; diff --git a/public/tiny_mce/plugins/preview/langs/en.js b/public/tiny_mce/plugins/preview/langs/en.js new file mode 100644 index 0000000..d94866d --- /dev/null +++ b/public/tiny_mce/plugins/preview/langs/en.js @@ -0,0 +1,3 @@ +// UK lang variables + +tinyMCELang['lang_preview_desc'] = 'Preview'; diff --git a/public/tiny_mce/plugins/preview/langs/fa.js b/public/tiny_mce/plugins/preview/langs/fa.js new file mode 100644 index 0000000..46877f4 --- /dev/null +++ b/public/tiny_mce/plugins/preview/langs/fa.js @@ -0,0 +1,8 @@ +// IR lang variables +// Persian (Farsi) language pack (for IRAN) +// By: Morteza Zafari +// Lost@LostLord.com +// http://www.LostLord.com + +tinyMCELang['lang_dir'] = 'rtl'; +tinyMCELang['lang_preview_desc'] = 'پیش نمایش'; diff --git a/public/tiny_mce/plugins/preview/langs/fr.js b/public/tiny_mce/plugins/preview/langs/fr.js new file mode 100644 index 0000000..18610dc --- /dev/null +++ b/public/tiny_mce/plugins/preview/langs/fr.js @@ -0,0 +1,3 @@ +// French lang variables by Laurent Dran + +tinyMCELang['lang_preview_desc'] = 'Prévisualisation'; diff --git a/public/tiny_mce/plugins/preview/langs/fr_ca.js b/public/tiny_mce/plugins/preview/langs/fr_ca.js new file mode 100644 index 0000000..bdab8c9 --- /dev/null +++ b/public/tiny_mce/plugins/preview/langs/fr_ca.js @@ -0,0 +1,3 @@ +// CAN_FR lang variables + +tinyMCELang['lang_preview_desc'] = 'Prvisualisation'; diff --git a/public/tiny_mce/plugins/preview/langs/it.js b/public/tiny_mce/plugins/preview/langs/it.js new file mode 100644 index 0000000..7a13b51 --- /dev/null +++ b/public/tiny_mce/plugins/preview/langs/it.js @@ -0,0 +1,3 @@ +// IT lang variables + +tinyMCELang['lang_preview_desc'] = 'Anteprima'; diff --git a/public/tiny_mce/plugins/preview/langs/ko.js b/public/tiny_mce/plugins/preview/langs/ko.js new file mode 100644 index 0000000..b3bb1f8 --- /dev/null +++ b/public/tiny_mce/plugins/preview/langs/ko.js @@ -0,0 +1,3 @@ +// KO lang variables + +tinyMCELang['lang_preview_desc'] = '̸'; diff --git a/public/tiny_mce/plugins/preview/langs/pl.js b/public/tiny_mce/plugins/preview/langs/pl.js new file mode 100644 index 0000000..6998539 --- /dev/null +++ b/public/tiny_mce/plugins/preview/langs/pl.js @@ -0,0 +1,4 @@ +// PL lang variables + + +tinyMCELang['lang_preview_desc'] = 'Podgląd'; \ No newline at end of file diff --git a/public/tiny_mce/plugins/preview/langs/pt.js b/public/tiny_mce/plugins/preview/langs/pt.js new file mode 100644 index 0000000..bc7e09d --- /dev/null +++ b/public/tiny_mce/plugins/preview/langs/pt.js @@ -0,0 +1,3 @@ +// UK lang variables + +tinyMCELang['lang_preview_desc'] = 'Pr-visualizao'; diff --git a/public/tiny_mce/plugins/preview/langs/pt_br.js b/public/tiny_mce/plugins/preview/langs/pt_br.js new file mode 100644 index 0000000..1a501c6 --- /dev/null +++ b/public/tiny_mce/plugins/preview/langs/pt_br.js @@ -0,0 +1,3 @@ +// pt_BR lang variables + +tinyMCELang['lang_preview_desc'] = 'Visualizar'; diff --git a/public/tiny_mce/plugins/preview/langs/sv.js b/public/tiny_mce/plugins/preview/langs/sv.js new file mode 100644 index 0000000..32d5850 --- /dev/null +++ b/public/tiny_mce/plugins/preview/langs/sv.js @@ -0,0 +1,3 @@ +// SE lang variables + +tinyMCELang['lang_preview_desc'] = 'Frhandsgranska'; diff --git a/public/tiny_mce/plugins/preview/langs/zh_cn.js b/public/tiny_mce/plugins/preview/langs/zh_cn.js new file mode 100644 index 0000000..2c8a1a3 --- /dev/null +++ b/public/tiny_mce/plugins/preview/langs/zh_cn.js @@ -0,0 +1,3 @@ +// Simplified Chinese lang variables contributed by cube316 (cube316@etang.com) + +tinyMCELang['lang_preview_desc'] = 'Ԥ'; diff --git a/public/tiny_mce/plugins/preview/readme.txt b/public/tiny_mce/plugins/preview/readme.txt new file mode 100644 index 0000000..01ca90c --- /dev/null +++ b/public/tiny_mce/plugins/preview/readme.txt @@ -0,0 +1,23 @@ + Preview plugin for TinyMCE +----------------------------------- + +Installation instructions: + * Copy the preview directory to the plugins directory of TinyMCE (/jscripts/tiny_mce/plugins). + * Add plugin to TinyMCE plugin option list example: plugins : "preview". + * Add the preview button name to button list, example: theme_advanced_buttons3_add : "preview". + +Initialization example: + tinyMCE.init({ + theme : "advanced", + mode : "textareas", + plugins : "preview", + theme_advanced_buttons3_add : "preview", + plugin_preview_width : "500", + plugin_preview_height : "600" + }); + +Configuration: + plugin_preview_width - Preview window width. Defaults to 550. + plugin_preview_height - Preview window height. Defaults to 600. + plugin_preview_pageurl - Custom preview page URL relative from theme + use "../../plugins/preview/example.html" for a example. diff --git a/public/tiny_mce/plugins/print/editor_plugin.js b/public/tiny_mce/plugins/print/editor_plugin.js new file mode 100644 index 0000000..59c2180 --- /dev/null +++ b/public/tiny_mce/plugins/print/editor_plugin.js @@ -0,0 +1,2 @@ +/* Import theme specific language pack */ + tinyMCE.importPluginLanguagePack('print','en,sv,zh_cn,fa,fr_ca,fr,de,pl,pt_br,cs');function TinyMCE_print_getControlHTML(control_name){switch(control_name){case "print":return '';}return "";}function TinyMCE_print_execCommand(editor_id,element,command,user_interface,value){switch(command){case "mcePrint":tinyMCE.getInstanceById(editor_id).contentWindow.print();return true;}return false;} \ No newline at end of file diff --git a/public/tiny_mce/plugins/print/editor_plugin_src.js b/public/tiny_mce/plugins/print/editor_plugin_src.js new file mode 100644 index 0000000..423ba0c --- /dev/null +++ b/public/tiny_mce/plugins/print/editor_plugin_src.js @@ -0,0 +1,26 @@ +/* Import theme specific language pack */ +tinyMCE.importPluginLanguagePack('print', 'en,sv,zh_cn,fa,fr_ca,fr,de,pl,pt_br,cs'); + +function TinyMCE_print_getControlHTML(control_name) { + switch (control_name) { + case "print": + return ''; + } + + return ""; +} + +/** + * Executes the search/replace commands. + */ +function TinyMCE_print_execCommand(editor_id, element, command, user_interface, value) { + // Handle commands + switch (command) { + case "mcePrint": + tinyMCE.getInstanceById(editor_id).contentWindow.print(); + return true; + } + + // Pass to next handler in chain + return false; +} diff --git a/public/tiny_mce/plugins/print/images/print.gif b/public/tiny_mce/plugins/print/images/print.gif new file mode 100644 index 0000000..1172f4d Binary files /dev/null and b/public/tiny_mce/plugins/print/images/print.gif differ diff --git a/public/tiny_mce/plugins/print/langs/cs.js b/public/tiny_mce/plugins/print/langs/cs.js new file mode 100644 index 0000000..2c373b4 --- /dev/null +++ b/public/tiny_mce/plugins/print/langs/cs.js @@ -0,0 +1,3 @@ +// CS lang variables + +tinyMCELang['lang_print_desc'] = 'Tisk'; diff --git a/public/tiny_mce/plugins/print/langs/de.js b/public/tiny_mce/plugins/print/langs/de.js new file mode 100644 index 0000000..b3913d0 --- /dev/null +++ b/public/tiny_mce/plugins/print/langs/de.js @@ -0,0 +1,3 @@ +// DE lang variables + +tinyMCELang['lang_print_desc'] = 'Drucken'; diff --git a/public/tiny_mce/plugins/print/langs/en.js b/public/tiny_mce/plugins/print/langs/en.js new file mode 100644 index 0000000..fcaa4ef --- /dev/null +++ b/public/tiny_mce/plugins/print/langs/en.js @@ -0,0 +1,3 @@ +// UK lang variables + +tinyMCELang['lang_print_desc'] = 'Print'; diff --git a/public/tiny_mce/plugins/print/langs/fa.js b/public/tiny_mce/plugins/print/langs/fa.js new file mode 100644 index 0000000..3850104 --- /dev/null +++ b/public/tiny_mce/plugins/print/langs/fa.js @@ -0,0 +1,8 @@ +// IR lang variables +// Persian (Farsi) language pack (for IRAN) +// By: Morteza Zafari +// Lost@LostLord.com +// http://www.LostLord.com + +tinyMCELang['lang_dir'] = 'rtl'; +tinyMCELang['lang_print_desc'] = 'چاپ'; diff --git a/public/tiny_mce/plugins/print/langs/fr.js b/public/tiny_mce/plugins/print/langs/fr.js new file mode 100644 index 0000000..46e5397 --- /dev/null +++ b/public/tiny_mce/plugins/print/langs/fr.js @@ -0,0 +1,3 @@ +// French lang variables by Laurent Dran + +tinyMCELang['lang_print_desc'] = 'Imprimer'; diff --git a/public/tiny_mce/plugins/print/langs/fr_ca.js b/public/tiny_mce/plugins/print/langs/fr_ca.js new file mode 100644 index 0000000..9245867 --- /dev/null +++ b/public/tiny_mce/plugins/print/langs/fr_ca.js @@ -0,0 +1,3 @@ +// CA_FR lang variables + +tinyMCELang['lang_print_desc'] = 'Imprimer'; diff --git a/public/tiny_mce/plugins/print/langs/pl.js b/public/tiny_mce/plugins/print/langs/pl.js new file mode 100644 index 0000000..e3be100 --- /dev/null +++ b/public/tiny_mce/plugins/print/langs/pl.js @@ -0,0 +1,4 @@ +// PL lang variables + + +tinyMCELang['lang_print_desc'] = 'Drukuj'; \ No newline at end of file diff --git a/public/tiny_mce/plugins/print/langs/pt_br.js b/public/tiny_mce/plugins/print/langs/pt_br.js new file mode 100644 index 0000000..0111867 --- /dev/null +++ b/public/tiny_mce/plugins/print/langs/pt_br.js @@ -0,0 +1,3 @@ +// pt_BR lang variables + +tinyMCELang['lang_print_desc'] = 'Imprimir'; diff --git a/public/tiny_mce/plugins/print/langs/sv.js b/public/tiny_mce/plugins/print/langs/sv.js new file mode 100644 index 0000000..6ef7982 --- /dev/null +++ b/public/tiny_mce/plugins/print/langs/sv.js @@ -0,0 +1,3 @@ +// SE lang variables + +tinyMCELang['lang_print_desc'] = 'Skriv ut'; diff --git a/public/tiny_mce/plugins/print/langs/zh_cn.js b/public/tiny_mce/plugins/print/langs/zh_cn.js new file mode 100644 index 0000000..de1c60a --- /dev/null +++ b/public/tiny_mce/plugins/print/langs/zh_cn.js @@ -0,0 +1,4 @@ +// Simplified Chinese lang variables contributed by cube316 (cube316@gmail.com) +// http://www.cube316.net/ ԻȡTinyMCE֧ + +tinyMCELang['lang_print_desc'] = 'ӡ'; diff --git a/public/tiny_mce/plugins/print/readme.txt b/public/tiny_mce/plugins/print/readme.txt new file mode 100644 index 0000000..66d15d1 --- /dev/null +++ b/public/tiny_mce/plugins/print/readme.txt @@ -0,0 +1,17 @@ + Print plugin for TinyMCE +----------------------------- + +About: + This plugin adds a print button to TinyMCE. + +Installation instructions: + * Copy the print directory to the plugins directory of TinyMCE (/jscripts/tiny_mce/plugins). + * Add plugin to TinyMCE plugin option list example: plugins : "print". + +Initialization example: + tinyMCE.init({ + theme : "advanced", + mode : "textareas", + plugins : "print", + theme_advanced_buttons1_add : "print", + }); diff --git a/public/tiny_mce/plugins/readme.txt b/public/tiny_mce/plugins/readme.txt new file mode 100644 index 0000000..b694fdb --- /dev/null +++ b/public/tiny_mce/plugins/readme.txt @@ -0,0 +1 @@ +This is the location you place TinyMCE plugins. diff --git a/public/tiny_mce/plugins/save/editor_plugin.js b/public/tiny_mce/plugins/save/editor_plugin.js new file mode 100644 index 0000000..0b4da45 --- /dev/null +++ b/public/tiny_mce/plugins/save/editor_plugin.js @@ -0,0 +1,2 @@ +/* Import plugin specific language pack */ + tinyMCE.importPluginLanguagePack('save','en,zh_cn,cs,fa,fr_ca,fr,de,pl,pt_br');function TinyMCE_save_getControlHTML(control_name){switch(control_name){case "save":return '';}return "";}function TinyMCE_save_execCommand(editor_id,element,command,user_interface,value){switch(command){case "mceSave":var formObj=tinyMCE.selectedInstance.formElement.form;if(formObj){tinyMCE.triggerSave();for(var i=0;i'; + } + return ""; +} + +/** + * Executes the save command. + */ +function TinyMCE_save_execCommand(editor_id, element, command, user_interface, value) { + // Handle commands + switch (command) { + case "mceSave": + var formObj = tinyMCE.selectedInstance.formElement.form; + + if (formObj) { + tinyMCE.triggerSave(); + + // Disable all UI form elements that TinyMCE created + for (var i=0; i';case "replace":return '';}return "";}function TinyMCE_searchreplace_execCommand(editor_id,element,command,user_interface,value){function defValue(key,default_value){value[key]=typeof(value[key])=="undefined"?default_value:value[key];}function replaceSel(search_str,str){if(!tinyMCE.isMSIE){var sel=instance.contentWindow.getSelection();var rng=sel.getRangeAt(0);}else{var rng=instance.contentWindow.document.selection.createRange();}if(!tinyMCE.isMSIE){var doc=instance.contentWindow.document;if(str.indexOf(search_str)==-1){rng.deleteContents();rng.insertNode(rng.createContextualFragment(str));rng.collapse(false);}else{doc.execCommand("insertimage",false,"#mce_temp_url#");var elm=tinyMCE.getElementByAttributeValue(doc.body,"img","src","#mce_temp_url#");elm.parentNode.replaceChild(doc.createTextNode(str),elm);}}else{if(rng.item)rng.item(0).outerHTML=str;else rng.pasteHTML(str);}}var instance=tinyMCE.getInstanceById(editor_id);if(!value)value=new Array();defValue("editor_id",editor_id);defValue("searchstring","");defValue("replacestring",null);defValue("replacemode","none");defValue("casesensitive",false);defValue("backwards",false);defValue("wrap",false);defValue("wholeword",false);switch(command){case "mceResetSearch":tinyMCE.lastSearchRng=null;return true;case "mceSearch":if(user_interface){var template=new Array();if(value['replacestring']!=null){template['file']='../../plugins/searchreplace/replace.htm';template['width']=310;template['height']=180;}else{template['file']='../../plugins/searchreplace/search.htm';template['width']=280;template['height']=180;}tinyMCE.openWindow(template,value);}else{var win=tinyMCE.getInstanceById(editor_id).contentWindow;var doc=tinyMCE.getInstanceById(editor_id).contentWindow.document;var body=tinyMCE.getInstanceById(editor_id).contentWindow.document.body;if(body.innerHTML==""){alert(tinyMCE.getLang('lang_searchreplace_notfound'));return true;}if(value['replacemode']=="current"){replaceSel(value['string'],value['replacestring']);value['replacemode']="none";tinyMCE.execInstanceCommand(editor_id,'mceSearch',user_interface,value,false);return true;}if(tinyMCE.isMSIE){var rng=tinyMCE.lastSearchRng?tinyMCE.lastSearchRng:doc.selection.createRange();var flags=0;if(value['wholeword'])flags=flags|2;if(value['casesensitive'])flags=flags|4;if(value['replacemode']=="all"){while(rng.findText(value['string'],value['backwards']?-1:1,flags)){rng.scrollIntoView();rng.select();rng.collapse(false);replaceSel(value['string'],value['replacestring']);}alert(tinyMCE.getLang('lang_searchreplace_allreplaced'));return true;}if(rng.findText(value['string'],value['backwards']?-1:1,flags)){rng.scrollIntoView();rng.select();rng.collapse(value['backwards']);tinyMCE.lastSearchRng=rng;}else alert(tinyMCE.getLang('lang_searchreplace_notfound'));}else{if(value['replacemode']=="all"){while(win.find(value['string'],value['casesensitive'],value['backwards'],value['wrap'],value['wholeword'],false,false))replaceSel(value['string'],value['replacestring']);alert(tinyMCE.getLang('lang_searchreplace_allreplaced'));return true;}if(!win.find(value['string'],value['casesensitive'],value['backwards'],value['wrap'],value['wholeword'],false,false))alert(tinyMCE.getLang('lang_searchreplace_notfound'));}}return true;case "mceSearchReplace":value['replacestring']="";tinyMCE.execInstanceCommand(editor_id,'mceSearch',user_interface,value,false);return true;}return false;}function TinyMCE_searchreplace_handleNodeChange(editor_id,node,undo_index,undo_levels,visual_aid,any_selection){return true;} \ No newline at end of file diff --git a/public/tiny_mce/plugins/searchreplace/editor_plugin_src.js b/public/tiny_mce/plugins/searchreplace/editor_plugin_src.js new file mode 100644 index 0000000..b62195b --- /dev/null +++ b/public/tiny_mce/plugins/searchreplace/editor_plugin_src.js @@ -0,0 +1,173 @@ +/* Import theme specific language pack */ +tinyMCE.importPluginLanguagePack('searchreplace', 'en,sv,zh_cn,fa,fr_ca,fr,de,pl,pt_br,cs'); + +function TinyMCE_searchreplace_getControlHTML(control_name) { + switch (control_name) { + case "search": + return ''; + + case "replace": + return ''; + } + + return ""; +} + +/** + * Executes the search/replace commands. + */ +function TinyMCE_searchreplace_execCommand(editor_id, element, command, user_interface, value) { + function defValue(key, default_value) { + value[key] = typeof(value[key]) == "undefined" ? default_value : value[key]; + } + + function replaceSel(search_str, str) { + // Get current selection + if (!tinyMCE.isMSIE) { + var sel = instance.contentWindow.getSelection(); + var rng = sel.getRangeAt(0); + } else { + var rng = instance.contentWindow.document.selection.createRange(); + } + + // Replace current one + if (!tinyMCE.isMSIE) { + var doc = instance.contentWindow.document; + + // This way works when the replace doesn't contain the search string + if (str.indexOf(search_str) == -1) { + rng.deleteContents(); + rng.insertNode(rng.createContextualFragment(str)); + rng.collapse(false); + } else { + // Insert content ugly way! Needed to move selection to after replace item + doc.execCommand("insertimage", false, "#mce_temp_url#"); + var elm = tinyMCE.getElementByAttributeValue(doc.body, "img", "src", "#mce_temp_url#"); + elm.parentNode.replaceChild(doc.createTextNode(str), elm); + } + } else { + if (rng.item) + rng.item(0).outerHTML = str; + else + rng.pasteHTML(str); + } + } + + var instance = tinyMCE.getInstanceById(editor_id); + + if (!value) + value = new Array(); + + // Setup defualt values + defValue("editor_id", editor_id); + defValue("searchstring", ""); + defValue("replacestring", null); + defValue("replacemode", "none"); + defValue("casesensitive", false); + defValue("backwards", false); + defValue("wrap", false); + defValue("wholeword", false); + + // Handle commands + switch (command) { + case "mceResetSearch": + tinyMCE.lastSearchRng = null; + return true; + + case "mceSearch": + if (user_interface) { + // Open search dialog + var template = new Array(); + + if (value['replacestring'] != null) { + template['file'] = '../../plugins/searchreplace/replace.htm'; // Relative to theme + template['width'] = 310; + template['height'] = 180; + } else { + template['file'] = '../../plugins/searchreplace/search.htm'; // Relative to theme + template['width'] = 280; + template['height'] = 180; + } + + tinyMCE.openWindow(template, value); + } else { + var win = tinyMCE.getInstanceById(editor_id).contentWindow; + var doc = tinyMCE.getInstanceById(editor_id).contentWindow.document; + var body = tinyMCE.getInstanceById(editor_id).contentWindow.document.body; + + // Whats the point + if (body.innerHTML == "") { + alert(tinyMCE.getLang('lang_searchreplace_notfound')); + return true; + } + + // Handle replace current + if (value['replacemode'] == "current") { + replaceSel(value['string'], value['replacestring']); + + // Search next one + value['replacemode'] = "none"; + tinyMCE.execInstanceCommand(editor_id, 'mceSearch', user_interface, value, false); + + return true; + } + + if (tinyMCE.isMSIE) { + var rng = tinyMCE.lastSearchRng ? tinyMCE.lastSearchRng : doc.selection.createRange(); + var flags = 0; + + if (value['wholeword']) + flags = flags | 2; + + if (value['casesensitive']) + flags = flags | 4; + + // Handle replace all mode + if (value['replacemode'] == "all") { + while (rng.findText(value['string'], value['backwards'] ? -1 : 1, flags)) { + rng.scrollIntoView(); + rng.select(); + rng.collapse(false); + replaceSel(value['string'], value['replacestring']); + } + + alert(tinyMCE.getLang('lang_searchreplace_allreplaced')); + return true; + } + + if (rng.findText(value['string'], value['backwards'] ? -1 : 1, flags)) { + rng.scrollIntoView(); + rng.select(); + rng.collapse(value['backwards']); + tinyMCE.lastSearchRng = rng; + } else + alert(tinyMCE.getLang('lang_searchreplace_notfound')); + } else { + if (value['replacemode'] == "all") { + while (win.find(value['string'], value['casesensitive'], value['backwards'], value['wrap'], value['wholeword'], false, false)) + replaceSel(value['string'], value['replacestring']); + + alert(tinyMCE.getLang('lang_searchreplace_allreplaced')); + return true; + } + + if (!win.find(value['string'], value['casesensitive'], value['backwards'], value['wrap'], value['wholeword'], false, false)) + alert(tinyMCE.getLang('lang_searchreplace_notfound')); + } + } + return true; + + case "mceSearchReplace": + value['replacestring'] = ""; + + tinyMCE.execInstanceCommand(editor_id, 'mceSearch', user_interface, value, false); + return true; + } + + // Pass to next handler in chain + return false; +} + +function TinyMCE_searchreplace_handleNodeChange(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) { + return true; +} diff --git a/public/tiny_mce/plugins/searchreplace/images/replace.gif b/public/tiny_mce/plugins/searchreplace/images/replace.gif new file mode 100644 index 0000000..e62354b Binary files /dev/null and b/public/tiny_mce/plugins/searchreplace/images/replace.gif differ diff --git a/public/tiny_mce/plugins/searchreplace/images/search.gif b/public/tiny_mce/plugins/searchreplace/images/search.gif new file mode 100644 index 0000000..40ae68e Binary files /dev/null and b/public/tiny_mce/plugins/searchreplace/images/search.gif differ diff --git a/public/tiny_mce/plugins/searchreplace/langs/cs.js b/public/tiny_mce/plugins/searchreplace/langs/cs.js new file mode 100644 index 0000000..0d2d447 --- /dev/null +++ b/public/tiny_mce/plugins/searchreplace/langs/cs.js @@ -0,0 +1,19 @@ +// CS lang variables + +tinyMCELang['lang_searchreplace_search_desc'] = 'Najdi'; +tinyMCELang['lang_searchreplace_searchnext_desc'] = 'Najdi znova'; +tinyMCELang['lang_searchreplace_replace_desc'] = 'Najdi/Nahradit'; +tinyMCELang['lang_searchreplace_notfound'] = 'Vyhledvan ukonc(eno. R(etezec nemusel bt nalezen.'; +tinyMCELang['lang_searchreplace_search_title'] = 'Najdi'; +tinyMCELang['lang_searchreplace_replace_title'] = 'Najdi/Nahradit'; +tinyMCELang['lang_searchreplace_allreplaced'] = 'Vechny vskyty r(etezce byli zme(neny.'; +tinyMCELang['lang_searchreplace_findwhat'] = 'Najt'; +tinyMCELang['lang_searchreplace_replacewith'] = 'Nahradit'; +tinyMCELang['lang_searchreplace_direction'] = 'Sme(r'; +tinyMCELang['lang_searchreplace_up'] = 'Nahoru'; +tinyMCELang['lang_searchreplace_down'] = 'Dolu*'; +tinyMCELang['lang_searchreplace_case'] = 'Pr(esn zhoda'; +tinyMCELang['lang_searchreplace_findnext'] = 'Najdi dal'; +tinyMCELang['lang_searchreplace_replace'] = 'Nahradit'; +tinyMCELang['lang_searchreplace_replaceall'] = 'Nahradit ve'; +tinyMCELang['lang_searchreplace_cancel'] = 'Zruit'; diff --git a/public/tiny_mce/plugins/searchreplace/langs/de.js b/public/tiny_mce/plugins/searchreplace/langs/de.js new file mode 100644 index 0000000..b972de7 --- /dev/null +++ b/public/tiny_mce/plugins/searchreplace/langs/de.js @@ -0,0 +1,19 @@ +// DE lang variables + +tinyMCELang['lang_searchreplace_search_desc'] = 'Suchen'; +tinyMCELang['lang_searchreplace_searchnext_desc'] = 'Erneut suchen'; +tinyMCELang['lang_searchreplace_replace_desc'] = 'Suchen/Ersetzen'; +tinyMCELang['lang_searchreplace_notfound'] = 'Die Suche wurde abgeschlossen. Das Suchwort wurde nicht gefunden.'; +tinyMCELang['lang_searchreplace_search_title'] = 'Suchen'; +tinyMCELang['lang_searchreplace_replace_title'] = 'Suchen/Ersetzen'; +tinyMCELang['lang_searchreplace_allreplaced'] = 'Die Suche wurde abgeschlossen. Alle Vorkommen wurden ersetzt.'; +tinyMCELang['lang_searchreplace_findwhat'] = 'Suchen nach'; +tinyMCELang['lang_searchreplace_replacewith'] = 'Ersetzem durch'; +tinyMCELang['lang_searchreplace_direction'] = 'Suchrichtung'; +tinyMCELang['lang_searchreplace_up'] = 'Rückwärts'; +tinyMCELang['lang_searchreplace_down'] = 'Vorwärts'; +tinyMCELang['lang_searchreplace_case'] = 'Groß-/Kleinschreibung beachten'; +tinyMCELang['lang_searchreplace_findnext'] = 'Weiter suchen'; +tinyMCELang['lang_searchreplace_replace'] = 'Ersetzen'; +tinyMCELang['lang_searchreplace_replaceall'] = 'Alle ersetzen'; +tinyMCELang['lang_searchreplace_cancel'] = 'Abbrechen'; diff --git a/public/tiny_mce/plugins/searchreplace/langs/en.js b/public/tiny_mce/plugins/searchreplace/langs/en.js new file mode 100644 index 0000000..0626fe9 --- /dev/null +++ b/public/tiny_mce/plugins/searchreplace/langs/en.js @@ -0,0 +1,19 @@ +// UK lang variables + +tinyMCELang['lang_searchreplace_search_desc'] = 'Find'; +tinyMCELang['lang_searchreplace_searchnext_desc'] = 'Find again'; +tinyMCELang['lang_searchreplace_replace_desc'] = 'Find/Replace'; +tinyMCELang['lang_searchreplace_notfound'] = 'The search has been compleated. The search string could not be found.'; +tinyMCELang['lang_searchreplace_search_title'] = 'Find'; +tinyMCELang['lang_searchreplace_replace_title'] = 'Find/Replace'; +tinyMCELang['lang_searchreplace_allreplaced'] = 'All occurrences of the search string was replaced.'; +tinyMCELang['lang_searchreplace_findwhat'] = 'Find what'; +tinyMCELang['lang_searchreplace_replacewith'] = 'Replace with'; +tinyMCELang['lang_searchreplace_direction'] = 'Direction'; +tinyMCELang['lang_searchreplace_up'] = 'Up'; +tinyMCELang['lang_searchreplace_down'] = 'Down'; +tinyMCELang['lang_searchreplace_case'] = 'Match case'; +tinyMCELang['lang_searchreplace_findnext'] = 'Find next'; +tinyMCELang['lang_searchreplace_replace'] = 'Replace'; +tinyMCELang['lang_searchreplace_replaceall'] = 'Replace all'; +tinyMCELang['lang_searchreplace_cancel'] = 'Cancel'; diff --git a/public/tiny_mce/plugins/searchreplace/langs/fa.js b/public/tiny_mce/plugins/searchreplace/langs/fa.js new file mode 100644 index 0000000..78f80e6 --- /dev/null +++ b/public/tiny_mce/plugins/searchreplace/langs/fa.js @@ -0,0 +1,24 @@ +// IR lang variables +// Persian (Farsi) language pack (for IRAN) +// By: Morteza Zafari +// Lost@LostLord.com +// http://www.LostLord.com + +tinyMCELang['lang_dir'] = 'rtl'; +tinyMCELang['lang_searchreplace_search_desc'] = 'جستجو'; +tinyMCELang['lang_searchreplace_searchnext_desc'] = 'جستجوي مجدد'; +tinyMCELang['lang_searchreplace_replace_desc'] = 'جستجو/جايگزيني'; +tinyMCELang['lang_searchreplace_notfound'] = 'جستجو پايان يافت. هيچ موردي يافت نشد.'; +tinyMCELang['lang_searchreplace_search_title'] = 'جستجو'; +tinyMCELang['lang_searchreplace_replace_title'] = 'جستجو/جايگزيني'; +tinyMCELang['lang_searchreplace_allreplaced'] = 'همه موارد جايگزين گرديد.'; +tinyMCELang['lang_searchreplace_findwhat'] = 'جستجو به دنبال'; +tinyMCELang['lang_searchreplace_replacewith'] = 'جايگزيني با'; +tinyMCELang['lang_searchreplace_direction'] = 'جهت جستجو'; +tinyMCELang['lang_searchreplace_up'] = 'به سمت بالا'; +tinyMCELang['lang_searchreplace_down'] = 'به سمت پايين'; +tinyMCELang['lang_searchreplace_case'] = 'تطبيق حروف کوچک و بزرگ'; +tinyMCELang['lang_searchreplace_findnext'] = 'مورد-بعدي'; +tinyMCELang['lang_searchreplace_replace'] = 'جايگزين-کن'; +tinyMCELang['lang_searchreplace_replaceall'] = 'جايگزيني-همه'; +tinyMCELang['lang_searchreplace_cancel'] = 'بيخيال'; diff --git a/public/tiny_mce/plugins/searchreplace/langs/fr.js b/public/tiny_mce/plugins/searchreplace/langs/fr.js new file mode 100644 index 0000000..1cedfc9 --- /dev/null +++ b/public/tiny_mce/plugins/searchreplace/langs/fr.js @@ -0,0 +1,19 @@ +// Franch lang variables by Laurent Dran + +tinyMCELang['lang_searchreplace_search_desc'] = 'Trouver'; +tinyMCELang['lang_searchreplace_searchnext_desc'] = 'Trouver encore'; +tinyMCELang['lang_searchreplace_replace_desc'] = 'Trouver/Remplacer'; +tinyMCELang['lang_searchreplace_notfound'] = 'Votre recherche a été compléé. La recherche de la chaine pourra ne pas aboutir.'; +tinyMCELang['lang_searchreplace_search_title'] = 'Trouver'; +tinyMCELang['lang_searchreplace_replace_title'] = 'Trouver/Remplacer'; +tinyMCELang['lang_searchreplace_allreplaced'] = 'Toutes les occurences de la chaine ont été remplcées.'; +tinyMCELang['lang_searchreplace_findwhat'] = 'Trouver le mot'; +tinyMCELang['lang_searchreplace_replacewith'] = 'Remplacer avec'; +tinyMCELang['lang_searchreplace_direction'] = 'Direction'; +tinyMCELang['lang_searchreplace_up'] = 'Haut'; +tinyMCELang['lang_searchreplace_down'] = 'Base'; +tinyMCELang['lang_searchreplace_case'] = 'Respecter la casse'; +tinyMCELang['lang_searchreplace_findnext'] = 'Trouver le prochain'; +tinyMCELang['lang_searchreplace_replace'] = 'Remplacer'; +tinyMCELang['lang_searchreplace_replaceall'] = 'Remplacer tout'; +tinyMCELang['lang_searchreplace_cancel'] = 'Annuler'; diff --git a/public/tiny_mce/plugins/searchreplace/langs/fr_ca.js b/public/tiny_mce/plugins/searchreplace/langs/fr_ca.js new file mode 100644 index 0000000..04dd1fa --- /dev/null +++ b/public/tiny_mce/plugins/searchreplace/langs/fr_ca.js @@ -0,0 +1,20 @@ +// CA_FR lang variables + +tinyMCELang['lang_searchreplace_search_desc'] = 'Chercher'; +tinyMCELang['lang_searchreplace_searchnext_desc'] = 'Chercher suivant'; +tinyMCELang['lang_searchreplace_replace_desc'] = 'Chercher/Remplacer'; +tinyMCELang['lang_searchreplace_notfound'] = 'La recherche est termine. Aucune occurence trouve.'; +tinyMCELang['lang_searchreplace_search_title'] = 'Chercher'; +tinyMCELang['lang_searchreplace_replace_title'] = 'Chercher/Remplacer'; +tinyMCELang['lang_searchreplace_allreplaced'] = 'Toutes les occurences ont t remplaces.'; +tinyMCELang['lang_searchreplace_findwhat'] = 'Chercher quoi'; +tinyMCELang['lang_searchreplace_replacewith'] = 'Remplacer par'; +tinyMCELang['lang_searchreplace_direction'] = 'Direction'; +tinyMCELang['lang_searchreplace_up'] = 'Monter'; +tinyMCELang['lang_searchreplace_down'] = 'Descendre'; +tinyMCELang['lang_searchreplace_case'] = 'Sensible la case'; +tinyMCELang['lang_searchreplace_findnext'] = 'Chercher suivant'; +tinyMCELang['lang_searchreplace_replace'] = 'Remplacer'; +tinyMCELang['lang_searchreplace_replaceall'] = 'Remplacer tous'; +tinyMCELang['lang_searchreplace_cancel'] = 'Annuler'; + diff --git a/public/tiny_mce/plugins/searchreplace/langs/pl.js b/public/tiny_mce/plugins/searchreplace/langs/pl.js new file mode 100644 index 0000000..9577b6d --- /dev/null +++ b/public/tiny_mce/plugins/searchreplace/langs/pl.js @@ -0,0 +1,20 @@ +// PL lang variables + + +tinyMCELang['lang_searchreplace_search_desc'] = 'Znajdź'; +tinyMCELang['lang_searchreplace_searchnext_desc'] = 'Znajdź ponownie'; +tinyMCELang['lang_searchreplace_replace_desc'] = 'Znajdź/Zastąp'; +tinyMCELang['lang_searchreplace_notfound'] = 'Ukończono wyszukiwanie. Poszukiwana fraza nie została odnaleziona.'; +tinyMCELang['lang_searchreplace_search_title'] = 'Znajdź'; +tinyMCELang['lang_searchreplace_replace_title'] = 'Znajdź/Zastąp'; +tinyMCELang['lang_searchreplace_allreplaced'] = 'Wszystkie wystąpienia poszukiwanej frazy zostały zastąpione. '; +tinyMCELang['lang_searchreplace_findwhat'] = 'Znajdź'; +tinyMCELang['lang_searchreplace_replacewith'] = 'Zastąp'; +tinyMCELang['lang_searchreplace_direction'] = 'Kierunek'; +tinyMCELang['lang_searchreplace_up'] = 'Do góry'; +tinyMCELang['lang_searchreplace_down'] = 'Do dołu'; +tinyMCELang['lang_searchreplace_case'] = 'Wielkość liter'; +tinyMCELang['lang_searchreplace_findnext'] = 'Znajdź następny'; +tinyMCELang['lang_searchreplace_replace'] = 'Zastąp'; +tinyMCELang['lang_searchreplace_replaceall'] = 'Zastąp wszystkie'; +tinyMCELang['lang_searchreplace_cancel'] = 'Wyjdź'; diff --git a/public/tiny_mce/plugins/searchreplace/langs/pt_br.js b/public/tiny_mce/plugins/searchreplace/langs/pt_br.js new file mode 100644 index 0000000..13bd51a --- /dev/null +++ b/public/tiny_mce/plugins/searchreplace/langs/pt_br.js @@ -0,0 +1,19 @@ +// pt_BR lang variables + +tinyMCELang['lang_searchreplace_search_desc'] = 'Procurar'; +tinyMCELang['lang_searchreplace_searchnext_desc'] = 'Procurar novamente'; +tinyMCELang['lang_searchreplace_replace_desc'] = 'Procurar/Substituir'; +tinyMCELang['lang_searchreplace_notfound'] = 'A procura foi concluda. A expresso buscada no foi encontrada.'; +tinyMCELang['lang_searchreplace_search_title'] = 'Procurar'; +tinyMCELang['lang_searchreplace_replace_title'] = 'Procurar/Substituir'; +tinyMCELang['lang_searchreplace_allreplaced'] = 'Todas as ocorrncias encontradas foram substitudas.'; +tinyMCELang['lang_searchreplace_findwhat'] = 'Procurar por'; +tinyMCELang['lang_searchreplace_replacewith'] = 'Substituir com'; +tinyMCELang['lang_searchreplace_direction'] = 'Direo'; +tinyMCELang['lang_searchreplace_up'] = 'Acima'; +tinyMCELang['lang_searchreplace_down'] = 'Abaixo'; +tinyMCELang['lang_searchreplace_case'] = 'Procurar exatamente'; +tinyMCELang['lang_searchreplace_findnext'] = 'Procurar prxima'; +tinyMCELang['lang_searchreplace_replace'] = 'Substituir'; +tinyMCELang['lang_searchreplace_replaceall'] = 'Substituir tudo'; +tinyMCELang['lang_searchreplace_cancel'] = 'Cancelar'; diff --git a/public/tiny_mce/plugins/searchreplace/langs/sv.js b/public/tiny_mce/plugins/searchreplace/langs/sv.js new file mode 100644 index 0000000..aac54d3 --- /dev/null +++ b/public/tiny_mce/plugins/searchreplace/langs/sv.js @@ -0,0 +1,19 @@ +// SE lang variables + +tinyMCELang['lang_searchreplace_search_desc'] = 'Sk'; +tinyMCELang['lang_searchreplace_searchnext_desc'] = 'Sk igen'; +tinyMCELang['lang_searchreplace_replace_desc'] = 'Sk/Erstt'; +tinyMCELang['lang_searchreplace_notfound'] = 'Skningen r slutfrd. Skstrngen kunde inte hittas.'; +tinyMCELang['lang_searchreplace_search_title'] = 'Sk'; +tinyMCELang['lang_searchreplace_replace_title'] = 'Sk/Erstt'; +tinyMCELang['lang_searchreplace_allreplaced'] = 'Alla trffar p skstrngen ersattes'; +tinyMCELang['lang_searchreplace_findwhat'] = 'Sk p'; +tinyMCELang['lang_searchreplace_replacewith'] = 'Erstt med'; +tinyMCELang['lang_searchreplace_direction'] = 'Skriktning'; +tinyMCELang['lang_searchreplace_up'] = 'Uppt'; +tinyMCELang['lang_searchreplace_down'] = 'Nert'; +tinyMCELang['lang_searchreplace_case'] = 'Matcha gemener/VERSALER'; +tinyMCELang['lang_searchreplace_findnext'] = 'Sk nsta'; +tinyMCELang['lang_searchreplace_replace'] = 'Erstt'; +tinyMCELang['lang_searchreplace_replaceall'] = 'Erstt alla'; +tinyMCELang['lang_searchreplace_cancel'] = 'Avbryt'; diff --git a/public/tiny_mce/plugins/searchreplace/langs/zh_cn.js b/public/tiny_mce/plugins/searchreplace/langs/zh_cn.js new file mode 100644 index 0000000..8ac7159 --- /dev/null +++ b/public/tiny_mce/plugins/searchreplace/langs/zh_cn.js @@ -0,0 +1,20 @@ +// Simplified Chinese lang variables contributed by cube316 (cube316@gmail.com) +// http://www.cube316.net/ ԻȡTinyMCE֧ + +tinyMCELang['lang_searchreplace_search_desc'] = ''; +tinyMCELang['lang_searchreplace_searchnext_desc'] = 'ٴβ'; +tinyMCELang['lang_searchreplace_replace_desc'] = '/滻'; +tinyMCELang['lang_searchreplace_notfound'] = 'ϣûҵҪҵַ'; +tinyMCELang['lang_searchreplace_search_title'] = ''; +tinyMCELang['lang_searchreplace_replace_title'] = '/滻'; +tinyMCELang['lang_searchreplace_allreplaced'] = 'гֵַ滻ϡ'; +tinyMCELang['lang_searchreplace_findwhat'] = ''; +tinyMCELang['lang_searchreplace_replacewith'] = '滻Ϊ'; +tinyMCELang['lang_searchreplace_direction'] = ''; +tinyMCELang['lang_searchreplace_up'] = ''; +tinyMCELang['lang_searchreplace_down'] = ''; +tinyMCELang['lang_searchreplace_case'] = 'ƥСд'; +tinyMCELang['lang_searchreplace_findnext'] = 'һ'; +tinyMCELang['lang_searchreplace_replace'] = '滻'; +tinyMCELang['lang_searchreplace_replaceall'] = 'ȫ滻'; +tinyMCELang['lang_searchreplace_cancel'] = 'ȡ'; diff --git a/public/tiny_mce/plugins/searchreplace/readme.txt b/public/tiny_mce/plugins/searchreplace/readme.txt new file mode 100644 index 0000000..ca543bf --- /dev/null +++ b/public/tiny_mce/plugins/searchreplace/readme.txt @@ -0,0 +1,18 @@ + searchreplace plugin for TinyMCE +----------------------------- + +About: + This plugin adds search/replace dialogs to TinyMCE. + +Installation instructions: + * Copy the searchreplace directory to the plugins directory of TinyMCE (/jscripts/tiny_mce/plugins). + * Add plugin to TinyMCE plugin option list example: plugins : "searchreplace". + * Add buttons "search,replace" to the button list. + +Initialization example: + tinyMCE.init({ + theme : "advanced", + mode : "textareas", + plugins : "searchreplace", + theme_advanced_buttons1_add : "search,replace", + }); diff --git a/public/tiny_mce/plugins/searchreplace/replace.htm b/public/tiny_mce/plugins/searchreplace/replace.htm new file mode 100644 index 0000000..a5b543e --- /dev/null +++ b/public/tiny_mce/plugins/searchreplace/replace.htm @@ -0,0 +1,88 @@ + + +{$lang_searchreplace_replace_title} + + + + +
    + + + + + + + + + + + + + + + +
    {$lang_searchreplace_findwhat}: 
    {$lang_searchreplace_replacewith}: 
    + + + + + + + +
    {$lang_searchreplace_direction}: {$lang_searchreplace_up}{$lang_searchreplace_down}
    + + + + +
    {$lang_searchreplace_case}
    + + + + + + + +
    +
    + + diff --git a/public/tiny_mce/plugins/searchreplace/search.htm b/public/tiny_mce/plugins/searchreplace/search.htm new file mode 100644 index 0000000..27c2402 --- /dev/null +++ b/public/tiny_mce/plugins/searchreplace/search.htm @@ -0,0 +1,77 @@ + + +{$lang_searchreplace_search_title} + + + + +
    + + + + + + + + + + +
    {$lang_searchreplace_findwhat}: 
    + + + + + + + +
    {$lang_searchreplace_direction}: {$lang_searchreplace_up}{$lang_searchreplace_down}
    + + + + +
    {$lang_searchreplace_case}
    + + + + + +
    +
    + + diff --git a/public/tiny_mce/plugins/table/cell.htm b/public/tiny_mce/plugins/table/cell.htm new file mode 100644 index 0000000..f9778b7 --- /dev/null +++ b/public/tiny_mce/plugins/table/cell.htm @@ -0,0 +1,137 @@ + + +{$lang_table_cell_title} + + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$lang_table_cell_title}
    {$lang_insert_table_align}:{$lang_insert_table_class}:
    {$lang_insert_table_valign}:  
    {$lang_insert_table_width}:{$lang_insert_table_height}:
      
    +
    + + diff --git a/public/tiny_mce/plugins/table/editor_plugin.js b/public/tiny_mce/plugins/table/editor_plugin.js new file mode 100644 index 0000000..839a6d9 --- /dev/null +++ b/public/tiny_mce/plugins/table/editor_plugin.js @@ -0,0 +1,2 @@ +/* Import plugin specific language pack */ + tinyMCE.importPluginLanguagePack('table','en,ar,cs,da,de,el,es,fi,fr_ca,hu,it,ja,ko,nl,no,pl,pt,sv,tw,zh_cn,fr,de');function TinyMCE_table_initInstance(inst){if(tinyMCE.isGecko)tinyMCE.addEvent(inst.getDoc(),"mouseup",TinyMCE_table_mouseDownHandler);inst.tableRowClipboard=null;}function TinyMCE_table_mouseDownHandler(e){var elm=tinyMCE.isMSIE?event.srcElement:e.target;var focusElm=tinyMCE.selectedInstance.getFocusElement();if(elm.nodeName=="BODY"&&(focusElm.nodeName=="TD"||(focusElm.parentNode&&focusElm.parentNode.nodeName=="TD"))){window.setTimeout(function(){var tableElm=tinyMCE.getParentElement(focusElm,"table");tinyMCE.handleVisualAid(tableElm,true,tinyMCE.settings['visual']);},10);}}function TinyMCE_table_getControlHTML(control_name){var controls=new Array(['table','table.gif','{$lang_table_desc}','mceInsertTable',true],['delete_col','table_delete_col.gif','{$lang_table_delete_col_desc}','mceTableDeleteCol'],['delete_row','table_delete_row.gif','{$lang_table_delete_row_desc}','mceTableDeleteRow'],['col_after','table_insert_col_after.gif','{$lang_table_insert_col_after_desc}','mceTableInsertColAfter'],['col_before','table_insert_col_before.gif','{$lang_table_insert_col_before_desc}','mceTableInsertColBefore'],['row_after','table_insert_row_after.gif','{$lang_table_insert_row_after_desc}','mceTableInsertRowAfter'],['row_before','table_insert_row_before.gif','{$lang_table_insert_row_before_desc}','mceTableInsertRowBefore'],['row_props','table_row_props.gif','{$lang_table_row_desc}','mceTableRowProps',true],['cell_props','table_cell_props.gif','{$lang_table_cell_desc}','mceTableCellProps',true],['split_cells','table_split_cells.gif','{$lang_table_split_cells_desc}','mceTableSplitCells',true],['merge_cells','table_merge_cells.gif','{$lang_table_merge_cells_desc}','mceTableMergeCells',true]);for(var i=0;i';else if(but[0]==control_name)return '';}if(control_name=="tablecontrols"){var html="";html+=tinyMCE.getControlHTML("table");html+=tinyMCE.getControlHTML("separator");html+=tinyMCE.getControlHTML("row_props");html+=tinyMCE.getControlHTML("cell_props");html+=tinyMCE.getControlHTML("separator");html+=tinyMCE.getControlHTML("row_before");html+=tinyMCE.getControlHTML("row_after");html+=tinyMCE.getControlHTML("delete_row");html+=tinyMCE.getControlHTML("separator");html+=tinyMCE.getControlHTML("col_before");html+=tinyMCE.getControlHTML("col_after");html+=tinyMCE.getControlHTML("delete_col");html+=tinyMCE.getControlHTML("separator");html+=tinyMCE.getControlHTML("split_cells");html+=tinyMCE.getControlHTML("merge_cells");return html;}return "";}function TinyMCE_table_execCommand(editor_id,element,command,user_interface,value){var inst=tinyMCE.getInstanceById(editor_id);var focusElm=inst.getFocusElement();var trElm=tinyMCE.getParentElement(focusElm,"tr");var tdElm=tinyMCE.getParentElement(focusElm,"td");var tableElm=tinyMCE.getParentElement(focusElm,"table");var doc=inst.contentWindow.document;var tableBorder=tableElm?tableElm.getAttribute("border"):"";if(trElm&&tdElm==null)tdElm=trElm.cells[0];function inArray(ar,v){for(var i=0;i0&&inArray(ar[i],v))return true;if(ar[i]==v)return true;}return false;}function makeTD(){var newTD=doc.createElement("td");newTD.innerHTML=" ";}function getColRowSpan(td){var colspan=tinyMCE.getAttrib(td,"colspan");var rowspan=tinyMCE.getAttrib(td,"rowspan");colspan=colspan==""?1:parseInt(colspan);rowspan=rowspan==""?1:parseInt(rowspan);return{colspan:colspan,rowspan:rowspan};}function getCellPos(grid,td){for(var y=0;y1){for(var i=x;i1)td.rowSpan=sd.rowspan+1;lastElm=td;}deleteMarked(tableElm);}}function prevElm(node,name){while((node=node.previousSibling)!=null){if(node.nodeName==name)return node;}return null;}function nextElm(node,name){while((node=node.nextSibling)!=null){if(node.nodeName==name)return node;}return null;}function deleteMarked(tbl){if(tbl.rows==0)return;var tr=tbl.rows[0];do{var next=nextElm(tr,"TR");if(tr._delete){tr.parentNode.removeChild(tr);continue;}var td=tr.cells[0];if(td.cells>1){do{var nexttd=nextElm(td,"TD");if(td._delete)td.parentNode.removeChild(td);}while((td=nexttd)!=null);}}while((tr=next)!=null);}function addRows(td_elm,tr_elm,rowspan){td_elm.rowSpan=1;var trNext=nextElm(tr_elm,"TR");for(var i=1;icols)cols=rowsAr[i].cells.length;cols=cols;rows=rowsAr.length;border=tinyMCE.getAttrib(tinyMCE.tableElm,'border',border);cellpadding=tinyMCE.getAttrib(tinyMCE.tableElm,'cellpadding',"");cellspacing=tinyMCE.getAttrib(tinyMCE.tableElm,'cellspacing',"");width=tinyMCE.getAttrib(tinyMCE.tableElm,'width',width);height=tinyMCE.getAttrib(tinyMCE.tableElm,'height',height);bordercolor=tinyMCE.getAttrib(tinyMCE.tableElm,'bordercolor',bordercolor);bgcolor=tinyMCE.getAttrib(tinyMCE.tableElm,'bgcolor',bgcolor);align=tinyMCE.getAttrib(tinyMCE.tableElm,'align',align);className=tinyMCE.getVisualAidClass(tinyMCE.getAttrib(tinyMCE.tableElm,'class'),false);if(tinyMCE.isMSIE){width=tinyMCE.tableElm.style.pixelWidth==0?tinyMCE.tableElm.getAttribute("width"):tinyMCE.tableElm.style.pixelWidth;height=tinyMCE.tableElm.style.pixelHeight==0?tinyMCE.tableElm.getAttribute("height"):tinyMCE.tableElm.style.pixelHeight;}action="update";}var template=new Array();template['file']='../../plugins/table/table.htm';if(tinyMCE.settings['table_color_fields']){template['width']=400;template['height']=240;}else{template['width']=340;template['height']=220;}template['width']+=tinyMCE.getLang('lang_insert_table_delta_width',0);template['height']+=tinyMCE.getLang('lang_insert_table_delta_height',0);tinyMCE.openWindow(template,{editor_id:inst.editorId,cols:cols,rows:rows,border:border,cellpadding:cellpadding,cellspacing:cellspacing,align:align,width:width,height:height,bordercolor:bordercolor,bgcolor:bgcolor,action:action,className:className});}else{var html='';var cols=2,rows=2,border=0,cellpadding=-1,cellspacing=-1,align,width,height,className,action;if(typeof(value)=='object'){cols=value['cols'];rows=value['rows'];border=value['border']!=""?value['border']:0;cellpadding=value['cellpadding']!=""?value['cellpadding']:-1;cellspacing=value['cellspacing']!=""?value['cellspacing']:-1;align=value['align'];width=value['width'];height=value['height'];bordercolor=value['bordercolor'];bgcolor=value['bgcolor'];className=value['className'];action=value['action'];}if(tinyMCE.tableElm&&action=="update"){inst.execCommand("mceAddUndoLevel");tinyMCE.setAttrib(tinyMCE.tableElm,'cellPadding',cellpadding,true);tinyMCE.setAttrib(tinyMCE.tableElm,'cellSpacing',cellspacing,true);tinyMCE.setAttrib(tinyMCE.tableElm,'border',border,true);tinyMCE.setAttrib(tinyMCE.tableElm,'width',width,true);tinyMCE.setAttrib(tinyMCE.tableElm,'height',height,true);tinyMCE.setAttrib(tinyMCE.tableElm,'bordercolor',bordercolor);tinyMCE.setAttrib(tinyMCE.tableElm,'bgcolor',bgcolor);tinyMCE.setAttrib(tinyMCE.tableElm,'align',align);tinyMCE.setAttrib(tinyMCE.tableElm,'class',className);if(tinyMCE.isMSIE){tinyMCE.tableElm.style.pixelWidth=(width==null||width=="")?0:width;tinyMCE.tableElm.style.pixelHeight=(height==null||height=="")?0:height;tinyMCE.tableElm.borderColor=bordercolor;tinyMCE.tableElm.bgColor=bgcolor;}tinyMCE.handleVisualAid(tinyMCE.tableElm,false,inst.visualAid);tinyMCE.tableElm.outerHTML=tinyMCE.tableElm.outerHTML;tinyMCE.triggerNodeChange();return true;}html+='";for(var x=0;x ';html+="";}html+="
    ";inst.execCommand('mceInsertContent',false,html);tinyMCE.handleVisualAid(inst.getBody(),true,tinyMCE.settings['visual']);}return true;case "mceTableSplitCells":case "mceTableMergeCells":case "mceTableInsertRowBefore":case "mceTableInsertRowAfter":case "mceTableDeleteRow":case "mceTableInsertColBefore":case "mceTableInsertColAfter":case "mceTableDeleteCol":case "mceTableCutRow":case "mceTableCopyRow":case "mceTablePasteRowBefore":case "mceTablePasteRowAfter":inst.execCommand("mceAddUndoLevel");if(!tableElm)return true;if(tableElm.firstChild&&tableElm.firstChild.nodeName.toLowerCase()=="tbody")tableElm=tableElm.firstChild;if(tableElm&&trElm){switch(command){case "mceTableInsertRowBefore":if(!trElm||!tdElm)return true;var grid=getTableGrid(tableElm);var cpos=getCellPos(grid,tdElm);var newTR=doc.createElement("tr");var lastTDElm=null;cpos.rowindex--;if(cpos.rowindex<0)cpos.rowindex=0;for(var x=0;tdElm=getCell(grid,cpos.rowindex,x);x++){if(tdElm!=lastTDElm){var sd=getColRowSpan(tdElm);if(sd['rowspan']==1){var newTD=doc.createElement("td");newTD.innerHTML=" ";newTD.colSpan=tdElm.colSpan;newTR.appendChild(newTD);}else tdElm.rowSpan=sd['rowspan']+1;lastTDElm=tdElm;}}trElm.parentNode.insertBefore(newTR,trElm);break;case "mceTableCutRow":if(!trElm||!tdElm)return true;inst.tableRowClipboard=copyRow(doc,tableElm,trElm);inst.execCommand("mceTableDeleteRow");break;case "mceTableCopyRow":if(!trElm||!tdElm)return true;inst.tableRowClipboard=copyRow(doc,tableElm,trElm);break;case "mceTablePasteRowBefore":if(!trElm||!tdElm)return true;var newTR=inst.tableRowClipboard.cloneNode(true);var prevTR=prevElm(trElm,"TR");if(prevTR!=null)trimRow(tableElm,prevTR,prevTR.cells[0],newTR);trElm.parentNode.insertBefore(newTR,trElm);break;case "mceTablePasteRowAfter":if(!trElm||!tdElm)return true;var nextTR=nextElm(trElm,"TR");var newTR=inst.tableRowClipboard.cloneNode(true);trimRow(tableElm,trElm,tdElm,newTR);if(nextTR==null)trElm.parentNode.appendChild(newTR);else nextTR.parentNode.insertBefore(newTR,nextTR);break;case "mceTableInsertRowAfter":if(!trElm||!tdElm)return true;var grid=getTableGrid(tableElm);var cpos=getCellPos(grid,tdElm);var newTR=doc.createElement("tr");var lastTDElm=null;for(var x=0;tdElm=getCell(grid,cpos.rowindex,x);x++){if(tdElm!=lastTDElm){var sd=getColRowSpan(tdElm);if(sd['rowspan']==1){var newTD=doc.createElement("td");newTD.innerHTML=" ";newTD.colSpan=tdElm.colSpan;newTR.appendChild(newTD);}else tdElm.rowSpan=sd['rowspan']+1;lastTDElm=tdElm;}}if(newTR.hasChildNodes()){var nextTR=nextElm(trElm,"TR");if(nextTR)nextTR.parentNode.insertBefore(newTR,nextTR);else tableElm.appendChild(newTR);}break;case "mceTableDeleteRow":if(!trElm||!tdElm)return true;var grid=getTableGrid(tableElm);var cpos=getCellPos(grid,tdElm);if(grid.length==1){tableElm.parentNode.removeChild(tableElm);return true;}var cells=trElm.cells;var nextTR=nextElm(trElm,"TR");for(var x=0;x1){var newTD=cells[x].cloneNode(true);var sd=getColRowSpan(cells[x]);newTD.rowSpan=sd.rowspan-1;var nextTD=nextTR.cells[x];if(nextTD==null)nextTR.appendChild(newTD);else nextTR.insertBefore(newTD,nextTD);}}var lastTDElm=null;for(var x=0;tdElm=getCell(grid,cpos.rowindex,x);x++){if(tdElm!=lastTDElm){var sd=getColRowSpan(tdElm);if(sd.rowspan>1){tdElm.rowSpan=sd.rowspan-1;}else{trElm=tdElm.parentNode;if(trElm.parentNode)trElm._delete=true;}lastTDElm=tdElm;}}deleteMarked(tableElm);cpos.rowindex--;if(cpos.rowindex<0)cpos.rowindex=0;inst.selectNode(getCell(grid,cpos.rowindex,0),true,true);break;case "mceTableInsertColBefore":if(!trElm||!tdElm)return true;var grid=getTableGrid(tableElm);var cpos=getCellPos(grid,tdElm);var lastTDElm=null;for(var y=0;tdElm=getCell(grid,y,cpos.cellindex);y++){if(tdElm!=lastTDElm){var sd=getColRowSpan(tdElm);if(sd['colspan']==1){var newTD=doc.createElement("td");newTD.innerHTML=" ";newTD.rowSpan=tdElm.rowSpan;tdElm.parentNode.insertBefore(newTD,tdElm);}else tdElm.colSpan++;lastTDElm=tdElm;}}break;case "mceTableInsertColAfter":if(!trElm||!tdElm)return true;var grid=getTableGrid(tableElm);var cpos=getCellPos(grid,tdElm);var lastTDElm=null;for(var y=0;tdElm=getCell(grid,y,cpos.cellindex);y++){if(tdElm!=lastTDElm){var sd=getColRowSpan(tdElm);if(sd['colspan']==1){var newTD=doc.createElement("td");newTD.innerHTML=" ";newTD.rowSpan=tdElm.rowSpan;var nextTD=nextElm(tdElm,"TD");if(nextTD==null)tdElm.parentNode.appendChild(newTD);else nextTD.parentNode.insertBefore(newTD,nextTD);}else tdElm.colSpan++;lastTDElm=tdElm;}}break;case "mceTableDeleteCol":if(!trElm||!tdElm)return true;var grid=getTableGrid(tableElm);var cpos=getCellPos(grid,tdElm);var lastTDElm=null;if(grid.length>1&&grid[0].length<=1){tableElm.parentNode.removeChild(tableElm);return true;}for(var y=0;tdElm=getCell(grid,y,cpos.cellindex);y++){if(tdElm!=lastTDElm){var sd=getColRowSpan(tdElm);if(sd['colspan']>1)tdElm.colSpan=sd['colspan']-1;else{if(tdElm.parentNode)tdElm.parentNode.removeChild(tdElm);}lastTDElm=tdElm;}}cpos.cellindex--;if(cpos.cellindex<0)cpos.cellindex=0;inst.selectNode(getCell(grid,0,cpos.cellindex),true,true);break;case "mceTableSplitCells":if(!trElm||!tdElm)return true;var spandata=getColRowSpan(tdElm);var colspan=spandata["colspan"];var rowspan=spandata["rowspan"];if(colspan>1||rowspan>1){tdElm.colSpan=1;for(var i=1;i1)addRows(newTD,trElm,rowspan);}addRows(tdElm,trElm,rowspan);}tableElm=tinyMCE.getParentElement(inst.getFocusElement(),"table");break;case "mceTableMergeCells":var rows=new Array();var sel=inst.getSel();var grid=getTableGrid(tableElm);if(tinyMCE.isMSIE||sel.rangeCount==1){if(user_interface){var template=new Array();var sp=getColRowSpan(tdElm);template['file']='../../plugins/table/merge_cells.htm';template['width']=160;template['height']=220;tinyMCE.openWindow(template,{editor_id:inst.editorId,action:"update",numcols:sp.colspan,numrows:sp.rowspan});return true;}else{var numRows=parseInt(value['numrows']);var numCols=parseInt(value['numcols']);var cpos=getCellPos(grid,tdElm);if((""+numRows)=="NaN")numRows=1;if((""+numCols)=="NaN")numCols=1;var tRows=tableElm.rows;for(var y=cpos.rowindex;y0)rows[rows.length]=rowCells;}}}else{var cells=new Array();var sel=inst.getSel();var lastTR=null;var curRow=null;var x1=-1,y1=-1,x2,y2;if(sel.rangeCount<2)return true;for(var i=0;i0)rows[rows.length]=rowCells;}var curRow=new Array();var lastTR=null;for(var y=0;ycolSpan)colSpan=rowColSpan;lastRowSpan=-1;}var lastColSpan=-1;for(var x=0;xrowSpan)rowSpan=colRowSpan;lastColSpan=-1;}tdElm=rows[0][0];tdElm.rowSpan=rowSpan;tdElm.colSpan=colSpan;for(var y=0;y0))tdElm.innerHTML+=html;if(rows[y][x]!=tdElm&&!rows[y][x]._deleted){var cpos=getCellPos(grid,rows[y][x]);var tr=rows[y][x].parentNode;tr.removeChild(rows[y][x]);rows[y][x]._deleted=true;if(!tr.hasChildNodes()){tr.parentNode.removeChild(tr);var lastCell=null;for(var x=0;cellElm=getCell(grid,cpos.rowindex,x);x++){if(cellElm!=lastCell&&cellElm.rowSpan>1)cellElm.rowSpan--;lastCell=cellElm;}if(tdElm.rowSpan>1)tdElm.rowSpan--;}}}}break;}tableElm=tinyMCE.getParentElement(inst.getFocusElement(),"table");tinyMCE.handleVisualAid(tableElm,true,tinyMCE.settings['visual']);tinyMCE.triggerNodeChange();inst.repaint();}return true;}return false;}function TinyMCE_table_handleNodeChange(editor_id,node,undo_index,undo_levels,visual_aid,any_selection){var colspan="1",rowspan="1";var inst=tinyMCE.getInstanceById(editor_id);tinyMCE.switchClassSticky(editor_id+'_table','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_row_props','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_cell_props','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_row_before','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_row_after','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_delete_row','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_col_before','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_col_after','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_delete_col','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_split_cells','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_merge_cells','mceButtonDisabled',true);if(tinyMCE.getParentElement(node,"tr"))tinyMCE.switchClassSticky(editor_id+'_row_props','mceButtonSelected',false);if(tdElm=tinyMCE.getParentElement(node,"td")){tinyMCE.switchClassSticky(editor_id+'_cell_props','mceButtonSelected',false);tinyMCE.switchClassSticky(editor_id+'_row_before','mceButtonNormal',false);tinyMCE.switchClassSticky(editor_id+'_row_after','mceButtonNormal',false);tinyMCE.switchClassSticky(editor_id+'_delete_row','mceButtonNormal',false);tinyMCE.switchClassSticky(editor_id+'_col_before','mceButtonNormal',false);tinyMCE.switchClassSticky(editor_id+'_col_after','mceButtonNormal',false);tinyMCE.switchClassSticky(editor_id+'_delete_col','mceButtonNormal',false);colspan=tinyMCE.getAttrib(tdElm,"colspan");rowspan=tinyMCE.getAttrib(tdElm,"rowspan");colspan=colspan==""?"1":colspan;rowspan=rowspan==""?"1":rowspan;if(colspan!="1"||rowspan!="1")tinyMCE.switchClassSticky(editor_id+'_split_cells','mceButtonNormal',false);}if(tinyMCE.getParentElement(node,"table")){tinyMCE.switchClassSticky(editor_id+'_table','mceButtonSelected');tinyMCE.switchClassSticky(editor_id+'_merge_cells','mceButtonNormal',false);}} \ No newline at end of file diff --git a/public/tiny_mce/plugins/table/editor_plugin_src.js b/public/tiny_mce/plugins/table/editor_plugin_src.js new file mode 100644 index 0000000..dde12a2 --- /dev/null +++ b/public/tiny_mce/plugins/table/editor_plugin_src.js @@ -0,0 +1,1142 @@ +/* Import plugin specific language pack */ +tinyMCE.importPluginLanguagePack('table', 'en,ar,cs,da,de,el,es,fi,fr_ca,hu,it,ja,ko,nl,no,pl,pt,sv,tw,zh_cn,fr,de'); + +function TinyMCE_table_initInstance(inst) { + if (tinyMCE.isGecko) + tinyMCE.addEvent(inst.getDoc(), "mouseup", TinyMCE_table_mouseDownHandler); + + inst.tableRowClipboard = null; +} + +function TinyMCE_table_mouseDownHandler(e) { + var elm = tinyMCE.isMSIE ? event.srcElement : e.target; + var focusElm = tinyMCE.selectedInstance.getFocusElement(); + + // If press on special Mozilla create TD/TR thingie + if (elm.nodeName == "BODY" && (focusElm.nodeName == "TD" || (focusElm.parentNode && focusElm.parentNode.nodeName == "TD"))) { + window.setTimeout(function() { + var tableElm = tinyMCE.getParentElement(focusElm, "table"); + tinyMCE.handleVisualAid(tableElm, true, tinyMCE.settings['visual']); + }, 10); + } +} + +/** + * Returns the HTML contents of the table control. + */ +function TinyMCE_table_getControlHTML(control_name) { + var controls = new Array( + ['table', 'table.gif', '{$lang_table_desc}', 'mceInsertTable', true], + ['delete_col', 'table_delete_col.gif', '{$lang_table_delete_col_desc}', 'mceTableDeleteCol'], + ['delete_row', 'table_delete_row.gif', '{$lang_table_delete_row_desc}', 'mceTableDeleteRow'], + ['col_after', 'table_insert_col_after.gif', '{$lang_table_insert_col_after_desc}', 'mceTableInsertColAfter'], + ['col_before', 'table_insert_col_before.gif', '{$lang_table_insert_col_before_desc}', 'mceTableInsertColBefore'], + ['row_after', 'table_insert_row_after.gif', '{$lang_table_insert_row_after_desc}', 'mceTableInsertRowAfter'], + ['row_before', 'table_insert_row_before.gif', '{$lang_table_insert_row_before_desc}', 'mceTableInsertRowBefore'], + ['row_props', 'table_row_props.gif', '{$lang_table_row_desc}', 'mceTableRowProps', true], + ['cell_props', 'table_cell_props.gif', '{$lang_table_cell_desc}', 'mceTableCellProps', true], + ['split_cells', 'table_split_cells.gif', '{$lang_table_split_cells_desc}', 'mceTableSplitCells', true], + ['merge_cells', 'table_merge_cells.gif', '{$lang_table_merge_cells_desc}', 'mceTableMergeCells', true]); + + // Render table control + for (var i=0; i'; + else if (but[0] == control_name) + return ''; + } + + // Special tablecontrols + if (control_name == "tablecontrols") { + var html = ""; + + html += tinyMCE.getControlHTML("table"); + html += tinyMCE.getControlHTML("separator"); + html += tinyMCE.getControlHTML("row_props"); + html += tinyMCE.getControlHTML("cell_props"); + html += tinyMCE.getControlHTML("separator"); + html += tinyMCE.getControlHTML("row_before"); + html += tinyMCE.getControlHTML("row_after"); + html += tinyMCE.getControlHTML("delete_row"); + html += tinyMCE.getControlHTML("separator"); + html += tinyMCE.getControlHTML("col_before"); + html += tinyMCE.getControlHTML("col_after"); + html += tinyMCE.getControlHTML("delete_col"); + html += tinyMCE.getControlHTML("separator"); + html += tinyMCE.getControlHTML("split_cells"); + html += tinyMCE.getControlHTML("merge_cells"); + + return html; + } + + return ""; +} + +/** + * Executes the table commands. + */ +function TinyMCE_table_execCommand(editor_id, element, command, user_interface, value) { + var inst = tinyMCE.getInstanceById(editor_id); + var focusElm = inst.getFocusElement(); + var trElm = tinyMCE.getParentElement(focusElm, "tr"); + var tdElm = tinyMCE.getParentElement(focusElm, "td"); + var tableElm = tinyMCE.getParentElement(focusElm, "table"); + var doc = inst.contentWindow.document; + var tableBorder = tableElm ? tableElm.getAttribute("border") : ""; + + // Get first TD if no TD found + if (trElm && tdElm == null) + tdElm = trElm.cells[0]; + + // ------- Inner functions --------- + function inArray(ar, v) { + for (var i=0; i 0 && inArray(ar[i], v)) + return true; + + // Found value + if (ar[i] == v) + return true; + } + + return false; + } + + function makeTD() { + var newTD = doc.createElement("td"); + newTD.innerHTML = " "; + } + + function getColRowSpan(td) { + var colspan = tinyMCE.getAttrib(td, "colspan"); + var rowspan = tinyMCE.getAttrib(td, "rowspan"); + + colspan = colspan == "" ? 1 : parseInt(colspan); + rowspan = rowspan == "" ? 1 : parseInt(rowspan); + + return {colspan : colspan, rowspan : rowspan}; + } + + function getCellPos(grid, td) { + for (var y=0; y 1) { // Remove due to colspan + for (var i=x; i 1) + td.rowSpan = sd.rowspan + 1; + + lastElm = td; + } + + deleteMarked(tableElm); + } + } + + function prevElm(node, name) { + while ((node = node.previousSibling) != null) { + if (node.nodeName == name) + return node; + } + + return null; + } + + function nextElm(node, name) { + while ((node = node.nextSibling) != null) { + if (node.nodeName == name) + return node; + } + + return null; + } + + function deleteMarked(tbl) { + if (tbl.rows == 0) + return; + + var tr = tbl.rows[0]; + do { + var next = nextElm(tr, "TR"); + + // Delete row + if (tr._delete) { + tr.parentNode.removeChild(tr); + continue; + } + + // Delete cells + var td = tr.cells[0]; + if (td.cells > 1) { + do { + var nexttd = nextElm(td, "TD"); + + if (td._delete) + td.parentNode.removeChild(td); + } while ((td = nexttd) != null); + } + } while ((tr = next) != null); + } + + function addRows(td_elm, tr_elm, rowspan) { + // Add rows + td_elm.rowSpan = 1; + var trNext = nextElm(tr_elm, "TR"); + for (var i=1; i cols) + cols = rowsAr[i].cells.length; + + cols = cols; + rows = rowsAr.length; + + border = tinyMCE.getAttrib(tinyMCE.tableElm, 'border', border); + cellpadding = tinyMCE.getAttrib(tinyMCE.tableElm, 'cellpadding', ""); + cellspacing = tinyMCE.getAttrib(tinyMCE.tableElm, 'cellspacing', ""); + width = tinyMCE.getAttrib(tinyMCE.tableElm, 'width', width); + height = tinyMCE.getAttrib(tinyMCE.tableElm, 'height', height); + bordercolor = tinyMCE.getAttrib(tinyMCE.tableElm, 'bordercolor', bordercolor); + bgcolor = tinyMCE.getAttrib(tinyMCE.tableElm, 'bgcolor', bgcolor); + align = tinyMCE.getAttrib(tinyMCE.tableElm, 'align', align); + className = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(tinyMCE.tableElm, 'class'), false); + + if (tinyMCE.isMSIE) { + width = tinyMCE.tableElm.style.pixelWidth == 0 ? tinyMCE.tableElm.getAttribute("width") : tinyMCE.tableElm.style.pixelWidth; + height = tinyMCE.tableElm.style.pixelHeight == 0 ? tinyMCE.tableElm.getAttribute("height") : tinyMCE.tableElm.style.pixelHeight; + } + + action = "update"; + } + + // Setup template + var template = new Array(); + + template['file'] = '../../plugins/table/table.htm'; + if (tinyMCE.settings['table_color_fields']) { + template['width'] = 400; + template['height'] = 240; + } else { + template['width'] = 340; + template['height'] = 220; + } + + // Language specific width and height addons + template['width'] += tinyMCE.getLang('lang_insert_table_delta_width', 0); + template['height'] += tinyMCE.getLang('lang_insert_table_delta_height', 0); + + // Open window + tinyMCE.openWindow(template, {editor_id : inst.editorId, cols : cols, rows : rows, border : border, cellpadding : cellpadding, cellspacing : cellspacing, align : align, width : width, height : height, bordercolor : bordercolor, bgcolor : bgcolor, action : action, className : className}); + } else { + var html = ''; + var cols = 2, rows = 2, border = 0, cellpadding = -1, cellspacing = -1, align, width, height, className, action; + + if (typeof(value) == 'object') { + cols = value['cols']; + rows = value['rows']; + border = value['border'] != "" ? value['border'] : 0; + cellpadding = value['cellpadding'] != "" ? value['cellpadding'] : -1; + cellspacing = value['cellspacing'] != "" ? value['cellspacing'] : -1; + align = value['align']; + width = value['width']; + height = value['height']; + bordercolor = value['bordercolor']; + bgcolor = value['bgcolor']; + className = value['className']; + action = value['action']; + } + + // Update table + if (tinyMCE.tableElm && action == "update") { + inst.execCommand("mceAddUndoLevel"); + + tinyMCE.setAttrib(tinyMCE.tableElm, 'cellPadding', cellpadding, true); + tinyMCE.setAttrib(tinyMCE.tableElm, 'cellSpacing', cellspacing, true); + tinyMCE.setAttrib(tinyMCE.tableElm, 'border', border, true); + tinyMCE.setAttrib(tinyMCE.tableElm, 'width', width, true); + tinyMCE.setAttrib(tinyMCE.tableElm, 'height', height, true); + tinyMCE.setAttrib(tinyMCE.tableElm, 'bordercolor', bordercolor); + tinyMCE.setAttrib(tinyMCE.tableElm, 'bgcolor', bgcolor); + tinyMCE.setAttrib(tinyMCE.tableElm, 'align', align); + tinyMCE.setAttrib(tinyMCE.tableElm, 'class', className); + + if (tinyMCE.isMSIE) { + tinyMCE.tableElm.style.pixelWidth = (width == null || width == "") ? 0 : width; + tinyMCE.tableElm.style.pixelHeight = (height == null || height == "") ? 0 : height; + tinyMCE.tableElm.borderColor = bordercolor; + tinyMCE.tableElm.bgColor = bgcolor; + } + + tinyMCE.handleVisualAid(tinyMCE.tableElm, false, inst.visualAid); + + // Fix for stange MSIE align bug + tinyMCE.tableElm.outerHTML = tinyMCE.tableElm.outerHTML; + + //inst.contentWindow.dispatchEvent(createEvent("click")); + + tinyMCE.triggerNodeChange(); + return true; + } + + // Create new table + html += ' 1) { + var newTD = cells[x].cloneNode(true); + var sd = getColRowSpan(cells[x]); + + newTD.rowSpan = sd.rowspan - 1; + + var nextTD = nextTR.cells[x]; + + if (nextTD == null) + nextTR.appendChild(newTD); + else + nextTR.insertBefore(newTD, nextTD); + } + } + + // Delete cells + var lastTDElm = null; + for (var x=0; tdElm = getCell(grid, cpos.rowindex, x); x++) { + if (tdElm != lastTDElm) { + var sd = getColRowSpan(tdElm); + + if (sd.rowspan > 1) { + tdElm.rowSpan = sd.rowspan - 1; + } else { + trElm = tdElm.parentNode; + + if (trElm.parentNode) + trElm._delete = true; + } + + lastTDElm = tdElm; + } + } + + deleteMarked(tableElm); + + cpos.rowindex--; + if (cpos.rowindex < 0) + cpos.rowindex = 0; + + inst.selectNode(getCell(grid, cpos.rowindex, 0), true, true); + break; + + case "mceTableInsertColBefore": + if (!trElm || !tdElm) + return true; + + var grid = getTableGrid(tableElm); + var cpos = getCellPos(grid, tdElm); + var lastTDElm = null; + + for (var y=0; tdElm = getCell(grid, y, cpos.cellindex); y++) { + if (tdElm != lastTDElm) { + var sd = getColRowSpan(tdElm); + + if (sd['colspan'] == 1) { + var newTD = doc.createElement("td"); + + newTD.innerHTML = " "; + newTD.rowSpan = tdElm.rowSpan; + + tdElm.parentNode.insertBefore(newTD, tdElm); + } else + tdElm.colSpan++; + + lastTDElm = tdElm; + } + } + break; + + case "mceTableInsertColAfter": + if (!trElm || !tdElm) + return true; + + var grid = getTableGrid(tableElm); + var cpos = getCellPos(grid, tdElm); + var lastTDElm = null; + + for (var y=0; tdElm = getCell(grid, y, cpos.cellindex); y++) { + if (tdElm != lastTDElm) { + var sd = getColRowSpan(tdElm); + + if (sd['colspan'] == 1) { + var newTD = doc.createElement("td"); + + newTD.innerHTML = " "; + newTD.rowSpan = tdElm.rowSpan; + + var nextTD = nextElm(tdElm, "TD"); + if (nextTD == null) + tdElm.parentNode.appendChild(newTD); + else + nextTD.parentNode.insertBefore(newTD, nextTD); + } else + tdElm.colSpan++; + + lastTDElm = tdElm; + } + } + break; + + case "mceTableDeleteCol": + if (!trElm || !tdElm) + return true; + + var grid = getTableGrid(tableElm); + var cpos = getCellPos(grid, tdElm); + var lastTDElm = null; + + // Only one col, remove whole table + if (grid.length > 1 && grid[0].length <= 1) { + tableElm.parentNode.removeChild(tableElm); + return true; + } + + // Delete cells + for (var y=0; tdElm = getCell(grid, y, cpos.cellindex); y++) { + if (tdElm != lastTDElm) { + var sd = getColRowSpan(tdElm); + + if (sd['colspan'] > 1) + tdElm.colSpan = sd['colspan'] - 1; + else { + if (tdElm.parentNode) + tdElm.parentNode.removeChild(tdElm); + } + + lastTDElm = tdElm; + } + } + + cpos.cellindex--; + if (cpos.cellindex < 0) + cpos.cellindex = 0; + + inst.selectNode(getCell(grid, 0, cpos.cellindex), true, true); + break; + + case "mceTableSplitCells": + if (!trElm || !tdElm) + return true; + + var spandata = getColRowSpan(tdElm); + + var colspan = spandata["colspan"]; + var rowspan = spandata["rowspan"]; + + // Needs splitting + if (colspan > 1 || rowspan > 1) { + // Generate cols + tdElm.colSpan = 1; + for (var i=1; i 1) + addRows(newTD, trElm, rowspan); + } + + addRows(tdElm, trElm, rowspan); + } + + // Apply visual aids + tableElm = tinyMCE.getParentElement(inst.getFocusElement(), "table"); + break; + + case "mceTableMergeCells": + var rows = new Array(); + var sel = inst.getSel(); + var grid = getTableGrid(tableElm); + + if (tinyMCE.isMSIE || sel.rangeCount == 1) { + if (user_interface) { + // Setup template + var template = new Array(); + var sp = getColRowSpan(tdElm); + + template['file'] = '../../plugins/table/merge_cells.htm'; + template['width'] = 160; + template['height'] = 220; + + // Open window + tinyMCE.openWindow(template, {editor_id : inst.editorId, action : "update", numcols : sp.colspan, numrows : sp.rowspan}); + + return true; + } else { + var numRows = parseInt(value['numrows']); + var numCols = parseInt(value['numcols']); + var cpos = getCellPos(grid, tdElm); + + if (("" + numRows) == "NaN") + numRows = 1; + + if (("" + numCols) == "NaN") + numCols = 1; + + // Get rows and cells + var tRows = tableElm.rows; + for (var y=cpos.rowindex; y 0) + rows[rows.length] = rowCells; + } + + //return true; + } + } else { + var cells = new Array(); + var sel = inst.getSel(); + var lastTR = null; + var curRow = null; + var x1 = -1, y1 = -1, x2, y2; + + // Only one cell selected, whats the point? + if (sel.rangeCount < 2) + return true; + + // Get all selected cells + for (var i=0; i 0) + rows[rows.length] = rowCells; + } + + // Find selected cells in grid and box + var curRow = new Array(); + var lastTR = null; + for (var y=0; y colSpan) + colSpan = rowColSpan; + + lastRowSpan = -1; + } + + // Validate vertical and get total rowspan + var lastColSpan = -1; + for (var x=0; x rowSpan) + rowSpan = colRowSpan; + + lastColSpan = -1; + } + + // Setup td + tdElm = rows[0][0]; + tdElm.rowSpan = rowSpan; + tdElm.colSpan = colSpan; + + // Merge cells + for (var y=0; y 0)) + tdElm.innerHTML += html; + + // Not current cell + if (rows[y][x] != tdElm && !rows[y][x]._deleted) { + var cpos = getCellPos(grid, rows[y][x]); + var tr = rows[y][x].parentNode; + + tr.removeChild(rows[y][x]); + rows[y][x]._deleted = true; + + // Empty TR, remove it + if (!tr.hasChildNodes()) { + tr.parentNode.removeChild(tr); + + var lastCell = null; + for (var x=0; cellElm = getCell(grid, cpos.rowindex, x); x++) { + if (cellElm != lastCell && cellElm.rowSpan > 1) + cellElm.rowSpan--; + + lastCell = cellElm; + } + + if (tdElm.rowSpan > 1) + tdElm.rowSpan--; + } + } + } + } + + break; + } + + tableElm = tinyMCE.getParentElement(inst.getFocusElement(), "table"); + tinyMCE.handleVisualAid(tableElm, true, tinyMCE.settings['visual']); + tinyMCE.triggerNodeChange(); + inst.repaint(); + } + + return true; + } + + // Pass to next handler in chain + return false; +} + +function TinyMCE_table_handleNodeChange(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) { + var colspan = "1", rowspan = "1"; + + var inst = tinyMCE.getInstanceById(editor_id); + + // Reset table controls + tinyMCE.switchClassSticky(editor_id + '_table', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_row_props', 'mceButtonDisabled', true); + tinyMCE.switchClassSticky(editor_id + '_cell_props', 'mceButtonDisabled', true); + tinyMCE.switchClassSticky(editor_id + '_row_before', 'mceButtonDisabled', true); + tinyMCE.switchClassSticky(editor_id + '_row_after', 'mceButtonDisabled', true); + tinyMCE.switchClassSticky(editor_id + '_delete_row', 'mceButtonDisabled', true); + tinyMCE.switchClassSticky(editor_id + '_col_before', 'mceButtonDisabled', true); + tinyMCE.switchClassSticky(editor_id + '_col_after', 'mceButtonDisabled', true); + tinyMCE.switchClassSticky(editor_id + '_delete_col', 'mceButtonDisabled', true); + tinyMCE.switchClassSticky(editor_id + '_split_cells', 'mceButtonDisabled', true); + tinyMCE.switchClassSticky(editor_id + '_merge_cells', 'mceButtonDisabled', true); + + // Within a tr element + if (tinyMCE.getParentElement(node, "tr")) + tinyMCE.switchClassSticky(editor_id + '_row_props', 'mceButtonSelected', false); + + // Within a td element + if (tdElm = tinyMCE.getParentElement(node, "td")) { + tinyMCE.switchClassSticky(editor_id + '_cell_props', 'mceButtonSelected', false); + tinyMCE.switchClassSticky(editor_id + '_row_before', 'mceButtonNormal', false); + tinyMCE.switchClassSticky(editor_id + '_row_after', 'mceButtonNormal', false); + tinyMCE.switchClassSticky(editor_id + '_delete_row', 'mceButtonNormal', false); + tinyMCE.switchClassSticky(editor_id + '_col_before', 'mceButtonNormal', false); + tinyMCE.switchClassSticky(editor_id + '_col_after', 'mceButtonNormal', false); + tinyMCE.switchClassSticky(editor_id + '_delete_col', 'mceButtonNormal', false); + + colspan = tinyMCE.getAttrib(tdElm, "colspan"); + rowspan = tinyMCE.getAttrib(tdElm, "rowspan"); + + colspan = colspan == "" ? "1" : colspan; + rowspan = rowspan == "" ? "1" : rowspan; + + if (colspan != "1" || rowspan != "1") + tinyMCE.switchClassSticky(editor_id + '_split_cells', 'mceButtonNormal', false); + } + + // Within table + if (tinyMCE.getParentElement(node, "table")) { + tinyMCE.switchClassSticky(editor_id + '_table', 'mceButtonSelected'); + tinyMCE.switchClassSticky(editor_id + '_merge_cells', 'mceButtonNormal', false); + } +} diff --git a/public/tiny_mce/plugins/table/images/buttons.gif b/public/tiny_mce/plugins/table/images/buttons.gif new file mode 100644 index 0000000..e5eacbf Binary files /dev/null and b/public/tiny_mce/plugins/table/images/buttons.gif differ diff --git a/public/tiny_mce/plugins/table/images/table.gif b/public/tiny_mce/plugins/table/images/table.gif new file mode 100644 index 0000000..f8a0054 Binary files /dev/null and b/public/tiny_mce/plugins/table/images/table.gif differ diff --git a/public/tiny_mce/plugins/table/images/table_cell_props.gif b/public/tiny_mce/plugins/table/images/table_cell_props.gif new file mode 100644 index 0000000..9e0f373 Binary files /dev/null and b/public/tiny_mce/plugins/table/images/table_cell_props.gif differ diff --git a/public/tiny_mce/plugins/table/images/table_delete_col.gif b/public/tiny_mce/plugins/table/images/table_delete_col.gif new file mode 100644 index 0000000..0b2f0fb Binary files /dev/null and b/public/tiny_mce/plugins/table/images/table_delete_col.gif differ diff --git a/public/tiny_mce/plugins/table/images/table_delete_row.gif b/public/tiny_mce/plugins/table/images/table_delete_row.gif new file mode 100644 index 0000000..1997065 Binary files /dev/null and b/public/tiny_mce/plugins/table/images/table_delete_row.gif differ diff --git a/public/tiny_mce/plugins/table/images/table_insert_col_after.gif b/public/tiny_mce/plugins/table/images/table_insert_col_after.gif new file mode 100644 index 0000000..c30dafa Binary files /dev/null and b/public/tiny_mce/plugins/table/images/table_insert_col_after.gif differ diff --git a/public/tiny_mce/plugins/table/images/table_insert_col_before.gif b/public/tiny_mce/plugins/table/images/table_insert_col_before.gif new file mode 100644 index 0000000..5d1ff37 Binary files /dev/null and b/public/tiny_mce/plugins/table/images/table_insert_col_before.gif differ diff --git a/public/tiny_mce/plugins/table/images/table_insert_row_after.gif b/public/tiny_mce/plugins/table/images/table_insert_row_after.gif new file mode 100644 index 0000000..c3aa15f Binary files /dev/null and b/public/tiny_mce/plugins/table/images/table_insert_row_after.gif differ diff --git a/public/tiny_mce/plugins/table/images/table_insert_row_before.gif b/public/tiny_mce/plugins/table/images/table_insert_row_before.gif new file mode 100644 index 0000000..c3271e5 Binary files /dev/null and b/public/tiny_mce/plugins/table/images/table_insert_row_before.gif differ diff --git a/public/tiny_mce/plugins/table/images/table_merge_cells.gif b/public/tiny_mce/plugins/table/images/table_merge_cells.gif new file mode 100644 index 0000000..494887e Binary files /dev/null and b/public/tiny_mce/plugins/table/images/table_merge_cells.gif differ diff --git a/public/tiny_mce/plugins/table/images/table_row_props.gif b/public/tiny_mce/plugins/table/images/table_row_props.gif new file mode 100644 index 0000000..a53cdd8 Binary files /dev/null and b/public/tiny_mce/plugins/table/images/table_row_props.gif differ diff --git a/public/tiny_mce/plugins/table/images/table_split_cells.gif b/public/tiny_mce/plugins/table/images/table_split_cells.gif new file mode 100644 index 0000000..b86179a Binary files /dev/null and b/public/tiny_mce/plugins/table/images/table_split_cells.gif differ diff --git a/public/tiny_mce/plugins/table/langs/ar.js b/public/tiny_mce/plugins/table/langs/ar.js new file mode 100644 index 0000000..9e474b5 --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/ar.js @@ -0,0 +1,41 @@ +// Arabic lang variables + +tinyMCELang['lang_table_desc'] = 'إدراج/تحرير جدول'; +tinyMCELang['lang_table_insert_row_before_desc'] = 'Insert row before'; +tinyMCELang['lang_table_insert_row_after_desc'] = 'Insert row after'; +tinyMCELang['lang_table_delete_row_desc'] = 'حذف صفوف'; +tinyMCELang['lang_table_insert_col_before_desc'] = 'Insert column before'; +tinyMCELang['lang_table_insert_col_after_desc'] = 'Insert column after'; +tinyMCELang['lang_table_delete_col_desc'] = 'حذف أعمدة'; +tinyMCELang['lang_insert_table_title'] = 'إدراج/تحرير جدول'; +tinyMCELang['lang_insert_table_width'] = 'العرض'; +tinyMCELang['lang_insert_table_height'] = 'الارتفاع'; +tinyMCELang['lang_insert_table_cols'] = 'أعمدة'; +tinyMCELang['lang_insert_table_rows'] = 'صفوف'; +tinyMCELang['lang_insert_table_cellspacing'] = 'تباعد الخلايا'; +tinyMCELang['lang_insert_table_cellpadding'] = 'المسافة البادئة'; +tinyMCELang['lang_insert_table_border'] = 'سمك الحدود'; +tinyMCELang['lang_insert_table_align'] = 'المحاذاة'; +tinyMCELang['lang_insert_table_align_default'] = 'Default'; +tinyMCELang['lang_insert_table_align_left'] = 'يسار'; +tinyMCELang['lang_insert_table_align_right'] = 'يمين'; +tinyMCELang['lang_insert_table_align_middle'] = 'وسط'; +tinyMCELang['lang_insert_table_class'] = 'Class'; +tinyMCELang['lang_table_row_title'] = 'Table row properties'; +tinyMCELang['lang_table_cell_title'] = 'Table cell properties'; +tinyMCELang['lang_table_row_desc'] = 'Table row properties'; +tinyMCELang['lang_table_cell_desc'] = 'Table cell properties'; +tinyMCELang['lang_insert_table_valign'] = 'Vertical alignment'; +tinyMCELang['lang_insert_table_align_top'] = 'Top'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Bottom'; +tinyMCELang['lang_table_props_desc'] = 'Table properties'; +tinyMCELang['lang_table_bordercolor'] = 'Border color'; +tinyMCELang['lang_table_bgcolor'] = 'Bg color'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/cs.js b/public/tiny_mce/plugins/table/langs/cs.js new file mode 100644 index 0000000..5d45ada --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/cs.js @@ -0,0 +1,41 @@ +// CZ lang variables thanks to "Pavel Novk" + +tinyMCELang['lang_table_desc'] = 'Vloit novou tabulku'; +tinyMCELang['lang_table_insert_row_before_desc'] = 'Vloit dek ped'; +tinyMCELang['lang_table_insert_row_after_desc'] = 'Vloit dek po'; +tinyMCELang['lang_table_delete_row_desc'] = 'Smazat dek'; +tinyMCELang['lang_table_insert_col_before_desc'] = 'Vloit sloupec ped'; +tinyMCELang['lang_table_insert_col_after_desc'] = 'Vloit sloupec po'; +tinyMCELang['lang_table_delete_col_desc'] = 'Odstranit sloupec'; +tinyMCELang['lang_insert_table_title'] = 'Vloit/upravit tabulku'; +tinyMCELang['lang_insert_table_width'] = 'ka'; +tinyMCELang['lang_insert_table_height'] = 'Vka'; +tinyMCELang['lang_insert_table_cols'] = 'Sloupce'; +tinyMCELang['lang_insert_table_rows'] = 'dky'; +tinyMCELang['lang_insert_table_cellspacing'] = 'Vnj okraj bunk'; +tinyMCELang['lang_insert_table_cellpadding'] = 'Vnitn okraj bunk'; +tinyMCELang['lang_insert_table_border'] = 'Rmeek'; +tinyMCELang['lang_insert_table_align'] = 'Zarovnn'; +tinyMCELang['lang_insert_table_align_default'] = 'Vchoz'; +tinyMCELang['lang_insert_table_align_left'] = 'Vlevo'; +tinyMCELang['lang_insert_table_align_right'] = 'Vpravo'; +tinyMCELang['lang_insert_table_align_middle'] = 'Na sted'; +tinyMCELang['lang_insert_table_class'] = 'Class'; +tinyMCELang['lang_table_row_title'] = 'Table row properties'; +tinyMCELang['lang_table_cell_title'] = 'Table cell properties'; +tinyMCELang['lang_table_row_desc'] = 'Table row properties'; +tinyMCELang['lang_table_cell_desc'] = 'Table cell properties'; +tinyMCELang['lang_insert_table_valign'] = 'Vertical alignment'; +tinyMCELang['lang_insert_table_align_top'] = 'Top'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Bottom'; +tinyMCELang['lang_table_props_desc'] = 'Table properties'; +tinyMCELang['lang_table_bordercolor'] = 'Border color'; +tinyMCELang['lang_table_bgcolor'] = 'Bg color'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/da.js b/public/tiny_mce/plugins/table/langs/da.js new file mode 100644 index 0000000..31d1cf0 --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/da.js @@ -0,0 +1,41 @@ +// DK lang variables contributed by Jan Moelgaard + +tinyMCELang['lang_table_desc'] = 'Indsætter en ny tabel'; +tinyMCELang['lang_table_insert_row_before_desc'] = 'Indsæt række foran'; +tinyMCELang['lang_table_insert_row_after_desc'] = 'Indsæt række efter'; +tinyMCELang['lang_table_delete_row_desc'] = 'Slet række'; +tinyMCELang['lang_table_insert_col_before_desc'] = 'Indsæt kolonne foran'; +tinyMCELang['lang_table_insert_col_after_desc'] = 'Indslt kolonne efter'; +tinyMCELang['lang_table_delete_col_desc'] = 'Fjern kolonne'; +tinyMCELang['lang_insert_table_title'] = 'Indsæt/rediger tabel'; +tinyMCELang['lang_insert_table_width'] = 'Bredde'; +tinyMCELang['lang_insert_table_height'] = 'Højde'; +tinyMCELang['lang_insert_table_cols'] = 'Kolonner'; +tinyMCELang['lang_insert_table_rows'] = 'Rækker'; +tinyMCELang['lang_insert_table_cellspacing'] = 'Afstand mellem celler'; +tinyMCELang['lang_insert_table_cellpadding'] = 'Cellemargen'; +tinyMCELang['lang_insert_table_border'] = 'Kant'; +tinyMCELang['lang_insert_table_align'] = 'Justering'; +tinyMCELang['lang_insert_table_align_default'] = 'Standard'; +tinyMCELang['lang_insert_table_align_left'] = 'Venstre'; +tinyMCELang['lang_insert_table_align_right'] = 'Højre'; +tinyMCELang['lang_insert_table_align_middle'] = 'Midt i'; +tinyMCELang['lang_insert_table_class'] = 'Klasse'; +tinyMCELang['lang_table_row_title'] = 'Table row properties'; +tinyMCELang['lang_table_cell_title'] = 'Table cell properties'; +tinyMCELang['lang_table_row_desc'] = 'Table row properties'; +tinyMCELang['lang_table_cell_desc'] = 'Table cell properties'; +tinyMCELang['lang_insert_table_valign'] = 'Vertical alignment'; +tinyMCELang['lang_insert_table_align_top'] = 'Top'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Bottom'; +tinyMCELang['lang_table_props_desc'] = 'Table properties'; +tinyMCELang['lang_table_bordercolor'] = 'Border color'; +tinyMCELang['lang_table_bgcolor'] = 'Bg color'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/de.js b/public/tiny_mce/plugins/table/langs/de.js new file mode 100644 index 0000000..ed228ae --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/de.js @@ -0,0 +1,41 @@ +// DE lang variables + +tinyMCELang['lang_table_desc'] = 'Neue Tabelle einfügen / Tabelle bearbeiten'; +tinyMCELang['lang_table_insert_row_before_desc'] = 'Zeile davor einfügen'; +tinyMCELang['lang_table_insert_row_after_desc'] = 'Zeile danach einfügen'; +tinyMCELang['lang_table_delete_row_desc'] = 'Zeile löschen'; +tinyMCELang['lang_table_insert_col_before_desc'] = 'Spalte davor einfügen'; +tinyMCELang['lang_table_insert_col_after_desc'] = ' Spalte danach einfügen'; +tinyMCELang['lang_table_delete_col_desc'] = 'Spalte löschen'; +tinyMCELang['lang_insert_table_title'] = 'Tabelle Einfügen/Bearbeiten'; +tinyMCELang['lang_insert_table_width'] = 'Breite'; +tinyMCELang['lang_insert_table_height'] = 'Höhe'; +tinyMCELang['lang_insert_table_cols'] = 'Spalten'; +tinyMCELang['lang_insert_table_rows'] = 'Zeilen'; +tinyMCELang['lang_insert_table_cellspacing'] = 'Außenabstand'; +tinyMCELang['lang_insert_table_cellpadding'] = 'Innenabstand'; +tinyMCELang['lang_insert_table_border'] = 'Rahmen'; +tinyMCELang['lang_insert_table_align'] = 'Ausrichten'; +tinyMCELang['lang_insert_table_align_default'] = 'Normal'; +tinyMCELang['lang_insert_table_align_left'] = 'Links'; +tinyMCELang['lang_insert_table_align_right'] = 'Rechts'; +tinyMCELang['lang_insert_table_align_middle'] = 'Zentriert'; +tinyMCELang['lang_insert_table_class'] = 'Klasse'; +tinyMCELang['lang_table_row_title'] = 'Zeileneigenschaften'; +tinyMCELang['lang_table_cell_title'] = 'Zelleneigenschaften'; +tinyMCELang['lang_table_row_desc'] = 'Reiheneigenschaften'; +tinyMCELang['lang_table_cell_desc'] = 'Zelleneigenschaften'; +tinyMCELang['lang_insert_table_valign'] = 'Vertikale Ausrichtung'; +tinyMCELang['lang_insert_table_align_top'] = 'Oben'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Unten'; +tinyMCELang['lang_table_props_desc'] = 'Tabelleneigenschaften'; +tinyMCELang['lang_table_bordercolor'] = 'Rahmenfarbe'; +tinyMCELang['lang_table_bgcolor'] = 'Hintergrundfarbe'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/el.js b/public/tiny_mce/plugins/table/langs/el.js new file mode 100644 index 0000000..672e6ca --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/el.js @@ -0,0 +1,41 @@ +// Greek lang variables by Jacaranda Bill + +tinyMCELang['lang_table_desc'] = ' '; +tinyMCELang['lang_table_insert_row_before_desc'] = ' '; +tinyMCELang['lang_table_insert_row_after_desc'] = ' '; +tinyMCELang['lang_table_delete_row_desc'] = ' '; +tinyMCELang['lang_table_insert_col_before_desc'] = ' '; +tinyMCELang['lang_table_insert_col_after_desc'] = ' '; +tinyMCELang['lang_table_delete_col_desc'] = ' '; +tinyMCELang['lang_insert_table_title'] = '/ '; +tinyMCELang['lang_insert_table_width'] = ''; +tinyMCELang['lang_insert_table_height'] = ''; +tinyMCELang['lang_insert_table_cols'] = ''; +tinyMCELang['lang_insert_table_rows'] = ''; +tinyMCELang['lang_insert_table_cellspacing'] = ''; +tinyMCELang['lang_insert_table_cellpadding'] = ''; +tinyMCELang['lang_insert_table_border'] = ''; +tinyMCELang['lang_insert_table_align'] = ''; +tinyMCELang['lang_insert_table_align_default'] = '.'; +tinyMCELang['lang_insert_table_align_left'] = ''; +tinyMCELang['lang_insert_table_align_right'] = ''; +tinyMCELang['lang_insert_table_align_middle'] = ' '; +tinyMCELang['lang_insert_table_class'] = ''; +tinyMCELang['lang_table_row_title'] = 'Table row properties'; +tinyMCELang['lang_table_cell_title'] = 'Table cell properties'; +tinyMCELang['lang_table_row_desc'] = 'Table row properties'; +tinyMCELang['lang_table_cell_desc'] = 'Table cell properties'; +tinyMCELang['lang_insert_table_valign'] = 'Vertical alignment'; +tinyMCELang['lang_insert_table_align_top'] = 'Top'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Bottom'; +tinyMCELang['lang_table_props_desc'] = 'Table properties'; +tinyMCELang['lang_table_bordercolor'] = 'Border color'; +tinyMCELang['lang_table_bgcolor'] = 'Bg color'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/en.js b/public/tiny_mce/plugins/table/langs/en.js new file mode 100644 index 0000000..40282c2 --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/en.js @@ -0,0 +1,41 @@ +// UK lang variables + +tinyMCELang['lang_table_desc'] = 'Inserts a new table'; +tinyMCELang['lang_table_insert_row_before_desc'] = 'Insert row before'; +tinyMCELang['lang_table_insert_row_after_desc'] = 'Insert row after'; +tinyMCELang['lang_table_delete_row_desc'] = 'Delete row'; +tinyMCELang['lang_table_insert_col_before_desc'] = 'Insert column before'; +tinyMCELang['lang_table_insert_col_after_desc'] = 'Insert column after'; +tinyMCELang['lang_table_delete_col_desc'] = 'Remove col'; +tinyMCELang['lang_insert_table_title'] = 'Insert/Modify table'; +tinyMCELang['lang_insert_table_width'] = 'Width'; +tinyMCELang['lang_insert_table_height'] = 'Height'; +tinyMCELang['lang_insert_table_cols'] = 'Columns'; +tinyMCELang['lang_insert_table_rows'] = 'Rows'; +tinyMCELang['lang_insert_table_cellspacing'] = 'Cellspacing'; +tinyMCELang['lang_insert_table_cellpadding'] = 'Cellpadding'; +tinyMCELang['lang_insert_table_border'] = 'Border'; +tinyMCELang['lang_insert_table_align'] = 'Alignment'; +tinyMCELang['lang_insert_table_align_default'] = 'Default'; +tinyMCELang['lang_insert_table_align_left'] = 'Left'; +tinyMCELang['lang_insert_table_align_right'] = 'Right'; +tinyMCELang['lang_insert_table_align_middle'] = 'Center'; +tinyMCELang['lang_insert_table_class'] = 'Class'; +tinyMCELang['lang_table_row_title'] = 'Table row properties'; +tinyMCELang['lang_table_cell_title'] = 'Table cell properties'; +tinyMCELang['lang_table_row_desc'] = 'Table row properties'; +tinyMCELang['lang_table_cell_desc'] = 'Table cell properties'; +tinyMCELang['lang_insert_table_valign'] = 'Vertical alignment'; +tinyMCELang['lang_insert_table_align_top'] = 'Top'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Bottom'; +tinyMCELang['lang_table_props_desc'] = 'Table properties'; +tinyMCELang['lang_table_bordercolor'] = 'Border color'; +tinyMCELang['lang_table_bgcolor'] = 'Bg color'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/es.js b/public/tiny_mce/plugins/table/langs/es.js new file mode 100644 index 0000000..ab703b5 --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/es.js @@ -0,0 +1,41 @@ +// ES lang variables by Alvaro Velasco + +tinyMCELang['lang_table_desc'] = 'Insertar una tabla nueva'; +tinyMCELang['lang_table_insert_row_before_desc'] = 'Insertar una fila antes'; +tinyMCELang['lang_table_insert_row_after_desc'] = 'Insertar una fila despues'; +tinyMCELang['lang_table_delete_row_desc'] = 'Eliminar una fila'; +tinyMCELang['lang_table_insert_col_before_desc'] = 'Insertar una columna before'; +tinyMCELang['lang_table_insert_col_after_desc'] = 'Insertar columna after'; +tinyMCELang['lang_table_delete_col_desc'] = 'Eliminar una columna'; +tinyMCELang['lang_insert_table_title'] = 'Insertar/Modificar tabla'; +tinyMCELang['lang_insert_table_width'] = 'Anchura'; +tinyMCELang['lang_insert_table_height'] = 'Altura'; +tinyMCELang['lang_insert_table_cols'] = 'Columnas'; +tinyMCELang['lang_insert_table_rows'] = 'Filas'; +tinyMCELang['lang_insert_table_cellspacing'] = 'Espacio entre celdas'; +tinyMCELang['lang_insert_table_cellpadding'] = 'Desplazamiento entre celdas'; +tinyMCELang['lang_insert_table_border'] = 'Borde'; +tinyMCELang['lang_insert_table_align'] = 'Alineamiento'; +tinyMCELang['lang_insert_table_align_default'] = 'Por defecto'; +tinyMCELang['lang_insert_table_align_left'] = 'Izquierda'; +tinyMCELang['lang_insert_table_align_right'] = 'Derecha'; +tinyMCELang['lang_insert_table_align_middle'] = 'Centro'; +tinyMCELang['lang_insert_table_class'] = 'Class'; +tinyMCELang['lang_table_row_title'] = 'Table row properties'; +tinyMCELang['lang_table_cell_title'] = 'Table cell properties'; +tinyMCELang['lang_table_row_desc'] = 'Table row properties'; +tinyMCELang['lang_table_cell_desc'] = 'Table cell properties'; +tinyMCELang['lang_insert_table_valign'] = 'Vertical alignment'; +tinyMCELang['lang_insert_table_align_top'] = 'Top'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Bottom'; +tinyMCELang['lang_table_props_desc'] = 'Table properties'; +tinyMCELang['lang_table_bordercolor'] = 'Border color'; +tinyMCELang['lang_table_bgcolor'] = 'Bg color'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/fa.js b/public/tiny_mce/plugins/table/langs/fa.js new file mode 100644 index 0000000..14ed242 --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/fa.js @@ -0,0 +1,45 @@ +// IR lang variables +// Persian (Farsi) language pack (for IRAN) +// By: Morteza Zafari +// Lost@LostLord.com +// http://www.LostLord.com + +tinyMCELang['lang_table_desc'] = '??? ???? ????'; +tinyMCELang['lang_table_insert_row_before_desc'] = '??? ??? ???? ??? ?? ??? ????'; +tinyMCELang['lang_table_insert_row_after_desc'] = '??? ??? ???? ?? ?? ??? ????'; +tinyMCELang['lang_table_delete_row_desc'] = '??? ???'; +tinyMCELang['lang_table_insert_col_before_desc'] = '??? ???? ???? ??? ?? ???? ????'; +tinyMCELang['lang_table_insert_col_after_desc'] = '??? ???? ???? ?? ?? ???? ????'; +tinyMCELang['lang_table_delete_col_desc'] = '??? ????'; +tinyMCELang['lang_insert_table_title'] = '??? ? ?????? ????'; +tinyMCELang['lang_insert_table_width'] = '???'; +tinyMCELang['lang_insert_table_height'] = '??????'; +tinyMCELang['lang_insert_table_cols'] = '????? ??????'; +tinyMCELang['lang_insert_table_rows'] = '????? ?????'; +tinyMCELang['lang_insert_table_cellspacing'] = '????? ?? ???? ????'; +tinyMCELang['lang_insert_table_cellpadding'] = '????? ??? ?? ?????? ????'; +tinyMCELang['lang_insert_table_border'] = '?????'; +tinyMCELang['lang_insert_table_align'] = '??? ???? ????'; +tinyMCELang['lang_insert_table_align_default'] = '??? ???'; +tinyMCELang['lang_insert_table_align_left'] = '??'; +tinyMCELang['lang_insert_table_align_right'] = '????'; +tinyMCELang['lang_insert_table_align_middle'] = '???'; +tinyMCELang['lang_insert_table_class'] = '????'; +tinyMCELang['lang_table_row_title'] = 'Table row properties'; +tinyMCELang['lang_table_cell_title'] = 'Table cell properties'; +tinyMCELang['lang_table_row_desc'] = 'Table row properties'; +tinyMCELang['lang_table_cell_desc'] = 'Table cell properties'; +tinyMCELang['lang_insert_table_valign'] = 'Vertical alignment'; +tinyMCELang['lang_insert_table_align_top'] = 'Top'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Bottom'; +tinyMCELang['lang_table_props_desc'] = 'Table properties'; +tinyMCELang['lang_table_bordercolor'] = 'Border color'; +tinyMCELang['lang_table_bgcolor'] = 'Bg color'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/fi.js b/public/tiny_mce/plugins/table/langs/fi.js new file mode 100644 index 0000000..a0866ee --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/fi.js @@ -0,0 +1,41 @@ +// FI lang variables by Urho Konttori from Absolutions + +tinyMCELang['lang_table_desc'] = 'Lis uusi taulu'; +tinyMCELang['lang_table_insert_row_before_desc'] = 'Lis rivi edelle'; +tinyMCELang['lang_table_insert_row_after_desc'] = 'Lis rivi jlkeen'; +tinyMCELang['lang_table_delete_row_desc'] = 'Posita rivi'; +tinyMCELang['lang_table_insert_col_before_desc'] = 'Lis sarake edelle'; +tinyMCELang['lang_table_insert_col_after_desc'] = 'Lis sarake jlkeen'; +tinyMCELang['lang_table_delete_col_desc'] = 'Poista sarake'; +tinyMCELang['lang_insert_table_title'] = 'Lis/muokkaa taulua'; +tinyMCELang['lang_insert_table_width'] = 'Leveys'; +tinyMCELang['lang_insert_table_height'] = 'Korkeus'; +tinyMCELang['lang_insert_table_cols'] = 'Sarakkeet'; +tinyMCELang['lang_insert_table_rows'] = 'Rivit'; +tinyMCELang['lang_insert_table_cellspacing'] = 'Solujen vli'; +tinyMCELang['lang_insert_table_cellpadding'] = 'Solun reunan ja sislln vli'; +tinyMCELang['lang_insert_table_border'] = 'Reuna'; +tinyMCELang['lang_insert_table_align'] = 'Asettelu'; +tinyMCELang['lang_insert_table_align_default'] = 'Oletus'; +tinyMCELang['lang_insert_table_align_left'] = 'Vasen'; +tinyMCELang['lang_insert_table_align_right'] = 'Oikea'; +tinyMCELang['lang_insert_table_align_middle'] = 'Keskelle'; +tinyMCELang['lang_insert_table_delta_height'] = 20; +tinyMCELang['lang_table_row_title'] = 'Table row properties'; +tinyMCELang['lang_table_cell_title'] = 'Table cell properties'; +tinyMCELang['lang_table_row_desc'] = 'Table row properties'; +tinyMCELang['lang_table_cell_desc'] = 'Table cell properties'; +tinyMCELang['lang_insert_table_valign'] = 'Vertical alignment'; +tinyMCELang['lang_insert_table_align_top'] = 'Top'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Bottom'; +tinyMCELang['lang_table_props_desc'] = 'Table properties'; +tinyMCELang['lang_table_bordercolor'] = 'Border color'; +tinyMCELang['lang_table_bgcolor'] = 'Bg color'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/fr.js b/public/tiny_mce/plugins/table/langs/fr.js new file mode 100644 index 0000000..b4511ac --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/fr.js @@ -0,0 +1,41 @@ +// French lang variables by Laurent Dran + +tinyMCELang['lang_table_desc'] = 'Insérer un nouveau tableau'; +tinyMCELang['lang_table_insert_row_before_desc'] = 'Insérer une ligne avant'; +tinyMCELang['lang_table_insert_row_after_desc'] = 'Insérer une ligne aprés'; +tinyMCELang['lang_table_delete_row_desc'] = 'Supprimer la ligne'; +tinyMCELang['lang_table_insert_col_before_desc'] = 'Insérer une colonne avant'; +tinyMCELang['lang_table_insert_col_after_desc'] = 'Insérer une colonne aprés'; +tinyMCELang['lang_table_delete_col_desc'] = 'Supprimer la colonne'; +tinyMCELang['lang_insert_table_title'] = 'Insérer/Modifier le tableau'; +tinyMCELang['lang_insert_table_width'] = 'Largeur'; +tinyMCELang['lang_insert_table_height'] = 'Hauteur'; +tinyMCELang['lang_insert_table_cols'] = 'Colonnes'; +tinyMCELang['lang_insert_table_rows'] = 'Lignes'; +tinyMCELang['lang_insert_table_cellspacing'] = 'Cellspacing'; +tinyMCELang['lang_insert_table_cellpadding'] = 'Cellpadding'; +tinyMCELang['lang_insert_table_border'] = 'Bordure'; +tinyMCELang['lang_insert_table_align'] = 'Alignement'; +tinyMCELang['lang_insert_table_align_default'] = 'Défaut'; +tinyMCELang['lang_insert_table_align_left'] = 'Gauche'; +tinyMCELang['lang_insert_table_align_right'] = 'Droit'; +tinyMCELang['lang_insert_table_align_middle'] = 'Milieu'; +tinyMCELang['lang_insert_table_class'] = 'Classe CSS'; +tinyMCELang['lang_table_row_title'] = 'Propriétés de la rangée'; +tinyMCELang['lang_table_cell_title'] = 'Propriétés de la cellule'; +tinyMCELang['lang_table_row_desc'] = 'Propriétés de la rangée'; +tinyMCELang['lang_table_cell_desc'] = 'Propriétés de la cellule'; +tinyMCELang['lang_insert_table_valign'] = 'Alignement Vertical'; +tinyMCELang['lang_insert_table_align_top'] = 'Haut'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Bas'; +tinyMCELang['lang_table_props_desc'] = 'Table properties'; +tinyMCELang['lang_table_bordercolor'] = 'Border color'; +tinyMCELang['lang_table_bgcolor'] = 'Bg color'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/fr_ca.js b/public/tiny_mce/plugins/table/langs/fr_ca.js new file mode 100644 index 0000000..e9bcdc9 --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/fr_ca.js @@ -0,0 +1,41 @@ +// Canadian French lang variables by Virtuelcom + +tinyMCELang['lang_table_desc'] = 'Insrer un nouveau tableau'; +tinyMCELang['lang_table_insert_row_before_desc'] = 'Insrer une ligne avant'; +tinyMCELang['lang_table_insert_row_after_desc'] = 'Insrer une ligne aprs'; +tinyMCELang['lang_table_delete_row_desc'] = 'Supprimer la ligne'; +tinyMCELang['lang_table_insert_col_before_desc'] = 'Insrer une colonne avant'; +tinyMCELang['lang_table_insert_col_after_desc'] = 'Insrer une colonne aprs'; +tinyMCELang['lang_table_delete_col_desc'] = 'Supprimer la colonne'; +tinyMCELang['lang_insert_table_title'] = 'Insrer/Modifier le tableau'; +tinyMCELang['lang_insert_table_width'] = 'Largeur'; +tinyMCELang['lang_insert_table_height'] = 'Hauteur'; +tinyMCELang['lang_insert_table_cols'] = 'Colonnes'; +tinyMCELang['lang_insert_table_rows'] = 'Lignes'; +tinyMCELang['lang_insert_table_cellspacing'] = 'Cellspacing'; +tinyMCELang['lang_insert_table_cellpadding'] = 'Cellpadding'; +tinyMCELang['lang_insert_table_border'] = 'Bordure'; +tinyMCELang['lang_insert_table_align'] = 'Alignement'; +tinyMCELang['lang_insert_table_align_default'] = 'Dfaut'; +tinyMCELang['lang_insert_table_align_left'] = 'Gauche'; +tinyMCELang['lang_insert_table_align_right'] = 'Droit'; +tinyMCELang['lang_insert_table_align_middle'] = 'Milieu'; +tinyMCELang['lang_insert_table_class'] = 'Classe CSS'; +tinyMCELang['lang_table_row_title'] = 'Proprits de ligne'; +tinyMCELang['lang_table_cell_title'] = 'Proprits de cellule'; +tinyMCELang['lang_table_row_desc'] = 'Proprits de ligne'; +tinyMCELang['lang_table_cell_desc'] = 'Proprits de cellule'; +tinyMCELang['lang_insert_table_valign'] = 'Alignement vertical'; +tinyMCELang['lang_insert_table_align_top'] = 'Haut'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Bas'; +tinyMCELang['lang_table_props_desc'] = 'Table properties'; +tinyMCELang['lang_table_bordercolor'] = 'Border color'; +tinyMCELang['lang_table_bgcolor'] = 'Bg color'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/hu.js b/public/tiny_mce/plugins/table/langs/hu.js new file mode 100644 index 0000000..2d53b89 --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/hu.js @@ -0,0 +1,41 @@ +// HU lang variables, Edited by 2XP (2xp@dino.hu) + +tinyMCELang['lang_table_desc'] = 'Új táblázat beillesztése'; +tinyMCELang['lang_table_insert_row_before_desc'] = 'Sor beillesztése elé'; +tinyMCELang['lang_table_insert_row_after_desc'] = 'Sor beillesztése utána'; +tinyMCELang['lang_table_delete_row_desc'] = 'Sor törlése'; +tinyMCELang['lang_table_insert_col_before_desc'] = 'Oszlop beillsztése elé'; +tinyMCELang['lang_table_insert_col_after_desc'] = 'Oszlop beillesztése utána'; +tinyMCELang['lang_table_delete_col_desc'] = 'Oszlop eltávolítása'; +tinyMCELang['lang_insert_table_title'] = 'Tábla beillesztése/módosítása'; +tinyMCELang['lang_insert_table_width'] = 'Szélesség'; +tinyMCELang['lang_insert_table_height'] = 'Magasság'; +tinyMCELang['lang_insert_table_cols'] = 'Oszlopok'; +tinyMCELang['lang_insert_table_rows'] = 'Sorok'; +tinyMCELang['lang_insert_table_cellspacing'] = 'Cellspacing'; +tinyMCELang['lang_insert_table_cellpadding'] = 'Cellpadding'; +tinyMCELang['lang_insert_table_border'] = 'Keret'; +tinyMCELang['lang_insert_table_align'] = 'Igazítás'; +tinyMCELang['lang_insert_table_align_default'] = 'Alapértelmezett'; +tinyMCELang['lang_insert_table_align_left'] = 'Balra'; +tinyMCELang['lang_insert_table_align_right'] = 'Jobbra'; +tinyMCELang['lang_insert_table_align_middle'] = 'Középre'; +tinyMCELang['lang_insert_table_class'] = 'Class'; +tinyMCELang['lang_table_row_title'] = 'Table row properties'; +tinyMCELang['lang_table_cell_title'] = 'Table cell properties'; +tinyMCELang['lang_table_row_desc'] = 'Table row properties'; +tinyMCELang['lang_table_cell_desc'] = 'Table cell properties'; +tinyMCELang['lang_insert_table_valign'] = 'Vertical alignment'; +tinyMCELang['lang_insert_table_align_top'] = 'Top'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Bottom'; +tinyMCELang['lang_table_props_desc'] = 'Table properties'; +tinyMCELang['lang_table_bordercolor'] = 'Border color'; +tinyMCELang['lang_table_bgcolor'] = 'Bg color'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/it.js b/public/tiny_mce/plugins/table/langs/it.js new file mode 100644 index 0000000..5e9380b --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/it.js @@ -0,0 +1,41 @@ +// Variabili di lingua IT - fabrix.xm@lombardiacom.it + +tinyMCELang['lang_table_desc'] = 'Inserisci una nuova tabella'; +tinyMCELang['lang_table_insert_row_before_desc'] = 'Inserisci una riga prima'; +tinyMCELang['lang_table_insert_row_after_desc'] = 'Inserisci una riga dopo'; +tinyMCELang['lang_table_delete_row_desc'] = 'Cancella riga'; +tinyMCELang['lang_table_insert_col_before_desc'] = 'Inserisci colonna prima'; +tinyMCELang['lang_table_insert_col_after_desc'] = 'Inserisci colonna dopo'; +tinyMCELang['lang_table_delete_col_desc'] = 'Rimuovi colonna'; +tinyMCELang['lang_insert_table_title'] = 'Inserisci/modifica tabella'; +tinyMCELang['lang_insert_table_width'] = 'Larghezza'; +tinyMCELang['lang_insert_table_height'] = 'Altezza'; +tinyMCELang['lang_insert_table_cols'] = 'Colonne'; +tinyMCELang['lang_insert_table_rows'] = 'Righe'; +tinyMCELang['lang_insert_table_cellspacing'] = 'Cellspacing'; +tinyMCELang['lang_insert_table_cellpadding'] = 'Cellpadding'; +tinyMCELang['lang_insert_table_border'] = 'Bordo'; +tinyMCELang['lang_insert_table_align'] = 'Allineamento'; +tinyMCELang['lang_insert_table_align_default'] = 'Default'; +tinyMCELang['lang_insert_table_align_left'] = 'Sinistra'; +tinyMCELang['lang_insert_table_align_right'] = 'Destra'; +tinyMCELang['lang_insert_table_align_middle'] = 'Centro'; +tinyMCELang['lang_insert_table_class'] = 'Classe'; +tinyMCELang['lang_table_row_title'] = 'Table row properties'; +tinyMCELang['lang_table_cell_title'] = 'Table cell properties'; +tinyMCELang['lang_table_row_desc'] = 'Table row properties'; +tinyMCELang['lang_table_cell_desc'] = 'Table cell properties'; +tinyMCELang['lang_insert_table_valign'] = 'Vertical alignment'; +tinyMCELang['lang_insert_table_align_top'] = 'Top'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Bottom'; +tinyMCELang['lang_table_props_desc'] = 'Table properties'; +tinyMCELang['lang_table_bordercolor'] = 'Border color'; +tinyMCELang['lang_table_bgcolor'] = 'Bg color'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/ja.js b/public/tiny_mce/plugins/table/langs/ja.js new file mode 100644 index 0000000..7d02594 --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/ja.js @@ -0,0 +1,41 @@ +// JP lang variables + +tinyMCELang['lang_table_desc'] = '$B%F!<%V%k(B'; +tinyMCELang['lang_table_insert_row_before_desc'] = '$B9TA^F~(B($BA0(B)'; +tinyMCELang['lang_table_insert_row_after_desc'] = '$B9TA^F~(B($B8e(B)'; +tinyMCELang['lang_table_delete_row_desc'] = '$B9T:o=|(B'; +tinyMCELang['lang_table_insert_col_before_desc'] = '$BNsA^F~(B($BA0(B)'; +tinyMCELang['lang_table_insert_col_after_desc'] = '$BNsA^F~(B($B8e(B)'; +tinyMCELang['lang_table_delete_col_desc'] = '$BNs:o=|(B'; +tinyMCELang['lang_insert_table_title'] = '$B%F!<%V%k$NA^F~(B/$BJT=8(B'; +tinyMCELang['lang_insert_table_cols'] = '$BNs?t(B'; +tinyMCELang['lang_insert_table_rows'] = '$B9T?t(B'; +tinyMCELang['lang_insert_table_cellspacing'] = '$B%;%kM>Gr(B'; +tinyMCELang['lang_insert_table_cellpadding'] = '$B%;%k5M$a(B'; +tinyMCELang['lang_insert_table_align'] = '$B0LCVD4@0(B'; +tinyMCELang['lang_insert_table_align_default'] = '$B0EL[(B'; +tinyMCELang['lang_insert_table_align_left'] = '$B:85M$a(B'; +tinyMCELang['lang_insert_table_align_right'] = '$B1&5M$a(B'; +tinyMCELang['lang_insert_table_align_middle'] = '$BCf1{4s$;(B'; +tinyMCELang['lang_insert_table_width'] = '$BI}(B'; +tinyMCELang['lang_insert_table_height'] = '$B9b$5(B'; +tinyMCELang['lang_insert_table_border'] = '$B6-3&@~(B'; +tinyMCELang['lang_insert_table_class'] = '$B%/%i%9(B'; +tinyMCELang['lang_table_row_title'] = 'Table row properties'; +tinyMCELang['lang_table_cell_title'] = 'Table cell properties'; +tinyMCELang['lang_table_row_desc'] = 'Table row properties'; +tinyMCELang['lang_table_cell_desc'] = 'Table cell properties'; +tinyMCELang['lang_insert_table_valign'] = 'Vertical alignment'; +tinyMCELang['lang_insert_table_align_top'] = 'Top'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Bottom'; +tinyMCELang['lang_table_props_desc'] = 'Table properties'; +tinyMCELang['lang_table_bordercolor'] = 'Border color'; +tinyMCELang['lang_table_bgcolor'] = 'Bg color'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/ko.js b/public/tiny_mce/plugins/table/langs/ko.js new file mode 100644 index 0000000..38389f8 --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/ko.js @@ -0,0 +1,41 @@ +// KO lang variables + +tinyMCELang['lang_table_desc'] = 'ǥ ֱ'; +tinyMCELang['lang_table_insert_row_before_desc'] = 'տ ֱ'; +tinyMCELang['lang_table_insert_row_after_desc'] = 'ڿ ֱ'; +tinyMCELang['lang_table_delete_row_desc'] = ' '; +tinyMCELang['lang_table_insert_col_before_desc'] = 'տ ֱ'; +tinyMCELang['lang_table_insert_col_after_desc'] = 'ڿ ֱ'; +tinyMCELang['lang_table_delete_col_desc'] = ' '; +tinyMCELang['lang_insert_table_title'] = 'ǥ ֱ/ġ'; +tinyMCELang['lang_insert_table_width'] = 'ʺ'; +tinyMCELang['lang_insert_table_height'] = ''; +tinyMCELang['lang_insert_table_cols'] = ''; +tinyMCELang['lang_insert_table_rows'] = ''; +tinyMCELang['lang_insert_table_cellspacing'] = ' '; +tinyMCELang['lang_insert_table_cellpadding'] = ' '; +tinyMCELang['lang_insert_table_border'] = '׵θ'; +tinyMCELang['lang_insert_table_align'] = ''; +tinyMCELang['lang_insert_table_align_default'] = '⺻'; +tinyMCELang['lang_insert_table_align_left'] = ''; +tinyMCELang['lang_insert_table_align_right'] = ''; +tinyMCELang['lang_insert_table_align_middle'] = ''; +tinyMCELang['lang_insert_table_class'] = 'Ŭ'; +tinyMCELang['lang_table_row_title'] = 'Table row properties'; +tinyMCELang['lang_table_cell_title'] = 'Table cell properties'; +tinyMCELang['lang_table_row_desc'] = 'Table row properties'; +tinyMCELang['lang_table_cell_desc'] = 'Table cell properties'; +tinyMCELang['lang_insert_table_valign'] = 'Vertical alignment'; +tinyMCELang['lang_insert_table_align_top'] = 'Top'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Bottom'; +tinyMCELang['lang_table_props_desc'] = 'Table properties'; +tinyMCELang['lang_table_bordercolor'] = 'Border color'; +tinyMCELang['lang_table_bgcolor'] = 'Bg color'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/nl.js b/public/tiny_mce/plugins/table/langs/nl.js new file mode 100644 index 0000000..ea48361 --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/nl.js @@ -0,0 +1,41 @@ +// NL lang variables + +tinyMCELang['lang_table_desc'] = 'Voeg een nieuwe tabel in'; +tinyMCELang['lang_table_insert_row_before_desc'] = 'Voeg rij in voor ...'; +tinyMCELang['lang_table_insert_row_after_desc'] = 'Voeg rij in na ...'; +tinyMCELang['lang_table_delete_row_desc'] = 'Verwijder rij'; +tinyMCELang['lang_table_insert_col_before_desc'] = 'Voeg kolom in voor ...'; +tinyMCELang['lang_table_insert_col_after_desc'] = 'Voeg kolom in na ...'; +tinyMCELang['lang_table_delete_col_desc'] = 'Verwijder kolom'; +tinyMCELang['lang_insert_table_title'] = 'Invoegen/Bewerken tabel'; +tinyMCELang['lang_insert_table_width'] = 'Breedte'; +tinyMCELang['lang_insert_table_height'] = 'Hoogte'; +tinyMCELang['lang_insert_table_cols'] = 'Kolommen'; +tinyMCELang['lang_insert_table_rows'] = 'Rijen'; +tinyMCELang['lang_insert_table_cellspacing'] = 'Celafstand'; +tinyMCELang['lang_insert_table_cellpadding'] = 'Celvulling'; +tinyMCELang['lang_insert_table_border'] = 'Omranding'; +tinyMCELang['lang_insert_table_align'] = 'Positionering'; +tinyMCELang['lang_insert_table_align_default'] = 'Standaard'; +tinyMCELang['lang_insert_table_align_left'] = 'Links'; +tinyMCELang['lang_insert_table_align_right'] = 'Rechts'; +tinyMCELang['lang_insert_table_align_middle'] = 'Midden'; +tinyMCELang['lang_insert_table_class'] = 'CSS-Stijl'; +tinyMCELang['lang_table_row_title'] = 'Table row properties'; +tinyMCELang['lang_table_cell_title'] = 'Table cell properties'; +tinyMCELang['lang_table_row_desc'] = 'Table row properties'; +tinyMCELang['lang_table_cell_desc'] = 'Table cell properties'; +tinyMCELang['lang_insert_table_valign'] = 'Vertical alignment'; +tinyMCELang['lang_insert_table_align_top'] = 'Top'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Bottom'; +tinyMCELang['lang_table_props_desc'] = 'Table properties'; +tinyMCELang['lang_table_bordercolor'] = 'Border color'; +tinyMCELang['lang_table_bgcolor'] = 'Bg color'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/no.js b/public/tiny_mce/plugins/table/langs/no.js new file mode 100644 index 0000000..db1a8d3 --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/no.js @@ -0,0 +1,41 @@ +// NO lang variables + +tinyMCELang['lang_table_desc'] = 'Opprett/endre tabell'; +tinyMCELang['lang_table_insert_row_before_desc'] = 'Opprett rad fr'; +tinyMCELang['lang_table_insert_row_after_desc'] = 'Opprett rad etter'; +tinyMCELang['lang_table_delete_row_desc'] = 'Fjern rad'; +tinyMCELang['lang_table_insert_col_before_desc'] = 'Opprett kolonne fr'; +tinyMCELang['lang_table_insert_col_after_desc'] = 'Opprett kolonne etter'; +tinyMCELang['lang_table_delete_col_desc'] = 'Fjern kolonne'; +tinyMCELang['lang_insert_table_title'] = 'Opprett/endre tabell'; +tinyMCELang['lang_insert_table_width'] = 'Bredde'; +tinyMCELang['lang_insert_table_height'] = 'Hyde'; +tinyMCELang['lang_insert_table_cols'] = 'Kolonner'; +tinyMCELang['lang_insert_table_rows'] = 'Rader'; +tinyMCELang['lang_insert_table_cellspacing'] = 'Celle-mellomrom'; +tinyMCELang['lang_insert_table_cellpadding'] = 'Celle-padding'; +tinyMCELang['lang_insert_table_border'] = 'Rammebredde'; +tinyMCELang['lang_insert_table_align'] = 'Justering'; +tinyMCELang['lang_insert_table_align_default'] = 'Ingen'; +tinyMCELang['lang_insert_table_align_left'] = 'Venstre'; +tinyMCELang['lang_insert_table_align_right'] = 'Hyre'; +tinyMCELang['lang_insert_table_align_middle'] = 'Midten'; +tinyMCELang['lang_insert_table_class'] = 'Stil'; +tinyMCELang['lang_table_row_title'] = 'Table row properties'; +tinyMCELang['lang_table_cell_title'] = 'Table cell properties'; +tinyMCELang['lang_table_row_desc'] = 'Table row properties'; +tinyMCELang['lang_table_cell_desc'] = 'Table cell properties'; +tinyMCELang['lang_insert_table_valign'] = 'Vertical alignment'; +tinyMCELang['lang_insert_table_align_top'] = 'Top'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Bottom'; +tinyMCELang['lang_table_props_desc'] = 'Table properties'; +tinyMCELang['lang_table_bordercolor'] = 'Border color'; +tinyMCELang['lang_table_bgcolor'] = 'Bg color'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/pl.js b/public/tiny_mce/plugins/table/langs/pl.js new file mode 100644 index 0000000..1b1dd30 --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/pl.js @@ -0,0 +1,39 @@ +// PL lang variables + +tinyMCELang['lang_table_desc'] = 'Wstaw nowa tabele'; +tinyMCELang['lang_table_insert_row_before_desc'] = 'Wstaw wiersz przed'; +tinyMCELang['lang_table_insert_row_after_desc'] = 'Wstaw wiersz po'; +tinyMCELang['lang_table_delete_row_desc'] = 'Skasuj wiersz'; +tinyMCELang['lang_table_insert_col_before_desc'] = 'Wstaw kolumne przed'; +tinyMCELang['lang_table_insert_col_after_desc'] = 'Wstaw kolumne po'; +tinyMCELang['lang_table_delete_col_desc'] = 'Skasuj kolumne'; +tinyMCELang['lang_insert_table_title'] = 'Wstaw/Modyfikuj tabele'; +tinyMCELang['lang_insert_table_width'] = 'Szerokosc'; +tinyMCELang['lang_insert_table_height'] = 'Wysokosc'; +tinyMCELang['lang_insert_table_cols'] = 'Kolumny'; +tinyMCELang['lang_insert_table_rows'] = 'Wiersze'; +tinyMCELang['lang_insert_table_cellspacing'] = 'Cellspacing'; +tinyMCELang['lang_insert_table_cellpadding'] = 'Cellpadding'; +tinyMCELang['lang_insert_table_border'] = 'Ramka'; +tinyMCELang['lang_insert_table_align'] = 'Wyrównanie'; +tinyMCELang['lang_insert_table_align_default'] = 'Domyslny'; +tinyMCELang['lang_insert_table_align_left'] = 'Do lewej'; +tinyMCELang['lang_insert_table_align_right'] = 'Do prawej'; +tinyMCELang['lang_insert_table_align_middle'] = 'Wycentrowanie'; +tinyMCELang['lang_insert_table_class'] = 'Klasa'; +tinyMCELang['lang_table_row_title'] = 'Wlasciwosci wiersza'; +tinyMCELang['lang_table_cell_title'] = 'Wlasciwosci komórki'; +tinyMCELang['lang_table_row_desc'] = 'Wlasciwosci wiersza'; +tinyMCELang['lang_table_cell_desc'] = 'Wlasciwosci komórki'; +tinyMCELang['lang_insert_table_valign'] = 'Wyrównanie pionowe'; +tinyMCELang['lang_insert_table_align_top'] = 'do góry'; +tinyMCELang['lang_insert_table_align_bottom'] = 'do dolu'; +tinyMCELang['lang_table_props_desc'] = 'Wlasciwosci tabeli'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/pt.js b/public/tiny_mce/plugins/table/langs/pt.js new file mode 100644 index 0000000..5a1c12a --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/pt.js @@ -0,0 +1,41 @@ +// PT lang variables + +tinyMCELang['lang_table_desc'] = 'Insere uma nova tabela'; +tinyMCELang['lang_table_insert_row_before_desc'] = 'Inserir linha antes'; +tinyMCELang['lang_table_insert_row_after_desc'] = 'Inserir linha depois'; +tinyMCELang['lang_table_delete_row_desc'] = 'Eliminar linha'; +tinyMCELang['lang_table_insert_col_before_desc'] = 'Inserir coluna antes'; +tinyMCELang['lang_table_insert_col_after_desc'] = 'Inserir coluna depois'; +tinyMCELang['lang_table_delete_col_desc'] = 'Remover coluna'; +tinyMCELang['lang_insert_table_title'] = 'Inserir/Modificar tabela'; +tinyMCELang['lang_insert_table_width'] = 'Largura'; +tinyMCELang['lang_insert_table_height'] = 'Altura'; +tinyMCELang['lang_insert_table_cols'] = 'Colunas'; +tinyMCELang['lang_insert_table_rows'] = 'Linhas'; +tinyMCELang['lang_insert_table_cellspacing'] = 'Espaa
    mento'; +tinyMCELang['lang_insert_table_cellpadding'] = 'Margem interior'; +tinyMCELang['lang_insert_table_border'] = 'Borda'; +tinyMCELang['lang_insert_table_align'] = 'Alinhamento'; +tinyMCELang['lang_insert_table_align_default'] = 'Por omisso'; +tinyMCELang['lang_insert_table_align_left'] = 'Esquerda'; +tinyMCELang['lang_insert_table_align_right'] = 'Direita'; +tinyMCELang['lang_insert_table_align_middle'] = 'Centrado'; +tinyMCELang['lang_insert_table_class'] = 'Classe de CSS'; +tinyMCELang['lang_table_row_title'] = 'Table row properties'; +tinyMCELang['lang_table_cell_title'] = 'Table cell properties'; +tinyMCELang['lang_table_row_desc'] = 'Table row properties'; +tinyMCELang['lang_table_cell_desc'] = 'Table cell properties'; +tinyMCELang['lang_insert_table_valign'] = 'Vertical alignment'; +tinyMCELang['lang_insert_table_align_top'] = 'Top'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Bottom'; +tinyMCELang['lang_table_props_desc'] = 'Table properties'; +tinyMCELang['lang_table_bordercolor'] = 'Border color'; +tinyMCELang['lang_table_bgcolor'] = 'Bg color'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/readme.txt b/public/tiny_mce/plugins/table/langs/readme.txt new file mode 100644 index 0000000..ef48d2b --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/readme.txt @@ -0,0 +1,4 @@ +Theme specific language packs. + +The language pack codes are based on ISO-639-2 +http://www.loc.gov/standards/iso639-2/englangn.html diff --git a/public/tiny_mce/plugins/table/langs/sv.js b/public/tiny_mce/plugins/table/langs/sv.js new file mode 100644 index 0000000..96155b7 --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/sv.js @@ -0,0 +1,41 @@ +// SE lang variables + +tinyMCELang['lang_table_desc'] = 'Skapa ny tabell'; +tinyMCELang['lang_table_insert_row_before_desc'] = 'Skapa rad före'; +tinyMCELang['lang_table_insert_row_after_desc'] = 'Skapa rad efter'; +tinyMCELang['lang_table_delete_row_desc'] = 'Ta bort rad'; +tinyMCELang['lang_table_insert_col_before_desc'] = 'Skapa kolumn före'; +tinyMCELang['lang_table_insert_col_after_desc'] = 'Skapa kolumn efter'; +tinyMCELang['lang_table_delete_col_desc'] = 'Ta bort kolumn'; +tinyMCELang['lang_insert_table_title'] = 'Skapa/Redigera tabell'; +tinyMCELang['lang_insert_table_width'] = 'Bredd'; +tinyMCELang['lang_insert_table_height'] = 'Höjd'; +tinyMCELang['lang_insert_table_cols'] = 'Kolumner'; +tinyMCELang['lang_insert_table_rows'] = 'Rader'; +tinyMCELang['lang_insert_table_cellspacing'] = 'Cellmellanrum'; +tinyMCELang['lang_insert_table_cellpadding'] = 'Cellutfyllnad'; +tinyMCELang['lang_insert_table_border'] = 'Rambredd'; +tinyMCELang['lang_insert_table_align'] = 'Justering'; +tinyMCELang['lang_insert_table_align_default'] = 'Ingen'; +tinyMCELang['lang_insert_table_align_left'] = 'Vänster'; +tinyMCELang['lang_insert_table_align_right'] = 'Höger'; +tinyMCELang['lang_insert_table_align_middle'] = 'Mitten'; +tinyMCELang['lang_insert_table_class'] = 'Stil'; +tinyMCELang['lang_table_row_title'] = 'Tabellradsinställningar'; +tinyMCELang['lang_table_cell_title'] = 'Tabellcellsinställningar'; +tinyMCELang['lang_table_row_desc'] = 'Tabellradsinställningar'; +tinyMCELang['lang_table_cell_desc'] = 'Tabellcellsinställningar'; +tinyMCELang['lang_insert_table_valign'] = 'Vertikal justering'; +tinyMCELang['lang_insert_table_align_top'] = 'Toppen'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Botten'; +tinyMCELang['lang_table_props_desc'] = 'Tabell egenskaper'; +tinyMCELang['lang_table_bordercolor'] = 'Ramfärg'; +tinyMCELang['lang_table_bgcolor'] = 'Bakgrundsfrd'; +tinyMCELang['lang_table_merge_cells_title'] = 'Sammanfoga tabell celler'; +tinyMCELang['lang_table_split_cells_desc'] = 'Delaupp tabell celler'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Sammanfoga tabell celler'; +tinyMCELang['lang_table_cut_row_desc'] = 'Klipput tabell rad'; +tinyMCELang['lang_table_copy_row_desc'] = 'Kopiera tabell rad'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Klistra in tabell rad före'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Klistra in tabell rad efter'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/tw.js b/public/tiny_mce/plugins/table/langs/tw.js new file mode 100644 index 0000000..ba5e763 --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/tw.js @@ -0,0 +1,41 @@ +// TW lang variables contributed by Jim Kou + +tinyMCELang['lang_insert_table_align'] = ''; +tinyMCELang['lang_insert_table_align_default'] = 'з'; +tinyMCELang['lang_insert_table_align_left'] = ''; +tinyMCELang['lang_insert_table_align_middle'] = 'm'; +tinyMCELang['lang_insert_table_align_right'] = 'k'; +tinyMCELang['lang_insert_table_border'] = 'ؽu'; +tinyMCELang['lang_insert_table_cellpadding'] = 'rPxs涡'; +tinyMCELang['lang_insert_table_cellspacing'] = 'xs涡'; +tinyMCELang['lang_insert_table_class'] = '˦'; +tinyMCELang['lang_insert_table_cols'] = ''; +tinyMCELang['lang_insert_table_height'] = ''; +tinyMCELang['lang_insert_table_rows'] = 'C'; +tinyMCELang['lang_insert_table_title'] = 'D'; +tinyMCELang['lang_insert_table_width'] = 'e'; +tinyMCELang['lang_table_delete_col_desc'] = 'R@xs'; +tinyMCELang['lang_table_delete_row_desc'] = 'R@Cxs'; +tinyMCELang['lang_table_desc'] = ''; +tinyMCELang['lang_table_insert_col_after_desc'] = 'sW@xs()'; +tinyMCELang['lang_table_insert_col_before_desc'] = 'sW@xs(e)'; +tinyMCELang['lang_table_insert_row_after_desc'] = 'sW@Cxs()'; +tinyMCELang['lang_table_insert_row_before_desc'] = 'sW@Cxs(e)'; +tinyMCELang['lang_table_row_title'] = 'Table row properties'; +tinyMCELang['lang_table_cell_title'] = 'Table cell properties'; +tinyMCELang['lang_table_row_desc'] = 'Table row properties'; +tinyMCELang['lang_table_cell_desc'] = 'Table cell properties'; +tinyMCELang['lang_insert_table_valign'] = 'Vertical alignment'; +tinyMCELang['lang_insert_table_align_top'] = 'Top'; +tinyMCELang['lang_insert_table_align_bottom'] = 'Bottom'; +tinyMCELang['lang_table_props_desc'] = 'Table properties'; +tinyMCELang['lang_table_bordercolor'] = 'Border color'; +tinyMCELang['lang_table_bgcolor'] = 'Bg color'; +tinyMCELang['lang_table_merge_cells_title'] = 'Merge table cells'; +tinyMCELang['lang_table_split_cells_desc'] = 'Split table cells'; +tinyMCELang['lang_table_merge_cells_desc'] = 'Merge table cells'; +tinyMCELang['lang_table_cut_row_desc'] = 'Cut table row'; +tinyMCELang['lang_table_copy_row_desc'] = 'Copy table row'; +tinyMCELang['lang_table_paste_row_before_desc'] = 'Paste table row before'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'Paste table row after'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/langs/zh_cn.js b/public/tiny_mce/plugins/table/langs/zh_cn.js new file mode 100644 index 0000000..b47fbe3 --- /dev/null +++ b/public/tiny_mce/plugins/table/langs/zh_cn.js @@ -0,0 +1,42 @@ +// Simplified Chinese lang variables contributed by cube316 (cube316@gmail.com) +// http://www.cube316.net/ ԻȡTinyMCE֧ + +tinyMCELang['lang_table_desc'] = '±'; +tinyMCELang['lang_table_insert_row_before_desc'] = 'ǰ'; +tinyMCELang['lang_table_insert_row_after_desc'] = 'ں'; +tinyMCELang['lang_table_delete_row_desc'] = 'ɾ'; +tinyMCELang['lang_table_insert_col_before_desc'] = 'ǰ'; +tinyMCELang['lang_table_insert_col_after_desc'] = 'ں'; +tinyMCELang['lang_table_delete_col_desc'] = 'ɾ'; +tinyMCELang['lang_insert_table_title'] = '/޸ '; +tinyMCELang['lang_insert_table_width'] = ''; +tinyMCELang['lang_insert_table_height'] = '߶'; +tinyMCELang['lang_insert_table_cols'] = ''; +tinyMCELang['lang_insert_table_rows'] = ''; +tinyMCELang['lang_insert_table_cellspacing'] = ''; +tinyMCELang['lang_insert_table_cellpadding'] = ''; +tinyMCELang['lang_insert_table_border'] = '߿'; +tinyMCELang['lang_insert_table_align'] = '뷽ʽ'; +tinyMCELang['lang_insert_table_align_default'] = 'Ĭ'; +tinyMCELang['lang_insert_table_align_left'] = ''; +tinyMCELang['lang_insert_table_align_right'] = 'Ҷ'; +tinyMCELang['lang_insert_table_align_middle'] = 'ж'; +tinyMCELang['lang_insert_table_class'] = ''; +tinyMCELang['lang_table_row_title'] = ''; +tinyMCELang['lang_table_cell_title'] = 'Ԫ'; +tinyMCELang['lang_table_row_desc'] = ''; +tinyMCELang['lang_table_cell_desc'] = 'Ԫ'; +tinyMCELang['lang_insert_table_valign'] = 'ֱ'; +tinyMCELang['lang_insert_table_align_top'] = ''; +tinyMCELang['lang_insert_table_align_bottom'] = 'ײ'; +tinyMCELang['lang_table_props_desc'] = ''; +tinyMCELang['lang_table_bordercolor'] = '߿ɫ'; +tinyMCELang['lang_table_bgcolor'] = 'ɫ'; +tinyMCELang['lang_table_merge_cells_title'] = 'ϲԪ'; +tinyMCELang['lang_table_split_cells_desc'] = 'ֵԪ'; +tinyMCELang['lang_table_merge_cells_desc'] = 'ϲԪ'; +tinyMCELang['lang_table_cut_row_desc'] = ''; +tinyMCELang['lang_table_copy_row_desc'] = ''; +tinyMCELang['lang_table_paste_row_before_desc'] = 'ǰ'; +tinyMCELang['lang_table_paste_row_after_desc'] = 'ں'; +tinyMCELang['lang_table_insert_desc'] = 'Insert a new table'; diff --git a/public/tiny_mce/plugins/table/merge_cells.htm b/public/tiny_mce/plugins/table/merge_cells.htm new file mode 100644 index 0000000..36d6299 --- /dev/null +++ b/public/tiny_mce/plugins/table/merge_cells.htm @@ -0,0 +1,56 @@ + + +{$lang_table_merge_cells_title} + + + + +
    +
    +{$lang_table_merge_cells_title} +
    + + + + + + + + + + + + +
    {$lang_insert_table_cols}: +
    {$lang_insert_table_rows}:
    + + + + diff --git a/public/tiny_mce/plugins/table/readme.txt b/public/tiny_mce/plugins/table/readme.txt new file mode 100644 index 0000000..ff2741a --- /dev/null +++ b/public/tiny_mce/plugins/table/readme.txt @@ -0,0 +1,44 @@ + Table plugin for TinyMCE +------------------------------ + +Installation instructions: + * Copy the table directory to the plugins directory of TinyMCE (/jscripts/tiny_mce/plugins). + * Add plugin to TinyMCE plugin option list example: plugins : "table". + * Add the table button name to button list, example: theme_advanced_buttons3_add_before : "tablecontrols". + +Initialization example: + tinyMCE.init({ + theme : "advanced", + mode : "textareas", + plugins : "table", + theme_advanced_buttons3_add_before : "tablecontrols" + }); + +Table controls: + tablecontrols All table control below and some separators between them. + table Insert table control. + row_props Edit row properties (tr). + cell_props Edit cell properties (td). + delete_col Delete column control. + delete_row Delete row control. + col_after Column after control. + col_before Column before control. + row_after Row after control. + row_before Row before control. + row_after Row after control. + row_before Row before control. + +Table plugin commands: + mceInsertTable Inserts a new table at cursor location the default size is 2x2. + If the value parameter is specified it should contain a name/value array, + this array has the following options cols, rows, border, cellspacing, cellpadding. + The default border is set to: 0. + mceTableInsertRowBefore Inserts a row before/above the current cursor location. + mceTableInsertRowAfter Inserts a row after/under the current cursor location. + mceTableDeleteRow Deletes the row at the current cursor location. + mceTableInsertColBefore Inserts a column before the current cursor location. + mceTableInsertColAfter Inserts a column after the current cursor location. + mceTableDeleteCol Deletes the column at the current cursor location. + +Options: + table_color_fields If set to true, tables dialogs will have color fields. diff --git a/public/tiny_mce/plugins/table/row.htm b/public/tiny_mce/plugins/table/row.htm new file mode 100644 index 0000000..bb77c2b --- /dev/null +++ b/public/tiny_mce/plugins/table/row.htm @@ -0,0 +1,127 @@ + + +{$lang_table_row_title} + + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$lang_table_row_title}
    {$lang_insert_table_align}:{$lang_insert_table_class}:
    {$lang_insert_table_valign}:{$lang_insert_table_height}:
      
    +
    + + diff --git a/public/tiny_mce/plugins/table/table.htm b/public/tiny_mce/plugins/table/table.htm new file mode 100644 index 0000000..667949e --- /dev/null +++ b/public/tiny_mce/plugins/table/table.htm @@ -0,0 +1,153 @@ + + +{$lang_insert_table_title} + + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$lang_insert_table_title}
    {$lang_insert_table_cols}:{$lang_insert_table_rows}:
    {$lang_insert_table_cellpadding}:{$lang_insert_table_cellspacing}:
    {$lang_insert_table_align}:{$lang_insert_table_border}:
    {$lang_insert_table_width}:{$lang_insert_table_height}:
    {$lang_insert_table_class}: +   
      
    +
    + + diff --git a/public/tiny_mce/plugins/zoom/editor_plugin.js b/public/tiny_mce/plugins/zoom/editor_plugin.js new file mode 100644 index 0000000..ec349a5 --- /dev/null +++ b/public/tiny_mce/plugins/zoom/editor_plugin.js @@ -0,0 +1,7 @@ +/* Import plugin specific language pack */ + function TinyMCE_zoom_getControlHTML(control_name){if(!tinyMCE.isMSIE||tinyMCE.isMSIE5_0)return "";switch(control_name){case "zoom":return '';}return "";}function TinyMCE_zoom_execCommand(editor_id,element,command,user_interface,value){switch(command){case "mceZoom":tinyMCE.getInstanceById(editor_id).contentDocument.body.style.zoom=value;tinyMCE.getInstanceById(editor_id).contentDocument.body.style.mozZoom=value;return true;}return false;} \ No newline at end of file diff --git a/public/tiny_mce/plugins/zoom/editor_plugin_src.js b/public/tiny_mce/plugins/zoom/editor_plugin_src.js new file mode 100644 index 0000000..e0af5af --- /dev/null +++ b/public/tiny_mce/plugins/zoom/editor_plugin_src.js @@ -0,0 +1,38 @@ +/* Import plugin specific language pack */ +//tinyMCE.importPluginLanguagePack('zoom', 'en,sv,pt,fr_ca,fr,de'); + +/** + * Returns the HTML contents of the zoom control. + */ +function TinyMCE_zoom_getControlHTML(control_name) { + if (!tinyMCE.isMSIE || tinyMCE.isMSIE5_0) + return ""; + + switch (control_name) { + case "zoom": + return ''; + } + + return ""; +} + +/** + * Executes the mceZoom command. + */ +function TinyMCE_zoom_execCommand(editor_id, element, command, user_interface, value) { + // Handle commands + switch (command) { + case "mceZoom": + tinyMCE.getInstanceById(editor_id).contentDocument.body.style.zoom = value; + tinyMCE.getInstanceById(editor_id).contentDocument.body.style.mozZoom = value; + return true; + } + + // Pass to next handler in chain + return false; +} diff --git a/public/tiny_mce/plugins/zoom/langs/fa.js b/public/tiny_mce/plugins/zoom/langs/fa.js new file mode 100644 index 0000000..a0414d9 --- /dev/null +++ b/public/tiny_mce/plugins/zoom/langs/fa.js @@ -0,0 +1,8 @@ +// IR lang variables +// Persian (Farsi) language pack (for IRAN) +// By: Morteza Zafari +// Lost@LostLord.com +// http://www.LostLord.com + +tinyMCELang['lang_dir'] = 'rtl'; +tinyMCELang['lang_zoom_prefix'] = 'بزرگنمایی'; diff --git a/public/tiny_mce/plugins/zoom/langs/fr_ca.js b/public/tiny_mce/plugins/zoom/langs/fr_ca.js new file mode 100644 index 0000000..11d3604 --- /dev/null +++ b/public/tiny_mce/plugins/zoom/langs/fr_ca.js @@ -0,0 +1,3 @@ +// CA_FR lang variables + +tinyMCELang['lang_zoom_prefix'] = 'Zoom'; diff --git a/public/tiny_mce/plugins/zoom/langs/pl.js b/public/tiny_mce/plugins/zoom/langs/pl.js new file mode 100644 index 0000000..1f49adb --- /dev/null +++ b/public/tiny_mce/plugins/zoom/langs/pl.js @@ -0,0 +1,4 @@ +// PL lang variables + +tinyMCELang['lang_dir'] = 'ltr'; +tinyMCELang['lang_zoom_prefix'] = 'Powiększenie'; \ No newline at end of file diff --git a/public/tiny_mce/plugins/zoom/langs/pt_br.js b/public/tiny_mce/plugins/zoom/langs/pt_br.js new file mode 100644 index 0000000..43a10c9 --- /dev/null +++ b/public/tiny_mce/plugins/zoom/langs/pt_br.js @@ -0,0 +1,3 @@ +// pt_BR lang variables + +tinyMCELang['lang_zoom_prefix'] = 'Zoom'; diff --git a/public/tiny_mce/plugins/zoom/langs/zh_cn.js b/public/tiny_mce/plugins/zoom/langs/zh_cn.js new file mode 100644 index 0000000..2833632 --- /dev/null +++ b/public/tiny_mce/plugins/zoom/langs/zh_cn.js @@ -0,0 +1,5 @@ +// Simplified Chinese lang variables contributed by cube316 (cube316@gmail.com) +// http://www.cube316.net/ ԻȡTinyMCE֧ + +tinyMCELang['lang_dir'] = 'ltr'; +tinyMCELang['lang_zoom_prefix'] = ''; \ No newline at end of file diff --git a/public/tiny_mce/plugins/zoom/readme.txt b/public/tiny_mce/plugins/zoom/readme.txt new file mode 100644 index 0000000..bf9e585 --- /dev/null +++ b/public/tiny_mce/plugins/zoom/readme.txt @@ -0,0 +1,22 @@ + Zoom plugin for TinyMCE +-------------------------- + +About: + Adds a zoom drop list in MSIE5.5+, this plugin was mostly created to + show how to add custom droplists as plugins. + +Installation instructions: + * Copy the zoom directory to the plugins directory of TinyMCE (/jscripts/tiny_mce/plugins). + * Add plugin to TinyMCE plugin option list example: plugins : "zoom". + * Add the preview button name to button list, example: theme_advanced_buttons3_add : "zoom". + +Initialization example: + tinyMCE.init({ + theme : "advanced", + mode : "textareas", + plugins : "preview", + theme_advanced_buttons3_add : "zoom" + }); + +Requirement: + This plugin requires MSIE on Mozilla the button will not be visible. diff --git a/public/tiny_mce/themes/advanced/anchor.htm b/public/tiny_mce/themes/advanced/anchor.htm new file mode 100644 index 0000000..38edd5a --- /dev/null +++ b/public/tiny_mce/themes/advanced/anchor.htm @@ -0,0 +1,45 @@ + + +{$lang_insert_anchor_title} + + + + +
    + + + + +
    + + + + + + + + + + + +
    {$lang_insert_anchor_title}
    {$lang_insert_anchor_name}:
    +
    +
    + + diff --git a/public/tiny_mce/themes/advanced/charmap.htm b/public/tiny_mce/themes/advanced/charmap.htm new file mode 100644 index 0000000..71ceb22 --- /dev/null +++ b/public/tiny_mce/themes/advanced/charmap.htm @@ -0,0 +1,378 @@ + + +{$lang_theme_charmap_title} + + + + + + + + + + + + + + + + +
    {$lang_theme_charmap_title}
    + + + + + + + + + +
     
     
    +
    + + + + + + + + + + + + + + + + +
    HTML-Code
     
     
    NUM-Code
     
    +
    + + + diff --git a/public/tiny_mce/themes/advanced/color_picker.htm b/public/tiny_mce/themes/advanced/color_picker.htm new file mode 100644 index 0000000..b1dc3aa --- /dev/null +++ b/public/tiny_mce/themes/advanced/color_picker.htm @@ -0,0 +1,271 @@ + + +{$lang_theme_colorpicker_title} + + + + +
    + +
    + + diff --git a/public/tiny_mce/themes/advanced/docs/en/about.htm b/public/tiny_mce/themes/advanced/docs/en/about.htm new file mode 100644 index 0000000..984a990 --- /dev/null +++ b/public/tiny_mce/themes/advanced/docs/en/about.htm @@ -0,0 +1,32 @@ + + + +About TinyMCE + + + + + + + + + + + +
    +
    +TinyMCE is a small WYSIWYG editor control for web browsers such as MSIE or Mozilla +that enables you to edit HTML contents in a more user friendly way. It has common +features that are found in most word processors and should not be difficult to +use.
    +
    +
    + + + + + + +
    + + diff --git a/public/tiny_mce/themes/advanced/docs/en/common_buttons.htm b/public/tiny_mce/themes/advanced/docs/en/common_buttons.htm new file mode 100644 index 0000000..c63d7dc --- /dev/null +++ b/public/tiny_mce/themes/advanced/docs/en/common_buttons.htm @@ -0,0 +1,163 @@ + + + +Common buttons + + + + + + + + + + + +
    +
    +Below is a short description about each button. +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Bold text style.
    Italic text style.
    Underline text style.
    Strikethrough text style.
    Align left.
    Align center.
    Align right.
    Align full.
    Unordered list/bullet list.
    Ordered list/numbered list
    Outdent/decrease indentation.
    Indent/incread indentation.
    Undo the last operation.
    Redo the last operation.
    Insert a new link, read more about this function in the Insert + link section.
    Unlinks the current selection/removes all selected links.
    Insert a new anchor, read more about this function in the Insert anchor section.
    Insert a new image, read more about this function in the Insert + image section.
    Cleanup code/Removes unwanted formating. This function is useful when + you copy contents from for example a office product.
    Shows this help window.
    Opens HTML source code editor.
    Inserts a new 2x2 table at the current location.
    Adds a row above the current one.
    Adds a row under the current one.
    Removes the row.
    Adds a column before the current one.
    Adds a column after the current one.
    Removes the current column.
    Inserts a new horizontal ruler
    Removes formatting from the selection.
    Makes the selection to be subscript.
    Makes the selection to be superscripted.
    +
    +
    + + + + + + + + diff --git a/public/tiny_mce/themes/advanced/docs/en/images/insert_anchor_window.gif b/public/tiny_mce/themes/advanced/docs/en/images/insert_anchor_window.gif new file mode 100644 index 0000000..5b5f528 Binary files /dev/null and b/public/tiny_mce/themes/advanced/docs/en/images/insert_anchor_window.gif differ diff --git a/public/tiny_mce/themes/advanced/docs/en/images/insert_image_window.gif b/public/tiny_mce/themes/advanced/docs/en/images/insert_image_window.gif new file mode 100644 index 0000000..cdc617e Binary files /dev/null and b/public/tiny_mce/themes/advanced/docs/en/images/insert_image_window.gif differ diff --git a/public/tiny_mce/themes/advanced/docs/en/images/insert_link_window.gif b/public/tiny_mce/themes/advanced/docs/en/images/insert_link_window.gif new file mode 100644 index 0000000..7bad758 Binary files /dev/null and b/public/tiny_mce/themes/advanced/docs/en/images/insert_link_window.gif differ diff --git a/public/tiny_mce/themes/advanced/docs/en/images/insert_table_window.gif b/public/tiny_mce/themes/advanced/docs/en/images/insert_table_window.gif new file mode 100644 index 0000000..6a032c5 Binary files /dev/null and b/public/tiny_mce/themes/advanced/docs/en/images/insert_table_window.gif differ diff --git a/public/tiny_mce/themes/advanced/docs/en/index.htm b/public/tiny_mce/themes/advanced/docs/en/index.htm new file mode 100644 index 0000000..0b0526a --- /dev/null +++ b/public/tiny_mce/themes/advanced/docs/en/index.htm @@ -0,0 +1,27 @@ + + + +Help Index + + + + + + + + + +
    +
    +Click the links below to go to the different help sections. + +
    + + diff --git a/public/tiny_mce/themes/advanced/docs/en/insert_anchor_button.htm b/public/tiny_mce/themes/advanced/docs/en/insert_anchor_button.htm new file mode 100644 index 0000000..e1118a2 --- /dev/null +++ b/public/tiny_mce/themes/advanced/docs/en/insert_anchor_button.htm @@ -0,0 +1,33 @@ + + + +Insert anchor button + + + + + + + + + + + +
    +
    +This button opens a new window with the insert/edit anchor function.
    +
    +
    +
    +There are one field in this window, this is where you enter the name of you anchor point. Remember the anchor name needs to be unique.
    +
    +
    + + + + + + +
    + + diff --git a/public/tiny_mce/themes/advanced/docs/en/insert_image_button.htm b/public/tiny_mce/themes/advanced/docs/en/insert_image_button.htm new file mode 100644 index 0000000..e101fff --- /dev/null +++ b/public/tiny_mce/themes/advanced/docs/en/insert_image_button.htm @@ -0,0 +1,66 @@ + + + +Insert image button + + + + + + + + + + + +
    +
    +The insert image button opens the window shown below.
    +
    +
    +
    +You simply enter a URL to the image you want to link to and enter a image description, +this is then displayed as an alternative text descripton of the image on the page.
    +
    +Field descriptions:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Image URL URL/path to the image.
    Image description Alternative description of image contents.
    DimentionsImage width/height.
    AlignmentImage alignment, useful when wrapping text around images.
    BorderBorder thickness.
    VSpaceVertical space, useful when wrapping text around images.
    HSpaceHorizontal space, useful when wrapping text around images.
    +
    +
    + + + + + + +
    + + diff --git a/public/tiny_mce/themes/advanced/docs/en/insert_link_button.htm b/public/tiny_mce/themes/advanced/docs/en/insert_link_button.htm new file mode 100644 index 0000000..ddfeb3a --- /dev/null +++ b/public/tiny_mce/themes/advanced/docs/en/insert_link_button.htm @@ -0,0 +1,34 @@ + + + +Insert link button + + + + + + + + + + + +
    +
    +This button opens a new window with the insert/edit link function.
    +
    +
    +
    +There are two fields in this window the first one "Link URL" is the +URL of the link. The target enables you to select how the link is to be opened.
    +
    +
    + + + + + + +
    + + diff --git a/public/tiny_mce/themes/advanced/docs/en/insert_table_button.htm b/public/tiny_mce/themes/advanced/docs/en/insert_table_button.htm new file mode 100644 index 0000000..d3bd196 --- /dev/null +++ b/public/tiny_mce/themes/advanced/docs/en/insert_table_button.htm @@ -0,0 +1,72 @@ + + + +Insert table button + + + + + + + + + + + +
    +
    +The insert table button opens the window shown below. This action enables you to create tables.
    +
    +
    +
    +Field descriptions:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ColumnsNumber of columns in the table.
    RowsNumber of rows in the new table.
    CellpaddingCellpadding of the table .
    CellspacingCellspacing of the table .
    AlignmentTable alignment .
    BorderBorder thinkness of table.
    WidthWidth in pixels of table .
    HeightHeight in pixels of table.
    ClassStyle or CSS class of table.
    +
    +
    +
    + + + + + + +
    + + diff --git a/public/tiny_mce/themes/advanced/docs/en/style.css b/public/tiny_mce/themes/advanced/docs/en/style.css new file mode 100644 index 0000000..722f537 --- /dev/null +++ b/public/tiny_mce/themes/advanced/docs/en/style.css @@ -0,0 +1,28 @@ +body { background-color: #FFFFFF; } +body, td, .content { font-family: Verdana, Arial, helvetica, sans-serif; font-size: 12px; } +.title { font-family: Verdana, Arial, helvetica, sans-serif; font-size: 16px; font-weight: bold; } +.subtitle { font-size: 12px; font-weight: bold; } + +.toc_ul, .toc_li { margin-left: 8 px; line-height: 16px; } +.step_ol, .step_li { margin-left: 11 px; line-height: 16px; } +img { border: #000000 solid 1px; } + +a:visited { color: #666666; text-decoration: underline; } +a:active { color: #666666; text-decoration: underline; } +a:hover { color: #666666; text-decoration: underline; } +a { color: #666666; text-decoration: underline; } + +.pageheader { border: #E0E0E0 solid 1px; } +.pagefooter { border: #E0E0E0 solid 1px; } +.sample { background-color: #FFFFFF; border: #000000 solid 1px; } +.samplecontent { font-size: 10px; } + +.code { background-color: #FFFFFF; border: #000000 solid 1px; } +.codecontent { font-size: 10px; } +.codecontent a:visited { color: #666666; text-decoration: none; font-weight: bold } +.codecontent a:active { color: #666666; text-decoration: none; font-weight: bold } +.codecontent a:hover { color: #666666; text-decoration: none; font-weight: bold } +.codecontent a { color: #666666; text-decoration: none; font-weight: bold } + +hr { height: 1px; } + diff --git a/public/tiny_mce/themes/advanced/docs/images/table.gif b/public/tiny_mce/themes/advanced/docs/images/table.gif new file mode 100644 index 0000000..f8a0054 Binary files /dev/null and b/public/tiny_mce/themes/advanced/docs/images/table.gif differ diff --git a/public/tiny_mce/themes/advanced/docs/images/table_delete_col.gif b/public/tiny_mce/themes/advanced/docs/images/table_delete_col.gif new file mode 100644 index 0000000..0b2f0fb Binary files /dev/null and b/public/tiny_mce/themes/advanced/docs/images/table_delete_col.gif differ diff --git a/public/tiny_mce/themes/advanced/docs/images/table_delete_row.gif b/public/tiny_mce/themes/advanced/docs/images/table_delete_row.gif new file mode 100644 index 0000000..1997065 Binary files /dev/null and b/public/tiny_mce/themes/advanced/docs/images/table_delete_row.gif differ diff --git a/public/tiny_mce/themes/advanced/docs/images/table_insert_col_after.gif b/public/tiny_mce/themes/advanced/docs/images/table_insert_col_after.gif new file mode 100644 index 0000000..c30dafa Binary files /dev/null and b/public/tiny_mce/themes/advanced/docs/images/table_insert_col_after.gif differ diff --git a/public/tiny_mce/themes/advanced/docs/images/table_insert_col_before.gif b/public/tiny_mce/themes/advanced/docs/images/table_insert_col_before.gif new file mode 100644 index 0000000..5d1ff37 Binary files /dev/null and b/public/tiny_mce/themes/advanced/docs/images/table_insert_col_before.gif differ diff --git a/public/tiny_mce/themes/advanced/docs/images/table_insert_row_after.gif b/public/tiny_mce/themes/advanced/docs/images/table_insert_row_after.gif new file mode 100644 index 0000000..c3aa15f Binary files /dev/null and b/public/tiny_mce/themes/advanced/docs/images/table_insert_row_after.gif differ diff --git a/public/tiny_mce/themes/advanced/docs/images/table_insert_row_before.gif b/public/tiny_mce/themes/advanced/docs/images/table_insert_row_before.gif new file mode 100644 index 0000000..c3271e5 Binary files /dev/null and b/public/tiny_mce/themes/advanced/docs/images/table_insert_row_before.gif differ diff --git a/public/tiny_mce/themes/advanced/editor_content.css b/public/tiny_mce/themes/advanced/editor_content.css new file mode 100644 index 0000000..75290ee --- /dev/null +++ b/public/tiny_mce/themes/advanced/editor_content.css @@ -0,0 +1,27 @@ +body { + background-color: #FFFFFF; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10px; + scrollbar-3dlight-color: #F0F0EE; + scrollbar-arrow-color: #676662; + scrollbar-base-color: #F0F0EE; + scrollbar-darkshadow-color: #DDDDDD; + scrollbar-face-color: #E0E0DD; + scrollbar-highlight-color: #F0F0EE; + scrollbar-shadow-color: #F0F0EE; + scrollbar-track-color: #F5F5F5; +} + +td { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10px; +} + +pre { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10px; +} + +.mceVisualAid { + border: 1px dashed #BBBBBB; +} diff --git a/public/tiny_mce/themes/advanced/editor_popup.css b/public/tiny_mce/themes/advanced/editor_popup.css new file mode 100644 index 0000000..d51982c --- /dev/null +++ b/public/tiny_mce/themes/advanced/editor_popup.css @@ -0,0 +1,121 @@ +body { + background-color: #F0F0EE; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; + scrollbar-3dlight-color: #F0F0EE; + scrollbar-arrow-color: #676662; + scrollbar-base-color: #F0F0EE; + scrollbar-darkshadow-color: #DDDDDD; + scrollbar-face-color: #E0E0DD; + scrollbar-highlight-color: #F0F0EE; + scrollbar-shadow-color: #F0F0EE; + scrollbar-track-color: #F5F5F5; +} + +td { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; +} + +input { + background: #FFFFFF; + border: 1px solid #cccccc; +} + +td, input, select, textarea { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10px; +} + +input, select, textarea { + border: 1px solid #808080; +} + +.input_noborder { + border: 0px solid #808080; +} + +#insert { + font-weight: bold; +} + +#cancel { + font-weight: bold; +} + +.title { + font-size: 12px; + font-weight: bold; +} + +table.charmap { + border-style: solid; + border-width: 1px; + border-color: #AAAAAA; +} + +td.charmap, td.charmapOver { + color: #000000; + border-color: #AAAAAA; + border-style: solid; + border-width: 1px; + text-align: center; + font-size: 12px; +} + +td.charmapOver { + background-color: #CCCCCC; + cursor: arrow; +} + +a.charmap { + color: #000000; + text-decoration: none +} + +.wordWrapCode { + vertical-align: middle; + border: 1px none #000000; + background-color: transparent; +} + +input.radio { + border: 1px none #000000; + background-color: transparent; + vertical-align: middle; +} + +input.checkbox { + border: 1px none #000000; + background-color: transparent; + vertical-align: middle; +} + +.mceButtonNormal, .mceButtonOver, .mceButtonDown, .mceSeparator, .mceButtonDisabled, .mceButtonSelected { + margin-left: 1px; +} + +.mceButtonNormal { + border-top: 1px solid; + border-left: 1px solid; + border-bottom: 1px solid; + border-right: 1px solid; + border-color: #F0F0EE; + cursor: arrow; +} + +.mceButtonOver { + border: 1px solid #0A246A; + cursor: arrow; + background-color: #B6BDD2; +} + +.mceButtonDown { + cursor: arrow; + border: 1px solid #0A246A; + background-color: #8592B5; +} + +legend { + font-weight: bold; +} diff --git a/public/tiny_mce/themes/advanced/editor_template.js b/public/tiny_mce/themes/advanced/editor_template.js new file mode 100644 index 0000000..473e7cc --- /dev/null +++ b/public/tiny_mce/themes/advanced/editor_template.js @@ -0,0 +1,31 @@ +/* Import theme specific language pack */ + tinyMCE.importThemeLanguagePack('advanced');var TinyMCE_advanced_autoImportCSSClasses=true;var TinyMCE_advanced_foreColor="#000000";var TinyMCE_advanced_anchorName="";var TinyMCE_advanced_buttons=[['bold','{$lang_bold_img}','{$lang_bold_desc}','Bold'],['italic','{$lang_italic_img}','{$lang_italic_desc}','Italic'],['underline','{$lang_underline_img}','{$lang_underline_desc}','Underline'],['strikethrough','strikethrough.gif','{$lang_striketrough_desc}','Strikethrough'],['justifyleft','left.gif','{$lang_justifyleft_desc}','JustifyLeft'],['justifycenter','center.gif','{$lang_justifycenter_desc}','JustifyCenter'],['justifyright','right.gif','{$lang_justifyright_desc}','JustifyRight'],['justifyfull','full.gif','{$lang_justifyfull_desc}','JustifyFull'],['bullist','bullist.gif','{$lang_bullist_desc}','InsertUnorderedList'],['numlist','numlist.gif','{$lang_numlist_desc}','InsertOrderedList'],['outdent','outdent.gif','{$lang_outdent_desc}','Outdent'],['indent','indent.gif','{$lang_indent_desc}','Indent'],['cut','cut.gif','{$lang_cut_desc}','Cut'],['copy','copy.gif','{$lang_copy_desc}','Copy'],['paste','paste.gif','{$lang_paste_desc}','Paste'],['undo','undo.gif','{$lang_undo_desc}','Undo'],['redo','redo.gif','{$lang_redo_desc}','Redo'],['link','link.gif','{$lang_link_desc}','mceLink',true],['attachment','attachment.gif','{$lang_attachment_desc}','mceAttachment',true],['unlink','unlink.gif','{$lang_unlink_desc}','unlink'],['image','image.gif','{$lang_image_desc}','mceImage',true],['cleanup','cleanup.gif','{$lang_cleanup_desc}','mceCleanup'],['help','help.gif','{$lang_help_desc}','mceHelp'],['code','code.gif','{$lang_theme_code_desc}','mceCodeEditor'],['hr','hr.gif','{$lang_theme_hr_desc}','inserthorizontalrule'],['removeformat','removeformat.gif','{$lang_theme_removeformat_desc}','removeformat'],['sub','sub.gif','{$lang_theme_sub_desc}','subscript'],['sup','sup.gif','{$lang_theme_sup_desc}','superscript'],['forecolor','forecolor.gif','{$lang_theme_forecolor_desc}','mceForeColor',true],['backcolor','backcolor.gif','{$lang_theme_backcolor_desc}','mceBackColor',true],['charmap','charmap.gif','{$lang_theme_charmap_desc}','mceCharMap'],['visualaid','visualaid.gif','{$lang_theme_visualaid_desc}','mceToggleVisualAid'],['anchor','anchor.gif','{$lang_theme_anchor_desc}','mceInsertAnchor']];function TinyMCE_advanced_getControlHTML(button_name){var buttonTileMap=new Array('anchor.gif','backcolor.gif','bullist.gif','center.gif','charmap.gif','cleanup.gif','code.gif','copy.gif','custom_1.gif','cut.gif','forecolor.gif','full.gif','help.gif','hr.gif','image.gif','indent.gif','left.gif','link.gif','attachment.gif','numlist.gif','outdent.gif','paste.gif','redo.gif','removeformat.gif','right.gif','strikethrough.gif','sub.gif','sup.gif','undo.gif','unlink.gif','visualaid.gif');for(var i=0;i';}}}return '';}}switch(button_name){case "formatselect":var html='';return html;case "styleselect":return '';case "fontselect":return '';case "fontsizeselect":return '';case "|":case "separator":return '';case "spacer":return '';case "rowseparator":return '
    ';}return "";}function TinyMCE_advanced_execCommand(editor_id,element,command,user_interface,value){switch(command){case "mceForeColor":var template=new Array();var inputColor=TinyMCE_advanced_foreColor;if(!inputColor){inputColor="#000000";}template['file']='color_picker.htm';template['width']=210;template['height']=200;tinyMCE.openWindow(template,{editor_id:editor_id,command:"forecolor",input_color:inputColor});return true;case "mceBackColor":var template=new Array();var inputColor=TinyMCE_advanced_foreColor;if(!inputColor){inputColor="#000000";}template['file']='color_picker.htm';template['width']=210;template['height']=200;tinyMCE.openWindow(template,{editor_id:editor_id,command:"HiliteColor",input_color:inputColor});return true;case "mceCodeEditor":var template=new Array();template['file']='source_editor.htm';template['width']=tinyMCE.getParam("theme_advanced_source_editor_width",500);template['height']=tinyMCE.getParam("theme_advanced_source_editor_height",400);tinyMCE.openWindow(template,{editor_id:editor_id,resizable:"yes",scrollbars:"no"});return true;case "mceCharMap":var template=new Array();template['file']='charmap.htm';template['width']=550;template['height']=280;tinyMCE.openWindow(template,{editor_id:editor_id});return true;case "mceInsertAnchor":var template=new Array();template['file']='anchor.htm';template['width']=320;template['height']=130;tinyMCE.openWindow(template,{editor_id:editor_id,name:TinyMCE_advanced_anchorName,action:(TinyMCE_advanced_anchorName==""?"insert":"update")});return true;}return false;}function TinyMCE_advanced_getEditorTemplate(settings,editorId){function removeFromArray(in_array,remove_array){var outArray=new Array();for(var i=0;i'+key+'';}TinyMCE_advanced_autoImportCSSClasses=false;}switch(layoutManager){case "SimpleLayout":var toolbarHTML="";var toolbarLocation=tinyMCE.getParam("theme_advanced_toolbar_location","bottom");var toolbarAlign=tinyMCE.getParam("theme_advanced_toolbar_align","center");var pathLocation=tinyMCE.getParam("theme_advanced_path_location","none");var buttonNamesRow1=tinyMCE.getParam("theme_advanced_buttons1","bold,italic,underline,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,styleselect,formatselect",true,',');buttonNamesRow1=removeFromArray(buttonNamesRow1,tinyMCE.getParam("theme_advanced_disable","",true,','));buttonNamesRow1=addToArray(buttonNamesRow1,tinyMCE.getParam("theme_advanced_buttons1_add","",true,','));buttonNamesRow1=addToArray(tinyMCE.getParam("theme_advanced_buttons1_add_before","",true,','),buttonNamesRow1);for(var i=0;i0){toolbarHTML+="
    ";deltaHeight-=23;}var buttonNamesRow2=tinyMCE.getParam("theme_advanced_buttons2","bullist,numlist,separator,outdent,indent,separator,undo,redo,separator,link,unlink,attachment,anchor,image,cleanup,help,code",true,',');buttonNamesRow2=removeFromArray(buttonNamesRow2,tinyMCE.getParam("theme_advanced_disable","",true,','));buttonNamesRow2=addToArray(buttonNamesRow2,tinyMCE.getParam("theme_advanced_buttons2_add","",true,','));buttonNamesRow2=addToArray(tinyMCE.getParam("theme_advanced_buttons2_add_before","",true,','),buttonNamesRow2);for(var i=0;i0){toolbarHTML+="
    ";deltaHeight-=23;}var buttonNamesRow3=tinyMCE.getParam("theme_advanced_buttons3","hr,removeformat,visualaid,separator,sub,sup,separator,charmap",true,',');buttonNamesRow3=removeFromArray(buttonNamesRow3,tinyMCE.getParam("theme_advanced_disable","",true,','));buttonNamesRow3=addToArray(buttonNamesRow3,tinyMCE.getParam("theme_advanced_buttons3_add","",true,','));buttonNamesRow3=addToArray(tinyMCE.getParam("theme_advanced_buttons3_add_before","",true,','),buttonNamesRow3);for(var i=0;i0){deltaHeight-=20;}template['html']='';if(toolbarLocation=="top"){template['html']+='';}if(pathLocation=="top"){template['html']+='';deltaHeight-=23;}template['html']+='';if(toolbarLocation=="bottom"){template['html']+='';}if(toolbarLocation=="external"){var bod=document.body;var elm=document.createElement("div");toolbarHTML=tinyMCE.replaceVars(toolbarHTML,tinyMCE.settings);toolbarHTML=tinyMCE.replaceVars(toolbarHTML,tinyMCELang);toolbarHTML=tinyMCE.replaceVar(toolbarHTML,'style_select_options',styleSelectHTML);toolbarHTML=tinyMCE.replaceVar(toolbarHTML,"editor_id",editorId);toolbarHTML=tinyMCE.replaceVar(toolbarHTML,"default_document",tinyMCE.baseURL+"/blank.htm");elm.className="mceToolbarExternal";elm.id="mceExternalToolbar";elm.innerHTML='
    '+toolbarHTML+'
    '+pathHTML+'
    '+toolbarHTML+'
    '+toolbarHTML+'
    ';bod.appendChild(elm);bod.style.marginTop=elm.offsetHeight+"px";tinyMCE.isExternalToolbar=true;}else{tinyMCE.isExternalToolbar=false;}if(pathLocation=="bottom"){template['html']+=''+pathHTML+'';deltaHeight-=23;}template['html']+='';break;case "RowLayout":template['html']='';var containers=tinyMCE.getParam("theme_advanced_containers","",true,",");var defaultContainerCSS=tinyMCE.getParam("theme_advanced_containers_default_class","container");var defaultContainerAlign=tinyMCE.getParam("theme_advanced_containers_default_align","center");for(var i=0;i';}else if(containers[i]=="mceElementpath"){var pathClass="mcePath";if(i==containers.length-1){pathClass="mcePathBottom";}else if(i==0){pathClass="mcePathTop";}else{deltaHeight-=2;}template['html']+='';deltaHeight-=22;}else{var curContainer=tinyMCE.getParam("theme_advanced_container_"+containers[i],"",true,',');var curContainerHTML="";var curAlign=tinyMCE.getParam("theme_advanced_container_"+containers[i]+"_align",defaultContainerAlign);var curCSS=tinyMCE.getParam("theme_advanced_container_"+containers[i]+"_class",defaultContainerCSS);for(var j=0;j0){curContainerHTML+="
    ";deltaHeight-=23;}template['html']+='
    ';}}template['html']+='
    \ + \ +
    '+pathHTML+'
    '+curContainerHTML+'
    ';break;case "BorderLayout":break;case "CustomLayout":var customLayout=tinyMCE.getParam("theme_advanced_custom_layout","");if(customLayout!=""&&eval("typeof("+customLayout+")")!="undefined"){template=eval(customLayout+"(template);");}break;default:alert('UNDEFINED LAYOUT MANAGER! PLEASE CHECK YOUR TINYMCE CONFIG!');break;}template['html']=tinyMCE.replaceVar(template['html'],'style_select_options',styleSelectHTML);template['delta_width']=0;template['delta_height']=deltaHeight;return template;}function TinyMCE_advanced_getInsertLinkTemplate(){var template=new Array();template['file']='link.htm';template['width']=300;template['height']=150;template['width']+=tinyMCE.getLang('lang_insert_link_delta_width',0);template['height']+=tinyMCE.getLang('lang_insert_link_delta_height',0);return template;};function TinyMCE_advanced_getInsertAttachmentTemplate(){var template=new Array();template['file']='attachment.htm';template['width']=300;template['height']=150;template['width']+=tinyMCE.getLang('lang_insert_attachment_delta_width',0);template['height']+=tinyMCE.getLang('lang_insert_attachment_delta_height',0);return template;}function TinyMCE_advanced_getInsertImageTemplate(){var template=new Array();template['file']='image.htm?src={$src}';template['width']=340;template['height']=280;template['width']+=tinyMCE.getLang('lang_insert_image_delta_width',0);template['height']+=tinyMCE.getLang('lang_insert_image_delta_height',0);return template;};function TinyMCE_advanced_handleNodeChange(editor_id,node,undo_index,undo_levels,visual_aid,any_selection){function selectByValue(select_elm,value){if(select_elm){for(var i=0;i=0;i--){var nodeName=path[i].nodeName.toLowerCase();var nodeData="";if(nodeName=="b"){nodeName="strong";}if(nodeName=="i"){nodeName="em";}if(getAttrib(path[i],'id')!=""){nodeData+="id: "+path[i].getAttribute('id')+" ";}if(getAttrib(path[i],'class')!=""){nodeData+="class: "+path[i].getAttribute('class')+" ";}if(getAttrib(path[i],'className')!=""){nodeData+="class: "+path[i].getAttribute('className')+" ";}if(getAttrib(path[i],'src')!=""){nodeData+="src: "+path[i].getAttribute('src')+" ";}if(getAttrib(path[i],'href')!=""){nodeData+="href: "+path[i].getAttribute('href')+" ";}if(nodeName=="img"&&getAttrib(path[i],'name')=="mce_plugin_flash"){nodeName="flash";nodeData="";}if(getAttrib(path[i],'name').indexOf("mce_")!=0){if(getAttrib(path[i],"className")!=""){nodeName+="."+getAttrib(path[i],"className");}else if(getAttrib(path[i],"class")!=""){nodeName+="."+getAttrib(path[i],"class");}}if(tinyMCE.isMSIE){html+=''+nodeName+'';}else{html+=''+nodeName+'';}if(i>0){html+=" » ";}}pathElm.innerHTML=html+" ";}var colorElm=tinyMCE.getParentElement(node,"font","color");if(colorElm){TinyMCE_advanced_foreColor=""+colorElm.color.toUpperCase();}tinyMCE.switchClassSticky(editor_id+'_justifyleft','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_justifyright','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_justifycenter','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_justifyfull','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_bold','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_italic','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_underline','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_strikethrough','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_bullist','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_numlist','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_sub','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_sup','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_anchor','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_link','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_attachment','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_unlink','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_outdent','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_image','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_hr','mceButtonNormal');var anchorName=tinyMCE.getParentElement(node,"a","name");TinyMCE_advanced_anchorName="";if(anchorName){TinyMCE_advanced_anchorName=anchorName.getAttribute("name");tinyMCE.switchClassSticky(editor_id+'_anchor','mceButtonSelected');}var anchorLink=tinyMCE.getParentElement(node,"a","href");if(anchorLink||any_selection){tinyMCE.switchClassSticky(editor_id+'_link',anchorLink?'mceButtonSelected':'mceButtonNormal',false);tinyMCE.switchClassSticky(editor_id+'_attachment',anchorLink?'mceButtonSelected':'mceButtonNormal',false);tinyMCE.switchClassSticky(editor_id+'_unlink',anchorLink?'mceButtonSelected':'mceButtonNormal',false);}tinyMCE.switchClassSticky(editor_id+'_visualaid',visual_aid?'mceButtonSelected':'mceButtonNormal',false);if(undo_levels!=-1){tinyMCE.switchClassSticky(editor_id+'_undo','mceButtonDisabled',true);tinyMCE.switchClassSticky(editor_id+'_redo','mceButtonDisabled',true);}if(tinyMCE.getParentElement(node,"li,blockquote")){tinyMCE.switchClassSticky(editor_id+'_outdent','mceButtonNormal',false);}if(undo_index!=-1&&(undo_index0)){tinyMCE.switchClassSticky(editor_id+'_redo','mceButtonNormal',false);}if(undo_index!=-1&&(undo_index>0&&undo_levels>0)){tinyMCE.switchClassSticky(editor_id+'_undo','mceButtonNormal',false);}var selectElm=document.getElementById(editor_id+"_styleSelect");if(selectElm){TinyMCE_advanced_setupCSSClasses(editor_id);classNode=node;breakOut=false;var index=0;do{if(classNode&&classNode.className){for(var i=0;i");}else{selectByValue(selectElm,"");}}var selectElm=document.getElementById(editor_id+"_fontNameSelect");if(selectElm){var elm=tinyMCE.getParentElement(node,"font","face");if(elm){selectByValue(selectElm,elm.getAttribute("face"));}else{selectByValue(selectElm,"");}}var selectElm=document.getElementById(editor_id+"_fontSizeSelect");if(selectElm){var elm=tinyMCE.getParentElement(node,"font","size");if(elm&&getAttrib(elm,"size")!=""){selectByValue(selectElm,elm.getAttribute("size"));}else{selectByValue(selectElm,"0");}}alignNode=node;breakOut=false;do{if(!alignNode.getAttribute||!alignNode.getAttribute('align')){continue;}switch(alignNode.getAttribute('align').toLowerCase()){case "left":tinyMCE.switchClassSticky(editor_id+'_justifyleft','mceButtonSelected');breakOut=true;break;case "right":tinyMCE.switchClassSticky(editor_id+'_justifyright','mceButtonSelected');breakOut=true;break;case "middle":case "center":tinyMCE.switchClassSticky(editor_id+'_justifycenter','mceButtonSelected');breakOut=true;break;case "justify":tinyMCE.switchClassSticky(editor_id+'_justifyfull','mceButtonSelected');breakOut=true;break;}}while(!breakOut&&(alignNode=alignNode.parentNode));if(tinyMCE.isGecko&&node.nodeType==3){var inst=tinyMCE.getInstanceById(editor_id);var doc=inst.getDoc();if(doc.queryCommandState("Bold")){tinyMCE.switchClassSticky(editor_id+'_bold','mceButtonSelected');}if(doc.queryCommandState("Italic")){tinyMCE.switchClassSticky(editor_id+'_italic','mceButtonSelected');}if(doc.queryCommandState("Underline")&&(node.parentNode==null||node.parentNode.nodeName!="A")){tinyMCE.switchClassSticky(editor_id+'_underline','mceButtonSelected');}if(doc.queryCommandState("Strikethrough")){tinyMCE.switchClassSticky(editor_id+'_strikethrough','mceButtonSelected');}}do{switch(node.nodeName.toLowerCase()){case "b":case "strong":tinyMCE.switchClassSticky(editor_id+'_bold','mceButtonSelected');break;case "i":case "em":tinyMCE.switchClassSticky(editor_id+'_italic','mceButtonSelected');break;case "u":tinyMCE.switchClassSticky(editor_id+'_underline','mceButtonSelected');break;case "strike":tinyMCE.switchClassSticky(editor_id+'_strikethrough','mceButtonSelected');break;case "ul":tinyMCE.switchClassSticky(editor_id+'_bullist','mceButtonSelected');break;case "ol":tinyMCE.switchClassSticky(editor_id+'_numlist','mceButtonSelected');break;case "sub":tinyMCE.switchClassSticky(editor_id+'_sub','mceButtonSelected');break;case "sup":tinyMCE.switchClassSticky(editor_id+'_sup','mceButtonSelected');break;case "hr":tinyMCE.switchClassSticky(editor_id+'_hr','mceButtonSelected');break;case "img":if(getAttrib(node,'name').indexOf('mce_')!=0){tinyMCE.switchClassSticky(editor_id+'_image','mceButtonSelected');}break;}}while((node=node.parentNode));};function TinyMCE_advanced_setupCSSClasses(editor_id){if(!TinyMCE_advanced_autoImportCSSClasses){return;}var selectElm=document.getElementById(editor_id+'_styleSelect');if(selectElm&&selectElm.getAttribute('cssImported')!='true'){var csses=tinyMCE.getCSSClasses(editor_id);if(csses&&selectElm){for(var i=0;i0){selectElm.setAttribute('cssImported','true');}}}; \ No newline at end of file diff --git a/public/tiny_mce/themes/advanced/editor_template_src.js b/public/tiny_mce/themes/advanced/editor_template_src.js new file mode 100644 index 0000000..d8f8180 --- /dev/null +++ b/public/tiny_mce/themes/advanced/editor_template_src.js @@ -0,0 +1,1010 @@ +/* Import theme specific language pack */ +tinyMCE.importThemeLanguagePack('advanced'); + +// Variable declarations +var TinyMCE_advanced_autoImportCSSClasses = true; +var TinyMCE_advanced_foreColor = "#000000"; +var TinyMCE_advanced_anchorName = ""; +var TinyMCE_advanced_buttons = [ + // Control id, button img, button title, command, user_interface, value + ['bold', '{$lang_bold_img}', '{$lang_bold_desc}', 'Bold'], + ['italic', '{$lang_italic_img}', '{$lang_italic_desc}', 'Italic'], + ['underline', '{$lang_underline_img}', '{$lang_underline_desc}', 'Underline'], + ['strikethrough', 'strikethrough.gif', '{$lang_striketrough_desc}', 'Strikethrough'], + ['justifyleft', 'left.gif', '{$lang_justifyleft_desc}', 'JustifyLeft'], + ['justifycenter', 'center.gif', '{$lang_justifycenter_desc}', 'JustifyCenter'], + ['justifyright', 'right.gif', '{$lang_justifyright_desc}', 'JustifyRight'], + ['justifyfull', 'full.gif', '{$lang_justifyfull_desc}', 'JustifyFull'], + ['bullist', 'bullist.gif', '{$lang_bullist_desc}', 'InsertUnorderedList'], + ['numlist', 'numlist.gif', '{$lang_numlist_desc}', 'InsertOrderedList'], + ['outdent', 'outdent.gif', '{$lang_outdent_desc}', 'Outdent'], + ['indent', 'indent.gif', '{$lang_indent_desc}', 'Indent'], + ['cut', 'cut.gif', '{$lang_cut_desc}', 'Cut'], + ['copy', 'copy.gif', '{$lang_copy_desc}', 'Copy'], + ['paste', 'paste.gif', '{$lang_paste_desc}', 'Paste'], + ['undo', 'undo.gif', '{$lang_undo_desc}', 'Undo'], + ['redo', 'redo.gif', '{$lang_redo_desc}', 'Redo'], + ['link', 'link.gif', '{$lang_link_desc}', 'mceLink', true], + ['attachment', 'attachment.gif', '{$lang_attachment_desc}', 'mceAttachment', true], + ['unlink', 'unlink.gif', '{$lang_unlink_desc}', 'unlink'], + ['image', 'image.gif', '{$lang_image_desc}', 'mceImage', true], + ['cleanup', 'cleanup.gif', '{$lang_cleanup_desc}', 'mceCleanup'], + ['help', 'help.gif', '{$lang_help_desc}', 'mceHelp'], + ['code', 'code.gif', '{$lang_theme_code_desc}', 'mceCodeEditor'], + ['hr', 'hr.gif', '{$lang_theme_hr_desc}', 'inserthorizontalrule'], + ['removeformat', 'removeformat.gif', '{$lang_theme_removeformat_desc}', 'removeformat'], + ['sub', 'sub.gif', '{$lang_theme_sub_desc}', 'subscript'], + ['sup', 'sup.gif', '{$lang_theme_sup_desc}', 'superscript'], + ['forecolor', 'forecolor.gif', '{$lang_theme_forecolor_desc}', 'mceForeColor', true], + ['backcolor', 'backcolor.gif', '{$lang_theme_backcolor_desc}', 'mceBackColor', true], + ['charmap', 'charmap.gif', '{$lang_theme_charmap_desc}', 'mceCharMap'], + ['visualaid', 'visualaid.gif', '{$lang_theme_visualaid_desc}', 'mceToggleVisualAid'], + ['anchor', 'anchor.gif', '{$lang_theme_anchor_desc}', 'mceInsertAnchor'] +]; + +/** + * Returns HTML code for the specificed control. + */ +function TinyMCE_advanced_getControlHTML(button_name) +{ + var buttonTileMap = new Array('anchor.gif','backcolor.gif','bullist.gif','center.gif', + 'charmap.gif','cleanup.gif','code.gif','copy.gif','custom_1.gif', + 'cut.gif','forecolor.gif','full.gif','help.gif','hr.gif', + 'image.gif','indent.gif','left.gif','link.gif','attachment.gif','numlist.gif', + 'outdent.gif','paste.gif','redo.gif','removeformat.gif', + 'right.gif','strikethrough.gif','sub.gif','sup.gif','undo.gif', + 'unlink.gif','visualaid.gif'); + + // Lookup button in button list + for (var i=0; i'; + } + } + } + + // Old style + return ''; + } + } + + // Custom controlls other than buttons + switch (button_name) + { + case "formatselect": + var html = ''; + //formatselect + return html; + + case "styleselect": + //styleselect + return ''; + + case "fontselect": + //fontselect + return ''; + + case "fontsizeselect": + //fontsizeselect + return ''; + + case "|": + case "separator": + return ''; + + case "spacer": + return ''; + + case "rowseparator": + return '
    '; + } + + return ""; +} + +/** + * Theme specific exec command handeling. + */ +function TinyMCE_advanced_execCommand(editor_id, element, command, user_interface, value) +{ + switch (command) + { + case "mceForeColor": + var template = new Array(); + var inputColor = TinyMCE_advanced_foreColor; + + if (!inputColor) + { + inputColor = "#000000"; + } + + template['file'] = 'color_picker.htm'; + template['width'] = 210; + template['height'] = 200; + + tinyMCE.openWindow(template, {editor_id : editor_id, command : "forecolor", input_color : inputColor}); + //mceForeColor + return true; + + case "mceBackColor": + var template = new Array(); + var inputColor = TinyMCE_advanced_foreColor; + + if (!inputColor) + { + inputColor = "#000000"; + } + + template['file'] = 'color_picker.htm'; + template['width'] = 210; + template['height'] = 200; + + tinyMCE.openWindow(template, {editor_id : editor_id, command : "HiliteColor", input_color : inputColor}); + //mceBackColor + return true; + + case "mceCodeEditor": + var template = new Array(); + + template['file'] = 'source_editor.htm'; + template['width'] = tinyMCE.getParam("theme_advanced_source_editor_width", 500); + template['height'] = tinyMCE.getParam("theme_advanced_source_editor_height", 400); + + tinyMCE.openWindow(template, {editor_id : editor_id, resizable : "yes", scrollbars : "no"}); + //mceCodeEditor + return true; + + case "mceCharMap": + var template = new Array(); + + template['file'] = 'charmap.htm'; + template['width'] = 550; + template['height'] = 280; + + tinyMCE.openWindow(template, {editor_id : editor_id}); + //mceCharMap + return true; + + case "mceInsertAnchor": + var template = new Array(); + + template['file'] = 'anchor.htm'; + template['width'] = 320; + template['height'] = 130; + + tinyMCE.openWindow(template, {editor_id : editor_id, name : TinyMCE_advanced_anchorName, action : (TinyMCE_advanced_anchorName == "" ? "insert" : "update")}); + //mceInsertAnchor + return true; + } + + // Default behavior + return false; +} + +/** + * Editor instance template function. + */ +function TinyMCE_advanced_getEditorTemplate(settings, editorId) +{ + function removeFromArray(in_array, remove_array) + { + var outArray = new Array(); + + for (var i=0; i' + key + ''; + } + + TinyMCE_advanced_autoImportCSSClasses = false; + } + + switch(layoutManager) + { + case "SimpleLayout" : //the default TinyMCE Layout (for backwards compatibility)... + var toolbarHTML = ""; + var toolbarLocation = tinyMCE.getParam("theme_advanced_toolbar_location", "bottom"); + var toolbarAlign = tinyMCE.getParam("theme_advanced_toolbar_align", "center"); + var pathLocation = tinyMCE.getParam("theme_advanced_path_location", "none"); + + // Render row 1 + var buttonNamesRow1 = tinyMCE.getParam("theme_advanced_buttons1", "bold,italic,underline,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,styleselect,formatselect", true, ','); + buttonNamesRow1 = removeFromArray(buttonNamesRow1, tinyMCE.getParam("theme_advanced_disable", "", true, ',')); + buttonNamesRow1 = addToArray(buttonNamesRow1, tinyMCE.getParam("theme_advanced_buttons1_add", "", true, ',')); + buttonNamesRow1 = addToArray(tinyMCE.getParam("theme_advanced_buttons1_add_before", "", true, ','), buttonNamesRow1); + + for (var i=0; i 0) + { + toolbarHTML += "
    "; + deltaHeight -= 23; + } + + // Render row 2 + var buttonNamesRow2 = tinyMCE.getParam("theme_advanced_buttons2", "bullist,numlist,separator,outdent,indent,separator,undo,redo,separator,link,unlink,attachment,anchor,image,cleanup,help,code", true, ','); + buttonNamesRow2 = removeFromArray(buttonNamesRow2, tinyMCE.getParam("theme_advanced_disable", "", true, ',')); + buttonNamesRow2 = addToArray(buttonNamesRow2, tinyMCE.getParam("theme_advanced_buttons2_add", "", true, ',')); + buttonNamesRow2 = addToArray(tinyMCE.getParam("theme_advanced_buttons2_add_before", "", true, ','), buttonNamesRow2); + + for (var i=0; i 0) + { + toolbarHTML += "
    "; + deltaHeight -= 23; + } + + // Render row 3 + var buttonNamesRow3 = tinyMCE.getParam("theme_advanced_buttons3", "hr,removeformat,visualaid,separator,sub,sup,separator,charmap", true, ','); + buttonNamesRow3 = removeFromArray(buttonNamesRow3, tinyMCE.getParam("theme_advanced_disable", "", true, ',')); + buttonNamesRow3 = addToArray(buttonNamesRow3, tinyMCE.getParam("theme_advanced_buttons3_add", "", true, ',')); + buttonNamesRow3 = addToArray(tinyMCE.getParam("theme_advanced_buttons3_add_before", "", true, ','), buttonNamesRow3); + + for (var i=0; i 0) + { + deltaHeight -= 20; + } + + // Setup template html + template['html'] = ''; + + if (toolbarLocation == "top") + { + template['html'] += ''; + } + + if (pathLocation == "top") + { + template['html'] += ''; + deltaHeight -= 23; + } + + template['html'] += ''; + + if (toolbarLocation == "bottom") + { + template['html'] += ''; + } + + // External toolbar changes + if (toolbarLocation == "external") + { + var bod = document.body; + var elm = document.createElement ("div"); + + toolbarHTML = tinyMCE.replaceVars(toolbarHTML, tinyMCE.settings); + toolbarHTML = tinyMCE.replaceVars(toolbarHTML, tinyMCELang); + toolbarHTML = tinyMCE.replaceVar(toolbarHTML, 'style_select_options', styleSelectHTML); + toolbarHTML = tinyMCE.replaceVar(toolbarHTML, "editor_id", editorId); + toolbarHTML = tinyMCE.replaceVar(toolbarHTML, "default_document", tinyMCE.baseURL + "/blank.htm"); + + elm.className = "mceToolbarExternal"; + elm.id = "mceExternalToolbar"; + elm.innerHTML = '
    ' + toolbarHTML + '
    ' + pathHTML + '
    ' + toolbarHTML + '
    '+toolbarHTML+'
    '; + bod.appendChild (elm); + bod.style.marginTop = elm.offsetHeight + "px"; + + tinyMCE.isExternalToolbar = true; + + //template['html'] = '
    '+toolbarHTML+'
    ' + template["html"]; + } + else + { + tinyMCE.isExternalToolbar = false; + } + + if (pathLocation == "bottom") + { + template['html'] += '' + pathHTML + ''; + deltaHeight -= 23; + } + + template['html'] += ''; + //"SimpleLayout" + break; + + case "RowLayout" : //Container Layout - containers defined in "theme_advanced_containers" are rendered from top to bottom. + template['html'] = ''; + + var containers = tinyMCE.getParam("theme_advanced_containers", "", true, ","); + var defaultContainerCSS = tinyMCE.getParam("theme_advanced_containers_default_class", "container"); + var defaultContainerAlign = tinyMCE.getParam("theme_advanced_containers_default_align", "center"); + + //Render Containers: + for (var i = 0; i < containers.length; i++) + { + if (containers[i] == "mceEditor") //Exceptions for mceEditor and ... + { + template['html'] += ''; + } + else if (containers[i] == "mceElementpath") // ... mceElementpath: + { + var pathClass = "mcePath"; + + if (i == containers.length-1) + { + pathClass = "mcePathBottom"; + } + else if (i == 0) + { + pathClass = "mcePathTop"; + } + else + { + deltaHeight-=2; + } + + template['html'] += ''; + deltaHeight -= 22; + } + else //Render normal Container: + { + var curContainer = tinyMCE.getParam("theme_advanced_container_"+containers[i], "", true, ','); + var curContainerHTML = ""; + var curAlign = tinyMCE.getParam("theme_advanced_container_"+containers[i]+"_align", defaultContainerAlign); + var curCSS = tinyMCE.getParam("theme_advanced_container_"+containers[i]+"_class", defaultContainerCSS); + + for (var j=0; j 0) + { + curContainerHTML += "
    "; + deltaHeight -= 23; + } + + template['html'] += '
    '; + } + } + + template['html'] += '
    \ + \ +
    ' + pathHTML + '
    ' + curContainerHTML + '
    '; + //RowLayout + break; + + case "BorderLayout" : //will be like java.awt.BorderLayout of SUN Java... + // Not implemented yet... + break; + + case "CustomLayout" : //User defined layout callback... + var customLayout = tinyMCE.getParam("theme_advanced_custom_layout",""); + + if (customLayout != "" && eval("typeof(" + customLayout + ")") != "undefined") + { + template = eval(customLayout + "(template);"); + } + break; + + default: + alert('UNDEFINED LAYOUT MANAGER! PLEASE CHECK YOUR TINYMCE CONFIG!'); + //CustomLayout + break; + } + + template['html'] = tinyMCE.replaceVar(template['html'], 'style_select_options', styleSelectHTML); + template['delta_width'] = 0; + template['delta_height'] = deltaHeight; + + return template; +} + +/** + * Insert link template function. + */ +function TinyMCE_advanced_getInsertLinkTemplate() +{ + var template = new Array(); + + template['file'] = 'link.htm'; + template['width'] = 300; + template['height'] = 150; + + // Language specific width and height addons + template['width'] += tinyMCE.getLang('lang_insert_link_delta_width', 0); + template['height'] += tinyMCE.getLang('lang_insert_link_delta_height', 0); + + return template; +}; + +/** + * Insert attachment template function. + */ +function TinyMCE_advanced_getInsertAttachmentTemplate() { + var template = new Array(); + + template['file'] = 'attachment.htm'; + template['width'] = 300; + template['height'] = 150; + + // Language specific width and height addons + template['width'] += tinyMCE.getLang('lang_insert_attachment_delta_width', 0); + template['height'] += tinyMCE.getLang('lang_insert_attachment_delta_height', 0); + + return template; +} + +/** + * Insert image template function. + */ +function TinyMCE_advanced_getInsertImageTemplate() +{ + var template = new Array(); + + template['file'] = 'image.htm?src={$src}'; + template['width'] = 340; + template['height'] = 280; + + // Language specific width and height addons + template['width'] += tinyMCE.getLang('lang_insert_image_delta_width', 0); + template['height'] += tinyMCE.getLang('lang_insert_image_delta_height', 0); + + return template; +}; + +/** + * Node change handler. + */ +function TinyMCE_advanced_handleNodeChange (editor_id, node, undo_index, + undo_levels, visual_aid, any_selection) +{ + function selectByValue(select_elm, value) + { + if (select_elm) + { + for (var i=0; i=0; i--) + { + var nodeName = path[i].nodeName.toLowerCase(); + var nodeData = ""; + + if (nodeName == "b") + { + nodeName = "strong"; + } + + if (nodeName == "i") + { + nodeName = "em"; + } + + if (getAttrib(path[i], 'id') != "") + { + nodeData += "id: " + path[i].getAttribute('id') + " "; + } + + if (getAttrib(path[i], 'class') != "") + { + nodeData += "class: " + path[i].getAttribute('class') + " "; + } + + if (getAttrib(path[i], 'className') != "") + { + nodeData += "class: " + path[i].getAttribute('className') + " "; + } + + if (getAttrib(path[i], 'src') != "") + { + nodeData += "src: " + path[i].getAttribute('src') + " "; + } + + if (getAttrib(path[i], 'href') != "") + { + nodeData += "href: " + path[i].getAttribute('href') + " "; + } + + if (nodeName == "img" && getAttrib(path[i], 'name') == "mce_plugin_flash") + { + nodeName = "flash"; + nodeData = ""; + } + + if (getAttrib(path[i], 'name').indexOf("mce_") != 0) + { + if (getAttrib(path[i], "className") != "") + { + nodeName += "." + getAttrib(path[i], "className"); + } + else if (getAttrib(path[i], "class") != "") + { + nodeName += "." + getAttrib(path[i], "class"); + } + } + + if (tinyMCE.isMSIE) + { + html += '' + nodeName + ''; + } + else + { + html += '' + nodeName + ''; + } + + if (i > 0) + { + html += " » "; + } + } + + pathElm.innerHTML = html + " "; + } + + // Get element color + var colorElm = tinyMCE.getParentElement(node, "font", "color"); + + if (colorElm) + { + TinyMCE_advanced_foreColor = "" + colorElm.color.toUpperCase(); + } + + // Reset old states + tinyMCE.switchClassSticky(editor_id + '_justifyleft', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_justifyright', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_justifycenter', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_justifyfull', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_bold', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_italic', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_underline', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_strikethrough', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_bullist', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_numlist', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_sub', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_sup', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_anchor', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_link', 'mceButtonDisabled', true); + tinyMCE.switchClassSticky(editor_id + '_attachment', 'mceButtonDisabled', true); + tinyMCE.switchClassSticky(editor_id + '_unlink', 'mceButtonDisabled', true); + tinyMCE.switchClassSticky(editor_id + '_outdent', 'mceButtonDisabled', true); + tinyMCE.switchClassSticky(editor_id + '_image', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_hr', 'mceButtonNormal'); + + // Get anchor name + var anchorName = tinyMCE.getParentElement(node, "a", "name"); + + TinyMCE_advanced_anchorName = ""; + + if (anchorName) + { + TinyMCE_advanced_anchorName = anchorName.getAttribute("name"); + tinyMCE.switchClassSticky(editor_id + '_anchor', 'mceButtonSelected'); + } + + // Get link + var anchorLink = tinyMCE.getParentElement(node, "a", "href"); + + if (anchorLink || any_selection) + { + tinyMCE.switchClassSticky(editor_id + '_link', anchorLink ? 'mceButtonSelected' : 'mceButtonNormal', false); + tinyMCE.switchClassSticky(editor_id + '_attachment', anchorLink ? 'mceButtonSelected' : 'mceButtonNormal', false); + tinyMCE.switchClassSticky(editor_id + '_unlink', anchorLink ? 'mceButtonSelected' : 'mceButtonNormal', false); + } + + // Handle visual aid + tinyMCE.switchClassSticky(editor_id + '_visualaid', visual_aid ? 'mceButtonSelected' : 'mceButtonNormal', false); + + if (undo_levels != -1) + { + tinyMCE.switchClassSticky(editor_id + '_undo', 'mceButtonDisabled', true); + tinyMCE.switchClassSticky(editor_id + '_redo', 'mceButtonDisabled', true); + } + + // Within li, blockquote + if (tinyMCE.getParentElement(node, "li,blockquote")) + { + tinyMCE.switchClassSticky(editor_id + '_outdent', 'mceButtonNormal', false); + } + + // Has redo levels + if (undo_index != -1 && (undo_index < undo_levels-1 && undo_levels > 0)) + { + tinyMCE.switchClassSticky(editor_id + '_redo', 'mceButtonNormal', false); + } + + // Has undo levels + if (undo_index != -1 && (undo_index > 0 && undo_levels > 0)) + { + tinyMCE.switchClassSticky(editor_id + '_undo', 'mceButtonNormal', false); + } + + // Select class in select box + var selectElm = document.getElementById(editor_id + "_styleSelect"); + + if (selectElm) + { + TinyMCE_advanced_setupCSSClasses(editor_id); + + classNode = node; + breakOut = false; + var index = 0; + + do + { + if (classNode && classNode.className) + { + for (var i=0; i"); + } + else + { + selectByValue(selectElm, ""); + } + } + + // Select fontselect + var selectElm = document.getElementById(editor_id + "_fontNameSelect"); + + if (selectElm) + { + var elm = tinyMCE.getParentElement(node, "font", "face"); + + if (elm) + { + selectByValue(selectElm, elm.getAttribute("face")); + } + else + { + selectByValue(selectElm, ""); + } + } + + // Select fontsize + var selectElm = document.getElementById(editor_id + "_fontSizeSelect"); + + if (selectElm) + { + var elm = tinyMCE.getParentElement(node, "font", "size"); + + if (elm && getAttrib(elm, "size") != "") + { + selectByValue(selectElm, elm.getAttribute("size")); + } + else + { + selectByValue(selectElm, "0"); + } + } + + // Handle align attributes + alignNode = node; + breakOut = false; + do + { + if (!alignNode.getAttribute || !alignNode.getAttribute('align')) + { + continue; + } + + switch (alignNode.getAttribute('align').toLowerCase()) + { + case "left": + tinyMCE.switchClassSticky(editor_id + '_justifyleft', 'mceButtonSelected'); + breakOut = true; + break; + + case "right": + tinyMCE.switchClassSticky(editor_id + '_justifyright', 'mceButtonSelected'); + breakOut = true; + break; + + case "middle": + case "center": + tinyMCE.switchClassSticky(editor_id + '_justifycenter', 'mceButtonSelected'); + breakOut = true; + break; + + case "justify": + tinyMCE.switchClassSticky(editor_id + '_justifyfull', 'mceButtonSelected'); + breakOut = true; + break; + } + } while (!breakOut && (alignNode = alignNode.parentNode)); + + // Do special text + if (tinyMCE.isGecko && node.nodeType == 3) + { + var inst = tinyMCE.getInstanceById(editor_id); + var doc = inst.getDoc(); + + if (doc.queryCommandState("Bold")) + { + tinyMCE.switchClassSticky(editor_id + '_bold', 'mceButtonSelected'); + } + + if (doc.queryCommandState("Italic")) + { + tinyMCE.switchClassSticky(editor_id + '_italic', 'mceButtonSelected'); + } + + if (doc.queryCommandState("Underline") && + (node.parentNode == null || node.parentNode.nodeName != "A")) + { + tinyMCE.switchClassSticky(editor_id + '_underline', 'mceButtonSelected'); + } + + if (doc.queryCommandState("Strikethrough")) + { + tinyMCE.switchClassSticky(editor_id + '_strikethrough', 'mceButtonSelected'); + } + } + + // Handle elements + do + { + switch (node.nodeName.toLowerCase()) + { + case "b": + case "strong": + tinyMCE.switchClassSticky(editor_id + '_bold', 'mceButtonSelected'); + break; + + case "i": + case "em": + tinyMCE.switchClassSticky(editor_id + '_italic', 'mceButtonSelected'); + break; + + case "u": + tinyMCE.switchClassSticky(editor_id + '_underline', 'mceButtonSelected'); + break; + + case "strike": + tinyMCE.switchClassSticky(editor_id + '_strikethrough', 'mceButtonSelected'); + break; + + case "ul": + tinyMCE.switchClassSticky(editor_id + '_bullist', 'mceButtonSelected'); + break; + + case "ol": + tinyMCE.switchClassSticky(editor_id + '_numlist', 'mceButtonSelected'); + break; + + case "sub": + tinyMCE.switchClassSticky(editor_id + '_sub', 'mceButtonSelected'); + break; + + case "sup": + tinyMCE.switchClassSticky(editor_id + '_sup', 'mceButtonSelected'); + break; + + case "hr": + tinyMCE.switchClassSticky(editor_id + '_hr', 'mceButtonSelected'); + break; + + case "img": + if (getAttrib(node, 'name').indexOf('mce_') != 0) + { + tinyMCE.switchClassSticky(editor_id + '_image', 'mceButtonSelected'); + } + break; + } + } while ((node = node.parentNode)); +}; + +// This function auto imports CSS classes into the class selection droplist +function TinyMCE_advanced_setupCSSClasses(editor_id) +{ + if (!TinyMCE_advanced_autoImportCSSClasses) + { + return; + } + + var selectElm = document.getElementById(editor_id + '_styleSelect'); + + if (selectElm && selectElm.getAttribute('cssImported') != 'true') + { + var csses = tinyMCE.getCSSClasses(editor_id); + if (csses && selectElm) + { + for (var i=0; i 0) + { + selectElm.setAttribute('cssImported', 'true'); + } + } +}; diff --git a/public/tiny_mce/themes/advanced/editor_ui.css b/public/tiny_mce/themes/advanced/editor_ui.css new file mode 100644 index 0000000..fd0bd76 --- /dev/null +++ b/public/tiny_mce/themes/advanced/editor_ui.css @@ -0,0 +1,199 @@ +.mceButtonNormal, .mceButtonOver, .mceButtonDown, .mceSeparator, .mceButtonDisabled, .mceButtonSelected { + margin-top: 1px; + margin-left: 1px; +} + +.mceButtonNormal { + border-top: 1px solid; + border-left: 1px solid; + border-bottom: 1px solid; + border-right: 1px solid; + border-color: #F0F0EE; + cursor: arrow; +} + +.mceButtonOver { +/* border-top: 1px solid buttonhighlight; + border-left: 1px solid buttonhighlight; + border-bottom: 1px solid buttonshadow; + border-right: 1px solid buttonshadow;*/ + border: 1px solid #0A246A; + cursor: arrow; + background-color: #B6BDD2; +} + +.mceButtonDown { +/* border-bottom: 1px solid buttonhighlight; + border-right: 1px solid buttonhighlight; + border-top: 1px solid buttonshadow; + border-left: 1px solid buttonshadow;*/ + cursor: arrow; + border: 1px solid #0A246A; + background-color: #8592B5; +} + +.mceButtonSelected { + border: 1px solid; + border-color: #C0C0BB; + cursor: arrow; +} + +.mceButtonDisabled { + filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); + -moz-opacity:0.3; + opacity: 0.3; + border-top: 1px solid; + border-left: 1px solid; + border-bottom: 1px solid; + border-right: 1px solid; + border-color: #F0F0EE; + cursor: arrow; +} + +.mceSeparator { + border-top: 1px solid buttonhighlight; + border-left: 1px solid buttonhighlight; + border-bottom: 1px solid buttonshadow; + border-right: 1px solid buttonshadow; + margin-right: 2px; + margin-left: 2px; +} + +.mceSeparatorLine { + margin:2px; + margin-left: 4px; + background-color: #F0F0EE; + border-top: 1px solid buttonshadow; + border-left: 1px solid buttonshadow; + border-bottom: 1px solid buttonhighlight; + border-right: 1px solid buttonhighlight; + width: 0px; + height: 15px; +} + +.mceSelectList { + font-family: "MS Sans Serif"; + font-size: 7pt; + font-weight: normal; + margin-top: 3px; + padding: 0px; + display: inline; + vertical-align: top; + background-color: #F0F0EE +} + +.mceLabel, .mceLabelDisabled { + font-family: "MS Sans Serif"; + font-size: 9pt; +} + +.mceLabel { + color: #000000; +} + +.mceLabelDisabled { + cursor: text; + color: #999999; +} + +.mceEditor { + background: #F0F0EE; + border: 1px solid #cccccc; +} + +.mceEditorArea { + font-family: "MS Sans Serif"; + background: #FFFFFF; +} + +.mceToolbarTop, .mceToolbarBottom { + background: #F0F0EE; +} + +.mceToolbarTop { + border-bottom: 1px solid #cccccc; +} + +.mceToolbarBottom { + border-top: 1px solid #cccccc; +} + +.mcePathTop, .mcePathBottom, .mcePath { + font-family: "MS Sans Serif"; + font-size: 9pt; + padding: 2px; + height: 20px; +} + +.mcePathTop { + border-bottom: 1px solid #cccccc; +} + +.mcePathBottom { + border-top: 1px solid #cccccc; +} + +.mcePathItem, .mcePathItem:link, .mcePathItem:visited, .mcePathItem:hover { + text-decoration: none; + font-family: "MS Sans Serif"; + font-size: 9pt; + color: #000000; +} + +.mcePathItem:hover { + text-decoration: underline; +} + +.mcePath { + border-bottom: 1px solid #cccccc; +} + +.mceDialog { + position: absolute; + left: 100px; + top: 100px; + z-index: 1000; +} + +.mceDialogHeader { + background: #F0F0EE; + width: 100%; + height: 16px; + margin: 0px; + padding: 0px; + border: 1px solid black; + border-bottom: 0px; +} + +.mceDialogTitle { + float: left; + font-family: "MS Sans Serif"; + font-size: 9pt; + height: 14px; +} + +.mceDialogClose { + float: right; + width: 16px; + height: 16px; + background-image: url('images/close.gif'); + background-repeat: no-repeat; + background-position: 0px 1px; + margin: 0px; + padding: 0px; +} + +.mceDialogClose a { + width: 16px; + height: 14px; + display: block; + font-family: "MS Sans Serif"; + font-size: 9pt; + margin: 0px; + padding: 0px; +} + +.mceDialogIFrameWrapper { + border: 1px solid black; + clear: both; +} diff --git a/public/tiny_mce/themes/advanced/image.htm b/public/tiny_mce/themes/advanced/image.htm new file mode 100644 index 0000000..61238e3 --- /dev/null +++ b/public/tiny_mce/themes/advanced/image.htm @@ -0,0 +1,186 @@ + + +{$lang_insert_image_title} + + + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$lang_insert_image_title}
    {$lang_insert_image_src}: + + + + +
    {$lang_insert_image_alt}:
    {$lang_insert_image_align}:
    {$lang_insert_image_dimensions}: + x +
    {$lang_insert_image_border}:
    {$lang_insert_image_vspace}:
    {$lang_insert_image_hspace}:
    +
    +
    + + diff --git a/public/tiny_mce/themes/advanced/images/anchor.gif b/public/tiny_mce/themes/advanced/images/anchor.gif new file mode 100644 index 0000000..ae7b2f3 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/anchor.gif differ diff --git a/public/tiny_mce/themes/advanced/images/attachment.gif b/public/tiny_mce/themes/advanced/images/attachment.gif new file mode 100644 index 0000000..b3d8042 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/attachment.gif differ diff --git a/public/tiny_mce/themes/advanced/images/backcolor.gif b/public/tiny_mce/themes/advanced/images/backcolor.gif new file mode 100644 index 0000000..d44277d Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/backcolor.gif differ diff --git a/public/tiny_mce/themes/advanced/images/bold.gif b/public/tiny_mce/themes/advanced/images/bold.gif new file mode 100644 index 0000000..31f004b Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/bold.gif differ diff --git a/public/tiny_mce/themes/advanced/images/bold_de_se.gif b/public/tiny_mce/themes/advanced/images/bold_de_se.gif new file mode 100644 index 0000000..2d86b00 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/bold_de_se.gif differ diff --git a/public/tiny_mce/themes/advanced/images/bold_fr.gif b/public/tiny_mce/themes/advanced/images/bold_fr.gif new file mode 100644 index 0000000..7782282 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/bold_fr.gif differ diff --git a/public/tiny_mce/themes/advanced/images/bold_ru.gif b/public/tiny_mce/themes/advanced/images/bold_ru.gif new file mode 100644 index 0000000..c9e89b2 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/bold_ru.gif differ diff --git a/public/tiny_mce/themes/advanced/images/browse.gif b/public/tiny_mce/themes/advanced/images/browse.gif new file mode 100644 index 0000000..590f2de Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/browse.gif differ diff --git a/public/tiny_mce/themes/advanced/images/bullist.gif b/public/tiny_mce/themes/advanced/images/bullist.gif new file mode 100644 index 0000000..12d0ec2 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/bullist.gif differ diff --git a/public/tiny_mce/themes/advanced/images/buttons.gif b/public/tiny_mce/themes/advanced/images/buttons.gif new file mode 100644 index 0000000..b5e454c Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/buttons.gif differ diff --git a/public/tiny_mce/themes/advanced/images/center.gif b/public/tiny_mce/themes/advanced/images/center.gif new file mode 100644 index 0000000..a9e13e0 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/center.gif differ diff --git a/public/tiny_mce/themes/advanced/images/charmap.gif b/public/tiny_mce/themes/advanced/images/charmap.gif new file mode 100644 index 0000000..b826f88 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/charmap.gif differ diff --git a/public/tiny_mce/themes/advanced/images/cleanup.gif b/public/tiny_mce/themes/advanced/images/cleanup.gif new file mode 100644 index 0000000..87b8f87 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/cleanup.gif differ diff --git a/public/tiny_mce/themes/advanced/images/close.gif b/public/tiny_mce/themes/advanced/images/close.gif new file mode 100644 index 0000000..78883bd Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/close.gif differ diff --git a/public/tiny_mce/themes/advanced/images/code.gif b/public/tiny_mce/themes/advanced/images/code.gif new file mode 100644 index 0000000..e16da11 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/code.gif differ diff --git a/public/tiny_mce/themes/advanced/images/copy.gif b/public/tiny_mce/themes/advanced/images/copy.gif new file mode 100644 index 0000000..f0b5187 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/copy.gif differ diff --git a/public/tiny_mce/themes/advanced/images/custom_1.gif b/public/tiny_mce/themes/advanced/images/custom_1.gif new file mode 100644 index 0000000..5e385c0 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/custom_1.gif differ diff --git a/public/tiny_mce/themes/advanced/images/cut.gif b/public/tiny_mce/themes/advanced/images/cut.gif new file mode 100644 index 0000000..6a969e5 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/cut.gif differ diff --git a/public/tiny_mce/themes/advanced/images/forecolor.gif b/public/tiny_mce/themes/advanced/images/forecolor.gif new file mode 100644 index 0000000..db21e1c Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/forecolor.gif differ diff --git a/public/tiny_mce/themes/advanced/images/full.gif b/public/tiny_mce/themes/advanced/images/full.gif new file mode 100644 index 0000000..5a78c63 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/full.gif differ diff --git a/public/tiny_mce/themes/advanced/images/help.gif b/public/tiny_mce/themes/advanced/images/help.gif new file mode 100644 index 0000000..a5d6771 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/help.gif differ diff --git a/public/tiny_mce/themes/advanced/images/hr.gif b/public/tiny_mce/themes/advanced/images/hr.gif new file mode 100644 index 0000000..8e6b34d Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/hr.gif differ diff --git a/public/tiny_mce/themes/advanced/images/image.gif b/public/tiny_mce/themes/advanced/images/image.gif new file mode 100644 index 0000000..36109de Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/image.gif differ diff --git a/public/tiny_mce/themes/advanced/images/indent.gif b/public/tiny_mce/themes/advanced/images/indent.gif new file mode 100644 index 0000000..7a17288 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/indent.gif differ diff --git a/public/tiny_mce/themes/advanced/images/italic.gif b/public/tiny_mce/themes/advanced/images/italic.gif new file mode 100644 index 0000000..ec03278 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/italic.gif differ diff --git a/public/tiny_mce/themes/advanced/images/italic_de_se.gif b/public/tiny_mce/themes/advanced/images/italic_de_se.gif new file mode 100644 index 0000000..6ce0d8d Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/italic_de_se.gif differ diff --git a/public/tiny_mce/themes/advanced/images/italic_ru.gif b/public/tiny_mce/themes/advanced/images/italic_ru.gif new file mode 100644 index 0000000..5c2f7fe Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/italic_ru.gif differ diff --git a/public/tiny_mce/themes/advanced/images/left.gif b/public/tiny_mce/themes/advanced/images/left.gif new file mode 100644 index 0000000..4225e00 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/left.gif differ diff --git a/public/tiny_mce/themes/advanced/images/link.gif b/public/tiny_mce/themes/advanced/images/link.gif new file mode 100644 index 0000000..0de4274 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/link.gif differ diff --git a/public/tiny_mce/themes/advanced/images/newdocument.gif b/public/tiny_mce/themes/advanced/images/newdocument.gif new file mode 100644 index 0000000..79a93da Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/newdocument.gif differ diff --git a/public/tiny_mce/themes/advanced/images/numlist.gif b/public/tiny_mce/themes/advanced/images/numlist.gif new file mode 100644 index 0000000..7ff907b Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/numlist.gif differ diff --git a/public/tiny_mce/themes/advanced/images/outdent.gif b/public/tiny_mce/themes/advanced/images/outdent.gif new file mode 100644 index 0000000..53e89a7 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/outdent.gif differ diff --git a/public/tiny_mce/themes/advanced/images/paste.gif b/public/tiny_mce/themes/advanced/images/paste.gif new file mode 100644 index 0000000..a676604 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/paste.gif differ diff --git a/public/tiny_mce/themes/advanced/images/redo.gif b/public/tiny_mce/themes/advanced/images/redo.gif new file mode 100644 index 0000000..26a146b Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/redo.gif differ diff --git a/public/tiny_mce/themes/advanced/images/removeformat.gif b/public/tiny_mce/themes/advanced/images/removeformat.gif new file mode 100644 index 0000000..38a9cdf Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/removeformat.gif differ diff --git a/public/tiny_mce/themes/advanced/images/right.gif b/public/tiny_mce/themes/advanced/images/right.gif new file mode 100644 index 0000000..88bfaf2 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/right.gif differ diff --git a/public/tiny_mce/themes/advanced/images/spacer.gif b/public/tiny_mce/themes/advanced/images/spacer.gif new file mode 100644 index 0000000..fc25609 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/spacer.gif differ diff --git a/public/tiny_mce/themes/advanced/images/strikethrough.gif b/public/tiny_mce/themes/advanced/images/strikethrough.gif new file mode 100644 index 0000000..ce7b653 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/strikethrough.gif differ diff --git a/public/tiny_mce/themes/advanced/images/sub.gif b/public/tiny_mce/themes/advanced/images/sub.gif new file mode 100644 index 0000000..4818407 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/sub.gif differ diff --git a/public/tiny_mce/themes/advanced/images/sup.gif b/public/tiny_mce/themes/advanced/images/sup.gif new file mode 100644 index 0000000..03f8efc Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/sup.gif differ diff --git a/public/tiny_mce/themes/advanced/images/table.gif b/public/tiny_mce/themes/advanced/images/table.gif new file mode 100644 index 0000000..f8a0054 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/table.gif differ diff --git a/public/tiny_mce/themes/advanced/images/table_delete_col.gif b/public/tiny_mce/themes/advanced/images/table_delete_col.gif new file mode 100644 index 0000000..0b2f0fb Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/table_delete_col.gif differ diff --git a/public/tiny_mce/themes/advanced/images/table_delete_row.gif b/public/tiny_mce/themes/advanced/images/table_delete_row.gif new file mode 100644 index 0000000..1997065 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/table_delete_row.gif differ diff --git a/public/tiny_mce/themes/advanced/images/table_insert_col_after.gif b/public/tiny_mce/themes/advanced/images/table_insert_col_after.gif new file mode 100644 index 0000000..c30dafa Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/table_insert_col_after.gif differ diff --git a/public/tiny_mce/themes/advanced/images/table_insert_col_before.gif b/public/tiny_mce/themes/advanced/images/table_insert_col_before.gif new file mode 100644 index 0000000..5d1ff37 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/table_insert_col_before.gif differ diff --git a/public/tiny_mce/themes/advanced/images/table_insert_row_after.gif b/public/tiny_mce/themes/advanced/images/table_insert_row_after.gif new file mode 100644 index 0000000..c3aa15f Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/table_insert_row_after.gif differ diff --git a/public/tiny_mce/themes/advanced/images/table_insert_row_before.gif b/public/tiny_mce/themes/advanced/images/table_insert_row_before.gif new file mode 100644 index 0000000..c3271e5 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/table_insert_row_before.gif differ diff --git a/public/tiny_mce/themes/advanced/images/underline.gif b/public/tiny_mce/themes/advanced/images/underline.gif new file mode 100644 index 0000000..d6b8afd Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/underline.gif differ diff --git a/public/tiny_mce/themes/advanced/images/underline_fr.gif b/public/tiny_mce/themes/advanced/images/underline_fr.gif new file mode 100644 index 0000000..a8e3018 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/underline_fr.gif differ diff --git a/public/tiny_mce/themes/advanced/images/underline_ru.gif b/public/tiny_mce/themes/advanced/images/underline_ru.gif new file mode 100644 index 0000000..2a517e8 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/underline_ru.gif differ diff --git a/public/tiny_mce/themes/advanced/images/undo.gif b/public/tiny_mce/themes/advanced/images/undo.gif new file mode 100644 index 0000000..b0722d0 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/undo.gif differ diff --git a/public/tiny_mce/themes/advanced/images/unlink.gif b/public/tiny_mce/themes/advanced/images/unlink.gif new file mode 100644 index 0000000..dd073a2 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/unlink.gif differ diff --git a/public/tiny_mce/themes/advanced/images/visualaid.gif b/public/tiny_mce/themes/advanced/images/visualaid.gif new file mode 100644 index 0000000..188b348 Binary files /dev/null and b/public/tiny_mce/themes/advanced/images/visualaid.gif differ diff --git a/public/tiny_mce/themes/advanced/langs/ar.js b/public/tiny_mce/themes/advanced/langs/ar.js new file mode 100644 index 0000000..29d93cf --- /dev/null +++ b/public/tiny_mce/themes/advanced/langs/ar.js @@ -0,0 +1,60 @@ +// Arabic lang variables + +tinyMCELang['lang_theme_style_select'] = 'تصاميم'; +tinyMCELang['lang_theme_code_desc'] = 'شفرة المصدر'; +tinyMCELang['lang_theme_code_title'] = 'شفرة المصدر'; +tinyMCELang['lang_theme_code_wordwrap'] = 'Word wrap'; +tinyMCELang['lang_theme_sub_desc'] = 'منخفض'; +tinyMCELang['lang_theme_sup_desc'] = 'مرتفع'; +tinyMCELang['lang_theme_hr_desc'] = 'إدراج خط فاصل'; +tinyMCELang['lang_theme_removeformat_desc'] = 'إزالة التنسيقات'; +tinyMCELang['lang_theme_custom1_desc'] = 'Your custom description here'; +tinyMCELang['lang_insert_image_border'] = 'سمك الحدود'; +tinyMCELang['lang_insert_image_dimensions'] = 'المواصفات'; +tinyMCELang['lang_insert_image_vspace'] = 'تباعد عمودي'; +tinyMCELang['lang_insert_image_hspace'] = 'تباعد أفقي'; +tinyMCELang['lang_insert_image_align'] = 'محاذاة'; +tinyMCELang['lang_insert_image_align_default'] = 'Default'; +tinyMCELang['lang_insert_image_align_baseline'] = 'على السطر'; +tinyMCELang['lang_insert_image_align_top'] = 'أعلى'; +tinyMCELang['lang_insert_image_align_middle'] = 'وسط'; +tinyMCELang['lang_insert_image_align_bottom'] = 'أسفل'; +tinyMCELang['lang_insert_image_align_texttop'] = 'أعلى النص'; +tinyMCELang['lang_insert_image_align_absmiddle'] = 'وسط السطر'; +tinyMCELang['lang_insert_image_align_absbottom'] = 'أسفل النص'; +tinyMCELang['lang_insert_image_align_left'] = 'يسار'; +tinyMCELang['lang_insert_image_align_right'] = 'يمين'; +tinyMCELang['lang_theme_font_size'] = '-- Font size --'; +tinyMCELang['lang_theme_fontdefault'] = '-- Font family --'; +tinyMCELang['lang_theme_block'] = '-- Format --'; +tinyMCELang['lang_theme_paragraph'] = 'Paragraph'; +tinyMCELang['lang_theme_div'] = 'Div'; +tinyMCELang['lang_theme_address'] = 'Address'; +tinyMCELang['lang_theme_pre'] = 'Preformatted'; +tinyMCELang['lang_theme_h1'] = 'Heading 1'; +tinyMCELang['lang_theme_h2'] = 'Heading 2'; +tinyMCELang['lang_theme_h3'] = 'Heading 3'; +tinyMCELang['lang_theme_h4'] = 'Heading 4'; +tinyMCELang['lang_theme_h5'] = 'Heading 5'; +tinyMCELang['lang_theme_h6'] = 'Heading 6'; +tinyMCELang['lang_theme_colorpicker_title'] = 'لون النص'; +tinyMCELang['lang_theme_colorpicker_apply'] = 'Apply'; +tinyMCELang['lang_theme_forecolor_desc'] = 'لون النص'; +tinyMCELang['lang_theme_backcolor_desc'] = 'Select background color'; +tinyMCELang['lang_theme_charmap_title'] = 'إدراج رمز..ِ'; +tinyMCELang['lang_theme_charmap_desc'] = 'إدراج رمز..ِ'; +tinyMCELang['lang_theme_visualaid_desc'] = 'Toggle guidelines/invisible elements'; +tinyMCELang['lang_insert_anchor_title'] = 'Insert/edit anchor'; +tinyMCELang['lang_insert_anchor_name'] = 'Anchor name'; +tinyMCELang['lang_theme_anchor_desc'] = 'Insert/edit anchor'; +tinyMCELang['lang_theme_insert_link_titlefield'] = 'Title'; +tinyMCELang['lang_theme_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?'; +tinyMCELang['lang_theme_path'] = 'Path'; +tinyMCELang['lang_cut_desc'] = 'Cut'; +tinyMCELang['lang_copy_desc'] = 'Copy'; +tinyMCELang['lang_paste_desc'] = 'Paste'; +tinyMCELang['lang_link_list'] = 'Link list'; +tinyMCELang['lang_image_list'] = 'Image list'; +tinyMCELang['lang_browse'] = 'Browse'; +tinyMCELang['lang_image_props_desc'] = 'Image properties'; +tinyMCELang['lang_newdocument_desc'] = 'New document'; diff --git a/public/tiny_mce/themes/advanced/langs/ca.js b/public/tiny_mce/themes/advanced/langs/ca.js new file mode 100644 index 0000000..989532a --- /dev/null +++ b/public/tiny_mce/themes/advanced/langs/ca.js @@ -0,0 +1,61 @@ +// CA lang variables by Marc Bria + +tinyMCELang['lang_theme_style_select'] = 'Estils'; +tinyMCELang['lang_theme_code_desc'] = 'Editar codi HTML'; +tinyMCELang['lang_theme_code_title'] = 'Editor codi HTML'; +tinyMCELang['lang_theme_code_wordwrap'] = 'Ajustar salt de lnea'; +tinyMCELang['lang_theme_sub_desc'] = 'Subndex'; +tinyMCELang['lang_theme_sup_desc'] = 'Superndex'; +tinyMCELang['lang_theme_hr_desc'] = 'Insertar un separador horitzontal'; +tinyMCELang['lang_theme_removeformat_desc'] = 'Eliminar format'; +tinyMCELang['lang_theme_custom1_desc'] = 'La teva descripci'; +tinyMCELang['lang_insert_image_border'] = 'Marc'; +tinyMCELang['lang_insert_image_dimensions'] = 'Dimensions'; +tinyMCELang['lang_insert_image_vspace'] = 'Espai vertical'; +tinyMCELang['lang_insert_image_hspace'] = 'Espai horizontal'; +tinyMCELang['lang_insert_image_align'] = 'Alineament'; +tinyMCELang['lang_insert_image_align_default'] = 'Per defecte'; +tinyMCELang['lang_insert_image_align_baseline'] = 'Lnea base'; +tinyMCELang['lang_insert_image_align_top'] = 'Superior'; +tinyMCELang['lang_insert_image_align_middle'] = 'Centre'; +tinyMCELang['lang_insert_image_align_bottom'] = 'Inferior'; +tinyMCELang['lang_insert_image_align_texttop'] = 'Alinear text amunt'; +tinyMCELang['lang_insert_image_align_absmiddle'] = 'Centrat horitzontal'; +tinyMCELang['lang_insert_image_align_absbottom'] = 'Centrat a baix'; +tinyMCELang['lang_insert_image_align_left'] = 'Esquerra'; +tinyMCELang['lang_insert_image_align_right'] = 'Dreta'; +tinyMCELang['lang_insert_image_delta_height'] = 10; +tinyMCELang['lang_theme_font_size'] = '-- Mida font --'; +tinyMCELang['lang_theme_fontdefault'] = '-- Font family --'; +tinyMCELang['lang_theme_block'] = '-- Format --'; +tinyMCELang['lang_theme_paragraph'] = 'Paragraph'; +tinyMCELang['lang_theme_div'] = 'Div'; +tinyMCELang['lang_theme_address'] = 'Address'; +tinyMCELang['lang_theme_pre'] = 'Preformatejat'; +tinyMCELang['lang_theme_h1'] = 'Capalera 1'; +tinyMCELang['lang_theme_h2'] = 'Capalera 2'; +tinyMCELang['lang_theme_h3'] = 'Capalera 3'; +tinyMCELang['lang_theme_h4'] = 'Capalera 4'; +tinyMCELang['lang_theme_h5'] = 'Capalera 5'; +tinyMCELang['lang_theme_h6'] = 'Capalera 6'; +tinyMCELang['lang_theme_colorpicker_title'] = 'Selecciona el color'; +tinyMCELang['lang_theme_colorpicker_apply'] = 'Apply'; +tinyMCELang['lang_theme_forecolor_desc'] = 'Selecciona color frontal'; +tinyMCELang['lang_theme_backcolor_desc'] = 'Selecciona color de fons'; +tinyMCELang['lang_theme_charmap_title'] = 'Selecciona un carcter especial'; +tinyMCELang['lang_theme_charmap_desc'] = 'Inserta un carcter especial'; +tinyMCELang['lang_theme_visualaid_desc'] = 'Alterna lniesguia/elements invisibles'; +tinyMCELang['lang_insert_anchor_title'] = 'Inserta/edita ncora'; +tinyMCELang['lang_insert_anchor_name'] = 'Nom de lncora'; +tinyMCELang['lang_theme_anchor_desc'] = 'Inserta/edita un ncora'; +tinyMCELang['lang_theme_insert_link_titlefield'] = 'Ttlo'; +tinyMCELang['lang_theme_clipboard_msg'] = 'Copiar/Tallar/Enganxar no s possible amb Mozilla i Firefox.\nVols ms informaci sobre aquest problema de seguretat?'; +tinyMCELang['lang_theme_path'] = 'Cam'; +tinyMCELang['lang_cut_desc'] = 'Retallar'; +tinyMCELang['lang_copy_desc'] = 'Copiar'; +tinyMCELang['lang_paste_desc'] = 'Enganxar'; +tinyMCELang['lang_link_list'] = 'Llistat denllaos'; +tinyMCELang['lang_image_list'] = 'Llistat dimatges'; +tinyMCELang['lang_browse'] = 'Explorar'; +tinyMCELang['lang_image_props_desc'] = 'Image properties'; +tinyMCELang['lang_newdocument_desc'] = 'New document'; diff --git a/public/tiny_mce/themes/advanced/langs/cs.js b/public/tiny_mce/themes/advanced/langs/cs.js new file mode 100644 index 0000000..be75bc3 --- /dev/null +++ b/public/tiny_mce/themes/advanced/langs/cs.js @@ -0,0 +1,60 @@ +// CZ lang variables thanks to "Pavel Novk", repaired by Josef Klimosz + +tinyMCELang['lang_theme_style_select'] = 'Styly'; +tinyMCELang['lang_theme_code_desc'] = 'Zobrazit HTML'; +tinyMCELang['lang_theme_code_title'] = 'Editace HTML'; +tinyMCELang['lang_theme_code_wordwrap'] = 'Bez dlen slov'; +tinyMCELang['lang_theme_sub_desc'] = 'Doln index'; +tinyMCELang['lang_theme_sup_desc'] = 'Horn index'; +tinyMCELang['lang_theme_hr_desc'] = 'Vloit vodorovn oddlova'; +tinyMCELang['lang_theme_removeformat_desc'] = 'Zruit formtovn'; +tinyMCELang['lang_theme_custom1_desc'] = 'Libovoln popisek'; +tinyMCELang['lang_insert_image_border'] = 'Rmeek'; +tinyMCELang['lang_insert_image_dimensions'] = 'Rozmry'; +tinyMCELang['lang_insert_image_vspace'] = 'Vertikln okraj'; +tinyMCELang['lang_insert_image_hspace'] = 'Horizontln okraj'; +tinyMCELang['lang_insert_image_align'] = 'Zarovnn'; +tinyMCELang['lang_insert_image_align_default'] = 'Vchoz'; +tinyMCELang['lang_insert_image_align_baseline'] = 'Na a'; +tinyMCELang['lang_insert_image_align_top'] = 'Nahoru'; +tinyMCELang['lang_insert_image_align_middle'] = 'Na sted'; +tinyMCELang['lang_insert_image_align_bottom'] = 'Dol'; +tinyMCELang['lang_insert_image_align_texttop'] = 'Nejvy bod textu'; +tinyMCELang['lang_insert_image_align_absmiddle'] = 'Sted dku'; +tinyMCELang['lang_insert_image_align_absbottom'] = 'Spodek dku'; +tinyMCELang['lang_insert_image_align_left'] = 'Vlevo'; +tinyMCELang['lang_insert_image_align_right'] = 'Vpravo'; +tinyMCELang['lang_theme_font_size'] = '-- Font size --'; +tinyMCELang['lang_theme_fontdefault'] = '-- Font family --'; +tinyMCELang['lang_theme_block'] = '-- Format --'; +tinyMCELang['lang_theme_paragraph'] = 'Odstavec'; +tinyMCELang['lang_theme_div'] = 'Div'; +tinyMCELang['lang_theme_address'] = 'Adresa'; +tinyMCELang['lang_theme_pre'] = 'Pedformt'; +tinyMCELang['lang_theme_h1'] = 'Nadpis 1'; +tinyMCELang['lang_theme_h2'] = 'Nadpis 2'; +tinyMCELang['lang_theme_h3'] = 'Nadpis 3'; +tinyMCELang['lang_theme_h4'] = 'Nadpis 4'; +tinyMCELang['lang_theme_h5'] = 'Nadpis 5'; +tinyMCELang['lang_theme_h6'] = 'Nadpis 6'; +tinyMCELang['lang_theme_colorpicker_title'] = 'Vbr barvy'; +tinyMCELang['lang_theme_colorpicker_apply'] = 'Vybrat'; +tinyMCELang['lang_theme_forecolor_desc'] = 'Barva poped'; +tinyMCELang['lang_theme_backcolor_desc'] = 'Barva pozad'; +tinyMCELang['lang_theme_charmap_title'] = 'Vbr uiv. znaku'; +tinyMCELang['lang_theme_charmap_desc'] = 'Vloit znak'; +tinyMCELang['lang_theme_visualaid_desc'] = 'Zapnout znaky/neviditeln prvky'; +tinyMCELang['lang_insert_anchor_title'] = 'Vloen/editace zloky'; +tinyMCELang['lang_insert_anchor_name'] = 'Nzev'; +tinyMCELang['lang_theme_anchor_desc'] = 'Vloit/editovat zloku'; +tinyMCELang['lang_theme_insert_link_titlefield'] = 'Nzev'; +tinyMCELang['lang_theme_clipboard_msg'] = 'Copy/Cut/Paste nen pouiteln v Mozille a Firefoxu.\nChcete vce informac o tomto problmu?'; +tinyMCELang['lang_theme_path'] = 'Cesta'; +tinyMCELang['lang_cut_desc'] = 'Vyjmout'; +tinyMCELang['lang_copy_desc'] = 'Koprovat'; +tinyMCELang['lang_paste_desc'] = 'Vloit'; +tinyMCELang['lang_link_list'] = 'Seznam'; +tinyMCELang['lang_image_list'] = 'Seznam'; +tinyMCELang['lang_browse'] = 'Browse'; +tinyMCELang['lang_image_props_desc'] = 'Vlastnosti obrzku'; +tinyMCELang['lang_newdocument_desc'] = 'Nov dokument'; diff --git a/public/tiny_mce/themes/advanced/langs/da.js b/public/tiny_mce/themes/advanced/langs/da.js new file mode 100644 index 0000000..631f7aa --- /dev/null +++ b/public/tiny_mce/themes/advanced/langs/da.js @@ -0,0 +1,61 @@ +// DK lang variables contributed by Jan Moelgaard + +tinyMCELang['lang_theme_style_select'] = 'Styles'; +tinyMCELang['lang_theme_code_desc'] = 'Rediger html-kode'; +tinyMCELang['lang_theme_code_title'] = 'HTML Kodeeditor'; +tinyMCELang['lang_theme_code_wordwrap'] = 'Word wrap'; +tinyMCELang['lang_theme_sub_desc'] = 'Sænket skrift'; +tinyMCELang['lang_theme_sup_desc'] = 'Hævet skrift'; +tinyMCELang['lang_theme_hr_desc'] = 'Indsæt horisontal linje'; +tinyMCELang['lang_theme_removeformat_desc'] = 'Fjern formatering'; +tinyMCELang['lang_theme_custom1_desc'] = 'Indsæt din egen beskrivelse her'; +tinyMCELang['lang_insert_image_border'] = 'Kant'; +tinyMCELang['lang_insert_image_dimensions'] = 'Dimensioner'; +tinyMCELang['lang_insert_image_vspace'] = 'VSpace'; +tinyMCELang['lang_insert_image_hspace'] = 'HSpace'; +tinyMCELang['lang_insert_image_align'] = 'Justering'; +tinyMCELang['lang_insert_image_align_default'] = 'Standard'; +tinyMCELang['lang_insert_image_align_baseline'] = 'Bundlinje'; +tinyMCELang['lang_insert_image_align_top'] = 'Top'; +tinyMCELang['lang_insert_image_align_middle'] = 'Midt i'; +tinyMCELang['lang_insert_image_align_bottom'] = 'I bunden'; +tinyMCELang['lang_insert_image_align_texttop'] = 'I toppen af teksten'; +tinyMCELang['lang_insert_image_align_absmiddle'] = 'Absolut midte'; +tinyMCELang['lang_insert_image_align_absbottom'] = 'Absolut bund'; +tinyMCELang['lang_insert_image_align_left'] = 'Venstre'; +tinyMCELang['lang_insert_image_align_right'] = 'Højre'; +tinyMCELang['lang_theme_font_size'] = '-- Font size --'; +tinyMCELang['lang_theme_fontdefault'] = '-- Font family --'; +tinyMCELang['lang_theme_block'] = '-- Format --'; +tinyMCELang['lang_theme_paragraph'] = 'Afsnit'; +tinyMCELang['lang_theme_div'] = 'Div'; +tinyMCELang['lang_theme_address'] = 'Addresse'; +tinyMCELang['lang_theme_pre'] = 'Præformateret'; +tinyMCELang['lang_theme_h1'] = 'Overskrift 1'; +tinyMCELang['lang_theme_h2'] = 'Overskrift 2'; +tinyMCELang['lang_theme_h3'] = 'Overskrift 3'; +tinyMCELang['lang_theme_h4'] = 'Overskrift 4'; +tinyMCELang['lang_theme_h5'] = 'Overskrift 5'; +tinyMCELang['lang_theme_h6'] = 'Overskrift 6'; +tinyMCELang['lang_theme_colorpicker_title'] = 'Vælg en farve'; +tinyMCELang['lang_theme_colorpicker_apply'] = 'Anvend'; +tinyMCELang['lang_theme_forecolor_desc'] = 'Vælg forgrundsfarve'; +tinyMCELang['lang_theme_backcolor_desc'] = 'Select background color'; +tinyMCELang['lang_theme_charmap_title'] = 'Vælg specialkarakter'; +tinyMCELang['lang_theme_charmap_desc'] = 'Indsæt specialkarakter'; +tinyMCELang['lang_theme_visualaid_desc'] = 'Slå linjer/usynlige elementer til og fra'; +tinyMCELang['lang_insert_anchor_title'] = 'Indsæt/rediger bogmærke'; +tinyMCELang['lang_insert_anchor_name'] = 'Bogmærkets navn'; +tinyMCELang['lang_theme_anchor_desc'] = 'Indsæt/rediger bogmærke'; +tinyMCELang['lang_theme_insert_link_titlefield'] = 'Title'; +tinyMCELang['lang_theme_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?'; +tinyMCELang['lang_theme_path'] = 'Path'; +tinyMCELang['lang_cut_desc'] = 'Cut'; +tinyMCELang['lang_copy_desc'] = 'Copy'; +tinyMCELang['lang_paste_desc'] = 'Paste'; +tinyMCELang['lang_link_list'] = 'Link list'; +tinyMCELang['lang_image_list'] = 'Image list'; +tinyMCELang['lang_browse'] = 'Browse'; +tinyMCELang['lang_image_props_desc'] = 'Image properties'; +tinyMCELang['lang_newdocument_desc'] = 'New document'; +tinyMCELang['lang_class'] = 'Klasse'; diff --git a/public/tiny_mce/themes/advanced/langs/de.js b/public/tiny_mce/themes/advanced/langs/de.js new file mode 100644 index 0000000..2c13050 --- /dev/null +++ b/public/tiny_mce/themes/advanced/langs/de.js @@ -0,0 +1,63 @@ +// DE lang variables +// Translated 2004 by Crazy Chrissi +// Edited 2004 by Krokogras + +tinyMCELang['lang_theme_style_select'] = 'Styles'; +tinyMCELang['lang_theme_code_desc'] = 'HTML-Modus'; +tinyMCELang['lang_theme_code_title'] = 'HTML-Code Editor'; +tinyMCELang['lang_theme_code_wordwrap'] = 'Zeilenumbruch'; +tinyMCELang['lang_theme_sub_desc'] = 'Tiefergestellt'; +tinyMCELang['lang_theme_sup_desc'] = 'Höhergestellt'; +tinyMCELang['lang_theme_hr_desc'] = 'Horizontale Linie einfügen'; +tinyMCELang['lang_theme_removeformat_desc'] = 'Formatierung löschen'; +tinyMCELang['lang_theme_custom1_desc'] = 'Beschreibung eingeben'; +tinyMCELang['lang_insert_image_border'] = 'Rahmen'; +tinyMCELang['lang_insert_image_dimensions'] = 'Größe'; +tinyMCELang['lang_insert_image_vspace'] = 'Vertikal einrücken'; +tinyMCELang['lang_insert_image_hspace'] = 'Horizontal einrücken'; +tinyMCELang['lang_insert_image_align'] = 'Ausrichten'; +tinyMCELang['lang_insert_image_align_default'] = 'Normal'; +tinyMCELang['lang_insert_image_align_baseline'] = 'Grundlinie'; +tinyMCELang['lang_insert_image_align_top'] = 'Oben'; +tinyMCELang['lang_insert_image_align_middle'] = 'Mitte'; +tinyMCELang['lang_insert_image_align_bottom'] = 'Unten'; +tinyMCELang['lang_insert_image_align_texttop'] = 'Textoberkante'; +tinyMCELang['lang_insert_image_align_absmiddle'] = 'Absolute Mitte'; +tinyMCELang['lang_insert_image_align_absbottom'] = 'Absolut unten'; +tinyMCELang['lang_insert_image_align_left'] = 'Links'; +tinyMCELang['lang_insert_image_align_right'] = 'Rechts'; +tinyMCELang['lang_theme_font_size'] = '-- Font size --'; +tinyMCELang['lang_theme_fontdefault'] = '-- Font family --'; +tinyMCELang['lang_theme_block'] = '-- Format --'; +tinyMCELang['lang_theme_paragraph'] = 'Standard-Text'; +tinyMCELang['lang_theme_div'] = 'Div'; +tinyMCELang['lang_theme_address'] = 'Addresse'; +tinyMCELang['lang_theme_pre'] = 'Vorformatiert (pre)'; +tinyMCELang['lang_theme_h1'] = 'Überschrift 1'; +tinyMCELang['lang_theme_h2'] = 'Überschrift 2'; +tinyMCELang['lang_theme_h3'] = 'Überschrift 3'; +tinyMCELang['lang_theme_h4'] = 'Überschrift 4'; +tinyMCELang['lang_theme_h5'] = 'Überschrift 5'; +tinyMCELang['lang_theme_h6'] = 'Überschrift 6'; +tinyMCELang['lang_theme_colorpicker_title'] = 'Wähle eine Farbe'; +tinyMCELang['lang_theme_colorpicker_apply'] = 'Übernehmen'; +tinyMCELang['lang_theme_forecolor_desc'] = 'Schriftfarbe auswhlen'; +tinyMCELang['lang_theme_backcolor_desc'] = 'Select background color'; +tinyMCELang['lang_theme_charmap_title'] = 'Wähle ein Sonderzeichen'; +tinyMCELang['lang_theme_charmap_desc'] = 'Sonderzeichen einfügen'; +tinyMCELang['lang_theme_visualaid_desc'] = 'Anzeige von Hilfslinien / unsichtbaren Elementen an/aus'; +tinyMCELang['lang_insert_anchor_title'] = 'Anker einfügen/bearbeiten'; +tinyMCELang['lang_insert_anchor_name'] = 'Ankername'; +tinyMCELang['lang_theme_anchor_desc'] = 'Anker einfügen/bearbeiten'; +tinyMCELang['lang_theme_insert_link_titlefield'] = 'Title'; +tinyMCELang['lang_theme_clipboard_msg'] = 'Kopieren/Ausschneiden/Einfügen sind in Mozilla und Firefox nicht verfügbar.\nMöchten sie weitere Informationen zu diesem Thema?'; +tinyMCELang['lang_theme_path'] = 'Pfad'; +tinyMCELang['lang_cut_desc'] = 'Ausschneiden'; +tinyMCELang['lang_copy_desc'] = 'Kopieren'; +tinyMCELang['lang_paste_desc'] = 'Einfügen'; +tinyMCELang['lang_link_list'] = 'Verweisliste'; +tinyMCELang['lang_image_list'] = 'Bildliste'; +tinyMCELang['lang_browse'] = 'Durchsuchen'; +tinyMCELang['lang_image_props_desc'] = 'Image properties'; +tinyMCELang['lang_newdocument_desc'] = 'New document'; +tinyMCELang['lang_class'] = 'Klasse'; diff --git a/public/tiny_mce/themes/advanced/langs/el.js b/public/tiny_mce/themes/advanced/langs/el.js new file mode 100644 index 0000000..9fa3508 --- /dev/null +++ b/public/tiny_mce/themes/advanced/langs/el.js @@ -0,0 +1,61 @@ +// Greek lang variables by Jacaranda Bill + +tinyMCELang['lang_theme_style_select'] = ''; +tinyMCELang['lang_theme_code_desc'] = ' HTML '; +tinyMCELang['lang_theme_code_title'] = ' HTML'; +tinyMCELang['lang_theme_code_wordwrap'] = 'Word wrap'; +tinyMCELang['lang_theme_sub_desc'] = ''; +tinyMCELang['lang_theme_sup_desc'] = ''; +tinyMCELang['lang_theme_hr_desc'] = ' '; +tinyMCELang['lang_theme_removeformat_desc'] = ' '; +tinyMCELang['lang_theme_custom1_desc'] = ''; +tinyMCELang['lang_insert_image_border'] = ''; +tinyMCELang['lang_insert_image_dimensions'] = ''; +tinyMCELang['lang_insert_image_vspace'] = '. '; +tinyMCELang['lang_insert_image_hspace'] = '. '; +tinyMCELang['lang_insert_image_align'] = ''; +tinyMCELang['lang_insert_image_align_default'] = ''; +tinyMCELang['lang_insert_image_align_baseline'] = ' '; +tinyMCELang['lang_insert_image_align_top'] = ''; +tinyMCELang['lang_insert_image_align_middle'] = ' '; +tinyMCELang['lang_insert_image_align_bottom'] = ''; +tinyMCELang['lang_insert_image_align_texttop'] = ' '; +tinyMCELang['lang_insert_image_align_absmiddle'] = ' '; +tinyMCELang['lang_insert_image_align_absbottom'] = ' '; +tinyMCELang['lang_insert_image_align_left'] = ''; +tinyMCELang['lang_insert_image_align_right'] = ''; +tinyMCELang['lang_theme_font_size'] = '-- Font size --'; +tinyMCELang['lang_theme_fontdefault'] = '-- Font family --'; +tinyMCELang['lang_theme_block'] = '-- Format --'; +tinyMCELang['lang_theme_paragraph'] = ''; +tinyMCELang['lang_theme_div'] = 'Div'; +tinyMCELang['lang_theme_address'] = ''; +tinyMCELang['lang_theme_pre'] = 'Preformatted'; +tinyMCELang['lang_theme_h1'] = ' 1'; +tinyMCELang['lang_theme_h2'] = ' 2'; +tinyMCELang['lang_theme_h3'] = ' 3'; +tinyMCELang['lang_theme_h4'] = ' 4'; +tinyMCELang['lang_theme_h5'] = ' 5'; +tinyMCELang['lang_theme_h6'] = ' 6'; +tinyMCELang['lang_theme_colorpicker_title'] = ''; +tinyMCELang['lang_theme_colorpicker_apply'] = ''; +tinyMCELang['lang_theme_forecolor_desc'] = ' '; +tinyMCELang['lang_theme_backcolor_desc'] = 'Select background color'; +tinyMCELang['lang_theme_charmap_title'] = ' '; +tinyMCELang['lang_theme_charmap_desc'] = ' '; +tinyMCELang['lang_theme_visualaid_desc'] = '/ '; +tinyMCELang['lang_insert_anchor_title'] = '/ '; +tinyMCELang['lang_insert_anchor_name'] = ' '; +tinyMCELang['lang_theme_anchor_desc'] = '/ '; +tinyMCELang['lang_theme_insert_link_titlefield'] = ''; +tinyMCELang['lang_theme_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?'; +tinyMCELang['lang_theme_path'] = 'Path'; +tinyMCELang['lang_cut_desc'] = 'Cut'; +tinyMCELang['lang_copy_desc'] = 'Copy'; +tinyMCELang['lang_paste_desc'] = 'Paste'; +tinyMCELang['lang_link_list'] = 'Link list'; +tinyMCELang['lang_image_list'] = 'Image list'; +tinyMCELang['lang_browse'] = 'Browse'; +tinyMCELang['lang_image_props_desc'] = 'Image properties'; +tinyMCELang['lang_newdocument_desc'] = 'New document'; +tinyMCELang['lang_class'] = ''; diff --git a/public/tiny_mce/themes/advanced/langs/en.js b/public/tiny_mce/themes/advanced/langs/en.js new file mode 100644 index 0000000..372187f --- /dev/null +++ b/public/tiny_mce/themes/advanced/langs/en.js @@ -0,0 +1,61 @@ +// UK lang variables + +tinyMCELang['lang_theme_style_select'] = '-- Styles --'; +tinyMCELang['lang_theme_code_desc'] = 'Edit HTML Source'; +tinyMCELang['lang_theme_code_title'] = 'HTML Source Editor'; +tinyMCELang['lang_theme_code_wordwrap'] = 'Word wrap'; +tinyMCELang['lang_theme_sub_desc'] = 'Subscript'; +tinyMCELang['lang_theme_sup_desc'] = 'Superscript'; +tinyMCELang['lang_theme_hr_desc'] = 'Insert horizontal ruler'; +tinyMCELang['lang_theme_removeformat_desc'] = 'Remove formatting'; +tinyMCELang['lang_theme_custom1_desc'] = 'Your custom description here'; +tinyMCELang['lang_insert_image_border'] = 'Border'; +tinyMCELang['lang_insert_image_dimensions'] = 'Dimensions'; +tinyMCELang['lang_insert_image_vspace'] = 'VSpace'; +tinyMCELang['lang_insert_image_hspace'] = 'HSpace'; +tinyMCELang['lang_insert_image_align'] = 'Alignment'; +tinyMCELang['lang_insert_image_align_default'] = 'Default'; +tinyMCELang['lang_insert_image_align_baseline'] = 'Baseline'; +tinyMCELang['lang_insert_image_align_top'] = 'Top'; +tinyMCELang['lang_insert_image_align_middle'] = 'Middle'; +tinyMCELang['lang_insert_image_align_bottom'] = 'Bottom'; +tinyMCELang['lang_insert_image_align_texttop'] = 'TextTop'; +tinyMCELang['lang_insert_image_align_absmiddle'] = 'Absolute Middle'; +tinyMCELang['lang_insert_image_align_absbottom'] = 'Absolute Bottom'; +tinyMCELang['lang_insert_image_align_left'] = 'Left'; +tinyMCELang['lang_insert_image_align_right'] = 'Right'; +tinyMCELang['lang_theme_font_size'] = 'Font size'; +tinyMCELang['lang_theme_fontdefault'] = '-- Font family --'; +tinyMCELang['lang_theme_block'] = '-- Format --'; +tinyMCELang['lang_theme_paragraph'] = 'Paragraph'; +tinyMCELang['lang_theme_div'] = 'Div'; +tinyMCELang['lang_theme_address'] = 'Address'; +tinyMCELang['lang_theme_pre'] = 'Preformatted'; +tinyMCELang['lang_theme_h1'] = 'Heading 1'; +tinyMCELang['lang_theme_h2'] = 'Heading 2'; +tinyMCELang['lang_theme_h3'] = 'Heading 3'; +tinyMCELang['lang_theme_h4'] = 'Heading 4'; +tinyMCELang['lang_theme_h5'] = 'Heading 5'; +tinyMCELang['lang_theme_h6'] = 'Heading 6'; +tinyMCELang['lang_theme_colorpicker_title'] = 'Select a color'; +tinyMCELang['lang_theme_colorpicker_apply'] = 'Apply'; +tinyMCELang['lang_theme_forecolor_desc'] = 'Select text color'; +tinyMCELang['lang_theme_backcolor_desc'] = 'Select background color'; +tinyMCELang['lang_theme_charmap_title'] = 'Select custom character'; +tinyMCELang['lang_theme_charmap_desc'] = 'Insert custom character'; +tinyMCELang['lang_theme_visualaid_desc'] = 'Toggle guidelines/invisible elements'; +tinyMCELang['lang_insert_anchor_title'] = 'Insert/edit anchor'; +tinyMCELang['lang_insert_anchor_name'] = 'Anchor name'; +tinyMCELang['lang_theme_anchor_desc'] = 'Insert/edit anchor'; +tinyMCELang['lang_theme_insert_link_titlefield'] = 'Title'; +tinyMCELang['lang_theme_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?'; +tinyMCELang['lang_theme_path'] = 'Path'; +tinyMCELang['lang_cut_desc'] = 'Cut'; +tinyMCELang['lang_copy_desc'] = 'Copy'; +tinyMCELang['lang_paste_desc'] = 'Paste'; +tinyMCELang['lang_link_list'] = 'Link list'; +tinyMCELang['lang_image_list'] = 'Image list'; +tinyMCELang['lang_browse'] = 'Browse'; +tinyMCELang['lang_image_props_desc'] = 'Image properties'; +tinyMCELang['lang_newdocument_desc'] = 'New document'; +tinyMCELang['lang_class'] = 'Class'; diff --git a/public/tiny_mce/themes/advanced/langs/es.js b/public/tiny_mce/themes/advanced/langs/es.js new file mode 100644 index 0000000..d052435 --- /dev/null +++ b/public/tiny_mce/themes/advanced/langs/es.js @@ -0,0 +1,61 @@ +// ES lang variables by Alvaro Velasco + +tinyMCELang['lang_theme_style_select'] = 'Estilos'; +tinyMCELang['lang_theme_code_desc'] = 'Editar codigo HTML'; +tinyMCELang['lang_theme_code_title'] = 'Editor codigo HTML'; +tinyMCELang['lang_theme_code_wordwrap'] = 'Word wrap'; +tinyMCELang['lang_theme_sub_desc'] = 'Subindice'; +tinyMCELang['lang_theme_sup_desc'] = 'Superindice'; +tinyMCELang['lang_theme_hr_desc'] = 'Insertar un separador horizontal'; +tinyMCELang['lang_theme_removeformat_desc'] = 'Quitar formato'; +tinyMCELang['lang_theme_custom1_desc'] = 'Tu descricion'; +tinyMCELang['lang_insert_image_border'] = 'Borde'; +tinyMCELang['lang_insert_image_dimensions'] = 'Dimensiones'; +tinyMCELang['lang_insert_image_vspace'] = 'Espacio vertical'; +tinyMCELang['lang_insert_image_hspace'] = 'Espacio horizontal'; +tinyMCELang['lang_insert_image_align'] = 'Alineamiento'; +tinyMCELang['lang_insert_image_align_default'] = 'Por defecto'; +tinyMCELang['lang_insert_image_align_baseline'] = 'Baseline'; +tinyMCELang['lang_insert_image_align_top'] = 'Superior'; +tinyMCELang['lang_insert_image_align_middle'] = 'Centro'; +tinyMCELang['lang_insert_image_align_bottom'] = 'Inferior'; +tinyMCELang['lang_insert_image_align_texttop'] = 'Alinear texto arriba'; +tinyMCELang['lang_insert_image_align_absmiddle'] = 'Centrado horizontal'; +tinyMCELang['lang_insert_image_align_absbottom'] = 'Centrado abajo'; +tinyMCELang['lang_insert_image_align_left'] = 'Izquierda'; +tinyMCELang['lang_insert_image_align_right'] = 'Derecha'; +tinyMCELang['lang_insert_image_delta_height'] = 10; +tinyMCELang['lang_theme_font_size'] = '-- Font size --'; +tinyMCELang['lang_theme_fontdefault'] = '-- Font family --'; +tinyMCELang['lang_theme_block'] = '-- Format --'; +tinyMCELang['lang_theme_paragraph'] = 'Paragraph'; +tinyMCELang['lang_theme_div'] = 'Div'; +tinyMCELang['lang_theme_address'] = 'Address'; +tinyMCELang['lang_theme_pre'] = 'Preformatted'; +tinyMCELang['lang_theme_h1'] = 'Heading 1'; +tinyMCELang['lang_theme_h2'] = 'Heading 2'; +tinyMCELang['lang_theme_h3'] = 'Heading 3'; +tinyMCELang['lang_theme_h4'] = 'Heading 4'; +tinyMCELang['lang_theme_h5'] = 'Heading 5'; +tinyMCELang['lang_theme_h6'] = 'Heading 6'; +tinyMCELang['lang_theme_colorpicker_title'] = 'Select a color'; +tinyMCELang['lang_theme_colorpicker_apply'] = 'Apply'; +tinyMCELang['lang_theme_forecolor_desc'] = 'Select forecolor'; +tinyMCELang['lang_theme_backcolor_desc'] = 'Select background color'; +tinyMCELang['lang_theme_charmap_title'] = 'Select custom character'; +tinyMCELang['lang_theme_charmap_desc'] = 'Insert custom character'; +tinyMCELang['lang_theme_visualaid_desc'] = 'Toggle guidelines/invisible elements'; +tinyMCELang['lang_insert_anchor_title'] = 'Insert/edit anchor'; +tinyMCELang['lang_insert_anchor_name'] = 'Anchor name'; +tinyMCELang['lang_theme_anchor_desc'] = 'Insert/edit anchor'; +tinyMCELang['lang_theme_insert_link_titlefield'] = 'Title'; +tinyMCELang['lang_theme_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?'; +tinyMCELang['lang_theme_path'] = 'Path'; +tinyMCELang['lang_cut_desc'] = 'Cut'; +tinyMCELang['lang_copy_desc'] = 'Copy'; +tinyMCELang['lang_paste_desc'] = 'Paste'; +tinyMCELang['lang_link_list'] = 'Link list'; +tinyMCELang['lang_image_list'] = 'Image list'; +tinyMCELang['lang_browse'] = 'Browse'; +tinyMCELang['lang_image_props_desc'] = 'Image properties'; +tinyMCELang['lang_newdocument_desc'] = 'New document'; diff --git a/public/tiny_mce/themes/advanced/langs/fa.js b/public/tiny_mce/themes/advanced/langs/fa.js new file mode 100644 index 0000000..e118cf9 --- /dev/null +++ b/public/tiny_mce/themes/advanced/langs/fa.js @@ -0,0 +1,62 @@ +// IR lang variables +// Persian (Farsi) language pack (for IRAN) +// By: Morteza Zafari +// Lost@LostLord.com +// http://www.LostLord.com + +tinyMCELang['lang_dir'] = 'rtl'; +tinyMCELang['lang_theme_style_select'] = '????'; +tinyMCELang['lang_theme_code_desc'] = '?????? ????'; +tinyMCELang['lang_theme_code_title'] = 'HTML ???????? ????'; +tinyMCELang['lang_theme_code_wordwrap'] = '?? ???'; +tinyMCELang['lang_theme_sub_desc'] = '??? ????'; +tinyMCELang['lang_theme_sup_desc'] = '???? ????'; +tinyMCELang['lang_theme_hr_desc'] = '??? ?? ????'; +tinyMCELang['lang_theme_removeformat_desc'] = '??? ?? ??? ???? ????'; +tinyMCELang['lang_theme_custom1_desc'] = 'Your custom description here'; +tinyMCELang['lang_insert_image_border'] = '?????'; +tinyMCELang['lang_insert_image_dimensions'] = '?????'; +tinyMCELang['lang_insert_image_vspace'] = '????? ?????'; +tinyMCELang['lang_insert_image_hspace'] = '????? ????'; +tinyMCELang['lang_insert_image_align'] = '??? ????????'; +tinyMCELang['lang_insert_image_align_default'] = '??? ???'; +tinyMCELang['lang_insert_image_align_baseline'] = '?? ????'; +tinyMCELang['lang_insert_image_align_top'] = '????'; +tinyMCELang['lang_insert_image_align_middle'] = '???'; +tinyMCELang['lang_insert_image_align_bottom'] = '?????'; +tinyMCELang['lang_insert_image_align_texttop'] = '????? ???'; +tinyMCELang['lang_insert_image_align_absmiddle'] = '??? ????'; +tinyMCELang['lang_insert_image_align_absbottom'] = '????? ????'; +tinyMCELang['lang_insert_image_align_left'] = '??'; +tinyMCELang['lang_insert_image_align_right'] = '????'; +tinyMCELang['lang_theme_font_size'] = '-- Font size --'; +tinyMCELang['lang_theme_fontdefault'] = '-- Font family --'; +tinyMCELang['lang_theme_block'] = '-- Format --'; +tinyMCELang['lang_theme_paragraph'] = '????????'; +tinyMCELang['lang_theme_div'] = 'Div'; +tinyMCELang['lang_theme_address'] = '????'; +tinyMCELang['lang_theme_pre'] = '?? ??? ????? ???'; +tinyMCELang['lang_theme_h1'] = '???? 1'; +tinyMCELang['lang_theme_h2'] = '???? 2'; +tinyMCELang['lang_theme_h3'] = '???? 3'; +tinyMCELang['lang_theme_h4'] = '???? 4'; +tinyMCELang['lang_theme_h5'] = '???? 5'; +tinyMCELang['lang_theme_h6'] = '???? 6'; +tinyMCELang['lang_theme_colorpicker_title'] = '??? ?? ?????? ????'; +tinyMCELang['lang_theme_colorpicker_apply'] = '?????'; +tinyMCELang['lang_theme_forecolor_desc'] = '?????? ??? ???'; +tinyMCELang['lang_theme_backcolor_desc'] = '?????? ??? ?????'; +tinyMCELang['lang_theme_charmap_title'] = '?????? ??????? ????'; +tinyMCELang['lang_theme_charmap_desc'] = '??? ??????? ????'; +tinyMCELang['lang_theme_visualaid_desc'] = '????? ???? ???? ? ????? ??????'; +tinyMCELang['lang_insert_anchor_title'] = '??? ? ?????? Anchor'; +tinyMCELang['lang_insert_anchor_name'] = '??? Anchor'; +tinyMCELang['lang_theme_anchor_desc'] = '??? ? ?????? Anchor'; +tinyMCELang['lang_theme_insert_link_titlefield'] = '?????'; +tinyMCELang['lang_theme_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?'; +tinyMCELang['lang_theme_path'] = '????'; +tinyMCELang['lang_cut_desc'] = 'Cut'; +tinyMCELang['lang_copy_desc'] = 'Copy'; +tinyMCELang['lang_paste_desc'] = 'Paste'; +tinyMCELang['lang_image_props_desc'] = 'Image properties'; +tinyMCELang['lang_newdocument_desc'] = 'New document'; diff --git a/public/tiny_mce/themes/advanced/langs/fi.js b/public/tiny_mce/themes/advanced/langs/fi.js new file mode 100644 index 0000000..7a812aa --- /dev/null +++ b/public/tiny_mce/themes/advanced/langs/fi.js @@ -0,0 +1,60 @@ +// FI lang variables by Urho Konttori from Absolutions + +tinyMCELang['lang_theme_style_select'] = 'Tyylit'; +tinyMCELang['lang_theme_code_desc'] = 'Muokkaa HTML lhdekoodia'; +tinyMCELang['lang_theme_code_title'] = 'HTML Lhdekoodin muokkaus'; +tinyMCELang['lang_theme_code_wordwrap'] = 'Word wrap'; +tinyMCELang['lang_theme_sub_desc'] = 'Alamre'; +tinyMCELang['lang_theme_sup_desc'] = 'Ylmre'; +tinyMCELang['lang_theme_hr_desc'] = 'Lis vaakaviiva'; +tinyMCELang['lang_theme_removeformat_desc'] = 'Poista muotoilu'; +tinyMCELang['lang_theme_custom1_desc'] = 'Kirjoita oma selityksesi thn'; +tinyMCELang['lang_insert_image_border'] = 'Reuna'; +tinyMCELang['lang_insert_image_dimensions'] = 'Mitat'; +tinyMCELang['lang_insert_image_vspace'] = 'Pystyvli'; +tinyMCELang['lang_insert_image_hspace'] = 'Vaakavli'; +tinyMCELang['lang_insert_image_align'] = 'Asettelu'; +tinyMCELang['lang_insert_image_align_default'] = 'Oletus'; +tinyMCELang['lang_insert_image_align_baseline'] = 'Perustasoon'; +tinyMCELang['lang_insert_image_align_top'] = 'Yllaitaan'; +tinyMCELang['lang_insert_image_align_middle'] = 'Keskelle'; +tinyMCELang['lang_insert_image_align_bottom'] = 'Alalaitaan'; +tinyMCELang['lang_insert_image_align_texttop'] = 'Tekstin yllaitaan'; +tinyMCELang['lang_insert_image_align_absmiddle'] = 'Absoluuttisen keskelle'; +tinyMCELang['lang_insert_image_align_absbottom'] = 'Absoluuttisen alas'; +tinyMCELang['lang_insert_image_align_left'] = 'Vasemmalle'; +tinyMCELang['lang_insert_image_align_right'] = 'Oikealle'; +tinyMCELang['lang_theme_font_size'] = '-- Font size --'; +tinyMCELang['lang_theme_fontdefault'] = '-- Font family --'; +tinyMCELang['lang_theme_block'] = '-- Format --'; +tinyMCELang['lang_theme_paragraph'] = 'Kappale'; +tinyMCELang['lang_theme_div'] = 'Div'; +tinyMCELang['lang_theme_address'] = 'Osoite'; +tinyMCELang['lang_theme_pre'] = 'Etukteen muotoiltu'; +tinyMCELang['lang_theme_h1'] = 'Otsikko 1'; +tinyMCELang['lang_theme_h2'] = 'Otsikko 2'; +tinyMCELang['lang_theme_h3'] = 'Otsikko 3'; +tinyMCELang['lang_theme_h4'] = 'Otsikko 4'; +tinyMCELang['lang_theme_h5'] = 'Otsikko 5'; +tinyMCELang['lang_theme_h6'] = 'Otsikko 6'; +tinyMCELang['lang_theme_colorpicker_title'] = 'Valitse vri'; +tinyMCELang['lang_theme_colorpicker_apply'] = 'Aseta vri'; +tinyMCELang['lang_theme_forecolor_desc'] = 'Valitse etuvri'; +tinyMCELang['lang_theme_backcolor_desc'] = 'Select background color'; +tinyMCELang['lang_theme_charmap_title'] = 'Select custom character'; +tinyMCELang['lang_theme_charmap_desc'] = 'Insert custom character'; +tinyMCELang['lang_theme_visualaid_desc'] = 'Toggle guidelines/invisible elements'; +tinyMCELang['lang_insert_anchor_title'] = 'Insert/edit anchor'; +tinyMCELang['lang_insert_anchor_name'] = 'Anchor name'; +tinyMCELang['lang_theme_anchor_desc'] = 'Insert/edit anchor'; +tinyMCELang['lang_theme_insert_link_titlefield'] = 'Title'; +tinyMCELang['lang_theme_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?'; +tinyMCELang['lang_theme_path'] = 'Path'; +tinyMCELang['lang_cut_desc'] = 'Cut'; +tinyMCELang['lang_copy_desc'] = 'Copy'; +tinyMCELang['lang_paste_desc'] = 'Paste'; +tinyMCELang['lang_link_list'] = 'Link list'; +tinyMCELang['lang_image_list'] = 'Image list'; +tinyMCELang['lang_browse'] = 'Browse'; +tinyMCELang['lang_image_props_desc'] = 'Image properties'; +tinyMCELang['lang_newdocument_desc'] = 'New document'; diff --git a/public/tiny_mce/themes/advanced/langs/fr.js b/public/tiny_mce/themes/advanced/langs/fr.js new file mode 100644 index 0000000..7c14d1f --- /dev/null +++ b/public/tiny_mce/themes/advanced/langs/fr.js @@ -0,0 +1,62 @@ +// Canadian French lang variables by Virtuelcom +// Modify by Laurent Dran 13-02-2006 + +tinyMCELang['lang_theme_style_select'] = 'Styles'; +tinyMCELang['lang_theme_code_desc'] = 'Modifier le code source HTML'; +tinyMCELang['lang_theme_code_title'] = 'Éditeur de code source HTML'; +tinyMCELang['lang_theme_code_wordwrap'] = 'Word wrap'; +tinyMCELang['lang_theme_sub_desc'] = 'Souscrit'; +tinyMCELang['lang_theme_sup_desc'] = 'Indice supérieur'; +tinyMCELang['lang_theme_hr_desc'] = 'Insérer un séparateur horizontal'; +tinyMCELang['lang_theme_removeformat_desc'] = 'Supprimer le formattage'; +tinyMCELang['lang_theme_custom1_desc'] = 'Votre description personnalisée ici'; +tinyMCELang['lang_insert_image_border'] = 'Bordure'; +tinyMCELang['lang_insert_image_dimensions'] = 'Dimensions'; +tinyMCELang['lang_insert_image_vspace'] = 'VSpace'; +tinyMCELang['lang_insert_image_hspace'] = 'HSpace'; +tinyMCELang['lang_insert_image_align'] = 'Alignement'; +tinyMCELang['lang_insert_image_align_default'] = 'Défaut'; +tinyMCELang['lang_insert_image_align_baseline'] = 'Baseline'; +tinyMCELang['lang_insert_image_align_top'] = 'Haut'; +tinyMCELang['lang_insert_image_align_middle'] = 'Milieu'; +tinyMCELang['lang_insert_image_align_bottom'] = 'Bas'; +tinyMCELang['lang_insert_image_align_texttop'] = 'TextTop'; +tinyMCELang['lang_insert_image_align_absmiddle'] = 'Milieu absolu'; +tinyMCELang['lang_insert_image_align_absbottom'] = 'Bas absolu'; +tinyMCELang['lang_insert_image_align_left'] = 'Gauche'; +tinyMCELang['lang_insert_image_align_right'] = 'Droit'; +tinyMCELang['lang_theme_font_size'] = '-- Font size --'; +tinyMCELang['lang_theme_fontdefault'] = '-- Font family --'; +tinyMCELang['lang_theme_block'] = '-- Format --'; +tinyMCELang['lang_theme_paragraph'] = 'Paragraphe'; +tinyMCELang['lang_theme_div'] = 'Div'; +tinyMCELang['lang_theme_address'] = 'Addresse'; +tinyMCELang['lang_theme_pre'] = 'Préformatté'; +tinyMCELang['lang_theme_h1'] = 'Entête 1'; +tinyMCELang['lang_theme_h2'] = 'Entête 2'; +tinyMCELang['lang_theme_h3'] = 'Entête 3'; +tinyMCELang['lang_theme_h4'] = 'Entête 4'; +tinyMCELang['lang_theme_h5'] = 'Entête 5'; +tinyMCELang['lang_theme_h6'] = 'Entête 6'; +tinyMCELang['lang_theme_colorpicker_title'] = 'Choisir une couleur'; +tinyMCELang['lang_theme_colorpicker_apply'] = 'Appliquer'; +tinyMCELang['lang_theme_forecolor_desc'] = 'Choisir la couleur d\'avant plan'; +tinyMCELang['lang_theme_backcolor_desc'] = 'Choisir la couleur de fond'; +tinyMCELang['lang_theme_charmap_title'] = 'Sélectionner un charactère spécial'; +tinyMCELang['lang_theme_charmap_desc'] = 'Insérer un charactère spécial'; +tinyMCELang['lang_theme_visualaid_desc'] = 'Active/Désactive les lignes guides et les éléments invisibles'; +tinyMCELang['lang_insert_anchor_title'] = 'Insérer/Modifier une ancre'; +tinyMCELang['lang_insert_anchor_name'] = 'Nom de l\'ancre'; +tinyMCELang['lang_theme_anchor_desc'] = 'Insérer/Modifier une ancre'; +tinyMCELang['lang_theme_insert_link_titlefield'] = 'Titre'; +tinyMCELang['lang_theme_clipboard_msg'] = 'Copier/Couper/Coller ne sont pas disponibles pour Mozilla et Firefox.\nVoulez vous plus d\'informations ce sujet?'; +tinyMCELang['lang_theme_path'] = 'Chemin'; +tinyMCELang['lang_cut_desc'] = 'Couper'; +tinyMCELang['lang_copy_desc'] = 'Copier'; +tinyMCELang['lang_paste_desc'] = 'Coller'; +tinyMCELang['lang_link_list'] = 'Lien de la liste'; +tinyMCELang['lang_image_list'] = 'Image de la liste'; +tinyMCELang['lang_browse'] = 'Naviguer'; +tinyMCELang['lang_image_props_desc'] = 'Image properties'; +tinyMCELang['lang_newdocument_desc'] = 'New document'; +tinyMCELang['lang_class'] = 'Classe CSS'; diff --git a/public/tiny_mce/themes/advanced/langs/fr_ca.js b/public/tiny_mce/themes/advanced/langs/fr_ca.js new file mode 100644 index 0000000..5315e4e --- /dev/null +++ b/public/tiny_mce/themes/advanced/langs/fr_ca.js @@ -0,0 +1,60 @@ +// Canadian French lang variables by Virtuelcom + +tinyMCELang['lang_theme_style_select'] = 'Styles'; +tinyMCELang['lang_theme_code_desc'] = 'Modifier le code source HTML'; +tinyMCELang['lang_theme_code_title'] = 'diteur de code source HTML'; +tinyMCELang['lang_theme_code_wordwrap'] = 'Word wrap'; +tinyMCELang['lang_theme_sub_desc'] = 'Souscrit'; +tinyMCELang['lang_theme_sup_desc'] = 'Indice suprieur'; +tinyMCELang['lang_theme_hr_desc'] = 'Insrer un sparateur horizontal'; +tinyMCELang['lang_theme_removeformat_desc'] = 'Supprimer le formattage'; +tinyMCELang['lang_theme_custom1_desc'] = 'Votre description personnalise ici'; +tinyMCELang['lang_insert_image_border'] = 'Bordure'; +tinyMCELang['lang_insert_image_dimensions'] = 'Dimensions'; +tinyMCELang['lang_insert_image_vspace'] = 'VSpace'; +tinyMCELang['lang_insert_image_hspace'] = 'HSpace'; +tinyMCELang['lang_insert_image_align'] = 'Alignement'; +tinyMCELang['lang_insert_image_align_default'] = 'Dfaut'; +tinyMCELang['lang_insert_image_align_baseline'] = 'Baseline'; +tinyMCELang['lang_insert_image_align_top'] = 'Haut'; +tinyMCELang['lang_insert_image_align_middle'] = 'Milieu'; +tinyMCELang['lang_insert_image_align_bottom'] = 'Bas'; +tinyMCELang['lang_insert_image_align_texttop'] = 'TextTop'; +tinyMCELang['lang_insert_image_align_absmiddle'] = 'Milieu absolu'; +tinyMCELang['lang_insert_image_align_absbottom'] = 'Bas absolu'; +tinyMCELang['lang_insert_image_align_left'] = 'Gauche'; +tinyMCELang['lang_insert_image_align_right'] = 'Droit'; +tinyMCELang['lang_theme_font_size'] = '-- Font size --'; +tinyMCELang['lang_theme_fontdefault'] = '-- Font family --'; +tinyMCELang['lang_theme_block'] = '-- Format --'; +tinyMCELang['lang_theme_paragraph'] = 'Paragraphe'; +tinyMCELang['lang_theme_div'] = 'Div'; +tinyMCELang['lang_theme_address'] = 'Addresse'; +tinyMCELang['lang_theme_pre'] = 'Prformatt'; +tinyMCELang['lang_theme_h1'] = 'Entte 1'; +tinyMCELang['lang_theme_h2'] = 'Entte 2'; +tinyMCELang['lang_theme_h3'] = 'Entte 3'; +tinyMCELang['lang_theme_h4'] = 'Entte 4'; +tinyMCELang['lang_theme_h5'] = 'Entte 5'; +tinyMCELang['lang_theme_h6'] = 'Entte 6'; +tinyMCELang['lang_theme_colorpicker_title'] = 'Choisir une couleur'; +tinyMCELang['lang_theme_colorpicker_apply'] = 'Appliquer'; +tinyMCELang['lang_theme_forecolor_desc'] = 'Choisir la couleur d\'avant plan'; +tinyMCELang['lang_theme_backcolor_desc'] = 'Choisir une couleur d\'arrire plan'; +tinyMCELang['lang_theme_charmap_title'] = 'Slectionner un charactre spcial'; +tinyMCELang['lang_theme_charmap_desc'] = 'Insrer un charactre spcial'; +tinyMCELang['lang_theme_visualaid_desc'] = 'Active/Dsactive les lignes guides et les lments invisibles'; +tinyMCELang['lang_insert_anchor_title'] = 'Insrer/Modifier une ancre'; +tinyMCELang['lang_insert_anchor_name'] = 'Nom de l\'ancre'; +tinyMCELang['lang_theme_anchor_desc'] = 'Insrer / Modifier une ancre'; +tinyMCELang['lang_theme_insert_link_titlefield'] = 'Titre'; +tinyMCELang['lang_theme_clipboard_msg'] = 'Copier/Couper/Coller ne sont pas disponibles dans Mozilla et FireFox.\nDsirez-vous consulter de plus amples informations ce sujet?'; +tinyMCELang['lang_theme_path'] = 'Chemin'; +tinyMCELang['lang_cut_desc'] = 'Couper'; +tinyMCELang['lang_copy_desc'] = 'Copier'; +tinyMCELang['lang_paste_desc'] = 'Coller'; +tinyMCELang['lang_link_list'] = 'Liste de liens'; +tinyMCELang['lang_image_list'] = 'Liste d\'images'; +tinyMCELang['lang_browse'] = 'Slectionner'; +tinyMCELang['lang_image_props_desc'] = 'Image properties'; +tinyMCELang['lang_newdocument_desc'] = 'New document'; diff --git a/public/tiny_mce/themes/advanced/langs/hu.js b/public/tiny_mce/themes/advanced/langs/hu.js new file mode 100644 index 0000000..bf9fb29 --- /dev/null +++ b/public/tiny_mce/themes/advanced/langs/hu.js @@ -0,0 +1,61 @@ +// HU lang variables +// Edited by 2XP (2xp@dino.hu) + +tinyMCELang['lang_theme_style_select'] = 'Stílusok'; +tinyMCELang['lang_theme_code_desc'] = 'HTML kód szerkesztése'; +tinyMCELang['lang_theme_code_title'] = 'HTML kódszerkeztõ'; +tinyMCELang['lang_theme_code_wordwrap'] = 'Word wrap'; +tinyMCELang['lang_theme_sub_desc'] = 'Alsó index'; +tinyMCELang['lang_theme_sup_desc'] = 'Felsõ index'; +tinyMCELang['lang_theme_hr_desc'] = 'Vízszintes vonal beillesztése'; +tinyMCELang['lang_theme_removeformat_desc'] = 'Formázás eltávolítása'; +tinyMCELang['lang_theme_custom1_desc'] = 'Az Ön által kiválasztott leírás'; +tinyMCELang['lang_insert_image_border'] = 'Keret'; +tinyMCELang['lang_insert_image_dimensions'] = 'Méretek'; +tinyMCELang['lang_insert_image_vspace'] = 'Függõleges térköz'; +tinyMCELang['lang_insert_image_hspace'] = 'Vízszintes térköz'; +tinyMCELang['lang_insert_image_align'] = 'Igazítés'; +tinyMCELang['lang_insert_image_align_default'] = 'Alapértelmezett'; +tinyMCELang['lang_insert_image_align_baseline'] = 'Alapvonalra'; +tinyMCELang['lang_insert_image_align_top'] = 'Felülre'; +tinyMCELang['lang_insert_image_align_middle'] = 'Középre'; +tinyMCELang['lang_insert_image_align_bottom'] = 'Alulra'; +tinyMCELang['lang_insert_image_align_texttop'] = 'TextTop'; +tinyMCELang['lang_insert_image_align_absmiddle'] = 'Abszolút középre'; +tinyMCELang['lang_insert_image_align_absbottom'] = 'Abszolút alulra'; +tinyMCELang['lang_insert_image_align_left'] = 'Balra'; +tinyMCELang['lang_insert_image_align_right'] = 'Jobbra'; +tinyMCELang['lang_theme_font_size'] = '-- Font size --'; +tinyMCELang['lang_theme_fontdefault'] = '-- Font family --'; +tinyMCELang['lang_theme_block'] = '-- Format --'; +tinyMCELang['lang_theme_paragraph'] = 'Paragraph'; +tinyMCELang['lang_theme_div'] = 'Div'; +tinyMCELang['lang_theme_address'] = 'Address'; +tinyMCELang['lang_theme_pre'] = 'Preformatted'; +tinyMCELang['lang_theme_h1'] = 'Heading 1'; +tinyMCELang['lang_theme_h2'] = 'Heading 2'; +tinyMCELang['lang_theme_h3'] = 'Heading 3'; +tinyMCELang['lang_theme_h4'] = 'Heading 4'; +tinyMCELang['lang_theme_h5'] = 'Heading 5'; +tinyMCELang['lang_theme_h6'] = 'Heading 6'; +tinyMCELang['lang_theme_colorpicker_title'] = 'Select a color'; +tinyMCELang['lang_theme_colorpicker_apply'] = 'Apply'; +tinyMCELang['lang_theme_forecolor_desc'] = 'Select forecolor'; +tinyMCELang['lang_theme_backcolor_desc'] = 'Select background color'; +tinyMCELang['lang_theme_charmap_title'] = 'Select custom character'; +tinyMCELang['lang_theme_charmap_desc'] = 'Insert custom character'; +tinyMCELang['lang_theme_visualaid_desc'] = 'Toggle guidelines/invisible elements'; +tinyMCELang['lang_insert_anchor_title'] = 'Insert/edit anchor'; +tinyMCELang['lang_insert_anchor_name'] = 'Anchor name'; +tinyMCELang['lang_theme_anchor_desc'] = 'Insert/edit anchor'; +tinyMCELang['lang_theme_insert_link_titlefield'] = 'Title'; +tinyMCELang['lang_theme_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?'; +tinyMCELang['lang_theme_path'] = 'Path'; +tinyMCELang['lang_cut_desc'] = 'Cut'; +tinyMCELang['lang_copy_desc'] = 'Copy'; +tinyMCELang['lang_paste_desc'] = 'Paste'; +tinyMCELang['lang_link_list'] = 'Link list'; +tinyMCELang['lang_image_list'] = 'Image list'; +tinyMCELang['lang_browse'] = 'Browse'; +tinyMCELang['lang_image_props_desc'] = 'Image properties'; +tinyMCELang['lang_newdocument_desc'] = 'New document'; diff --git a/public/tiny_mce/themes/advanced/langs/it.js b/public/tiny_mce/themes/advanced/langs/it.js new file mode 100644 index 0000000..69038a4 --- /dev/null +++ b/public/tiny_mce/themes/advanced/langs/it.js @@ -0,0 +1,61 @@ +// Variabili di lingua IT - fabrix.xm@lombardiacom.it + +tinyMCELang['lang_theme_style_select'] = 'Stili'; +tinyMCELang['lang_theme_code_desc'] = 'Edita il sorgente HTML'; +tinyMCELang['lang_theme_code_title'] = 'Editor Sorgente HTML'; +tinyMCELang['lang_theme_code_wordwrap'] = 'Word wrap'; +tinyMCELang['lang_theme_sub_desc'] = 'Pedice'; +tinyMCELang['lang_theme_sup_desc'] = 'Apice'; +tinyMCELang['lang_theme_hr_desc'] = 'Inserisce linea orizzontale'; +tinyMCELang['lang_theme_removeformat_desc'] = 'Rimuovi formattazione'; +tinyMCELang['lang_theme_custom1_desc'] = 'Scrivi qui la tua descrizione personalizzata'; +tinyMCELang['lang_insert_image_border'] = 'Bordo'; +tinyMCELang['lang_insert_image_dimensions'] = 'Dimensioni'; +tinyMCELang['lang_insert_image_vspace'] = 'Spazio verticale'; +tinyMCELang['lang_insert_image_hspace'] = 'Spazio orizzontale'; +tinyMCELang['lang_insert_image_align'] = 'Allineamento'; +tinyMCELang['lang_insert_image_align_default'] = 'Default'; +tinyMCELang['lang_insert_image_align_baseline'] = 'Baseline'; +tinyMCELang['lang_insert_image_align_top'] = 'Superiore'; +tinyMCELang['lang_insert_image_align_middle'] = 'Centrale'; +tinyMCELang['lang_insert_image_align_bottom'] = 'Inferiore'; +tinyMCELang['lang_insert_image_align_texttop'] = 'TextTop'; +tinyMCELang['lang_insert_image_align_absmiddle'] = 'Centro assoluto'; +tinyMCELang['lang_insert_image_align_absbottom'] = 'Inferiore assoluto'; +tinyMCELang['lang_insert_image_align_left'] = 'Sinistra'; +tinyMCELang['lang_insert_image_align_right'] = 'Destra'; +tinyMCELang['lang_theme_font_size'] = '-- Font size --'; +tinyMCELang['lang_theme_fontdefault'] = '-- Font family --'; +tinyMCELang['lang_theme_block'] = '-- Format --'; +tinyMCELang['lang_theme_paragraph'] = 'Paragrafo'; +tinyMCELang['lang_theme_div'] = 'Div'; +tinyMCELang['lang_theme_address'] = 'Indirizzo'; +tinyMCELang['lang_theme_pre'] = 'Preformattato'; +tinyMCELang['lang_theme_h1'] = 'Intestazione 1'; +tinyMCELang['lang_theme_h2'] = 'Intestazione 2'; +tinyMCELang['lang_theme_h3'] = 'Intestazione 3'; +tinyMCELang['lang_theme_h4'] = 'Intestazione 4'; +tinyMCELang['lang_theme_h5'] = 'Intestazione 5'; +tinyMCELang['lang_theme_h6'] = 'Intestazione 6'; +tinyMCELang['lang_theme_colorpicker_title'] = 'Seleziona un colore'; +tinyMCELang['lang_theme_colorpicker_apply'] = 'Appplica'; +tinyMCELang['lang_theme_forecolor_desc'] = 'Seleziona il colore'; +tinyMCELang['lang_theme_backcolor_desc'] = 'Select background color'; +tinyMCELang['lang_theme_charmap_title'] = 'Seleziona un carattere custom'; +tinyMCELang['lang_theme_charmap_desc'] = 'Inserisci un carattere custom'; +tinyMCELang['lang_theme_visualaid_desc'] = 'Mostra/nascondi linee guida e elementi invisibili'; +tinyMCELang['lang_insert_anchor_title'] = 'Inserisci/modifica àncora'; +tinyMCELang['lang_insert_anchor_name'] = 'Nome àncora'; +tinyMCELang['lang_theme_anchor_desc'] = 'Inserisci/modifica àncora'; +tinyMCELang['lang_theme_insert_link_titlefield'] = 'Titolo'; +tinyMCELang['lang_theme_clipboard_msg'] = 'Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?'; +tinyMCELang['lang_theme_path'] = 'Path'; +tinyMCELang['lang_cut_desc'] = 'Cut'; +tinyMCELang['lang_copy_desc'] = 'Copy'; +tinyMCELang['lang_paste_desc'] = 'Paste'; +tinyMCELang['lang_link_list'] = 'Link list'; +tinyMCELang['lang_image_list'] = 'Image list'; +tinyMCELang['lang_browse'] = 'Browse'; +tinyMCELang['lang_image_props_desc'] = 'Image properties'; +tinyMCELang['lang_newdocument_desc'] = 'New document'; +tinyMCELang['lang_class'] = 'Classe'; diff --git a/public/tiny_mce/themes/advanced/langs/ja.js b/public/tiny_mce/themes/advanced/langs/ja.js new file mode 100644 index 0000000..c905cac --- /dev/null +++ b/public/tiny_mce/themes/advanced/langs/ja.js @@ -0,0 +1,59 @@ +// JP lang variables + +tinyMCELang['lang_theme_style_select'] = '$B%9%?%$%k(B'; +tinyMCELang['lang_theme_paragraph'] = '$BJ8L.(B'; +tinyMCELang['lang_theme_address'] = '$B%"%I%l%9(B'; +tinyMCELang['lang_theme_pre'] = '$B@07A:Q$_(B'; +tinyMCELang['lang_theme_h1'] = 'H1'; +tinyMCELang['lang_theme_h2'] = 'H2'; +tinyMCELang['lang_theme_h3'] = 'H3'; +tinyMCELang['lang_theme_h4'] = 'H4'; +tinyMCELang['lang_theme_h5'] = 'H5'; +tinyMCELang['lang_theme_h6'] = 'H6'; +tinyMCELang['lang_theme_div'] = 'Div'; +tinyMCELang['lang_insert_anchor_title'] = '$B%"%s%+!<$NA^F~(B/$BJT=8(B'; +tinyMCELang['lang_insert_anchor_name'] = '$B%"%s%+!<$NL>A0(B'; +tinyMCELang['lang_theme_anchor_desc'] = '$B%"%s%+!<$NA^F~(B/$BJT=8(B'; +tinyMCELang['lang_theme_code_desc'] = 'HTML$B$ND>@\JT=8(B'; +tinyMCELang['lang_theme_code_title'] = 'HTML$B$NJT=8(B'; +tinyMCELang['lang_theme_code_wordwrap'] = 'Word wrap'; +tinyMCELang['lang_theme_hr_desc'] = '$B?eJ?@~(B'; +tinyMCELang['lang_theme_removeformat_desc'] = '$B@07A>pJs:o=|(B'; +tinyMCELang['lang_theme_visualaid_desc'] = '$BJd=u>pJs$N;k3P2=(B($B%H%0%k(B)'; +tinyMCELang['lang_theme_sub_desc'] = '$BE:;z2<(B'; +tinyMCELang['lang_theme_sup_desc'] = '$BE:;z>e(B'; +tinyMCELang['lang_theme_charmap_desc'] = '$BFC + +{$lang_insert_link_title} + + + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$lang_insert_link_title}
    {$lang_insert_link_url}: + + + + +
    {$lang_insert_link_target}:
    {$lang_theme_insert_link_titlefield}:
    {$lang_class}: +   
    +
    +
    + + diff --git a/public/tiny_mce/themes/advanced/source_editor.htm b/public/tiny_mce/themes/advanced/source_editor.htm new file mode 100644 index 0000000..235470b --- /dev/null +++ b/public/tiny_mce/themes/advanced/source_editor.htm @@ -0,0 +1,86 @@ + + +{$lang_theme_code_title} + + + + + +
    + + + + + + + + + + + +
    {$lang_theme_code_title}
    + +
    +
    + + diff --git a/public/tiny_mce/themes/default/docs/en/about.htm b/public/tiny_mce/themes/default/docs/en/about.htm new file mode 100644 index 0000000..984a990 --- /dev/null +++ b/public/tiny_mce/themes/default/docs/en/about.htm @@ -0,0 +1,32 @@ + + + +About TinyMCE + + + + + + + + + + + +
    +
    +TinyMCE is a small WYSIWYG editor control for web browsers such as MSIE or Mozilla +that enables you to edit HTML contents in a more user friendly way. It has common +features that are found in most word processors and should not be difficult to +use.
    +
    +
    + + + + + + +
    + + diff --git a/public/tiny_mce/themes/default/docs/en/common_buttons.htm b/public/tiny_mce/themes/default/docs/en/common_buttons.htm new file mode 100644 index 0000000..d01f751 --- /dev/null +++ b/public/tiny_mce/themes/default/docs/en/common_buttons.htm @@ -0,0 +1,111 @@ + + + +Common buttons + + + + + + + + + + + +
    +
    +Below is a short description about each button. +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Bold text style.
    Italic text style.
    Underline text style.
    Strikethrough text style.
    Align left.
    Align center.
    Align right.
    Align full.
    Unordered list/bullet list.
    Ordered list/numbered list
    Outdent/decrease indentation.
    Indent/incread indentation.
    Undo the last operation.
    Redo the last operation.
    Insert a new link, read more about this function in the Insert + link section.
    Unlinks the current selection/removes all selected links.
    Insert a new image, read more about this function in the Insert + image section.
    Cleanup code/Removes unwanted formating. This function is useful when + you copy contents from for example a office product.
    Shows this help window.
    +
    +
    + + + + + + + + diff --git a/public/tiny_mce/themes/default/docs/en/images/insert_image_window.gif b/public/tiny_mce/themes/default/docs/en/images/insert_image_window.gif new file mode 100644 index 0000000..37de443 Binary files /dev/null and b/public/tiny_mce/themes/default/docs/en/images/insert_image_window.gif differ diff --git a/public/tiny_mce/themes/default/docs/en/images/insert_link_window.gif b/public/tiny_mce/themes/default/docs/en/images/insert_link_window.gif new file mode 100644 index 0000000..7bad758 Binary files /dev/null and b/public/tiny_mce/themes/default/docs/en/images/insert_link_window.gif differ diff --git a/public/tiny_mce/themes/default/docs/en/index.htm b/public/tiny_mce/themes/default/docs/en/index.htm new file mode 100644 index 0000000..dd547c2 --- /dev/null +++ b/public/tiny_mce/themes/default/docs/en/index.htm @@ -0,0 +1,25 @@ + + + +Help Index + + + + + + + + + +
    +
    +Click the links below to go to the different help sections. + +
    + + diff --git a/public/tiny_mce/themes/default/docs/en/insert_image_button.htm b/public/tiny_mce/themes/default/docs/en/insert_image_button.htm new file mode 100644 index 0000000..45255f0 --- /dev/null +++ b/public/tiny_mce/themes/default/docs/en/insert_image_button.htm @@ -0,0 +1,34 @@ + + + +Insert image button + + + + + + + + + + + +
    +
    +The insert image button opens the window shown below.
    +
    +
    +
    +You simply enter a URL to the image you want to link to and enter a image description, +this is then displayed as an alternative text descripton of the image on the page.
    +
    +
    + + + + + + +
    + + diff --git a/public/tiny_mce/themes/default/docs/en/insert_link_button.htm b/public/tiny_mce/themes/default/docs/en/insert_link_button.htm new file mode 100644 index 0000000..ddfeb3a --- /dev/null +++ b/public/tiny_mce/themes/default/docs/en/insert_link_button.htm @@ -0,0 +1,34 @@ + + + +Insert link button + + + + + + + + + + + +
    +
    +This button opens a new window with the insert/edit link function.
    +
    +
    +
    +There are two fields in this window the first one "Link URL" is the +URL of the link. The target enables you to select how the link is to be opened.
    +
    +
    + + + + + + +
    + + diff --git a/public/tiny_mce/themes/default/docs/en/style.css b/public/tiny_mce/themes/default/docs/en/style.css new file mode 100644 index 0000000..722f537 --- /dev/null +++ b/public/tiny_mce/themes/default/docs/en/style.css @@ -0,0 +1,28 @@ +body { background-color: #FFFFFF; } +body, td, .content { font-family: Verdana, Arial, helvetica, sans-serif; font-size: 12px; } +.title { font-family: Verdana, Arial, helvetica, sans-serif; font-size: 16px; font-weight: bold; } +.subtitle { font-size: 12px; font-weight: bold; } + +.toc_ul, .toc_li { margin-left: 8 px; line-height: 16px; } +.step_ol, .step_li { margin-left: 11 px; line-height: 16px; } +img { border: #000000 solid 1px; } + +a:visited { color: #666666; text-decoration: underline; } +a:active { color: #666666; text-decoration: underline; } +a:hover { color: #666666; text-decoration: underline; } +a { color: #666666; text-decoration: underline; } + +.pageheader { border: #E0E0E0 solid 1px; } +.pagefooter { border: #E0E0E0 solid 1px; } +.sample { background-color: #FFFFFF; border: #000000 solid 1px; } +.samplecontent { font-size: 10px; } + +.code { background-color: #FFFFFF; border: #000000 solid 1px; } +.codecontent { font-size: 10px; } +.codecontent a:visited { color: #666666; text-decoration: none; font-weight: bold } +.codecontent a:active { color: #666666; text-decoration: none; font-weight: bold } +.codecontent a:hover { color: #666666; text-decoration: none; font-weight: bold } +.codecontent a { color: #666666; text-decoration: none; font-weight: bold } + +hr { height: 1px; } + diff --git a/public/tiny_mce/themes/default/editor_content.css b/public/tiny_mce/themes/default/editor_content.css new file mode 100644 index 0000000..75290ee --- /dev/null +++ b/public/tiny_mce/themes/default/editor_content.css @@ -0,0 +1,27 @@ +body { + background-color: #FFFFFF; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10px; + scrollbar-3dlight-color: #F0F0EE; + scrollbar-arrow-color: #676662; + scrollbar-base-color: #F0F0EE; + scrollbar-darkshadow-color: #DDDDDD; + scrollbar-face-color: #E0E0DD; + scrollbar-highlight-color: #F0F0EE; + scrollbar-shadow-color: #F0F0EE; + scrollbar-track-color: #F5F5F5; +} + +td { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10px; +} + +pre { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10px; +} + +.mceVisualAid { + border: 1px dashed #BBBBBB; +} diff --git a/public/tiny_mce/themes/default/editor_popup.css b/public/tiny_mce/themes/default/editor_popup.css new file mode 100644 index 0000000..81a58d5 --- /dev/null +++ b/public/tiny_mce/themes/default/editor_popup.css @@ -0,0 +1,41 @@ +body { + background-color: #F0F0EE; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; + scrollbar-3dlight-color: #F0F0EE; + scrollbar-arrow-color: #676662; + scrollbar-base-color: #F0F0EE; + scrollbar-darkshadow-color: #DDDDDD; + scrollbar-face-color: #E0E0DD; + scrollbar-highlight-color: #F0F0EE; + scrollbar-shadow-color: #F0F0EE; + scrollbar-track-color: #F5F5F5; +} + +td { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; +} + +input { + background: #FFFFFF; + border: 1px solid #cccccc; +} + +td, input, select, textarea { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10px; +} + +input, select, textarea { + border: 1px solid #808080; +} + +.input_noborder { + border: 0px solid #808080; +} + +.title { + font-size: 12px; + font-weight: bold; +} \ No newline at end of file diff --git a/public/tiny_mce/themes/default/editor_template.js b/public/tiny_mce/themes/default/editor_template.js new file mode 100644 index 0000000..de3b73e --- /dev/null +++ b/public/tiny_mce/themes/default/editor_template.js @@ -0,0 +1,32 @@ +function TinyMCE_default_getEditorTemplate(){var template=new Array();template['html']='\ +\ +\ +\ +
    \ +IFRAME\ +
    \ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +
    \ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +
    ';template['delta_width']=0;template['delta_height']=-40;return template;}function TinyMCE_default_getInsertLinkTemplate(){var template=new Array();template['file']='link.htm';template['width']=320;template['height']=200;template['width']+=tinyMCE.getLang('lang_insert_link_delta_width',0);template['height']+=tinyMCE.getLang('lang_insert_link_delta_height',0);return template;}function TinyMCE_default_getInsertImageTemplate(){var template=new Array();template['file']='image.htm';template['width']=360;template['height']=200;template['width']+=tinyMCE.getLang('lang_insert_image_delta_width',0);template['height']+=tinyMCE.getLang('lang_insert_image_delta_height',0);return template;}function TinyMCE_default_handleNodeChange(editor_id,node){tinyMCE.switchClassSticky(editor_id+'_left','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_right','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_center','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_full','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_bold','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_italic','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_underline','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_strikethrough','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_bullist','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_numlist','mceButtonNormal');alignNode=node;breakOut=false;do{if(!alignNode.getAttribute||!alignNode.getAttribute('align'))continue;switch(alignNode.getAttribute('align').toLowerCase()){case "left":tinyMCE.switchClassSticky(editor_id+'_left','mceButtonSelected');breakOut=true;break;case "right":tinyMCE.switchClassSticky(editor_id+'_right','mceButtonSelected');breakOut=true;break;case "middle":case "center":tinyMCE.switchClassSticky(editor_id+'_center','mceButtonSelected');breakOut=true;break;case "justify":tinyMCE.switchClassSticky(editor_id+'_full','mceButtonSelected');breakOut=true;break;}}while(!breakOut&&(alignNode=alignNode.parentNode));do{switch(node.nodeName.toLowerCase()){case "b":case "strong":tinyMCE.switchClassSticky(editor_id+'_bold','mceButtonSelected');break;case "i":case "em":tinyMCE.switchClassSticky(editor_id+'_italic','mceButtonSelected');break;case "u":tinyMCE.switchClassSticky(editor_id+'_underline','mceButtonSelected');break;case "strike":tinyMCE.switchClassSticky(editor_id+'_strikethrough','mceButtonSelected');break;case "ul":tinyMCE.switchClassSticky(editor_id+'_bullist','mceButtonSelected');break;case "ol":tinyMCE.switchClassSticky(editor_id+'_numlist','mceButtonSelected');break;}}while((node=node.parentNode));} \ No newline at end of file diff --git a/public/tiny_mce/themes/default/editor_template_src.js b/public/tiny_mce/themes/default/editor_template_src.js new file mode 100644 index 0000000..4a317b6 --- /dev/null +++ b/public/tiny_mce/themes/default/editor_template_src.js @@ -0,0 +1,151 @@ +function TinyMCE_default_getEditorTemplate() { + var template = new Array(); + + template['html'] = '\ +\ +\ +\ +
    \ +IFRAME\ +
    \ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +
    \ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +
    '; + + template['delta_width'] = 0; + template['delta_height'] = -40; + + return template; +} + +/** + * Insert link template function. + */ +function TinyMCE_default_getInsertLinkTemplate() { + var template = new Array(); + + template['file'] = 'link.htm'; + template['width'] = 320; + template['height'] = 200; + + // Language specific width and height addons + template['width'] += tinyMCE.getLang('lang_insert_link_delta_width', 0); + template['height'] += tinyMCE.getLang('lang_insert_link_delta_height', 0); + + return template; +} + +/** + * Insert image template function. + */ +function TinyMCE_default_getInsertImageTemplate() { + var template = new Array(); + + template['file'] = 'image.htm'; + template['width'] = 360; + template['height'] = 200; + + // Language specific width and height addons + template['width'] += tinyMCE.getLang('lang_insert_image_delta_width', 0); + template['height'] += tinyMCE.getLang('lang_insert_image_delta_height', 0); + + return template; +} + +function TinyMCE_default_handleNodeChange(editor_id, node) { + // Reset old states + tinyMCE.switchClassSticky(editor_id + '_left', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_right', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_center', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_full', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_bold', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_italic', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_underline', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_strikethrough', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_bullist', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_numlist', 'mceButtonNormal'); + + // Handle align attributes + alignNode = node; + breakOut = false; + do { + if (!alignNode.getAttribute || !alignNode.getAttribute('align')) + continue; + + switch (alignNode.getAttribute('align').toLowerCase()) { + case "left": + tinyMCE.switchClassSticky(editor_id + '_left', 'mceButtonSelected'); + breakOut = true; + break; + + case "right": + tinyMCE.switchClassSticky(editor_id + '_right', 'mceButtonSelected'); + breakOut = true; + break; + + case "middle": + case "center": + tinyMCE.switchClassSticky(editor_id + '_center', 'mceButtonSelected'); + breakOut = true; + break; + + case "justify": + tinyMCE.switchClassSticky(editor_id + '_full', 'mceButtonSelected'); + breakOut = true; + break; + } + } while (!breakOut && (alignNode = alignNode.parentNode)); + + // Handle elements + do { + switch (node.nodeName.toLowerCase()) { + case "b": + case "strong": + tinyMCE.switchClassSticky(editor_id + '_bold', 'mceButtonSelected'); + break; + + case "i": + case "em": + tinyMCE.switchClassSticky(editor_id + '_italic', 'mceButtonSelected'); + break; + + case "u": + tinyMCE.switchClassSticky(editor_id + '_underline', 'mceButtonSelected'); + break; + + case "strike": + tinyMCE.switchClassSticky(editor_id + '_strikethrough', 'mceButtonSelected'); + break; + + case "ul": + tinyMCE.switchClassSticky(editor_id + '_bullist', 'mceButtonSelected'); + break; + + case "ol": + tinyMCE.switchClassSticky(editor_id + '_numlist', 'mceButtonSelected'); + break; + } + } while ((node = node.parentNode)); +} diff --git a/public/tiny_mce/themes/default/editor_ui.css b/public/tiny_mce/themes/default/editor_ui.css new file mode 100644 index 0000000..5324fc0 --- /dev/null +++ b/public/tiny_mce/themes/default/editor_ui.css @@ -0,0 +1,100 @@ +.mceButtonNormal, .mceButtonOver, .mceButtonDown, .mceSeparator, .mceButtonDisabled, .mceButtonSelected { + margin-top: 1px; + margin-left: 1px; +} + +.mceButtonNormal { + border-top: 1px solid; + border-left: 1px solid; + border-bottom: 1px solid; + border-right: 1px solid; + border-color: #F0F0EE; + cursor: arrow; +} + +.mceButtonOver { +/* border-top: 1px solid buttonhighlight; + border-left: 1px solid buttonhighlight; + border-bottom: 1px solid buttonshadow; + border-right: 1px solid buttonshadow;*/ + border: 1px solid #0A246A; + cursor: arrow; + background-color: #B6BDD2; +} + +.mceButtonDown { +/* border-bottom: 1px solid buttonhighlight; + border-right: 1px solid buttonhighlight; + border-top: 1px solid buttonshadow; + border-left: 1px solid buttonshadow;*/ + cursor: arrow; + border: 1px solid #0A246A; + background-color: #8592B5; +} + +.mceButtonDisabled { + filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); + border-top: 1px solid; + border-left: 1px solid; + border-bottom: 1px solid; + border-right: 1px solid; + border-color: #F0F0EE; + cursor: arrow; +} + +.mceSeparator { + border-top: 1px solid buttonhighlight; + border-left: 1px solid buttonhighlight; + border-bottom: 1px solid buttonshadow; + border-right: 1px solid buttonshadow; + margin-right: 2px; + margin-left: 2px; +} + +.mceSeparatorLine { + margin:2px; + margin-left: 4px; + background-color: #F0F0EE; + border-top: 1px solid buttonshadow; + border-left: 1px solid buttonshadow; + border-bottom: 1px solid buttonhighlight; + border-right: 1px solid buttonhighlight; + width: 0px; + height: 15px; +} + +.mceSelectList { + font-family: "MS Sans Serif"; + font-size: 7pt; + font-weight: normal; + margin-top: 2px; +} + +.mceLabel, .mceLabelDisabled { + font-family: "MS Sans Serif"; + font-size: 9pt; +} + +.mceLabel { + color: #000000; +} + +.mceLabelDisabled { + cursor: text; + color: #999999; +} + +.mceEditor { + background: #F0F0EE; + border: 1px solid #cccccc; +} + +.mceEditorArea { + font-family: "MS Sans Serif"; + background: #FFFFFF; +} + +.mceToolbar { + background: #F0F0EE; + border-top: 1px solid #cccccc; +} \ No newline at end of file diff --git a/public/tiny_mce/themes/default/image.htm b/public/tiny_mce/themes/default/image.htm new file mode 100644 index 0000000..96de555 --- /dev/null +++ b/public/tiny_mce/themes/default/image.htm @@ -0,0 +1,57 @@ + + +{$lang_insert_image_title} + + + + +
    + + + + +
    + + + + + + + + + + + + + + + +
    {$lang_insert_image_title}
    {$lang_insert_image_src}:
    {$lang_insert_image_alt}:
    +
    +
    + + diff --git a/public/tiny_mce/themes/default/images/bold.gif b/public/tiny_mce/themes/default/images/bold.gif new file mode 100644 index 0000000..31f004b Binary files /dev/null and b/public/tiny_mce/themes/default/images/bold.gif differ diff --git a/public/tiny_mce/themes/default/images/bold_de_se.gif b/public/tiny_mce/themes/default/images/bold_de_se.gif new file mode 100644 index 0000000..2d86b00 Binary files /dev/null and b/public/tiny_mce/themes/default/images/bold_de_se.gif differ diff --git a/public/tiny_mce/themes/default/images/bold_fr.gif b/public/tiny_mce/themes/default/images/bold_fr.gif new file mode 100644 index 0000000..7782282 Binary files /dev/null and b/public/tiny_mce/themes/default/images/bold_fr.gif differ diff --git a/public/tiny_mce/themes/default/images/bold_ru.gif b/public/tiny_mce/themes/default/images/bold_ru.gif new file mode 100644 index 0000000..c9e89b2 Binary files /dev/null and b/public/tiny_mce/themes/default/images/bold_ru.gif differ diff --git a/public/tiny_mce/themes/default/images/bullist.gif b/public/tiny_mce/themes/default/images/bullist.gif new file mode 100644 index 0000000..12d0ec2 Binary files /dev/null and b/public/tiny_mce/themes/default/images/bullist.gif differ diff --git a/public/tiny_mce/themes/default/images/center.gif b/public/tiny_mce/themes/default/images/center.gif new file mode 100644 index 0000000..a9e13e0 Binary files /dev/null and b/public/tiny_mce/themes/default/images/center.gif differ diff --git a/public/tiny_mce/themes/default/images/cleanup.gif b/public/tiny_mce/themes/default/images/cleanup.gif new file mode 100644 index 0000000..87b8f87 Binary files /dev/null and b/public/tiny_mce/themes/default/images/cleanup.gif differ diff --git a/public/tiny_mce/themes/default/images/copy.gif b/public/tiny_mce/themes/default/images/copy.gif new file mode 100644 index 0000000..f0b5187 Binary files /dev/null and b/public/tiny_mce/themes/default/images/copy.gif differ diff --git a/public/tiny_mce/themes/default/images/cut.gif b/public/tiny_mce/themes/default/images/cut.gif new file mode 100644 index 0000000..6a969e5 Binary files /dev/null and b/public/tiny_mce/themes/default/images/cut.gif differ diff --git a/public/tiny_mce/themes/default/images/full.gif b/public/tiny_mce/themes/default/images/full.gif new file mode 100644 index 0000000..5a78c63 Binary files /dev/null and b/public/tiny_mce/themes/default/images/full.gif differ diff --git a/public/tiny_mce/themes/default/images/help.gif b/public/tiny_mce/themes/default/images/help.gif new file mode 100644 index 0000000..a5d6771 Binary files /dev/null and b/public/tiny_mce/themes/default/images/help.gif differ diff --git a/public/tiny_mce/themes/default/images/image.gif b/public/tiny_mce/themes/default/images/image.gif new file mode 100644 index 0000000..36109de Binary files /dev/null and b/public/tiny_mce/themes/default/images/image.gif differ diff --git a/public/tiny_mce/themes/default/images/indent.gif b/public/tiny_mce/themes/default/images/indent.gif new file mode 100644 index 0000000..7a17288 Binary files /dev/null and b/public/tiny_mce/themes/default/images/indent.gif differ diff --git a/public/tiny_mce/themes/default/images/italic.gif b/public/tiny_mce/themes/default/images/italic.gif new file mode 100644 index 0000000..ec03278 Binary files /dev/null and b/public/tiny_mce/themes/default/images/italic.gif differ diff --git a/public/tiny_mce/themes/default/images/italic_de_se.gif b/public/tiny_mce/themes/default/images/italic_de_se.gif new file mode 100644 index 0000000..6ce0d8d Binary files /dev/null and b/public/tiny_mce/themes/default/images/italic_de_se.gif differ diff --git a/public/tiny_mce/themes/default/images/italic_ru.gif b/public/tiny_mce/themes/default/images/italic_ru.gif new file mode 100644 index 0000000..5c2f7fe Binary files /dev/null and b/public/tiny_mce/themes/default/images/italic_ru.gif differ diff --git a/public/tiny_mce/themes/default/images/left.gif b/public/tiny_mce/themes/default/images/left.gif new file mode 100644 index 0000000..4225e00 Binary files /dev/null and b/public/tiny_mce/themes/default/images/left.gif differ diff --git a/public/tiny_mce/themes/default/images/link.gif b/public/tiny_mce/themes/default/images/link.gif new file mode 100644 index 0000000..0de4274 Binary files /dev/null and b/public/tiny_mce/themes/default/images/link.gif differ diff --git a/public/tiny_mce/themes/default/images/numlist.gif b/public/tiny_mce/themes/default/images/numlist.gif new file mode 100644 index 0000000..7ff907b Binary files /dev/null and b/public/tiny_mce/themes/default/images/numlist.gif differ diff --git a/public/tiny_mce/themes/default/images/outdent.gif b/public/tiny_mce/themes/default/images/outdent.gif new file mode 100644 index 0000000..53e89a7 Binary files /dev/null and b/public/tiny_mce/themes/default/images/outdent.gif differ diff --git a/public/tiny_mce/themes/default/images/paste.gif b/public/tiny_mce/themes/default/images/paste.gif new file mode 100644 index 0000000..a676604 Binary files /dev/null and b/public/tiny_mce/themes/default/images/paste.gif differ diff --git a/public/tiny_mce/themes/default/images/redo.gif b/public/tiny_mce/themes/default/images/redo.gif new file mode 100644 index 0000000..26a146b Binary files /dev/null and b/public/tiny_mce/themes/default/images/redo.gif differ diff --git a/public/tiny_mce/themes/default/images/right.gif b/public/tiny_mce/themes/default/images/right.gif new file mode 100644 index 0000000..88bfaf2 Binary files /dev/null and b/public/tiny_mce/themes/default/images/right.gif differ diff --git a/public/tiny_mce/themes/default/images/spacer.gif b/public/tiny_mce/themes/default/images/spacer.gif new file mode 100644 index 0000000..fc25609 Binary files /dev/null and b/public/tiny_mce/themes/default/images/spacer.gif differ diff --git a/public/tiny_mce/themes/default/images/strikethrough.gif b/public/tiny_mce/themes/default/images/strikethrough.gif new file mode 100644 index 0000000..ce7b653 Binary files /dev/null and b/public/tiny_mce/themes/default/images/strikethrough.gif differ diff --git a/public/tiny_mce/themes/default/images/underline.gif b/public/tiny_mce/themes/default/images/underline.gif new file mode 100644 index 0000000..d6b8afd Binary files /dev/null and b/public/tiny_mce/themes/default/images/underline.gif differ diff --git a/public/tiny_mce/themes/default/images/underline_ru.gif b/public/tiny_mce/themes/default/images/underline_ru.gif new file mode 100644 index 0000000..2a517e8 Binary files /dev/null and b/public/tiny_mce/themes/default/images/underline_ru.gif differ diff --git a/public/tiny_mce/themes/default/images/undo.gif b/public/tiny_mce/themes/default/images/undo.gif new file mode 100644 index 0000000..b0722d0 Binary files /dev/null and b/public/tiny_mce/themes/default/images/undo.gif differ diff --git a/public/tiny_mce/themes/default/images/unlink.gif b/public/tiny_mce/themes/default/images/unlink.gif new file mode 100644 index 0000000..dd073a2 Binary files /dev/null and b/public/tiny_mce/themes/default/images/unlink.gif differ diff --git a/public/tiny_mce/themes/default/link.htm b/public/tiny_mce/themes/default/link.htm new file mode 100644 index 0000000..013c9b1 --- /dev/null +++ b/public/tiny_mce/themes/default/link.htm @@ -0,0 +1,64 @@ + + +{$lang_insert_link_title} + + + + +
    + + + + +
    + + + + + + + + + + + + + + + +
    {$lang_insert_link_title}
    {$lang_insert_link_url}:
    {$lang_insert_link_target}:
    +
    +
    + + diff --git a/public/tiny_mce/themes/simple/editor_content.css b/public/tiny_mce/themes/simple/editor_content.css new file mode 100644 index 0000000..75290ee --- /dev/null +++ b/public/tiny_mce/themes/simple/editor_content.css @@ -0,0 +1,27 @@ +body { + background-color: #FFFFFF; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10px; + scrollbar-3dlight-color: #F0F0EE; + scrollbar-arrow-color: #676662; + scrollbar-base-color: #F0F0EE; + scrollbar-darkshadow-color: #DDDDDD; + scrollbar-face-color: #E0E0DD; + scrollbar-highlight-color: #F0F0EE; + scrollbar-shadow-color: #F0F0EE; + scrollbar-track-color: #F5F5F5; +} + +td { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10px; +} + +pre { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10px; +} + +.mceVisualAid { + border: 1px dashed #BBBBBB; +} diff --git a/public/tiny_mce/themes/simple/editor_popup.css b/public/tiny_mce/themes/simple/editor_popup.css new file mode 100644 index 0000000..81a58d5 --- /dev/null +++ b/public/tiny_mce/themes/simple/editor_popup.css @@ -0,0 +1,41 @@ +body { + background-color: #F0F0EE; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; + scrollbar-3dlight-color: #F0F0EE; + scrollbar-arrow-color: #676662; + scrollbar-base-color: #F0F0EE; + scrollbar-darkshadow-color: #DDDDDD; + scrollbar-face-color: #E0E0DD; + scrollbar-highlight-color: #F0F0EE; + scrollbar-shadow-color: #F0F0EE; + scrollbar-track-color: #F5F5F5; +} + +td { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; +} + +input { + background: #FFFFFF; + border: 1px solid #cccccc; +} + +td, input, select, textarea { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10px; +} + +input, select, textarea { + border: 1px solid #808080; +} + +.input_noborder { + border: 0px solid #808080; +} + +.title { + font-size: 12px; + font-weight: bold; +} \ No newline at end of file diff --git a/public/tiny_mce/themes/simple/editor_template.js b/public/tiny_mce/themes/simple/editor_template.js new file mode 100644 index 0000000..8cddcf1 --- /dev/null +++ b/public/tiny_mce/themes/simple/editor_template.js @@ -0,0 +1,20 @@ +function TinyMCE_simple_getEditorTemplate(){var template=new Array();template['html']='\ +\ +\ +\ +
    \ +IFRAME\ +
    \ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +
    ';template['delta_width']=0;template['delta_height']=-20;return template;}function TinyMCE_simple_handleNodeChange(editor_id,node){tinyMCE.switchClassSticky(editor_id+'_bold','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_italic','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_underline','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_strikethrough','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_bullist','mceButtonNormal');tinyMCE.switchClassSticky(editor_id+'_numlist','mceButtonNormal');do{switch(node.nodeName.toLowerCase()){case "b":case "strong":tinyMCE.switchClassSticky(editor_id+'_bold','mceButtonSelected');break;case "i":case "em":tinyMCE.switchClassSticky(editor_id+'_italic','mceButtonSelected');break;case "u":tinyMCE.switchClassSticky(editor_id+'_underline','mceButtonSelected');break;case "strike":tinyMCE.switchClassSticky(editor_id+'_strikethrough','mceButtonSelected');break;case "ul":tinyMCE.switchClassSticky(editor_id+'_bullist','mceButtonSelected');break;case "ol":tinyMCE.switchClassSticky(editor_id+'_numlist','mceButtonSelected');break;}}while((node=node.parentNode));} \ No newline at end of file diff --git a/public/tiny_mce/themes/simple/editor_template_src.js b/public/tiny_mce/themes/simple/editor_template_src.js new file mode 100644 index 0000000..3dbf187 --- /dev/null +++ b/public/tiny_mce/themes/simple/editor_template_src.js @@ -0,0 +1,70 @@ +function TinyMCE_simple_getEditorTemplate() { + var template = new Array(); + + template['html'] = '\ +\ +\ +\ +
    \ +IFRAME\ +
    \ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +
    '; + + template['delta_width'] = 0; + template['delta_height'] = -20; + + return template; +} + +function TinyMCE_simple_handleNodeChange(editor_id, node) { + // Reset old states + tinyMCE.switchClassSticky(editor_id + '_bold', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_italic', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_underline', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_strikethrough', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_bullist', 'mceButtonNormal'); + tinyMCE.switchClassSticky(editor_id + '_numlist', 'mceButtonNormal'); + + // Handle elements + do { + switch (node.nodeName.toLowerCase()) { + case "b": + case "strong": + tinyMCE.switchClassSticky(editor_id + '_bold', 'mceButtonSelected'); + break; + + case "i": + case "em": + tinyMCE.switchClassSticky(editor_id + '_italic', 'mceButtonSelected'); + break; + + case "u": + tinyMCE.switchClassSticky(editor_id + '_underline', 'mceButtonSelected'); + break; + + case "strike": + tinyMCE.switchClassSticky(editor_id + '_strikethrough', 'mceButtonSelected'); + break; + + case "ul": + tinyMCE.switchClassSticky(editor_id + '_bullist', 'mceButtonSelected'); + break; + + case "ol": + tinyMCE.switchClassSticky(editor_id + '_numlist', 'mceButtonSelected'); + break; + } + } while ((node = node.parentNode)); +} diff --git a/public/tiny_mce/themes/simple/editor_ui.css b/public/tiny_mce/themes/simple/editor_ui.css new file mode 100644 index 0000000..7f57981 --- /dev/null +++ b/public/tiny_mce/themes/simple/editor_ui.css @@ -0,0 +1,100 @@ +.mceButtonNormal, .mceButtonOver, .mceButtonDown, .mceSeparator, .mceButtonDisabled, .mceButtonSelected { + margin-top: 1px; + margin-left: 1px; +} + +.mceButtonNormal { + border-top: 1px solid; + border-left: 1px solid; + border-bottom: 1px solid; + border-right: 1px solid; + border-color: #F0F0EE; + cursor: arrow; +} + +.mceButtonOver { + border: 1px solid #0A246A; + cursor: arrow; + background-color: #B6BDD2; +} + +.mceButtonDown { + cursor: arrow; + border: 1px solid #0A246A; + background-color: #8592B5; +} + +.mceButtonSelected { + border: 1px solid; + border-color: #C0C0BB; + cursor: arrow; +} + +.mceButtonDisabled { + filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); + -moz-opacity:0.3; + opacity: 0.3; + border-top: 1px solid; + border-left: 1px solid; + border-bottom: 1px solid; + border-right: 1px solid; + border-color: #F0F0EE; + cursor: arrow; +} + +.mceSeparator { + border-top: 1px solid buttonhighlight; + border-left: 1px solid buttonhighlight; + border-bottom: 1px solid buttonshadow; + border-right: 1px solid buttonshadow; + margin-right: 2px; + margin-left: 2px; +} + +.mceSeparatorLine { + margin:2px; + margin-left: 4px; + background-color: #F0F0EE; + border-top: 1px solid buttonshadow; + border-left: 1px solid buttonshadow; + border-bottom: 1px solid buttonhighlight; + border-right: 1px solid buttonhighlight; + width: 0px; + height: 15px; +} + +.mceSelectList { + font-family: "MS Sans Serif"; + font-size: 7pt; + font-weight: normal; + margin-top: 2px; +} + +.mceLabel, .mceLabelDisabled { + font-family: "MS Sans Serif"; + font-size: 9pt; +} + +.mceLabel { + color: #000000; +} + +.mceLabelDisabled { + cursor: text; + color: #999999; +} + +.mceEditor { + background: #F0F0EE; + border: 1px solid #cccccc; +} + +.mceEditorArea { + font-family: "MS Sans Serif"; + background: #FFFFFF; +} + +.mceToolbar { + background: #F0F0EE; + border-top: 1px solid #cccccc; +} \ No newline at end of file diff --git a/public/tiny_mce/themes/simple/images/bold.gif b/public/tiny_mce/themes/simple/images/bold.gif new file mode 100644 index 0000000..31f004b Binary files /dev/null and b/public/tiny_mce/themes/simple/images/bold.gif differ diff --git a/public/tiny_mce/themes/simple/images/bold_de_se.gif b/public/tiny_mce/themes/simple/images/bold_de_se.gif new file mode 100644 index 0000000..2d86b00 Binary files /dev/null and b/public/tiny_mce/themes/simple/images/bold_de_se.gif differ diff --git a/public/tiny_mce/themes/simple/images/bold_fr.gif b/public/tiny_mce/themes/simple/images/bold_fr.gif new file mode 100644 index 0000000..7782282 Binary files /dev/null and b/public/tiny_mce/themes/simple/images/bold_fr.gif differ diff --git a/public/tiny_mce/themes/simple/images/bold_ru.gif b/public/tiny_mce/themes/simple/images/bold_ru.gif new file mode 100644 index 0000000..c9e89b2 Binary files /dev/null and b/public/tiny_mce/themes/simple/images/bold_ru.gif differ diff --git a/public/tiny_mce/themes/simple/images/bullist.gif b/public/tiny_mce/themes/simple/images/bullist.gif new file mode 100644 index 0000000..12d0ec2 Binary files /dev/null and b/public/tiny_mce/themes/simple/images/bullist.gif differ diff --git a/public/tiny_mce/themes/simple/images/cleanup.gif b/public/tiny_mce/themes/simple/images/cleanup.gif new file mode 100644 index 0000000..87b8f87 Binary files /dev/null and b/public/tiny_mce/themes/simple/images/cleanup.gif differ diff --git a/public/tiny_mce/themes/simple/images/italic.gif b/public/tiny_mce/themes/simple/images/italic.gif new file mode 100644 index 0000000..ec03278 Binary files /dev/null and b/public/tiny_mce/themes/simple/images/italic.gif differ diff --git a/public/tiny_mce/themes/simple/images/italic_de_se.gif b/public/tiny_mce/themes/simple/images/italic_de_se.gif new file mode 100644 index 0000000..6ce0d8d Binary files /dev/null and b/public/tiny_mce/themes/simple/images/italic_de_se.gif differ diff --git a/public/tiny_mce/themes/simple/images/italic_ru.gif b/public/tiny_mce/themes/simple/images/italic_ru.gif new file mode 100644 index 0000000..5c2f7fe Binary files /dev/null and b/public/tiny_mce/themes/simple/images/italic_ru.gif differ diff --git a/public/tiny_mce/themes/simple/images/numlist.gif b/public/tiny_mce/themes/simple/images/numlist.gif new file mode 100644 index 0000000..7ff907b Binary files /dev/null and b/public/tiny_mce/themes/simple/images/numlist.gif differ diff --git a/public/tiny_mce/themes/simple/images/redo.gif b/public/tiny_mce/themes/simple/images/redo.gif new file mode 100644 index 0000000..26a146b Binary files /dev/null and b/public/tiny_mce/themes/simple/images/redo.gif differ diff --git a/public/tiny_mce/themes/simple/images/spacer.gif b/public/tiny_mce/themes/simple/images/spacer.gif new file mode 100644 index 0000000..fc25609 Binary files /dev/null and b/public/tiny_mce/themes/simple/images/spacer.gif differ diff --git a/public/tiny_mce/themes/simple/images/strikethrough.gif b/public/tiny_mce/themes/simple/images/strikethrough.gif new file mode 100644 index 0000000..ce7b653 Binary files /dev/null and b/public/tiny_mce/themes/simple/images/strikethrough.gif differ diff --git a/public/tiny_mce/themes/simple/images/underline.gif b/public/tiny_mce/themes/simple/images/underline.gif new file mode 100644 index 0000000..0809c02 Binary files /dev/null and b/public/tiny_mce/themes/simple/images/underline.gif differ diff --git a/public/tiny_mce/themes/simple/images/underline_ru.gif b/public/tiny_mce/themes/simple/images/underline_ru.gif new file mode 100644 index 0000000..2a517e8 Binary files /dev/null and b/public/tiny_mce/themes/simple/images/underline_ru.gif differ diff --git a/public/tiny_mce/themes/simple/images/undo.gif b/public/tiny_mce/themes/simple/images/undo.gif new file mode 100644 index 0000000..b0722d0 Binary files /dev/null and b/public/tiny_mce/themes/simple/images/undo.gif differ diff --git a/public/tiny_mce/tiny_mce.js b/public/tiny_mce/tiny_mce.js new file mode 100644 index 0000000..3124ffb --- /dev/null +++ b/public/tiny_mce/tiny_mce.js @@ -0,0 +1,12 @@ +/** + * $RCSfile: tiny_mce_src.js,v $ + * $Revision: 1.210 $ + * $Date: 2005/06/15 09:05:32 $ + * + * @author Moxiecode + * @copyright Copyright 2004, Moxiecode Systems AB, All rights reserved. + */ + function TinyMCE(){this.instances=new Array();this.stickyClassesLookup=new Array();this.windowArgs=new Array();this.loadedFiles=new Array();this.configs=new Array();this.currentConfig=0;this.eventHandlers=new Array();this.isMSIE=(navigator.appName=="Microsoft Internet Explorer");this.isMSIE5=this.isMSIE&&(navigator.userAgent.indexOf('MSIE 5')!=-1);this.isMSIE5_0=this.isMSIE&&(navigator.userAgent.indexOf('MSIE 5.0')!=-1);this.isGecko=navigator.userAgent.indexOf('Gecko')!=-1;this.isSafari=navigator.userAgent.indexOf('Safari')!=-1;this.isMac=navigator.userAgent.indexOf('Mac')!=-1;this.dialogCounter=0;this.idCounter=0;};TinyMCE.prototype.defParam=function(key,def_val){this.settings[key]=tinyMCE.getParam(key,def_val);};TinyMCE.prototype.init=function(settings){var theme;this.settings=settings;if(typeof(document.execCommand)=='undefined')return;if(!tinyMCE.baseURL){var elements=document.getElementsByTagName('script');for(var i=0;i');this.loadedFiles[this.loadedFiles.length]=url;};TinyMCE.prototype.loadCSS=function(url){for(var i=0;i');this.loadedFiles[this.loadedFiles.length]=url;};TinyMCE.prototype.importCSS=function(doc,css_file){if(tinyMCE.isMSIE)var styleSheet=doc.createStyleSheet(css_file);else{var elm=doc.createElement("link");elm.rel="stylesheet";elm.href=css_file;if(headArr=doc.getElementsByTagName("head"))headArr[0].appendChild(elm);}};TinyMCE.prototype.confirmAdd=function(e,settings){var elm=tinyMCE.isMSIE?event.srcElement:e.target;var elementId=elm.name?elm.name:elm.id;tinyMCE.settings=settings;if(!elm.getAttribute('mce_noask')&&confirm(tinyMCELang['lang_edit_confirm']))tinyMCE.addMCEControl(elm,elementId);elm.setAttribute('mce_noask','true');};TinyMCE.prototype.updateContent=function(form_element_name){var formElement=document.getElementById(form_element_name);for(var n in tinyMCE.instances){var inst=tinyMCE.instances[n];if(typeof(inst)=="function")continue;inst.switchSettings();if(inst.formElement==formElement){var doc=inst.getDoc();tinyMCE._setHTML(doc,inst.formElement.value);if(!tinyMCE.isMSIE)doc.body.innerHTML=tinyMCE._cleanupHTML(doc,this.settings,doc.body,inst.visualAid);}}};TinyMCE.prototype.addMCEControl=function(replace_element,form_element_name,target_document){var id="mce_editor_"+tinyMCE.idCounter++;var inst=new TinyMCEControl(tinyMCE.settings);inst.editorId=id;this.instances[id]=inst;inst.onAdd(replace_element,form_element_name,target_document);};TinyMCE.prototype.triggerSave=function(skip_cleanup,skip_callback){for(var n in tinyMCE.instances){var inst=tinyMCE.instances[n];if(typeof(inst)=="function")continue;inst.switchSettings();tinyMCE.settings['preformatted']=false;if(typeof(skip_cleanup)=="undefined")skip_cleanup=false;if(typeof(skip_callback)=="undefined")skip_callback=false;tinyMCE._setHTML(inst.getDoc(),inst.getBody().innerHTML);var htm=skip_cleanup?inst.getBody().innerHTML:tinyMCE._cleanupHTML(inst.getDoc(),this.settings,inst.getBody(),this.visualAid,true);if(tinyMCE.settings["encoding"]=="xml"||tinyMCE.settings["encoding"]=="html")htm=tinyMCE.convertStringToXML(htm);if(!skip_callback&&tinyMCE.settings['save_callback']!="")var content=eval(tinyMCE.settings['save_callback']+"(inst.formTargetElementId,htm,inst.getBody());");if((typeof(content)!="undefined")&&content!=null)htm=content;htm=tinyMCE.regexpReplace(htm,"(","(","gi");htm=tinyMCE.regexpReplace(htm,")",")","gi");htm=tinyMCE.regexpReplace(htm,";",";","gi");htm=tinyMCE.regexpReplace(htm,""",""","gi");htm=tinyMCE.regexpReplace(htm,"^","^","gi");if(inst.formElement)inst.formElement.value=htm;}};TinyMCE.prototype._convertOnClick=function(node){if(tinyMCE.isMSIE5)return;var elms=node.getElementsByTagName("a");for(var i=0;i","gi");content=tinyMCE.regexpReplace(content,"\r","
    ","gi");content=tinyMCE.regexpReplace(content,"\n","
    ","gi");}content=tinyMCE._customCleanup("insert_to_editor",content);if(tinyMCE.isMSIE){window.setInterval('try{tinyMCE.getCSSClasses(document.frames["'+editor_id+'"].document, "'+editor_id+'");}catch(e){}',500);if(tinyMCE.settings["force_br_newlines"])document.frames[editor_id].document.styleSheets[0].addRule("p","margin: 0px;");var body=document.frames[editor_id].document.body;tinyMCE.addEvent(body,"beforepaste",TinyMCE.prototype.eventPatch);tinyMCE.addEvent(body,"beforecut",TinyMCE.prototype.eventPatch);tinyMCE.addEvent(body,"paste",TinyMCE.prototype.eventPatch);body.editorId=editor_id;}if(!tinyMCE.isMSIE){var contentElement=inst.getDoc().createElement("body");var doc=inst.getDoc();contentElement.innerHTML=content;if(tinyMCE.settings['force_p_newlines'])content=content.replace(new RegExp('<>','g'),"");if(tinyMCE.settings['cleanup_on_startup'])inst.getBody().innerHTML=tinyMCE._cleanupHTML(doc,this.settings,contentElement);else{content=tinyMCE.regexpReplace(content,"","","gi");content=tinyMCE.regexpReplace(content,"","","gi");inst.getBody().innerHTML=content;}inst.convertAllRelativeURLs();}else{if(tinyMCE.settings['cleanup_on_startup']){tinyMCE._setHTML(inst.getDoc(),content);eval('try {inst.getBody().innerHTML = tinyMCE._cleanupHTML(inst.contentDocument, this.settings, inst.getBody());} catch(e) {}');}else inst.getBody().innerHTML=content;}tinyMCE._convertOnClick(inst.getBody());var parentElm=document.getElementById(inst.editorId+'_parent');if(parentElm.lastChild.nodeName.toLowerCase()=="input")inst.formElement=parentElm.lastChild;else inst.formElement=parentElm.nextSibling;tinyMCE.handleVisualAid(inst.getBody(),true,tinyMCE.settings['visual']);tinyMCE.executeCallback('setupcontent_callback','_setupContent',0,editor_id,inst.getBody(),inst.getDoc());if(!tinyMCE.isMSIE)TinyMCE.prototype.addEventHandlers(editor_id);inst.startContent=inst.getBody().innerHTML;tinyMCE.selectedInstance=inst;tinyMCE.selectedElement=inst.contentWindow.document.body;tinyMCE.triggerNodeChange(false,true);tinyMCE._customCleanup("insert_to_editor_dom",inst.contentWindow.document.body);};TinyMCE.prototype.cancelEvent=function(e){if(tinyMCE.isMSIE){e.returnValue=false;e.cancelBubble=true;}else e.preventDefault();};TinyMCE.prototype.removeTinyMCEFormElements=function(form_obj){for(var i=0;i");rng.collapse(false);rng.select();tinyMCE.triggerNodeChange(false);return false;}}if(e.keyCode==8||e.keyCode==46){tinyMCE.selectedElement=e.target;tinyMCE.linkElement=tinyMCE.getParentElement(e.target,"a");tinyMCE.imgElement=tinyMCE.getParentElement(e.target,"img");tinyMCE.triggerNodeChange(false);}return false;break;case "keyup":case "keydown":if(e.target.editorId)tinyMCE.selectedInstance=tinyMCE.instances[e.target.editorId];else return;if(tinyMCE.selectedInstance)tinyMCE.selectedInstance.switchSettings();if(tinyMCE.isGecko&&tinyMCE.settings['force_p_newlines']&&(e.keyCode==8||e.keyCode==46)&&!e.shiftKey){if(tinyMCE.selectedInstance._handleBackSpace(e.type)){e.preventDefault();return false;}}tinyMCE.selectedElement=null;tinyMCE.selectedNode=null;var elm=tinyMCE.selectedInstance.getFocusElement();tinyMCE.linkElement=tinyMCE.getParentElement(elm,"a");tinyMCE.imgElement=tinyMCE.getParentElement(elm,"img");tinyMCE.selectedElement=elm;if(tinyMCE.isGecko&&e.type=="keyup"&&e.keyCode==9)tinyMCE.handleVisualAid(tinyMCE.selectedInstance.getBody(),true,tinyMCE.settings['visual']);if(tinyMCE.isGecko&&tinyMCE.settings['document_base_url']!=""+document.location.href&&e.type=="keyup"&&e.ctrlKey&&e.keyCode==86)tinyMCE.selectedInstance.fixBrokenURLs();if(tinyMCE.isMSIE&&tinyMCE.settings['custom_undo_redo']){var keys=new Array(13,45,36,35,33,34,37,38,39,40);var posKey=false;for(var i=0;i18&&e.keyCode!=255)){tinyMCE.selectedInstance.execCommand("mceAddUndoLevel");tinyMCE.selectedInstance.typing=true;tinyMCE.triggerNodeChange(false);}if(posKey&&e.type=="keyup")tinyMCE.triggerNodeChange(false);var keys=new Array(8,46);for(var i=0;i0){for(var i=0;i"+this.convertStringToXML(String.fromCharCode(160))+"";if(tinyMCE.isMSIE&&elementName=="script")return "<"+elementName+elementAttribs+">"+node.text+"";if(node.hasChildNodes()){if(elementName=="p"&&tinyMCE.cleanup_force_br_newlines)output+="";else output+="<"+elementName+elementAttribs+">";for(var i=0;i
    ";else output+="";}else{if(openTag)output+="<"+elementName+elementAttribs+">";else{output+="<"+elementName+elementAttribs+" />";}}return output;case 3:if(node.parentNode.nodeName.toLowerCase()=="script")return node.nodeValue;return this.convertStringToXML(node.nodeValue);case 8:return "";default:return "[UNKNOWN NODETYPE "+node.nodeType+"]";}};TinyMCE.prototype.convertStringToXML=function(html_data){var output="";for(var i=0;i127)output+='&#'+chr+";";else output+=String.fromCharCode(chr);continue;}if(tinyMCE.settings['entity_encoding']=="raw"){output+=String.fromCharCode(chr);continue;}if(typeof(tinyMCE.cleanup_entities["c"+chr])!='undefined'&&tinyMCE.cleanup_entities["c"+chr]!='')output+='&'+tinyMCE.cleanup_entities["c"+chr]+';';else output+=''+String.fromCharCode(chr);}return output;};TinyMCE.prototype._getCleanupElementName=function(chunk){var pos;if(chunk.charAt(0)=='+')chunk=chunk.substring(1);if((pos=chunk.indexOf('/'))!=-1)chunk=chunk.substring(0,pos);if((pos=chunk.indexOf('['))!=-1)chunk=chunk.substring(0,pos);return chunk;};TinyMCE.prototype._initCleanup=function(){var validElements=tinyMCE.settings["valid_elements"];validElements=validElements.split(',');var extendedValidElements=tinyMCE.settings["extended_valid_elements"];extendedValidElements=extendedValidElements.split(',');for(var i=0;i[ \n\r]*
    [ \n\r]*

    ','
    ','gi');element.innerHTML=tinyMCE.regexpReplace(element.innerHTML,'','','gi');}var html=this.cleanupNode(element);if(tinyMCE.settings['debug'])alert("Cleanup process executed in: "+(new Date().getTime()-startTime)+" ms.");html=tinyMCE.regexpReplace(html,'


    ','
    ');html=tinyMCE.regexpReplace(html,'

     


     

    ','
    ');if(!tinyMCE.isMSIE)html=html.replace(new RegExp('','g'),"");if(tinyMCE.settings['apply_source_formatting']){html=html.replace(new RegExp('<(p|div)([^>]*)>','g'),"\n<$1$2>\n");html=html.replace(new RegExp('<\/(p|div)([^>]*)>','g'),"\n\n");html=html.replace(new RegExp('
    ','g'),"
    \n");}if(tinyMCE.settings['force_br_newlines']){var re=new RegExp('

     

    ','g');html=html.replace(re,"
    ");}if(tinyMCE.settings['force_p_newlines']){var re=new RegExp('<>','g');html=html.replace(re,"");}if(tinyMCE.settings['remove_linebreaks'])html=html.replace(new RegExp('\r|\n','g'),' ');html=tinyMCE._customCleanup(on_save?"get_from_editor":"insert_to_editor",html);var chk=tinyMCE.regexpReplace(html,"[ \t\r\n]","");if(chk=="
    "||chk=="
    "||chk=="

     

    "||chk=="

     

    "||chk=="

    ")html="";if(tinyMCE.settings["preformatted"])return "
    "+html+"
    ";return html;};TinyMCE.prototype.setAttrib=function(element,name,value,no_fix_value){if(!no_fix_value&&value!=null){var re=new RegExp('[^0-9%]','g');value=value.replace(re,'');}if(value!=null&&value!="")element.setAttribute(name,value);else element.removeAttribute(name);if(value!=null&&value!="")element.setAttribute(name,value);else element.removeAttribute(name);};TinyMCE.prototype.insertLink=function(href,target,title,onclick,style_class){this.execCommand("mceAddUndoLevel");if(this.selectedInstance&&this.selectedElement&&this.selectedElement.nodeName.toLowerCase()=="img"){var doc=this.selectedInstance.getDoc();var linkElement=tinyMCE.getParentElement(this.selectedElement,"a");var newLink=false;if(!linkElement){linkElement=doc.createElement("a");newLink=true;}href=eval(tinyMCE.settings['urlconverter_callback']+"(href, linkElement);");tinyMCE.setAttrib(linkElement,'href',href);tinyMCE.setAttrib(linkElement,'target',target);tinyMCE.setAttrib(linkElement,'title',title);tinyMCE.setAttrib(linkElement,'mce_onclick',onclick);tinyMCE.setAttrib(linkElement,'class',style_class);if(newLink){linkElement.appendChild(this.selectedElement.cloneNode(true));this.selectedElement.parentNode.replaceChild(linkElement,this.selectedElement);}return;}if(!this.linkElement&&this.selectedInstance){this.selectedInstance.contentDocument.execCommand("createlink",false,"#mce_temp_url#");tinyMCE.linkElement=this.getElementByAttributeValue(this.selectedInstance.contentDocument.body,"a","href","#mce_temp_url#");var elementArray=this.getElementsByAttributeValue(this.selectedInstance.contentDocument.body,"a","href","#mce_temp_url#");for(var i=0;i=strTok2.length){for(var i=0;i=strTok2.length||strTok1[i]!=strTok2[i]){breakPoint=i+1;break;}}}if(strTok1.length=strTok1.length||strTok1[i]!=strTok2[i]){breakPoint=i+1;break;}}}if(breakPoint==1)return url_to_relative;for(var i=0;i<(strTok1.length-(breakPoint-1));i++)outputString+="../";for(var i=breakPoint-1;i=0;i--){if(baseURLParts[i].length==0)continue;newBaseURLParts[newBaseURLParts.length]=baseURLParts[i];}baseURLParts=newBaseURLParts.reverse();var newRelURLParts=new Array();var numBack=0;for(var i=relURLParts.length-1;i>=0;i--){if(relURLParts[i].length==0||relURLParts[i]==".")continue;if(relURLParts[i]=='..'){numBack++;continue;}if(numBack>0){numBack--;continue;}newRelURLParts[newRelURLParts.length]=relURLParts[i];}relURLParts=newRelURLParts.reverse();var len=baseURLParts.length-numBack;var absPath=(len<=0?"":"/")+baseURLParts.slice(0,len).join('/')+"/"+relURLParts.join('/');var start="",end="";if(baseURL['protocol'])start+=baseURL['protocol']+"://";if(baseURL['host'])start+=baseURL['host'];if(baseURL['port'])start+=":"+baseURL['port'];if(relURL['query'])end+="?"+relURL['query'];if(relURL['anchor'])end+="#"+relURL['anchor'];if(relative_url.charAt(relative_url.length-1)=="/")end+="/";return start+absPath+end;};TinyMCE.prototype.getParam=function(name,default_value,strip_whitespace,split_chr){var value=(typeof(this.settings[name])=="undefined")?default_value:this.settings[name];if(value=="true"||value=="false")return(value=="true");if(strip_whitespace)value=tinyMCE.regexpReplace(value,"[ \t\r\n]","");if(typeof(split_chr)!="undefined"&&split_chr!=null){value=value.split(split_chr);var outArray=new Array();for(var i=0;i0);if(tinyMCE.settings['custom_undo_redo']){undoIndex=inst.undoIndex;undoLevels=inst.undoLevels.length;}tinyMCE.executeCallback('handleNodeChangeCallback','_handleNodeChange',0,editorId,elm,undoIndex,undoLevels,inst.visualAid,anySelection);}}if(this.selectedInstance&&(typeof(focus)=="undefined"||focus))this.selectedInstance.contentWindow.focus();};TinyMCE.prototype._customCleanup=function(type,content){var customCleanup=tinyMCE.settings['cleanup_callback'];if(customCleanup!=""&&eval("typeof("+customCleanup+")")!="undefined")content=eval(customCleanup+"(type, content);");var plugins=tinyMCE.getParam('plugins','',true,',');for(var i=0;i
    ';div.innerHTML=html;document.body.appendChild(div);tinyMCE._currentDialog=id;}}};TinyMCE.prototype.closeDialog=function(){if(tinyMCE.settings["dialog_type"]=="div"){var div=document.getElementById(tinyMCE._currentDialog);if(div)div.parentNode.removeChild(div);}else window.close();};TinyMCE.prototype.getVisualAidClass=function(class_name,state){var aidClass=tinyMCE.settings['visual_table_class'];if(typeof(state)=="undefined")state=tinyMCE.settings['visual'];var classNames=new Array();var ar=class_name.split(' ');for(var i=0;i0)className+=" ";className+=classNames[i];}return className;};TinyMCE.prototype.handleVisualAid=function(element,deep,state){if(!element)return;var tableElement=null;switch(element.nodeName.toLowerCase()){case "table":var oldW=element.style.width;var oldH=element.style.height;element.className=tinyMCE.getVisualAidClass(element.className,state&&element.getAttribute("border")==0);element.style.width=oldW;element.style.height=oldH;for(var y=0;y

    ','g');html_content=html_content.replace(re,"
    ");}doc.body.innerHTML=html_content;if(tinyMCE.isMSIE&&tinyMCE.settings['fix_content_duplication']){var paras=doc.getElementsByTagName("P");for(var i=0;i<\/o:p>","
    ");html=tinyMCE.regexpReplace(html," <\/o:p>","");html=tinyMCE.regexpReplace(html,"","");html=tinyMCE.regexpReplace(html,"

    <\/p>","");html=tinyMCE.regexpReplace(html,"

    <\/p>\r\n

    <\/p>","");html=tinyMCE.regexpReplace(html,"

     <\/p>","
    ");html=tinyMCE.regexpReplace(html,"

    \s*(

    \s*)?","

    ");html=tinyMCE.regexpReplace(html,"<\/p>\s*(<\/p>\s*)?","

    ");}doc.body.innerHTML=html;}};TinyMCE.prototype.getImageSrc=function(str){var pos=-1;if(!str)return "";if((pos=str.indexOf('this.src='))!=-1){var src=str.substring(pos+10);src=src.substring(0,src.indexOf('\''));return src;}return "";};TinyMCE.prototype._getElementById=function(element_id){var elm=document.getElementById(element_id);if(!elm){for(var j=0;j0){var csses=null;eval("try {var csses = tinyMCE.isMSIE ? doc.styleSheets(0).rules : doc.styleSheets[0].cssRules;} catch(e) {}");if(!csses)return new Array();for(var i=0;i0)tinyMCE.cssClasses=output;return output;};TinyMCE.prototype.regexpReplace=function(in_str,reg_exp,replace_str,opts){if(typeof(opts)=="undefined")opts='g';var re=new RegExp(reg_exp,opts);return in_str.replace(re,replace_str);};TinyMCE.prototype.cleanupEventStr=function(str){str=""+str;str=str.replace('function anonymous()\n{\n','');str=str.replace('\n}','');return str;};TinyMCE.prototype.getAbsPosition=function(node){var pos=new Object();pos.absLeft=pos.absTop=0;var parentNode=node;while(parentNode){pos.absLeft+=parentNode.offsetLeft;pos.absTop+=parentNode.offsetTop;parentNode=parentNode.offsetParent;}return pos;};TinyMCE.prototype.openFileBrowser=function(field_name,url,type,win){var cb=tinyMCE.getParam("file_browser_callback");this.setWindowArg("window",win);if(eval('typeof('+cb+')')=="undefined")alert("Callback function: "+cb+" could not be found.");else eval(cb+"(field_name, url, type, win);");};TinyMCE.prototype.getControlHTML=function(control_name){var themePlugins=tinyMCE.getParam('plugins','',true,',');var templateFunction;for(var i=themePlugins.length;i>=0;i--){templateFunction='TinyMCE_'+themePlugins[i]+"_getControlHTML";if(eval("typeof("+templateFunction+")")!='undefined'){var html=eval(templateFunction+"('"+control_name+"');");if(html!="")return tinyMCE.replaceVar(html,"pluginurl",tinyMCE.baseURL+"/plugins/"+themePlugins[i]);}}return eval('TinyMCE_'+tinyMCE.settings['theme']+"_getControlHTML"+"('"+control_name+"');");};TinyMCE.prototype._themeExecCommand=function(editor_id,element,command,user_interface,value){var themePlugins=tinyMCE.getParam('plugins','',true,',');var templateFunction;for(var i=themePlugins.length;i>=0;i--){templateFunction='TinyMCE_'+themePlugins[i]+"_execCommand";if(eval("typeof("+templateFunction+")")!='undefined'){if(eval(templateFunction+"(editor_id, element, command, user_interface, value);"))return true;}}templateFunction='TinyMCE_'+tinyMCE.settings['theme']+"_execCommand";if(eval("typeof("+templateFunction+")")!='undefined')return eval(templateFunction+"(editor_id, element, command, user_interface, value);");return false;};TinyMCE.prototype._getThemeFunction=function(suffix,skip_plugins){if(skip_plugins)return 'TinyMCE_'+tinyMCE.settings['theme']+suffix;var themePlugins=tinyMCE.getParam('plugins','',true,',');var templateFunction;for(var i=themePlugins.length;i>=0;i--){templateFunction='TinyMCE_'+themePlugins[i]+suffix;if(eval("typeof("+templateFunction+")")!='undefined')return templateFunction;}return 'TinyMCE_'+tinyMCE.settings['theme']+suffix;};TinyMCE.prototype.isFunc=function(func_name){if(func_name==null||func_name=="")return false;return eval("typeof("+func_name+")")!="undefined";};TinyMCE.prototype.exec=function(func_name,args){var str=func_name+'(';for(var i=3;i1&&tinyMCE.currentConfig!=this.settings['index']){tinyMCE.settings=this.settings;tinyMCE.currentConfig=this.settings['index'];}};TinyMCEControl.prototype.fixBrokenURLs=function(){var body=this.getBody();var elms=body.getElementsByTagName("img");for(var i=0;i0)rng.selectNodeContents(nodes[0]);else rng.selectNodeContents(node);}else rng.selectNode(node);if(collapse){if(!to_start&&node.nodeType==3){rng.setStart(node,node.nodeValue.length);rng.setEnd(node,node.nodeValue.length);}else rng.collapse(to_start);}sel.removeAllRanges();sel.addRange(rng);}this.scrollToNode(node);tinyMCE.selectedElement=null;if(node.nodeType==1)tinyMCE.selectedElement=node;};TinyMCEControl.prototype.scrollToNode=function(node){var pos=tinyMCE.getAbsPosition(node);var doc=this.getDoc();var scrollX=doc.body.scrollLeft+doc.documentElement.scrollLeft;var scrollY=doc.body.scrollTop+doc.documentElement.scrollTop;var height=tinyMCE.isMSIE?document.getElementById(this.editorId).style.pixelHeight:this.targetElement.clientHeight;if(!tinyMCE.settings['auto_resize']&&!(node.absTop>scrollY&&node.absTop<(scrollY-25+height)))this.contentWindow.scrollTo(pos.absLeft,pos.absTop-height+25);};TinyMCEControl.prototype.getBody=function(){return this.getDoc().body;};TinyMCEControl.prototype.getDoc=function(){return this.contentWindow.document;};TinyMCEControl.prototype.getWin=function(){return this.contentWindow;};TinyMCEControl.prototype.getSel=function(){if(tinyMCE.isMSIE)return this.getDoc().selection;var sel=this.contentWindow.getSelection();if(tinyMCE.isSafari&&!sel.getRangeAt){var newSel=new Object();var doc=this.getDoc();function getRangeAt(idx){var rng=new Object();rng.startContainer=this.focusNode;rng.endContainer=this.anchorNode;rng.commonAncestorContainer=this.focusNode;rng.createContextualFragment=function(html){if(html.charAt(0)=='<'){var elm=doc.createElement("div");elm.innerHTML=html;return elm.firstChild;}return doc.createTextNode("UNSUPPORTED, DUE TO LIMITATIONS IN SAFARI!");};rng.deleteContents=function(){doc.execCommand("Delete",false,"");};return rng;}newSel.focusNode=sel.baseNode;newSel.focusOffset=sel.baseOffset;newSel.anchorNode=sel.extentNode;newSel.anchorOffset=sel.extentOffset;newSel.getRangeAt=getRangeAt;newSel.text=""+sel;newSel.realSelection=sel;newSel.toString=function(){return this.text;};return newSel;}return sel;};TinyMCEControl.prototype.getRng=function(){var sel=this.getSel();if(sel==null)return null;if(tinyMCE.isMSIE)return sel.createRange();return this.getSel().getRangeAt(0);};TinyMCEControl.prototype._insertPara=function(e){function isEmpty(para){function isEmptyHTML(html){return html.replace(new RegExp('[ \t\r\n]+','g'),'').toLowerCase()=="";}if(para.getElementsByTagName("img").length>0)return false;if(para.getElementsByTagName("table").length>0)return false;if(para.getElementsByTagName("hr").length>0)return false;var nodes=tinyMCE.getNodeTree(para,new Array(),3);for(var i=0;i <"+blockName+"> ";paraAfter=body.childNodes[1];}this.selectNode(paraAfter,true,true);return true;}if(startChop.nodeName==blockName)rngBefore.setStart(startChop,0);else rngBefore.setStartBefore(startChop);rngBefore.setEnd(startNode,startOffset);paraBefore.appendChild(rngBefore.cloneContents());rngAfter.setEndAfter(endChop);rngAfter.setStart(endNode,endOffset);var contents=rngAfter.cloneContents();if(contents.firstChild&&contents.firstChild.nodeName==blockName){var nodes=contents.firstChild.childNodes;for(var i=0;i0)rng.pasteHTML('
    '+rng.htmlText+"
    ");tinyMCE.triggerNodeChange();return;}}}switch(command){case "mceSelectNode":this.selectNode(value);tinyMCE.triggerNodeChange();tinyMCE.selectedNode=value;break;case "FormatBlock":if(value==null||value==""){var elm=tinyMCE.getParentElement(this.getFocusElement(),"p,div,h1,h2,h3,h4,h5,h6,pre,address");if(elm)this.execCommand("mceRemoveNode",false,elm);}else this.getDoc().execCommand("FormatBlock",false,value);tinyMCE.triggerNodeChange();break;case "mceRemoveNode":if(!value)value=tinyMCE.getParentElement(this.getFocusElement());if(tinyMCE.isMSIE){value.outerHTML=value.innerHTML;}else{var rng=value.ownerDocument.createRange();rng.setStartBefore(value);rng.setEndAfter(value);rng.deleteContents();rng.insertNode(rng.createContextualFragment(value.innerHTML));}tinyMCE.triggerNodeChange();break;case "mceSelectNodeDepth":var parentNode=this.getFocusElement();for(var i=0;parentNode;i++){if(parentNode.nodeName.toLowerCase()=="body")break;if(parentNode.nodeName.toLowerCase()=="#text"){i--;parentNode=parentNode.parentNode;continue;}if(i==value){this.selectNode(parentNode,false);tinyMCE.triggerNodeChange();tinyMCE.selectedNode=parentNode;return;}parentNode=parentNode.parentNode;}break;case "HiliteColor":if(tinyMCE.isGecko){this.getDoc().execCommand("useCSS",false,false);this.getDoc().execCommand('hilitecolor',false,value);this.getDoc().execCommand("useCSS",false,true);}else this.getDoc().execCommand('BackColor',false,value);break;case "Cut":case "Copy":case "Paste":var cmdFailed=false;eval('try {this.getDoc().execCommand(command, user_interface, value);} catch (e) {cmdFailed = true;}');if(tinyMCE.isGecko&&cmdFailed){if(confirm(tinyMCE.getLang('lang_clipboard_msg')))window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html','mceExternal');return;}else tinyMCE.triggerNodeChange();break;case "mceSetContent":if(!value)value="";value=tinyMCE._customCleanup("insert_to_editor",value);tinyMCE._setHTML(doc,value);doc.body.innerHTML=tinyMCE._cleanupHTML(doc,tinyMCE.settings,doc.body);tinyMCE.handleVisualAid(doc.body,true,this.visualAid);return true;case "mceLink":var selectedText="";if(tinyMCE.isMSIE){var rng=doc.selection.createRange();selectedText=rng.text;}else selectedText=this.getSel().toString();if(!tinyMCE.linkElement){if((tinyMCE.selectedElement.nodeName.toLowerCase()!="img")&&(selectedText.length<=0))return;}var href="",target="",title="",onclick="",action="insert",style_class="";if(tinyMCE.selectedElement.nodeName.toLowerCase()=="a")tinyMCE.linkElement=tinyMCE.selectedElement;if(tinyMCE.linkElement!=null&&tinyMCE.getAttrib(tinyMCE.linkElement,'href')=="")tinyMCE.linkElement=null;if(tinyMCE.linkElement){href=tinyMCE.getAttrib(tinyMCE.linkElement,'href');target=tinyMCE.getAttrib(tinyMCE.linkElement,'target');title=tinyMCE.getAttrib(tinyMCE.linkElement,'title');onclick=tinyMCE.getAttrib(tinyMCE.linkElement,'mce_onclick');style_class=tinyMCE.getAttrib(tinyMCE.linkElement,'class');if(onclick=="")onclick=tinyMCE.getAttrib(tinyMCE.linkElement,'onclick');onclick=tinyMCE.cleanupEventStr(onclick);mceRealHref=tinyMCE.getAttrib(tinyMCE.linkElement,'mce_real_href');if(mceRealHref!="")href=mceRealHref;href=eval(tinyMCE.settings['urlconverter_callback']+"(href, tinyMCE.linkElement, true);");action="update";}if(this.settings['insertlink_callback']){var returnVal=eval(this.settings['insertlink_callback']+"(href, target, title, onclick, action, style_class);");if(returnVal&&returnVal['href'])tinyMCE.insertLink(returnVal['href'],returnVal['target'],returnVal['title'],returnVal['onclick'],returnVal['style_class']);}else{tinyMCE.openWindow(this.insertLinkTemplate,{href:href,target:target,title:title,onclick:onclick,action:action,className:style_class});}break;case "mceAttachment":var selectedText="";if(tinyMCE.isMSIE){var rng=doc.selection.createRange();selectedText=rng.text;}else selectedText=this.getSel().toString();if(!tinyMCE.linkElement){if((tinyMCE.selectedElement.nodeName.toLowerCase()!="img")&&(selectedText.length<=0))return;}var href="",target="",title="",onclick="",action="insert";if(tinyMCE.selectedElement.nodeName.toLowerCase()=="a")tinyMCE.linkElement=tinyMCE.selectedElement;if(tinyMCE.linkElement!=null&&tinyMCE.getAttrib(tinyMCE.linkElement,'href')=="")tinyMCE.linkElement=null;if(tinyMCE.linkElement){href=tinyMCE.getAttrib(tinyMCE.linkElement,'href');target=tinyMCE.getAttrib(tinyMCE.linkElement,'target');title=tinyMCE.getAttrib(tinyMCE.linkElement,'title');onclick=tinyMCE.getAttrib(tinyMCE.linkElement,'mce_onclick');if(onclick=="")onclick=tinyMCE.getAttrib(tinyMCE.linkElement,'onclick');onclick=tinyMCE.cleanupEventStr(onclick);mceRealHref=tinyMCE.getAttrib(tinyMCE.linkElement,'mce_real_href');if(mceRealHref!="")href=mceRealHref;href=eval(tinyMCE.settings['urlconverter_callback']+"(href, tinyMCE.linkElement, true);");action="update";}if(this.settings['insertlink_callback']){var returnVal=eval(this.settings['insertlink_callback']+"(href, target, title, onclick, action);");if(returnVal&&returnVal['href'])tinyMCE.insertLink(returnVal['href'],returnVal['target'],returnVal['title'],returnVal['onclick']);}else{tinyMCE.openWindow(this.insertAttachmentTemplate,{href:href,target:target,title:title,onclick:onclick,action:action});}break;case "mceImage":var src="",alt="",border="",hspace="",vspace="",width="",height="",align="";var title="",onmouseover="",onmouseout="",action="insert";var img=tinyMCE.imgElement;if(tinyMCE.selectedElement!=null&&tinyMCE.selectedElement.nodeName.toLowerCase()=="img"){img=tinyMCE.selectedElement;tinyMCE.imgElement=img;}if(img){if(tinyMCE.getAttrib(img,'name').indexOf('mce_')==0)return;src=tinyMCE.getAttrib(img,'src');alt=tinyMCE.getAttrib(img,'alt');if(alt=="")alt=tinyMCE.getAttrib(img,'title');if(tinyMCE.isGecko){var w=img.style.width;if(w!=null&&w!="")img.setAttribute("width",w);var h=img.style.height;if(h!=null&&h!="")img.setAttribute("height",h);}border=tinyMCE.getAttrib(img,'border');hspace=tinyMCE.getAttrib(img,'hspace');vspace=tinyMCE.getAttrib(img,'vspace');width=tinyMCE.getAttrib(img,'width');height=tinyMCE.getAttrib(img,'height');align=tinyMCE.getAttrib(img,'align');onmouseover=tinyMCE.getAttrib(img,'onmouseover');onmouseout=tinyMCE.getAttrib(img,'onmouseout');title=tinyMCE.getAttrib(img,'title');if(tinyMCE.isMSIE){width=img.attributes['width'].specified?width:"";height=img.attributes['height'].specified?height:"";}onmouseover=tinyMCE.getImageSrc(tinyMCE.cleanupEventStr(onmouseover));onmouseout=tinyMCE.getImageSrc(tinyMCE.cleanupEventStr(onmouseout));mceRealSrc=tinyMCE.getAttrib(img,'mce_real_src');if(mceRealSrc!="")src=mceRealSrc;src=eval(tinyMCE.settings['urlconverter_callback']+"(src, img, true);");if(onmouseover!="")onmouseover=eval(tinyMCE.settings['urlconverter_callback']+"(onmouseover, img, true);");if(onmouseout!="")onmouseout=eval(tinyMCE.settings['urlconverter_callback']+"(onmouseout, img, true);");action="update";}if(this.settings['insertimage_callback']){var returnVal=eval(this.settings['insertimage_callback']+"(src, alt, border, hspace, vspace, width, height, align, title, onmouseover, onmouseout, action);");if(returnVal&&returnVal['src'])tinyMCE.insertImage(returnVal['src'],returnVal['alt'],returnVal['border'],returnVal['hspace'],returnVal['vspace'],returnVal['width'],returnVal['height'],returnVal['align'],returnVal['title'],returnVal['onmouseover'],returnVal['onmouseout']);}else tinyMCE.openWindow(this.insertImageTemplate,{src:src,alt:alt,border:border,hspace:hspace,vspace:vspace,width:width,height:height,align:align,title:title,onmouseover:onmouseover,onmouseout:onmouseout,action:action});break;case "mceCleanupWord":if(tinyMCE.isMSIE){var html=this.getBody().createTextRange().htmlText;if(html.indexOf('="mso')!=-1){tinyMCE._setHTML(this.contentDocument,this.getBody().innerHTML);html=tinyMCE._cleanupHTML(this.contentDocument,this.settings,this.getBody(),this.visualAid);}this.getBody().innerHTML=html;}break;case "mceCleanup":tinyMCE._setHTML(this.contentDocument,this.getBody().innerHTML);this.getBody().innerHTML=tinyMCE._cleanupHTML(this.contentDocument,this.settings,this.getBody(),this.visualAid);tinyMCE.handleVisualAid(this.getBody(),true,this.visualAid);this.repaint();tinyMCE.triggerNodeChange();break;case "mceAnchor":if(!user_interface){var aElm=tinyMCE.getParentElement(this.getFocusElement(),"a","name");if(aElm){if(value==null||value==""){if(tinyMCE.isMSIE){aElm.outerHTML=aElm.innerHTML;}else{var rng=aElm.ownerDocument.createRange();rng.setStartBefore(aElm);rng.setEndAfter(aElm);rng.deleteContents();rng.insertNode(rng.createContextualFragment(aElm.innerHTML));}}else aElm.setAttribute('name',value);}else{this.getDoc().execCommand("fontname",false,"#mce_temp_font#");var elementArray=tinyMCE.getElementsByAttributeValue(this.getBody(),"font","face","#mce_temp_font#");for(var x=0;x0){value=tinyMCE.replaceVar(value,"selection",selectedText);tinyMCE.execCommand('mceInsertContent',false,value);}tinyMCE.triggerNodeChange();break;case "mceSetAttribute":if(typeof(value)=='object'){var targetElms=(typeof(value['targets'])=="undefined")?"p,img,span,div,td,h1,h2,h3,h4,h5,h6,pre,address":value['targets'];var targetNode=tinyMCE.getParentElement(this.getFocusElement(),targetElms);if(targetNode){targetNode.setAttribute(value['name'],value['value']);tinyMCE.triggerNodeChange();}}break;case "mceSetCSSClass":var selectedText=false;if(tinyMCE.isMSIE){var rng=doc.selection.createRange();selectedText=(rng.text&&rng.text.length>0);}else selectedText=(this.getSel().toString().length>0);if(tinyMCE.selectedNode)tinyMCE.selectedElement=tinyMCE.selectedNode;if(selectedText&&!tinyMCE.selectedNode){this.getDoc().execCommand("RemoveFormat",false,null);if(value==null)return this.execCommand("RemoveFormat",false,null);this.getDoc().execCommand("fontname",false,"#mce_temp_font#");var elementArray=tinyMCE.getElementsByAttributeValue(this.getBody(),"font","face","#mce_temp_font#");for(var x=0;xcustomUndoLevels){for(var i=0;i0){this.undoIndex--;this.getBody().innerHTML=this.undoLevels[this.undoIndex];}tinyMCE.triggerNodeChange();}else this.getDoc().execCommand(command,user_interface,value);break;case "Redo":if(tinyMCE.settings['custom_undo_redo']){if(this.undoIndex<(this.undoLevels.length-1)){this.undoIndex++;this.getBody().innerHTML=this.undoLevels[this.undoIndex];}tinyMCE.triggerNodeChange();}else this.getDoc().execCommand(command,user_interface,value);break;case "mceToggleVisualAid":this.visualAid=!this.visualAid;tinyMCE.handleVisualAid(this.getBody(),true,this.visualAid);tinyMCE.triggerNodeChange();break;case "removeformat":var text=this.getSelectedText();if(tinyMCE.isMSIE){try{win.focus();var rng=doc.selection.createRange();rng.execCommand("RemoveFormat",false,null);rng.pasteHTML(rng.text);}catch(e){}}else this.getDoc().execCommand(command,user_interface,value);if(text.length==0)this.execCommand("mceSetCSSClass",false,"");tinyMCE.triggerNodeChange();break;default:this.getDoc().execCommand(command,user_interface,value);tinyMCE.triggerNodeChange();}};TinyMCEControl.prototype.queryCommandValue=function(command){return this.getDoc().queryCommandValue(command);};TinyMCEControl.prototype.queryCommandState=function(command){return this.getDoc().queryCommandState(command);};TinyMCEControl.prototype.onAdd=function(replace_element,form_element_name,target_document){var targetDoc=target_document?target_document:document;this.targetDoc=targetDoc;tinyMCE.themeURL=tinyMCE.baseURL+"/themes/"+this.settings['theme'];this.settings['themeurl']=tinyMCE.themeURL;if(!replace_element){alert("Error: Could not find the target element.");return false;}var templateFunction=tinyMCE._getThemeFunction('_getInsertLinkTemplate');if(eval("typeof("+templateFunction+")")!='undefined')this.insertLinkTemplate=eval(templateFunction+'(this.settings);');var templateFunction=tinyMCE._getThemeFunction('_getInsertAttachmentTemplate');if(eval("typeof("+templateFunction+")")!='undefined')this.insertAttachmentTemplate=eval(templateFunction+'(this.settings);');var templateFunction=tinyMCE._getThemeFunction('_getInsertImageTemplate');if(eval("typeof("+templateFunction+")")!='undefined')this.insertImageTemplate=eval(templateFunction+'(this.settings);');var templateFunction=tinyMCE._getThemeFunction('_getEditorTemplate');if(eval("typeof("+templateFunction+")")=='undefined'){alert("Error: Could not find the template function: "+templateFunction);return false;}var editorTemplate=eval(templateFunction+'(this.settings, this.editorId);');var deltaWidth=editorTemplate['delta_width']?editorTemplate['delta_width']:0;var deltaHeight=editorTemplate['delta_height']?editorTemplate['delta_height']:0;var html=''+editorTemplate['html'];var templateFunction=tinyMCE._getThemeFunction('_handleNodeChange',true);if(eval("typeof("+templateFunction+")")!='undefined')this.settings['handleNodeChangeCallback']=templateFunction;html=tinyMCE.replaceVar(html,"editor_id",this.editorId);html=tinyMCE.replaceVar(html,"default_document",tinyMCE.baseURL+"/blank.htm");this.settings['default_document']=tinyMCE.baseURL+"/blank.htm";this.settings['old_width']=this.settings['width'];this.settings['old_height']=this.settings['height'];if(this.settings['width']==-1)this.settings['width']=replace_element.offsetWidth;if(this.settings['height']==-1)this.settings['height']=replace_element.offsetHeight;if(this.settings['width']==0)this.settings['width']=replace_element.style.width;if(this.settings['height']==0)this.settings['height']=replace_element.style.height;if(this.settings['width']==0)this.settings['width']=320;if(this.settings['height']==0)this.settings['height']=240;this.settings['area_width']=parseInt(this.settings['width']);this.settings['area_height']=parseInt(this.settings['height']);this.settings['area_width']+=deltaWidth;this.settings['area_height']+=deltaHeight;if((""+this.settings['width']).indexOf('%')!=-1)this.settings['area_width']="100%";if((""+this.settings['height']).indexOf('%')!=-1)this.settings['area_height']="100%";if((""+replace_element.style.width).indexOf('%')!=-1){this.settings['width']=replace_element.style.width;this.settings['area_width']="100%";}if((""+replace_element.style.height).indexOf('%')!=-1){this.settings['height']=replace_element.style.height;this.settings['area_height']="100%";}html=tinyMCE.applyTemplate(html);this.settings['width']=this.settings['old_width'];this.settings['height']=this.settings['old_height'];this.visualAid=this.settings['visual'];this.formTargetElementId=form_element_name;if(replace_element.nodeName.toLowerCase()=="textarea")this.startContent=replace_element.value;else this.startContent=replace_element.innerHTML;if(replace_element.nodeName.toLowerCase()!="textarea"){this.oldTargetElement=replace_element.cloneNode(true);if(tinyMCE.settings['debug'])html+='';else html+='';html+='';if(!tinyMCE.isMSIE){var rng=replace_element.ownerDocument.createRange();rng.setStartBefore(replace_element);var fragment=rng.createContextualFragment(html);replace_element.parentNode.replaceChild(fragment,replace_element);}else replace_element.outerHTML=html;}else{html+='';this.oldTargetElement=replace_element;if(!tinyMCE.settings['debug'])this.oldTargetElement.style.display="none";if(!tinyMCE.isMSIE){var rng=replace_element.ownerDocument.createRange();rng.setStartBefore(replace_element);var fragment=rng.createContextualFragment(html);replace_element.parentNode.insertBefore(fragment,replace_element);}else replace_element.insertAdjacentHTML("beforeBegin",html);}var dynamicIFrame=false;var tElm=targetDoc.getElementById(this.editorId);if(!tinyMCE.isMSIE){if(tElm&&tElm.nodeName.toLowerCase()=="span"){tElm=tinyMCE._createIFrame(tElm);dynamicIFrame=true;}this.targetElement=tElm;this.iframeElement=tElm;this.contentDocument=tElm.contentDocument;this.contentWindow=tElm.contentWindow;}else{if(tElm&&tElm.nodeName.toLowerCase()=="span")tElm=tinyMCE._createIFrame(tElm);else tElm=targetDoc.frames[this.editorId];this.targetElement=tElm;this.iframeElement=targetDoc.getElementById(this.editorId);this.contentDocument=tElm.window.document;this.contentWindow=tElm.window;this.getDoc().designMode="on";}var doc=this.contentDocument;if(dynamicIFrame){var html=""+''+''+''+''+'blank_page'+''+''+''+''+'';try{this.getDoc().designMode="on";doc.open();doc.write(html);doc.close();}catch(e){this.getDoc().location.href=tinyMCE.baseURL+"/blank.htm";}}if(tinyMCE.isMSIE)window.setTimeout("TinyMCE.prototype.addEventHandlers('"+this.editorId+"');",1);tinyMCE.setupContent(this.editorId,true);return true;};TinyMCEControl.prototype.getFocusElement=function(){if(tinyMCE.isMSIE){var doc=this.getDoc();var rng=doc.selection.createRange();if(rng.collapse)rng.collapse(true);var elm=rng.item?rng.item(0):rng.parentElement();}else{var sel=this.getSel();var elm=(sel&&sel.anchorNode)?sel.anchorNode:null;if(tinyMCE.selectedElement!=null&&tinyMCE.selectedElement.nodeName.toLowerCase()=="img")elm=tinyMCE.selectedElement;}return elm;};var tinyMCE=new TinyMCE();var tinyMCELang=new Array();function debug(){var msg="";var elm=document.getElementById("tinymce_debug");if(!elm){var debugDiv=document.createElement("div");debugDiv.setAttribute("className","debugger");debugDiv.className="debugger";debugDiv.innerHTML='\ + Debug output:\ + ';document.body.appendChild(debugDiv);elm=document.getElementById("tinymce_debug");}var args=this.debug.arguments;for(var i=0;i + +var TinyMCECompressed_settings = null; + +function TinyMCECompressed() { +} + +TinyMCECompressed.prototype.init = function(settings) { + var elements = document.getElementsByTagName('script'); + var scriptURL = ""; + + for (var i=0; i'); + + TinyMCECompressed_settings = settings; +} + +var tinyMCE = new TinyMCECompressed(); diff --git a/public/tiny_mce/tiny_mce_popup.js b/public/tiny_mce/tiny_mce_popup.js new file mode 100644 index 0000000..8b03e50 --- /dev/null +++ b/public/tiny_mce/tiny_mce_popup.js @@ -0,0 +1,96 @@ +// Get tinyMCE window +var win = window.opener ? window.opener : window.dialogArguments; + +var tinyMCE = null; +var tinyMCELang = null; + +// Use top window if not defined +if (!win) + win = top; + +var tinyMCE = win.tinyMCE; +var tinyMCELang = win.tinyMCELang; + +if (!tinyMCE) + alert("tinyMCE object reference not found from popup."); + +// Setup window openerer +window.opener = win; + +// Setup title +var re = new RegExp('{|\\\$|}', 'g'); +var title = document.title.replace(re, ""); +if (typeof tinyMCELang[title] != "undefined") { + var divElm = document.createElement("div"); + divElm.innerHTML = tinyMCELang[title]; + document.title = divElm.innerHTML; +} + +// Setup dir +if (tinyMCELang['lang_dir']) + document.dir = tinyMCELang['lang_dir']; + +function TinyMCEPlugin_onLoad() { + if (tinyMCE.getWindowArg('mce_replacevariables', true)) + document.body.innerHTML = tinyMCE.applyTemplate(document.body.innerHTML, tinyMCE.windowArgs); + + // Auto resize window + if (tinyMCE.getWindowArg('mce_windowresize', true)) + TinyMCEPopup_autoResize(); + + if (tinyMCE.settings["dialog_type"] == "window") + window.focus(); +} + +function TinyMCEPopup_autoResize() { + // Div mode, skip resize + if (tinyMCE.settings["dialog_type"] == "div") + return; + + var isMSIE = (navigator.appName == "Microsoft Internet Explorer"); + var isOpera = (navigator.userAgent.indexOf("Opera") != -1); + + if (isOpera) + return; + + if (isMSIE) { + try { window.resizeTo(10, 10); } catch (e) {} + + var elm = document.body; + var width = elm.offsetWidth; + var height = elm.offsetHeight; + var dx = (elm.scrollWidth - width) + 4; + var dy = elm.scrollHeight - height; + + try { window.resizeBy(dx, dy); } catch (e) {} + } else { + window.scrollBy(1000, 1000); + if (window.scrollX > 0 || window.scrollY > 0) { + window.resizeBy(window.innerWidth * 2, window.innerHeight * 2); + window.sizeToContent(); + window.scrollTo(0, 0); + var x = parseInt(screen.width / 2.0) - (window.outerWidth / 2.0); + var y = parseInt(screen.height / 2.0) - (window.outerHeight / 2.0); + window.moveTo(x, y); + } + } +} + +// Re-patch it +if (tinyMCE.settings["dialog_type"] == "window") { + tinyMCE.closeDialog = function() { + // Remove div or close window + if (tinyMCE.settings["dialog_type"] == "div") { + var div = document.getElementById(tinyMCE._currentDialog); + if (div) + div.parentNode.removeChild(div); + } else + window.close(); + }; +} + +// Add onload trigger +tinyMCE.addEvent(window, "load", TinyMCEPlugin_onLoad); + +// Output Popup CSS class +document.write(''); diff --git a/public/tiny_mce/tiny_mce_src.js b/public/tiny_mce/tiny_mce_src.js new file mode 100644 index 0000000..25fa0d3 --- /dev/null +++ b/public/tiny_mce/tiny_mce_src.js @@ -0,0 +1,4884 @@ +/** + * $RCSfile: tiny_mce_src.js,v $ + * $Revision: 1.210 $ + * $Date: 2005/06/15 09:05:32 $ + * + * @author Moxiecode + * @copyright Copyright 2004, Moxiecode Systems AB, All rights reserved. + */ + +function TinyMCE() { + this.instances = new Array(); + this.stickyClassesLookup = new Array(); + this.windowArgs = new Array(); + this.loadedFiles = new Array(); + this.configs = new Array(); + this.currentConfig = 0; + this.eventHandlers = new Array(); + + // Browser check + this.isMSIE = (navigator.appName == "Microsoft Internet Explorer"); + this.isMSIE5 = this.isMSIE && (navigator.userAgent.indexOf('MSIE 5') != -1); + this.isMSIE5_0 = this.isMSIE && (navigator.userAgent.indexOf('MSIE 5.0') != -1); + this.isGecko = navigator.userAgent.indexOf('Gecko') != -1; + this.isSafari = navigator.userAgent.indexOf('Safari') != -1; + this.isMac = navigator.userAgent.indexOf('Mac') != -1; + this.dialogCounter = 0; + + // TinyMCE editor id instance counter + this.idCounter = 0; +}; + +TinyMCE.prototype.defParam = function(key, def_val) { + this.settings[key] = tinyMCE.getParam(key, def_val); +}; + +TinyMCE.prototype.init = function(settings) { + var theme; + + this.settings = settings; + + // Check if valid browser has execcommand support + if (typeof(document.execCommand) == 'undefined') + return; + + // Get script base path + if (!tinyMCE.baseURL) { + var elements = document.getElementsByTagName('script'); + + for (var i=0; i'); + + this.loadedFiles[this.loadedFiles.length] = url; +}; + +TinyMCE.prototype.loadCSS = function(url) { + for (var i=0; i'); + + this.loadedFiles[this.loadedFiles.length] = url; +}; + +TinyMCE.prototype.importCSS = function(doc, css_file) { + if (tinyMCE.isMSIE) + var styleSheet = doc.createStyleSheet(css_file); + else { + var elm = doc.createElement("link"); + + elm.rel = "stylesheet"; + elm.href = css_file; + + if (headArr = doc.getElementsByTagName("head")) + headArr[0].appendChild(elm); + } +}; + +TinyMCE.prototype.confirmAdd = function(e, settings) { + var elm = tinyMCE.isMSIE ? event.srcElement : e.target; + var elementId = elm.name ? elm.name : elm.id; + + tinyMCE.settings = settings; + + if (!elm.getAttribute('mce_noask') && confirm(tinyMCELang['lang_edit_confirm'])) + tinyMCE.addMCEControl(elm, elementId); + + elm.setAttribute('mce_noask', 'true'); +}; + +TinyMCE.prototype.updateContent = function(form_element_name) { + // Find MCE instance linked to given form element and copy it's value + var formElement = document.getElementById(form_element_name); + for (var n in tinyMCE.instances) { + var inst = tinyMCE.instances[n]; + if (typeof(inst) == "function") continue; + inst.switchSettings(); + + if (inst.formElement == formElement) { + var doc = inst.getDoc(); + + tinyMCE._setHTML(doc, inst.formElement.value); + + if (!tinyMCE.isMSIE) + doc.body.innerHTML = tinyMCE._cleanupHTML(doc, this.settings, doc.body, inst.visualAid); + } + } +}; + +TinyMCE.prototype.addMCEControl = function(replace_element, form_element_name, target_document) { + var id = "mce_editor_" + tinyMCE.idCounter++; + var inst = new TinyMCEControl(tinyMCE.settings); + + inst.editorId = id; + this.instances[id] = inst; + + inst.onAdd(replace_element, form_element_name, target_document); +}; + +TinyMCE.prototype.triggerSave = function(skip_cleanup, skip_callback) { + // Cleanup and set all form fields + for (var n in tinyMCE.instances) { + var inst = tinyMCE.instances[n]; + if (typeof(inst) == "function") continue; + inst.switchSettings(); + + tinyMCE.settings['preformatted'] = false; + + // Default to false + if (typeof(skip_cleanup) == "undefined") + skip_cleanup = false; + + // Default to false + if (typeof(skip_callback) == "undefined") + skip_callback = false; + + tinyMCE._setHTML(inst.getDoc(), inst.getBody().innerHTML); + + var htm = skip_cleanup ? inst.getBody().innerHTML : tinyMCE._cleanupHTML(inst.getDoc(), this.settings, inst.getBody(), this.visualAid, true); + + //var htm = tinyMCE._cleanupHTML(inst.getDoc(), tinyMCE.settings, inst.getBody(), false, true); + + if (tinyMCE.settings["encoding"] == "xml" || tinyMCE.settings["encoding"] == "html") + htm = tinyMCE.convertStringToXML(htm); + + if (!skip_callback && tinyMCE.settings['save_callback'] != "") + var content = eval(tinyMCE.settings['save_callback'] + "(inst.formTargetElementId,htm,inst.getBody());"); + + // Use callback content if available + if ((typeof(content) != "undefined") && content != null) + htm = content; + + // Replace some weird entities (Bug: #1056343) + htm = tinyMCE.regexpReplace(htm, "(", "(", "gi"); + htm = tinyMCE.regexpReplace(htm, ")", ")", "gi"); + htm = tinyMCE.regexpReplace(htm, ";", ";", "gi"); + htm = tinyMCE.regexpReplace(htm, """, """, "gi"); + htm = tinyMCE.regexpReplace(htm, "^", "^", "gi"); + + if (inst.formElement) + inst.formElement.value = htm; + } +}; + +TinyMCE.prototype._convertOnClick = function(node) { + // Skip on MSIE < 6+ + if (tinyMCE.isMSIE5) + return; + + // Convert all onclick to mce_onclick + var elms = node.getElementsByTagName("a"); + for (var i=0; i", "gi"); + content = tinyMCE.regexpReplace(content, "\r", "
    ", "gi"); + content = tinyMCE.regexpReplace(content, "\n", "
    ", "gi"); + } + + // Call custom cleanup code + content = tinyMCE._customCleanup("insert_to_editor", content); + + if (tinyMCE.isMSIE) { + // Ugly!!! + window.setInterval('try{tinyMCE.getCSSClasses(document.frames["' + editor_id + '"].document, "' + editor_id + '");}catch(e){}', 500); + + if (tinyMCE.settings["force_br_newlines"]) + document.frames[editor_id].document.styleSheets[0].addRule("p", "margin: 0px;"); + + var body = document.frames[editor_id].document.body; + + tinyMCE.addEvent(body, "beforepaste", TinyMCE.prototype.eventPatch); + tinyMCE.addEvent(body, "beforecut", TinyMCE.prototype.eventPatch); + tinyMCE.addEvent(body, "paste", TinyMCE.prototype.eventPatch); + + body.editorId = editor_id; + } + + // Fix for bug #958637 + if (!tinyMCE.isMSIE) { + var contentElement = inst.getDoc().createElement("body"); + var doc = inst.getDoc(); + + contentElement.innerHTML = content; + + // Remove weridness! + if (tinyMCE.settings['force_p_newlines']) + content = content.replace(new RegExp('<>', 'g'), ""); + + if (tinyMCE.settings['cleanup_on_startup']) + inst.getBody().innerHTML = tinyMCE._cleanupHTML(doc, this.settings, contentElement); + else { + // Convert all strong/em to b/i + content = tinyMCE.regexpReplace(content, "", "", "gi"); + content = tinyMCE.regexpReplace(content, "", "", "gi"); + inst.getBody().innerHTML = content; + } + + inst.convertAllRelativeURLs(); + } else { + if (tinyMCE.settings['cleanup_on_startup']) { + tinyMCE._setHTML(inst.getDoc(), content); + // Produces permission denied error in MSIE 5.5 + eval('try {inst.getBody().innerHTML = tinyMCE._cleanupHTML(inst.contentDocument, this.settings, inst.getBody());} catch(e) {}'); + } else + inst.getBody().innerHTML = content; + } + + tinyMCE._convertOnClick(inst.getBody()); + + // Fix for bug #957681 + //inst.getDoc().designMode = inst.getDoc().designMode; + + // Setup element references + var parentElm = document.getElementById(inst.editorId + '_parent'); + if (parentElm.lastChild.nodeName.toLowerCase() == "input") + inst.formElement = parentElm.lastChild; + else + inst.formElement = parentElm.nextSibling; + + tinyMCE.handleVisualAid(inst.getBody(), true, tinyMCE.settings['visual']); + tinyMCE.executeCallback('setupcontent_callback', '_setupContent', 0, editor_id, inst.getBody(), inst.getDoc()); + + // Re-add design mode on mozilla + if (!tinyMCE.isMSIE) + TinyMCE.prototype.addEventHandlers(editor_id); + + inst.startContent = inst.getBody().innerHTML; + + // Trigger node change, this call locks buttons for tables and so forth + tinyMCE.selectedInstance = inst; + tinyMCE.selectedElement = inst.contentWindow.document.body; + tinyMCE.triggerNodeChange(false, true); + + // Call custom DOM cleanup + tinyMCE._customCleanup("insert_to_editor_dom", inst.contentWindow.document.body); +}; + +TinyMCE.prototype.cancelEvent = function(e) { + if (tinyMCE.isMSIE) { + e.returnValue = false; + e.cancelBubble = true; + } else + e.preventDefault(); +}; + +TinyMCE.prototype.removeTinyMCEFormElements = function(form_obj) { + // Disable all UI form elements that TinyMCE created + for (var i=0; i"); + rng.collapse(false); + rng.select(); + + tinyMCE.triggerNodeChange(false); + return false; + } + } + + // Backspace or delete + if (e.keyCode == 8 || e.keyCode == 46) { + tinyMCE.selectedElement = e.target; + tinyMCE.linkElement = tinyMCE.getParentElement(e.target, "a"); + tinyMCE.imgElement = tinyMCE.getParentElement(e.target, "img"); + tinyMCE.triggerNodeChange(false); + } + + return false; + break; + + case "keyup": + case "keydown": + if (e.target.editorId) + tinyMCE.selectedInstance = tinyMCE.instances[e.target.editorId]; + else + return; + + if (tinyMCE.selectedInstance) + tinyMCE.selectedInstance.switchSettings(); + + // Handle backspace + if (tinyMCE.isGecko && tinyMCE.settings['force_p_newlines'] && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) { + // Insert P element instead of BR + if (tinyMCE.selectedInstance._handleBackSpace(e.type)) { + // Cancel event + e.preventDefault(); + return false; + } + } + + tinyMCE.selectedElement = null; + tinyMCE.selectedNode = null; + var elm = tinyMCE.selectedInstance.getFocusElement(); + tinyMCE.linkElement = tinyMCE.getParentElement(elm, "a"); + tinyMCE.imgElement = tinyMCE.getParentElement(elm, "img"); + tinyMCE.selectedElement = elm; + + // Update visualaids on tabs + if (tinyMCE.isGecko && e.type == "keyup" && e.keyCode == 9) + tinyMCE.handleVisualAid(tinyMCE.selectedInstance.getBody(), true, tinyMCE.settings['visual']); + + // Run image/link fix on Gecko if diffrent document base on paste + if (tinyMCE.isGecko && tinyMCE.settings['document_base_url'] != "" + document.location.href && e.type == "keyup" && e.ctrlKey && e.keyCode == 86) + tinyMCE.selectedInstance.fixBrokenURLs(); + + // Insert space instead of   +/* if (e.type == "keydown" && e.keyCode == 32) { + if (tinyMCE.selectedInstance._insertSpace()) { + // Cancel event + e.returnValue = false; + e.cancelBubble = true; + return false; + } + }*/ + + // MSIE custom key handling + if (tinyMCE.isMSIE && tinyMCE.settings['custom_undo_redo']) { + // Check if it's a position key press + var keys = new Array(13,45,36,35,33,34,37,38,39,40); + var posKey = false; + for (var i=0; i 18 && e.keyCode != 255)) { + tinyMCE.selectedInstance.execCommand("mceAddUndoLevel"); + tinyMCE.selectedInstance.typing = true; + tinyMCE.triggerNodeChange(false); + } + + if (posKey && e.type == "keyup") + tinyMCE.triggerNodeChange(false); + + var keys = new Array(8,46); // Backspace,Delete + for (var i=0; i 0) { + for (var i=0; i" + this.convertStringToXML(String.fromCharCode(160)) + ""; + + // Is MSIE script element + if (tinyMCE.isMSIE && elementName == "script") + return "<" + elementName + elementAttribs + ">" + node.text + ""; + + // Clean up children + if (node.hasChildNodes()) { + // Force BR + if (elementName == "p" && tinyMCE.cleanup_force_br_newlines) + output += ""; + else + output += "<" + elementName + elementAttribs + ">"; + + for (var i=0; i"; + } else { + // Allways leave anchor elements open + if (openTag) + output += "<" + elementName + elementAttribs + ">"; + else { + // No children + output += "<" + elementName + elementAttribs + " />"; + } + } + + return output; + + case 3: // Text + // Do not convert script elements + if (node.parentNode.nodeName.toLowerCase() == "script") + return node.nodeValue; + + return this.convertStringToXML(node.nodeValue); + + case 8: // Comment + return ""; + + default: // Unknown + return "[UNKNOWN NODETYPE " + node.nodeType + "]"; + } +}; + +TinyMCE.prototype.convertStringToXML = function(html_data) { + var output = ""; + + for (var i=0; i 127) + output += '&#' + chr + ";"; + else + output += String.fromCharCode(chr); + + continue; + } + + // Raw entities + if (tinyMCE.settings['entity_encoding'] == "raw") { + output += String.fromCharCode(chr); + continue; + } + + // Named entities + if (typeof(tinyMCE.cleanup_entities["c" + chr]) != 'undefined' && tinyMCE.cleanup_entities["c" + chr] != '') + output += '&' + tinyMCE.cleanup_entities["c" + chr] + ';'; + else + output += '' + String.fromCharCode(chr); + } + + return output; +}; + +TinyMCE.prototype._getCleanupElementName = function(chunk) { + var pos; + + if (chunk.charAt(0) == '+') + chunk = chunk.substring(1); + + if ((pos = chunk.indexOf('/')) != -1) + chunk = chunk.substring(0, pos); + + if ((pos = chunk.indexOf('[')) != -1) + chunk = chunk.substring(0, pos); + + return chunk; +}; + +TinyMCE.prototype._initCleanup = function() { + // Parse valid elements and attributes + var validElements = tinyMCE.settings["valid_elements"]; + validElements = validElements.split(','); + + // Handle extended valid elements + var extendedValidElements = tinyMCE.settings["extended_valid_elements"]; + extendedValidElements = extendedValidElements.split(','); + for (var i=0; i[ \n\r]*
    [ \n\r]*

    ', '
    ', 'gi'); + element.innerHTML = tinyMCE.regexpReplace(element.innerHTML, '', '', 'gi'); + } + + var html = this.cleanupNode(element); + + if (tinyMCE.settings['debug']) + alert("Cleanup process executed in: " + (new Date().getTime()-startTime) + " ms."); + + // Remove pesky HR paragraphs + html = tinyMCE.regexpReplace(html, '


    ', '
    '); + html = tinyMCE.regexpReplace(html, '

     


     

    ', '
    '); + + // Remove some mozilla crap + if (!tinyMCE.isMSIE) + html = html.replace(new RegExp('', 'g'), ""); + + if (tinyMCE.settings['apply_source_formatting']) { + html = html.replace(new RegExp('<(p|div)([^>]*)>', 'g'), "\n<$1$2>\n"); + html = html.replace(new RegExp('<\/(p|div)([^>]*)>', 'g'), "\n\n"); + html = html.replace(new RegExp('
    ', 'g'), "
    \n"); + } + + if (tinyMCE.settings['force_br_newlines']) { + var re = new RegExp('

     

    ', 'g'); + html = html.replace(re, "
    "); + } + + if (tinyMCE.settings['force_p_newlines']) { + // Remove weridness! + var re = new RegExp('<>', 'g'); + html = html.replace(re, ""); + } + + if (tinyMCE.settings['remove_linebreaks']) + html = html.replace(new RegExp('\r|\n', 'g'), ' '); + + // Call custom cleanup code + html = tinyMCE._customCleanup(on_save ? "get_from_editor" : "insert_to_editor", html); + + // Emtpy node, return empty + var chk = tinyMCE.regexpReplace(html, "[ \t\r\n]", ""); + if (chk == "
    " || chk == "
    " || chk == "

     

    " || chk == "

     

    " || chk == "

    ") + html = ""; + + if (tinyMCE.settings["preformatted"]) + return "
    " + html + "
    "; + + return html; +}; + +TinyMCE.prototype.setAttrib = function(element, name, value, no_fix_value) { + if (!no_fix_value && value != null) { + var re = new RegExp('[^0-9%]', 'g'); + value = value.replace(re, ''); + } + + if (value != null && value != "") + element.setAttribute(name, value); + else + element.removeAttribute(name); + + if (value != null && value != "") + element.setAttribute(name, value); + else + element.removeAttribute(name); +}; + +TinyMCE.prototype.insertLink = function(href, target, title, onclick, style_class) { + this.execCommand("mceAddUndoLevel"); + + if (this.selectedInstance && this.selectedElement && this.selectedElement.nodeName.toLowerCase() == "img") { + var doc = this.selectedInstance.getDoc(); + var linkElement = tinyMCE.getParentElement(this.selectedElement, "a"); + var newLink = false; + + if (!linkElement) { + linkElement = doc.createElement("a"); + newLink = true; + } + + href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, linkElement);"); + tinyMCE.setAttrib(linkElement, 'href', href); + tinyMCE.setAttrib(linkElement, 'target', target); + tinyMCE.setAttrib(linkElement, 'title', title); + tinyMCE.setAttrib(linkElement, 'mce_onclick', onclick); + tinyMCE.setAttrib(linkElement, 'class', style_class); + + if (newLink) { + linkElement.appendChild(this.selectedElement.cloneNode(true)); + this.selectedElement.parentNode.replaceChild(linkElement, this.selectedElement); + } + + return; + } + + if (!this.linkElement && this.selectedInstance) { + this.selectedInstance.contentDocument.execCommand("createlink", false, "#mce_temp_url#"); + tinyMCE.linkElement = this.getElementByAttributeValue(this.selectedInstance.contentDocument.body, "a", "href", "#mce_temp_url#"); + + var elementArray = this.getElementsByAttributeValue(this.selectedInstance.contentDocument.body, "a", "href", "#mce_temp_url#"); + + for (var i=0; i= strTok2.length) { + for (var i=0; i= strTok2.length || strTok1[i] != strTok2[i]) { + breakPoint = i + 1; + break; + } + } + } + + if (strTok1.length < strTok2.length) { + for (var i=0; i= strTok1.length || strTok1[i] != strTok2[i]) { + breakPoint = i + 1; + break; + } + } + } + + if (breakPoint == 1) + return url_to_relative; + + for (var i=0; i<(strTok1.length-(breakPoint-1)); i++) + outputString += "../"; + + for (var i=breakPoint-1; i=0; i--) { + if (baseURLParts[i].length == 0) + continue; + + newBaseURLParts[newBaseURLParts.length] = baseURLParts[i]; + } + baseURLParts = newBaseURLParts.reverse(); + + // Merge relURLParts chunks + var newRelURLParts = new Array(); + var numBack = 0; + for (var i=relURLParts.length-1; i>=0; i--) { + if (relURLParts[i].length == 0 || relURLParts[i] == ".") + continue; + + if (relURLParts[i] == '..') { + numBack++; + continue; + } + + if (numBack > 0) { + numBack--; + continue; + } + + newRelURLParts[newRelURLParts.length] = relURLParts[i]; + } + + relURLParts = newRelURLParts.reverse(); + + // Remove end from absolute path + var len = baseURLParts.length-numBack; + var absPath = (len <= 0 ? "" : "/") + baseURLParts.slice(0, len).join('/') + "/" + relURLParts.join('/'); + var start = "", end = ""; + + // Build start part + if (baseURL['protocol']) + start += baseURL['protocol'] + "://"; + + if (baseURL['host']) + start += baseURL['host']; + + if (baseURL['port']) + start += ":" + baseURL['port']; + + // Build end part + if (relURL['query']) + end += "?" + relURL['query']; + + if (relURL['anchor']) + end += "#" + relURL['anchor']; + + // Re-add trailing slash if it's removed + if (relative_url.charAt(relative_url.length-1) == "/") + end += "/"; + + return start + absPath + end; +}; + +TinyMCE.prototype.getParam = function(name, default_value, strip_whitespace, split_chr) { + var value = (typeof(this.settings[name]) == "undefined") ? default_value : this.settings[name]; + + // Fix bool values + if (value == "true" || value == "false") + return (value == "true"); + + if (strip_whitespace) + value = tinyMCE.regexpReplace(value, "[ \t\r\n]", ""); + + if (typeof(split_chr) != "undefined" && split_chr != null) { + value = value.split(split_chr); + var outArray = new Array(); + + for (var i=0; i 0); + + if (tinyMCE.settings['custom_undo_redo']) { + undoIndex = inst.undoIndex; + undoLevels = inst.undoLevels.length; + } + + tinyMCE.executeCallback('handleNodeChangeCallback', '_handleNodeChange', 0, editorId, elm, undoIndex, undoLevels, inst.visualAid, anySelection); + } + } + + if (this.selectedInstance && (typeof(focus) == "undefined" || focus)) + this.selectedInstance.contentWindow.focus(); +}; + +TinyMCE.prototype._customCleanup = function(type, content) { + // Call custom cleanup + var customCleanup = tinyMCE.settings['cleanup_callback']; + if (customCleanup != "" && eval("typeof(" + customCleanup + ")") != "undefined") + content = eval(customCleanup + "(type, content);"); + + // Trigger plugin cleanups + var plugins = tinyMCE.getParam('plugins', '', true, ','); + for (var i=0; i'; + + div.innerHTML = html; + + document.body.appendChild(div); + + tinyMCE._currentDialog = id; + } + /*}*/ + } +}; + +TinyMCE.prototype.closeDialog = function() { + // Remove div or close window + if (tinyMCE.settings["dialog_type"] == "div") { + var div = document.getElementById(tinyMCE._currentDialog); + if (div) + div.parentNode.removeChild(div); + } else + window.close(); +}; + +TinyMCE.prototype.getVisualAidClass = function(class_name, state) { + var aidClass = tinyMCE.settings['visual_table_class']; + + if (typeof(state) == "undefined") + state = tinyMCE.settings['visual']; + + // Split + var classNames = new Array(); + var ar = class_name.split(' '); + for (var i=0; i 0) + className += " "; + + className += classNames[i]; + } + + return className; +}; + +TinyMCE.prototype.handleVisualAid = function(element, deep, state) { + if (!element) + return; + + var tableElement = null; + + switch (element.nodeName.toLowerCase()) { + case "table": + var oldW = element.style.width; + var oldH = element.style.height; + + element.className = tinyMCE.getVisualAidClass(element.className, state && element.getAttribute("border") == 0); + + element.style.width = oldW; + element.style.height = oldH; + + for (var y=0; y'; + return; + } + + break;*/ + } + + if (deep && element.hasChildNodes()) { + for (var i=0; i

    breaks runtime? + if (tinyMCE.isMSIE) { + var re = new RegExp('


    ', 'g'); + html_content = html_content.replace(re, "
    "); + } + + doc.body.innerHTML = html_content; + + // Content duplication bug fix + if (tinyMCE.isMSIE && tinyMCE.settings['fix_content_duplication']) { + // Remove P elements in P elements + var paras = doc.getElementsByTagName("P"); + for (var i=0; i<\/o:p>", "
    "); + html = tinyMCE.regexpReplace(html, " <\/o:p>", ""); + html = tinyMCE.regexpReplace(html, "", ""); + html = tinyMCE.regexpReplace(html, "

    <\/p>", ""); + html = tinyMCE.regexpReplace(html, "

    <\/p>\r\n

    <\/p>", ""); + html = tinyMCE.regexpReplace(html, "

     <\/p>", "
    "); + html = tinyMCE.regexpReplace(html, "

    \s*(

    \s*)?", "

    "); + html = tinyMCE.regexpReplace(html, "<\/p>\s*(<\/p>\s*)?", "

    "); + } + + // Always set the htmlText output + doc.body.innerHTML = html; + } +}; + +TinyMCE.prototype.getImageSrc = function(str) { + var pos = -1; + + if (!str) + return ""; + + if ((pos = str.indexOf('this.src=')) != -1) { + var src = str.substring(pos + 10); + + src = src.substring(0, src.indexOf('\'')); + + return src; + } + + return ""; +}; + +TinyMCE.prototype._getElementById = function(element_id) { + var elm = document.getElementById(element_id); + if (!elm) { + // Check for element in forms + for (var j=0; j 0) { + var csses = null; + + // Just ignore any errors + eval("try {var csses = tinyMCE.isMSIE ? doc.styleSheets(0).rules : doc.styleSheets[0].cssRules;} catch(e) {}"); + if (!csses) + return new Array(); + + for (var i=0; i 0) + tinyMCE.cssClasses = output; + + return output; +}; + +TinyMCE.prototype.regexpReplace = function(in_str, reg_exp, replace_str, opts) { + if (typeof(opts) == "undefined") + opts = 'g'; + + var re = new RegExp(reg_exp, opts); + return in_str.replace(re, replace_str); +}; + +TinyMCE.prototype.cleanupEventStr = function(str) { + str = "" + str; + str = str.replace('function anonymous()\n{\n', ''); + str = str.replace('\n}', ''); + + return str; +}; + +TinyMCE.prototype.getAbsPosition = function(node) { + var pos = new Object(); + + pos.absLeft = pos.absTop = 0; + + var parentNode = node; + while (parentNode) { + pos.absLeft += parentNode.offsetLeft; + pos.absTop += parentNode.offsetTop; + + parentNode = parentNode.offsetParent; + } + + return pos; +}; + +TinyMCE.prototype.openFileBrowser = function(field_name, url, type, win) { + var cb = tinyMCE.getParam("file_browser_callback"); + + this.setWindowArg("window", win); + + // Call to external callback + if(eval('typeof('+cb+')') == "undefined") + alert("Callback function: " + cb + " could not be found."); + else + eval(cb + "(field_name, url, type, win);"); +}; + +TinyMCE.prototype.getControlHTML = function(control_name) { + var themePlugins = tinyMCE.getParam('plugins', '', true, ','); + var templateFunction; + + // Is it defined in any plugins + for (var i=themePlugins.length; i>=0; i--) { + templateFunction = 'TinyMCE_' + themePlugins[i] + "_getControlHTML"; + if (eval("typeof(" + templateFunction + ")") != 'undefined') { + var html = eval(templateFunction + "('" + control_name + "');"); + if (html != "") + return tinyMCE.replaceVar(html, "pluginurl", tinyMCE.baseURL + "/plugins/" + themePlugins[i]); + } + } + + return eval('TinyMCE_' + tinyMCE.settings['theme'] + "_getControlHTML" + "('" + control_name + "');"); +}; + +TinyMCE.prototype._themeExecCommand = function(editor_id, element, command, user_interface, value) { + var themePlugins = tinyMCE.getParam('plugins', '', true, ','); + var templateFunction; + + // Is it defined in any plugins + for (var i=themePlugins.length; i>=0; i--) { + templateFunction = 'TinyMCE_' + themePlugins[i] + "_execCommand"; + if (eval("typeof(" + templateFunction + ")") != 'undefined') { + if (eval(templateFunction + "(editor_id, element, command, user_interface, value);")) + return true; + } + } + + // Theme funtion + templateFunction = 'TinyMCE_' + tinyMCE.settings['theme'] + "_execCommand"; + if (eval("typeof(" + templateFunction + ")") != 'undefined') + return eval(templateFunction + "(editor_id, element, command, user_interface, value);"); + + // Pass to normal + return false; +}; + +TinyMCE.prototype._getThemeFunction = function(suffix, skip_plugins) { + if (skip_plugins) + return 'TinyMCE_' + tinyMCE.settings['theme'] + suffix; + + var themePlugins = tinyMCE.getParam('plugins', '', true, ','); + var templateFunction; + + // Is it defined in any plugins + for (var i=themePlugins.length; i>=0; i--) { + templateFunction = 'TinyMCE_' + themePlugins[i] + suffix; + if (eval("typeof(" + templateFunction + ")") != 'undefined') + return templateFunction; + } + + return 'TinyMCE_' + tinyMCE.settings['theme'] + suffix; +}; + + +TinyMCE.prototype.isFunc = function(func_name) { + if (func_name == null || func_name == "") + return false; + + return eval("typeof(" + func_name + ")") != "undefined"; +}; + +TinyMCE.prototype.exec = function(func_name, args) { + var str = func_name + '('; + + // Add all arguments + for (var i=3; i 1 && tinyMCE.currentConfig != this.settings['index']) { + tinyMCE.settings = this.settings; + tinyMCE.currentConfig = this.settings['index']; + } +}; + +TinyMCEControl.prototype.fixBrokenURLs = function() { + var body = this.getBody(); + + var elms = body.getElementsByTagName("img"); + for (var i=0; i 0) + rng.selectNodeContents(nodes[0]); + else + rng.selectNodeContents(node); + } else + rng.selectNode(node); + + if (collapse) { + // Special treatment of textnode collapse + if (!to_start && node.nodeType == 3) { + rng.setStart(node, node.nodeValue.length); + rng.setEnd(node, node.nodeValue.length); + } else + rng.collapse(to_start); + } + + sel.removeAllRanges(); + sel.addRange(rng); + } + + this.scrollToNode(node); + + // Set selected element + tinyMCE.selectedElement = null; + if (node.nodeType == 1) + tinyMCE.selectedElement = node; +}; + +TinyMCEControl.prototype.scrollToNode = function(node) { + // Scroll to node position + var pos = tinyMCE.getAbsPosition(node); + var doc = this.getDoc(); + var scrollX = doc.body.scrollLeft + doc.documentElement.scrollLeft; + var scrollY = doc.body.scrollTop + doc.documentElement.scrollTop; + var height = tinyMCE.isMSIE ? document.getElementById(this.editorId).style.pixelHeight : this.targetElement.clientHeight; + + // Only scroll if out of visible area + if (!tinyMCE.settings['auto_resize'] && !(node.absTop > scrollY && node.absTop < (scrollY - 25 + height))) + this.contentWindow.scrollTo(pos.absLeft, pos.absTop - height + 25); +}; + +TinyMCEControl.prototype.getBody = function() { + return this.getDoc().body; +}; + +TinyMCEControl.prototype.getDoc = function() { + return this.contentWindow.document; +}; + +TinyMCEControl.prototype.getWin = function() { + return this.contentWindow; +}; + +TinyMCEControl.prototype.getSel = function() { + if (tinyMCE.isMSIE) + return this.getDoc().selection; + + var sel = this.contentWindow.getSelection(); + + // Fake getRangeAt + if (tinyMCE.isSafari && !sel.getRangeAt) { + var newSel = new Object(); + var doc = this.getDoc(); + + function getRangeAt(idx) { + var rng = new Object(); + + rng.startContainer = this.focusNode; + rng.endContainer = this.anchorNode; + rng.commonAncestorContainer = this.focusNode; + rng.createContextualFragment = function (html) { + // Seems to be a tag + if (html.charAt(0) == '<') { + var elm = doc.createElement("div"); + + elm.innerHTML = html; + + return elm.firstChild; + } + + return doc.createTextNode("UNSUPPORTED, DUE TO LIMITATIONS IN SAFARI!"); + }; + + rng.deleteContents = function () { + doc.execCommand("Delete", false, ""); + }; + + return rng; + } + + // Patch selection + + newSel.focusNode = sel.baseNode; + newSel.focusOffset = sel.baseOffset; + newSel.anchorNode = sel.extentNode; + newSel.anchorOffset = sel.extentOffset; + newSel.getRangeAt = getRangeAt; + newSel.text = "" + sel; + newSel.realSelection = sel; + + newSel.toString = function () {return this.text;}; + + return newSel; + } + + return sel; +}; + +TinyMCEControl.prototype.getRng = function() { + var sel = this.getSel(); + if (sel == null) + return null; + + if (tinyMCE.isMSIE) + return sel.createRange(); + + return this.getSel().getRangeAt(0); +}; + +TinyMCEControl.prototype._insertPara = function(e) { + function isEmpty(para) { + function isEmptyHTML(html) { + return html.replace(new RegExp('[ \t\r\n]+', 'g'), '').toLowerCase() == ""; + } + + // Check for images + if (para.getElementsByTagName("img").length > 0) + return false; + + // Check for tables + if (para.getElementsByTagName("table").length > 0) + return false; + + // Check for HRs + if (para.getElementsByTagName("hr").length > 0) + return false; + + // Check all textnodes + var nodes = tinyMCE.getNodeTree(para, new Array(), 3); + for (var i=0; i <" + blockName + "> "; + paraAfter = body.childNodes[1]; + } + + this.selectNode(paraAfter, true, true); + + return true; + } + + // Place first part within new paragraph + if (startChop.nodeName == blockName) + rngBefore.setStart(startChop, 0); + else + rngBefore.setStartBefore(startChop); + rngBefore.setEnd(startNode, startOffset); + paraBefore.appendChild(rngBefore.cloneContents()); + + // Place secound part within new paragraph + rngAfter.setEndAfter(endChop); + rngAfter.setStart(endNode, endOffset); + var contents = rngAfter.cloneContents(); + if (contents.firstChild && contents.firstChild.nodeName == blockName) { + var nodes = contents.firstChild.childNodes; + for (var i=0; i 0) + rng.pasteHTML('
    ' + rng.htmlText + "
    "); + + tinyMCE.triggerNodeChange(); + return; + } + } + } + + switch (command) { + case "mceSelectNode": + this.selectNode(value); + tinyMCE.triggerNodeChange(); + tinyMCE.selectedNode = value; + break; + + case "FormatBlock": + if (value == null || value == "") { + var elm = tinyMCE.getParentElement(this.getFocusElement(), "p,div,h1,h2,h3,h4,h5,h6,pre,address"); + + if (elm) + this.execCommand("mceRemoveNode", false, elm); + } else + this.getDoc().execCommand("FormatBlock", false, value); + + tinyMCE.triggerNodeChange(); + + break; + + case "mceRemoveNode": + if (!value) + value = tinyMCE.getParentElement(this.getFocusElement()); + + if (tinyMCE.isMSIE) { + value.outerHTML = value.innerHTML; + } else { + var rng = value.ownerDocument.createRange(); + rng.setStartBefore(value); + rng.setEndAfter(value); + rng.deleteContents(); + rng.insertNode(rng.createContextualFragment(value.innerHTML)); + } + + tinyMCE.triggerNodeChange(); + + break; + + case "mceSelectNodeDepth": + var parentNode = this.getFocusElement(); + for (var i=0; parentNode; i++) { + if (parentNode.nodeName.toLowerCase() == "body") + break; + + if (parentNode.nodeName.toLowerCase() == "#text") { + i--; + parentNode = parentNode.parentNode; + continue; + } + + if (i == value) { + this.selectNode(parentNode, false); + tinyMCE.triggerNodeChange(); + tinyMCE.selectedNode = parentNode; + return; + } + + parentNode = parentNode.parentNode; + } + + break; + + case "HiliteColor": + if (tinyMCE.isGecko) { + this.getDoc().execCommand("useCSS", false, false); + this.getDoc().execCommand('hilitecolor', false, value); + this.getDoc().execCommand("useCSS", false, true); + } else + this.getDoc().execCommand('BackColor', false, value); + + break; + + case "Cut": + case "Copy": + case "Paste": + var cmdFailed = false; + + // Try executing command + eval('try {this.getDoc().execCommand(command, user_interface, value);} catch (e) {cmdFailed = true;}'); + + // Alert error in gecko if command failed + if (tinyMCE.isGecko && cmdFailed) { + // Confirm more info + if (confirm(tinyMCE.getLang('lang_clipboard_msg'))) + window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', 'mceExternal'); + + return; + } else + tinyMCE.triggerNodeChange(); + break; + + case "mceSetContent": + if (!value) + value = ""; + + // Call custom cleanup code + value = tinyMCE._customCleanup("insert_to_editor", value); + tinyMCE._setHTML(doc, value); + doc.body.innerHTML = tinyMCE._cleanupHTML(doc, tinyMCE.settings, doc.body); + tinyMCE.handleVisualAid(doc.body, true, this.visualAid); + return true; + + case "mceLink": + var selectedText = ""; + + if (tinyMCE.isMSIE) { + var rng = doc.selection.createRange(); + selectedText = rng.text; + } else + selectedText = this.getSel().toString(); + + if (!tinyMCE.linkElement) { + if ((tinyMCE.selectedElement.nodeName.toLowerCase() != "img") && (selectedText.length <= 0)) + return; + } + + var href = "", target = "", title = "", onclick = "", action = "insert", style_class = ""; + + if (tinyMCE.selectedElement.nodeName.toLowerCase() == "a") + tinyMCE.linkElement = tinyMCE.selectedElement; + + // Is anchor not a link + if (tinyMCE.linkElement != null && tinyMCE.getAttrib(tinyMCE.linkElement, 'href') == "") + tinyMCE.linkElement = null; + + if (tinyMCE.linkElement) { + href = tinyMCE.getAttrib(tinyMCE.linkElement, 'href'); + target = tinyMCE.getAttrib(tinyMCE.linkElement, 'target'); + title = tinyMCE.getAttrib(tinyMCE.linkElement, 'title'); + onclick = tinyMCE.getAttrib(tinyMCE.linkElement, 'mce_onclick'); + style_class = tinyMCE.getAttrib(tinyMCE.linkElement, 'class'); + + // Try old onclick to if copy/pasted content + if (onclick == "") + onclick = tinyMCE.getAttrib(tinyMCE.linkElement, 'onclick'); + + onclick = tinyMCE.cleanupEventStr(onclick); + + // Fix for drag-drop/copy paste bug in Mozilla + mceRealHref = tinyMCE.getAttrib(tinyMCE.linkElement, 'mce_real_href'); + if (mceRealHref != "") + href = mceRealHref; + + href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement, true);"); + action = "update"; + } + + if (this.settings['insertlink_callback']) { + var returnVal = eval(this.settings['insertlink_callback'] + "(href, target, title, onclick, action, style_class);"); + if (returnVal && returnVal['href']) + tinyMCE.insertLink(returnVal['href'], returnVal['target'], returnVal['title'], returnVal['onclick'], returnVal['style_class']); + } else { + tinyMCE.openWindow(this.insertLinkTemplate, {href : href, target : target, title : title, onclick : onclick, action : action, className : style_class}); + } + break; + + case "mceAttachment": + var selectedText = ""; + + if (tinyMCE.isMSIE) { + var rng = doc.selection.createRange(); + selectedText = rng.text; + } else + selectedText = this.getSel().toString(); + + if (!tinyMCE.linkElement) { + if ((tinyMCE.selectedElement.nodeName.toLowerCase() != "img") && (selectedText.length <= 0)) + return; + } + + var href = "", target = "", title = "", onclick = "", action = "insert"; + + if (tinyMCE.selectedElement.nodeName.toLowerCase() == "a") + tinyMCE.linkElement = tinyMCE.selectedElement; + + // Is anchor not a link + if (tinyMCE.linkElement != null && tinyMCE.getAttrib(tinyMCE.linkElement, 'href') == "") + tinyMCE.linkElement = null; + + if (tinyMCE.linkElement) { + href = tinyMCE.getAttrib(tinyMCE.linkElement, 'href'); + target = tinyMCE.getAttrib(tinyMCE.linkElement, 'target'); + title = tinyMCE.getAttrib(tinyMCE.linkElement, 'title'); + onclick = tinyMCE.getAttrib(tinyMCE.linkElement, 'mce_onclick'); + + // Try old onclick to if copy/pasted content + if (onclick == "") + onclick = tinyMCE.getAttrib(tinyMCE.linkElement, 'onclick'); + + onclick = tinyMCE.cleanupEventStr(onclick); + + // Fix for drag-drop/copy paste bug in Mozilla + mceRealHref = tinyMCE.getAttrib(tinyMCE.linkElement, 'mce_real_href'); + if (mceRealHref != "") + href = mceRealHref; + + href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement, true);"); + action = "update"; + } + + if (this.settings['insertlink_callback']) { + var returnVal = eval(this.settings['insertlink_callback'] + "(href, target, title, onclick, action);"); + if (returnVal && returnVal['href']) + tinyMCE.insertLink(returnVal['href'], returnVal['target'], returnVal['title'], returnVal['onclick']); + } else { + tinyMCE.openWindow(this.insertAttachmentTemplate, {href : href, target : target, title : title, onclick : onclick, action : action}); + } + break; + + case "mceImage": + var src = "", alt = "", border = "", hspace = "", vspace = "", width = "", height = "", align = ""; + var title = "", onmouseover = "", onmouseout = "", action = "insert"; + var img = tinyMCE.imgElement; + + if (tinyMCE.selectedElement != null && tinyMCE.selectedElement.nodeName.toLowerCase() == "img") { + img = tinyMCE.selectedElement; + tinyMCE.imgElement = img; + } + + if (img) { + // Is it a internal MCE visual aid image, then skip this one. + if (tinyMCE.getAttrib(img, 'name').indexOf('mce_') == 0) + return; + + src = tinyMCE.getAttrib(img, 'src'); + alt = tinyMCE.getAttrib(img, 'alt'); + + // Try polling out the title + if (alt == "") + alt = tinyMCE.getAttrib(img, 'title'); + + // Fix width/height attributes if the styles is specified + if (tinyMCE.isGecko) { + var w = img.style.width; + if (w != null && w != "") + img.setAttribute("width", w); + + var h = img.style.height; + if (h != null && h != "") + img.setAttribute("height", h); + } + + border = tinyMCE.getAttrib(img, 'border'); + hspace = tinyMCE.getAttrib(img, 'hspace'); + vspace = tinyMCE.getAttrib(img, 'vspace'); + width = tinyMCE.getAttrib(img, 'width'); + height = tinyMCE.getAttrib(img, 'height'); + align = tinyMCE.getAttrib(img, 'align'); + onmouseover = tinyMCE.getAttrib(img, 'onmouseover'); + onmouseout = tinyMCE.getAttrib(img, 'onmouseout'); + title = tinyMCE.getAttrib(img, 'title'); + + // Is realy specified? + if (tinyMCE.isMSIE) { + width = img.attributes['width'].specified ? width : ""; + height = img.attributes['height'].specified ? height : ""; + } + + onmouseover = tinyMCE.getImageSrc(tinyMCE.cleanupEventStr(onmouseover)); + onmouseout = tinyMCE.getImageSrc(tinyMCE.cleanupEventStr(onmouseout)); + + // Fix for drag-drop/copy paste bug in Mozilla + mceRealSrc = tinyMCE.getAttrib(img, 'mce_real_src'); + if (mceRealSrc != "") + src = mceRealSrc; + + src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, img, true);"); + + if (onmouseover != "") + onmouseover = eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseover, img, true);"); + + if (onmouseout != "") + onmouseout = eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseout, img, true);"); + + action = "update"; + } + + if (this.settings['insertimage_callback']) { + var returnVal = eval(this.settings['insertimage_callback'] + "(src, alt, border, hspace, vspace, width, height, align, title, onmouseover, onmouseout, action);"); + if (returnVal && returnVal['src']) + tinyMCE.insertImage(returnVal['src'], returnVal['alt'], returnVal['border'], returnVal['hspace'], returnVal['vspace'], returnVal['width'], returnVal['height'], returnVal['align'], returnVal['title'], returnVal['onmouseover'], returnVal['onmouseout']); + } else + tinyMCE.openWindow(this.insertImageTemplate, {src : src, alt : alt, border : border, hspace : hspace, vspace : vspace, width : width, height : height, align : align, title : title, onmouseover : onmouseover, onmouseout : onmouseout, action : action}); + break; + + case "mceCleanupWord": + if (tinyMCE.isMSIE) { + var html = this.getBody().createTextRange().htmlText; + + if (html.indexOf('="mso') != -1) { + tinyMCE._setHTML(this.contentDocument, this.getBody().innerHTML); + html = tinyMCE._cleanupHTML(this.contentDocument, this.settings, this.getBody(), this.visualAid); + } + + this.getBody().innerHTML = html; + } + break; + + case "mceCleanup": + tinyMCE._setHTML(this.contentDocument, this.getBody().innerHTML); + this.getBody().innerHTML = tinyMCE._cleanupHTML(this.contentDocument, this.settings, this.getBody(), this.visualAid); + tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid); + this.repaint(); + tinyMCE.triggerNodeChange(); + break; + + case "mceAnchor": + if (!user_interface) { + var aElm = tinyMCE.getParentElement(this.getFocusElement(), "a", "name"); + if (aElm) { + if (value == null || value == "") { + if (tinyMCE.isMSIE) { + aElm.outerHTML = aElm.innerHTML; + } else { + var rng = aElm.ownerDocument.createRange(); + rng.setStartBefore(aElm); + rng.setEndAfter(aElm); + rng.deleteContents(); + rng.insertNode(rng.createContextualFragment(aElm.innerHTML)); + } + } else + aElm.setAttribute('name', value); + } else { + this.getDoc().execCommand("fontname", false, "#mce_temp_font#"); + var elementArray = tinyMCE.getElementsByAttributeValue(this.getBody(), "font", "face", "#mce_temp_font#"); + for (var x=0; x 0) { + value = tinyMCE.replaceVar(value, "selection", selectedText); + tinyMCE.execCommand('mceInsertContent', false, value); + } + + tinyMCE.triggerNodeChange(); + break; + + case "mceSetAttribute": + if (typeof(value) == 'object') { + var targetElms = (typeof(value['targets']) == "undefined") ? "p,img,span,div,td,h1,h2,h3,h4,h5,h6,pre,address" : value['targets']; + var targetNode = tinyMCE.getParentElement(this.getFocusElement(), targetElms); + + if (targetNode) { + targetNode.setAttribute(value['name'], value['value']); + tinyMCE.triggerNodeChange(); + } + } + break; + + case "mceSetCSSClass": + var selectedText = false; + + if (tinyMCE.isMSIE) { + var rng = doc.selection.createRange(); + selectedText = (rng.text && rng.text.length > 0); + } else + selectedText = (this.getSel().toString().length > 0); + + // Use selectedNode instead if defined + if (tinyMCE.selectedNode) + tinyMCE.selectedElement = tinyMCE.selectedNode; + + if (selectedText && !tinyMCE.selectedNode) { + this.getDoc().execCommand("RemoveFormat", false, null); + if (value == null) + return this.execCommand("RemoveFormat", false, null); + + this.getDoc().execCommand("fontname", false, "#mce_temp_font#"); + var elementArray = tinyMCE.getElementsByAttributeValue(this.getBody(), "font", "face", "#mce_temp_font#"); + + // Change them all + for (var x=0; x customUndoLevels) { + for (var i=0; i 0) { + this.undoIndex--; + this.getBody().innerHTML = this.undoLevels[this.undoIndex]; + } + + // debug("Undo - undo levels:" + this.undoLevels.length + ", undo index: " + this.undoIndex); + tinyMCE.triggerNodeChange(); + } else + this.getDoc().execCommand(command, user_interface, value); + break; + + case "Redo": + if (tinyMCE.settings['custom_undo_redo']) { + if (this.undoIndex < (this.undoLevels.length-1)) { + this.undoIndex++; + this.getBody().innerHTML = this.undoLevels[this.undoIndex]; + // debug("Redo - undo levels:" + this.undoLevels.length + ", undo index: " + this.undoIndex); + } + + tinyMCE.triggerNodeChange(); + } else + this.getDoc().execCommand(command, user_interface, value); + break; + + case "mceToggleVisualAid": + this.visualAid = !this.visualAid; + tinyMCE.handleVisualAid(this.getBody(), true, this.visualAid); + tinyMCE.triggerNodeChange(); + break; + + case "removeformat": + var text = this.getSelectedText(); + + if (tinyMCE.isMSIE) { + try { + win.focus(); + var rng = doc.selection.createRange(); + rng.execCommand("RemoveFormat", false, null); + rng.pasteHTML(rng.text); + } catch (e) { + // Do nothing + } + } else + this.getDoc().execCommand(command, user_interface, value); + + // Remove class + if (text.length == 0) + this.execCommand("mceSetCSSClass", false, ""); + + tinyMCE.triggerNodeChange(); + break; + + default: + this.getDoc().execCommand(command, user_interface, value); + tinyMCE.triggerNodeChange(); + } +}; + +TinyMCEControl.prototype.queryCommandValue = function(command) { + return this.getDoc().queryCommandValue(command); +}; + +TinyMCEControl.prototype.queryCommandState = function(command) { + return this.getDoc().queryCommandState(command); +}; + +TinyMCEControl.prototype.onAdd = function(replace_element, form_element_name, target_document) { + var targetDoc = target_document ? target_document : document; + + this.targetDoc = targetDoc; + + tinyMCE.themeURL = tinyMCE.baseURL + "/themes/" + this.settings['theme']; + this.settings['themeurl'] = tinyMCE.themeURL; + + if (!replace_element) { + alert("Error: Could not find the target element."); + return false; + } + + var templateFunction = tinyMCE._getThemeFunction('_getInsertLinkTemplate'); + if (eval("typeof(" + templateFunction + ")") != 'undefined') + this.insertLinkTemplate = eval(templateFunction + '(this.settings);'); + + var templateFunction = tinyMCE._getThemeFunction('_getInsertAttachmentTemplate'); + if (eval("typeof(" + templateFunction + ")") != 'undefined') + this.insertAttachmentTemplate = eval(templateFunction + '(this.settings);'); + + var templateFunction = tinyMCE._getThemeFunction('_getInsertImageTemplate'); + if (eval("typeof(" + templateFunction + ")") != 'undefined') + this.insertImageTemplate = eval(templateFunction + '(this.settings);'); + + var templateFunction = tinyMCE._getThemeFunction('_getEditorTemplate'); + if (eval("typeof(" + templateFunction + ")") == 'undefined') { + alert("Error: Could not find the template function: " + templateFunction); + return false; + } + + var editorTemplate = eval(templateFunction + '(this.settings, this.editorId);'); + + var deltaWidth = editorTemplate['delta_width'] ? editorTemplate['delta_width'] : 0; + var deltaHeight = editorTemplate['delta_height'] ? editorTemplate['delta_height'] : 0; + var html = '' + editorTemplate['html']; + + var templateFunction = tinyMCE._getThemeFunction('_handleNodeChange', true); + if (eval("typeof(" + templateFunction + ")") != 'undefined') + this.settings['handleNodeChangeCallback'] = templateFunction; + + html = tinyMCE.replaceVar(html, "editor_id", this.editorId); + html = tinyMCE.replaceVar(html, "default_document", tinyMCE.baseURL + "/blank.htm"); + this.settings['default_document'] = tinyMCE.baseURL + "/blank.htm"; + + this.settings['old_width'] = this.settings['width']; + this.settings['old_height'] = this.settings['height']; + + // Set default width, height + if (this.settings['width'] == -1) + this.settings['width'] = replace_element.offsetWidth; + + if (this.settings['height'] == -1) + this.settings['height'] = replace_element.offsetHeight; + + // Try the style width + if (this.settings['width'] == 0) + this.settings['width'] = replace_element.style.width; + + // Try the style height + if (this.settings['height'] == 0) + this.settings['height'] = replace_element.style.height; + + // If no width/height then default to 320x240, better than nothing + if (this.settings['width'] == 0) + this.settings['width'] = 320; + + if (this.settings['height'] == 0) + this.settings['height'] = 240; + + this.settings['area_width'] = parseInt(this.settings['width']); + this.settings['area_height'] = parseInt(this.settings['height']); + this.settings['area_width'] += deltaWidth; + this.settings['area_height'] += deltaHeight; + + // Special % handling + if (("" + this.settings['width']).indexOf('%') != -1) + this.settings['area_width'] = "100%"; + + if (("" + this.settings['height']).indexOf('%') != -1) + this.settings['area_height'] = "100%"; + + if (("" + replace_element.style.width).indexOf('%') != -1) { + this.settings['width'] = replace_element.style.width; + this.settings['area_width'] = "100%"; + } + + if (("" + replace_element.style.height).indexOf('%') != -1) { + this.settings['height'] = replace_element.style.height; + this.settings['area_height'] = "100%"; + } + + html = tinyMCE.applyTemplate(html); + + this.settings['width'] = this.settings['old_width']; + this.settings['height'] = this.settings['old_height']; + + this.visualAid = this.settings['visual']; + this.formTargetElementId = form_element_name; + + // Get replace_element contents + if (replace_element.nodeName.toLowerCase() == "textarea") + this.startContent = replace_element.value; + else + this.startContent = replace_element.innerHTML; + + // If not text area + if (replace_element.nodeName.toLowerCase() != "textarea") { + this.oldTargetElement = replace_element.cloneNode(true); + + // Debug mode + if (tinyMCE.settings['debug']) + html += ''; + else + html += ''; + + html += ''; + + // Output HTML and set editable + if (!tinyMCE.isMSIE) { + var rng = replace_element.ownerDocument.createRange(); + rng.setStartBefore(replace_element); + + var fragment = rng.createContextualFragment(html); + replace_element.parentNode.replaceChild(fragment, replace_element); + } else + replace_element.outerHTML = html; + } else { + html += ''; + + // Just hide the textarea element + this.oldTargetElement = replace_element; + + if (!tinyMCE.settings['debug']) + this.oldTargetElement.style.display = "none"; + + // Output HTML and set editable + if (!tinyMCE.isMSIE) { + var rng = replace_element.ownerDocument.createRange(); + rng.setStartBefore(replace_element); + + var fragment = rng.createContextualFragment(html); + replace_element.parentNode.insertBefore(fragment, replace_element); + } else + replace_element.insertAdjacentHTML("beforeBegin", html); + } + + // Setup iframe + var dynamicIFrame = false; + var tElm = targetDoc.getElementById(this.editorId); + + if (!tinyMCE.isMSIE) { + if (tElm && tElm.nodeName.toLowerCase() == "span") { + tElm = tinyMCE._createIFrame(tElm); + dynamicIFrame = true; + } + + this.targetElement = tElm; + this.iframeElement = tElm; + this.contentDocument = tElm.contentDocument; + this.contentWindow = tElm.contentWindow; + + //this.getDoc().designMode = "on"; + } else { + if (tElm && tElm.nodeName.toLowerCase() == "span") + tElm = tinyMCE._createIFrame(tElm); + else + tElm = targetDoc.frames[this.editorId]; + + this.targetElement = tElm; + this.iframeElement = targetDoc.getElementById(this.editorId); + this.contentDocument = tElm.window.document; + this.contentWindow = tElm.window; + this.getDoc().designMode = "on"; + } + + // Setup base HTML + var doc = this.contentDocument; + if (dynamicIFrame) { + var html = "" + + '' + + '' + + '' + + '' + + 'blank_page' + + '' + + '' + + '' + + '' + + ''; + + try { + this.getDoc().designMode = "on"; + doc.open(); + doc.write(html); + doc.close(); + } catch (e) { + // Failed Mozilla 1.3 + this.getDoc().location.href = tinyMCE.baseURL + "/blank.htm"; + } + } + + // This timeout is needed in MSIE 5.5 for some odd reason + // it seems that the document.frames isn't initialized yet? + if (tinyMCE.isMSIE) + window.setTimeout("TinyMCE.prototype.addEventHandlers('" + this.editorId + "');", 1); + + tinyMCE.setupContent(this.editorId, true); + + return true; +}; + +TinyMCEControl.prototype.getFocusElement = function() { + if (tinyMCE.isMSIE) { + var doc = this.getDoc(); + var rng = doc.selection.createRange(); + + if (rng.collapse) + rng.collapse(true); + + var elm = rng.item ? rng.item(0) : rng.parentElement(); + } else { + var sel = this.getSel(); + var elm = (sel && sel.anchorNode) ? sel.anchorNode : null; + + if (tinyMCE.selectedElement != null && tinyMCE.selectedElement.nodeName.toLowerCase() == "img") + elm = tinyMCE.selectedElement; + } + + return elm; +}; + +// Global instances +var tinyMCE = new TinyMCE(); +var tinyMCELang = new Array(); + +function debug() { + var msg = ""; + + var elm = document.getElementById("tinymce_debug"); + if (!elm) { + var debugDiv = document.createElement("div"); + debugDiv.setAttribute("className", "debugger"); + debugDiv.className = "debugger"; + debugDiv.innerHTML = '\ + Debug output:\ + '; + + document.body.appendChild(debugDiv); + elm = document.getElementById("tinymce_debug"); + } + + var args = this.debug.arguments; + for (var i=0; i 0 +end + +puts "Done - #{total_replacements} total replacements made." diff --git a/script/localize b/script/localize new file mode 100755 index 0000000..1757ecf --- /dev/null +++ b/script/localize @@ -0,0 +1,48 @@ +#!/usr/bin/env ruby + +# we need fileutils for easy file access +require 'fileutils' +require 'rubygems' +include FileUtils +# we will need the modified rgettext.rb that can read erb templates +require File.dirname(__FILE__) + '/rgettext' + + +# RAILS_ROOT is just one up +RAILS_ROOT = File.expand_path(File.dirname(__FILE__) + '/..') +# $DEBUG = true +# goto RAILS_ROOT so we can address all files relatively from there +Dir.chdir(RAILS_ROOT) + +# the potfile will hold the temporary data before it is merged; note the +# filename .messages.pot (if you don't prepend a dot to the filename Dir.glob +# will get confused later on) +potfile = "#{RAILS_ROOT}/locale/.messages.pot" + +# if the potfile exists from the previous run, delete it +rm_f potfile + +# directories and extensions to harvest +dirpattern = '{app,components,config,custom,lib}' +extpattern = 'r{b,html,xml}' +files = Dir.glob("#{dirpattern}/**/*.#{extpattern}") + +# run the harvester on the collected filenames and output to potfile +RGettext.new.start files, potfile + +# now iterate through all locale dirs and update/merge +Dir.glob('locale/*').each do |dir| + # check if every dir has a pofile to begin with, else msmerge will fail + # if not, use the potfile and don't merge + pofile = "#{RAILS_ROOT}/#{dir}/LC_MESSAGES/messages.po" + if File.exists?(pofile) + print "Updating pofile #{pofile} " + system "msgmerge --force-po --no-location --update #{pofile} #{potfile}" + else + print "The pofile '#{pofile}' does not exist. I will create it for you " + path_to_pofile = File.dirname(pofile) + mkdir path_to_pofile unless File.exists?(path_to_pofile) + cp potfile, pofile + puts ' .... done.' + end +end diff --git a/script/performance/benchmarker b/script/performance/benchmarker new file mode 100755 index 0000000..462cae1 --- /dev/null +++ b/script/performance/benchmarker @@ -0,0 +1,3 @@ +#!/usr/bin/ruby18 +require File.dirname(__FILE__) + '/../../config/boot' +require 'commands/performance/benchmarker' diff --git a/script/performance/profiler b/script/performance/profiler new file mode 100755 index 0000000..8b3a633 --- /dev/null +++ b/script/performance/profiler @@ -0,0 +1,3 @@ +#!/usr/bin/ruby18 +require File.dirname(__FILE__) + '/../../config/boot' +require 'commands/performance/profiler' diff --git a/script/process/reaper b/script/process/reaper new file mode 100755 index 0000000..af0b34d --- /dev/null +++ b/script/process/reaper @@ -0,0 +1,3 @@ +#!/usr/bin/ruby18 +require File.dirname(__FILE__) + '/../../config/boot' +require 'commands/process/reaper' diff --git a/script/process/spawner b/script/process/spawner new file mode 100755 index 0000000..ffb55ae --- /dev/null +++ b/script/process/spawner @@ -0,0 +1,3 @@ +#!/usr/bin/ruby18 +require File.dirname(__FILE__) + '/../../config/boot' +require 'commands/process/spawner' diff --git a/script/process/spinner b/script/process/spinner new file mode 100755 index 0000000..c1ce730 --- /dev/null +++ b/script/process/spinner @@ -0,0 +1,3 @@ +#!/usr/bin/ruby18 +require File.dirname(__FILE__) + '/../../config/boot' +require 'commands/process/spinner' diff --git a/script/profiler b/script/profiler new file mode 100755 index 0000000..77c9fbe --- /dev/null +++ b/script/profiler @@ -0,0 +1,34 @@ +#!/usr/bin/env ruby +if ARGV.empty? + $stderr.puts "Usage: profiler 'Person.expensive_method(10)' [times]" + exit(1) +end + +# Keep the expensive require out of the profile. +$stderr.puts 'Loading Rails...' +require File.dirname(__FILE__) + '/../config/environment' + +# Define a method to profile. +if ARGV[1] and ARGV[1].to_i > 1 + eval "def profile_me() #{ARGV[1]}.times { #{ARGV[0]} } end" +else + eval "def profile_me() #{ARGV[0]} end" +end + +# Use the ruby-prof extension if available. Fall back to stdlib profiler. +begin + require 'prof' + $stderr.puts 'Using the ruby-prof extension.' + Prof.clock_mode = Prof::GETTIMEOFDAY + Prof.start + profile_me + results = Prof.stop + require 'rubyprof_ext' + Prof.print_profile(results, $stderr) +rescue LoadError + $stderr.puts 'Using the standard Ruby profiler.' + Profiler__.start_profile + profile_me + Profiler__.stop_profile + Profiler__.print_profile($stderr) +end diff --git a/script/rgettext.rb b/script/rgettext.rb new file mode 100755 index 0000000..3702f47 --- /dev/null +++ b/script/rgettext.rb @@ -0,0 +1,215 @@ +#!/usr/bin/env ruby +=begin + rgettext - ruby version of xgettext + Copyright (C) 2005 Sascha Ebach + Copyright (C) 2003,2004 Masao Mutoh + Copyright (C) 2001,2002 Yasushi Shoji, Masao Mutoh + + Yasushi Shoji + Masao Mutoh + Sascha Ebach + + You may redistribute it and/or modify it under the same + license terms as Ruby. + + 2005-03-12: Added support for eruby templates (Sascha Ebach) + 2005-03-20: Added second parameter to RGetext.start to allow different + output when not called from the command line. Pulled out + RGetext.set_output(). + +=end + +require 'gettext/parser/ruby' +require 'gettext/parser/glade' + +require 'getoptlong' +require 'gettext' + +require 'tempfile' +require 'erb' + +class RGettext + include GetText + + # constant values + VERSION = %w($Revision: 1.15 $)[1].scan(/\d+/).collect {|s| s.to_i} + DATE = %w($Date: 2004/11/05 18:19:08 $)[1] + MAX_LINE_LEN = 70 + + def start(files=ARGV, output = nil) + opt = check_options + opt['output'] = output unless output.nil? + set_output(opt) + + + if files.empty? + print_help + exit + end + + ary = [] + files.each do |file| + begin + $stderr.puts "Processing #{file}" + if glade_file?(file) + ary = GladeParser.parse(file, ary) + elsif erb_file?(file) + content = File.open(file, 'r') {|f| f.read } + tf = Tempfile.new('erb-gettext') + tf.puts ERB.new(content).src + tf.close + old_index = ary.size - 1 + ary = GetText::RubyParser.parse(tf.path, ary) + #replace tokens with /tmp/... with real file names + for i in old_index..ary.size-1 + for j in 0..ary[i].size-1 + ary[i][j] = ary[i][j].gsub("#{tf.path}", file) + end + end + tf.close true + else + ary = RubyParser.parse(file, ary) + end + rescue + puts $! + exit 1 + end + end + generate_pot_header + generate_pot(ary) + @out.close + end + + # following methods are + private + XML_RE = /<\?xml/ + GLADE_RE = /glade-2.0.dtd/ + + def erb_file?(file) + File.extname(file) == '.rhtml' + end + + def glade_file?(file) + data = IO.readlines(file) + if XML_RE =~ data[0] + if GLADE_RE =~ data[1] + return true + else + raise _("%s is not glade-2.0 format.") % [file] + end + else + return false + end + end + + def initialize + bindtextdomain("rgettext") + end + + def generate_pot_header + time = Time.now.strftime("%Y-%m-%d %H:%M%z") + @out << "# SOME DESCRIPTIVE TITLE.\n" + @out << "# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n" + @out << "# This file is distributed under the same license as the PACKAGE package.\n" + @out << "# FIRST AUTHOR , YEAR.\n" + @out << "#\n" + @out << "#, fuzzy\n" + @out << "msgid \"\"\n" + @out << "msgstr \"\"\n" + @out << "\"Project-Id-Version: PACKAGE VERSION\\n\"\n" + @out << "\"POT-Creation-Date: #{time}\\n\"\n" + @out << "\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n" + @out << "\"Last-Translator: FULL NAME \\n\"\n" + @out << "\"Language-Team: LANGUAGE \\n\"\n" + @out << "\"MIME-Version: 1.0\\n\"\n" + @out << "\"Content-Type: text/plain; charset=UTF-8\\n\"\n" + @out << "\"Content-Transfer-Encoding: 8bit\\n\"\n" + @out << "\"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n\"\n" + end + + def generate_pot(ary) + result = Array.new + ary.each do |key| + msgid = key.shift + curr_pos = MAX_LINE_LEN + key.each do |e| + if curr_pos + e.size > MAX_LINE_LEN + @out << "\n#:" + curr_pos = 3 + else + curr_pos += (e.size + 1) + end + @out << " " << e + end + msgid.gsub!(/"/, '\"') + msgid.gsub!(/\r/, '') + if msgid.include?("\000") + ids = msgid.split(/\000/) + @out << "\nmsgid \"" << ids[0] << "\"\n" + @out << "msgid_plural \"" << ids[1] << "\"\n" + @out << "msgstr[0] \"\"\n" + @out << "msgstr[1] \"\"\n" + else + @out << "\nmsgid \"" << msgid << "\"\n" + @out << "msgstr \"\"\n" + end + end + end + + def print_help + printf _("Usage: %s input.rb -o output.pot\n"), $0 + print _("Extract translatable strings from given input files.\n\n") + end + + def check_options + command_options = [ + ['--help', '-h', GetoptLong::NO_ARGUMENT], #'print this help and exit'], + ['--version', '-v', GetoptLong::NO_ARGUMENT], #'print version info and exit'], + ['--output', '-o', GetoptLong::REQUIRED_ARGUMENT]#, ['FILE', 'write output to specified file']] + ] + + parser = GetoptLong.new + parser.set_options(*command_options) + + opt = Hash.new + parser.each do |name, arg| + opt.store(name.sub(/^--/, ""), arg || true) + end + + if opt['version'] + print "#{$0} #{VERSION.join('.')} \(#{DATE}\)\n\n" + exit + end + + if opt['help'] + print_help + exit + end + + opt + end + + def set_output(opt) + if opt['output'] + unless FileTest.exist? opt['output'] + @out = File.new(File.expand_path(opt['output']), "w+") + else + if $>.tty? + # FIXME + printf $stderr, "File '#{opt['output']}' already exists\n" + exit 1 + else + printf $stderr, "File '#{opt['output']}' already exists" + exit 1 + end + end + else + @out = STDOUT + end + end +end # class RGettext + +if __FILE__ == $0 # in case we want to start it from somewhere else + rgettext = RGettext.new + rgettext.start +end diff --git a/script/runner b/script/runner new file mode 100755 index 0000000..57211c6 --- /dev/null +++ b/script/runner @@ -0,0 +1,3 @@ +#!/usr/bin/ruby18 +require File.dirname(__FILE__) + '/../config/boot' +require 'commands/runner' \ No newline at end of file diff --git a/script/scgi_rails b/script/scgi_rails new file mode 100755 index 0000000..dc470d8 --- /dev/null +++ b/script/scgi_rails @@ -0,0 +1,339 @@ +#!/usr/bin/env ruby + +require 'stringio' +require 'yaml' +require 'digest/sha1' +require 'logger' +require 'fileutils' +require 'socket' +require 'cgi' +require 'rubygems' +require 'cmdparse' +require 'monitor' + +def log(msg) + $stderr.print msg,"\n" +end + +def error(msg, exc=nil) + if exc + $stderr.print "ERROR: #{msg}: #{exc}\n" + $stderr.puts exc.backtrace + else + $stderr.print "ERROR: #{msg}\n" + end +end + + +# Modifies CGI so that we can use it. +class SCGIFixed < ::CGI + public :env_table + + def initialize(params, data, out, *args) + @env_table = params + @args = *args + @input = StringIO.new(data) + @out = out + super(*args) + end + def args + @args + end + def env_table + @env_table + end + def stdinput + @input + end + def stdoutput + @out + end +end + + +class SCGIProcessor < Monitor + + def initialize(settings) + @env = settings[:env] || "development" + @debug = settings[:debug] || false + @host = settings[:host] || "127.0.0.1" + @port = settings[:port] || "9999" + @children = settings[:children] || 1 + @pid_file = settings[:pid_file] || "children.yaml" + @status_dir = settings[:status_dir] || "/tmp" + @log_file = settings[:logfile] || "log/scgi.log" + @maxconns = settings[:maxconns] + @busy_msg = settings[:busy_msg] || "BUSY" + @settings = settings + @started = Time.now + @conns = 0 + @total_conns = 0 + @errors = 0 + + if @maxconns + @maxconns = @maxconns.to_i + else + @maxconns = 2**30-1 + end + + if settings[:conns_second] + @throttle_sleep = 1.0/settings[:conns_second].to_i + end + + super() + end + + def run + ENV['RAILS_ENV'] = @env + + begin + require_gem 'rails' + require "config/environment" + rescue Object + error("loading rails environment", $!) + end + + server = TCPServer.new(@host, @port) + + if @debug + log("Listening for connections on #@host:#@port") + listen(server) + else + childpids = [] + @children.to_i.times do + # fork each child listening to the same port. very simple yet effective way to spread the load + # to multiple processes without using threads and still using high performance libevent + begin + pid = fork do + $stderr = open(@log_file,"w") + $stderr.sync = false + listen(server) + end + childpids << pid + Process.detach(pid) + rescue Object + error("Could not fork child processes. Your system might not support fork. Use -D instead.", $!) + end + end + + # tell the user what the sha1 is so they can check for modification later + log("#@pid_file will have SHA1 #{Digest::SHA1.hexdigest(YAML.dump(childpids))}") + log("Record this somewhere so you know if it was modified later by someone else.") + # all children forked and the pids are now ready to write to the pid file + open(@pid_file,"w") { |f| f.write(YAML.dump(childpids)) } + end + end + + + def listen(socket) + thread = Thread.new do + while true + handle_client(socket.accept) + sleep @throttle_sleep if @throttle_sleep + + @total_conns += 1 + end + end + + begin + thread.join + rescue Interrupt + log("Shutting down from SIGINT.") + rescue Object + error("while listening for connections on #@host:#@port", $!) + end + end + + + def handle_client(socket) + Thread.new do + begin + synchronize { @conns += 1} + + len = "" + # we only read 10 bytes of the length. any request longer than this is invalid + while len.length <= 10 + c = socket.read(1) + if c == ':' + # found the terminal, len now has a length in it so read the payload + break + else + len << c + end + end + + # we should now either have a payload length to get + payload = socket.read(len.to_i) + if (c = socket.read(1)) != ',' + error("Malformed request, does not end with ','") + else + read_header(socket, payload, @conns) + end + rescue IOError + error("received IOError #$! when handling client. Your web server doesn't like me.") + rescue Object + @errors += 1 + error("after accepting client #@host:#@port -- #{$!.class}", $!) + ensure + synchronize { @conns -= 1} + socket.close if not socket.closed? + end + end + + end + + + def read_header(socket, payload, conns) + return if socket.closed? + request = split_body(payload) + if request and request["CONTENT_LENGTH"] + length = request["CONTENT_LENGTH"].to_i + if length > 0 + body = socket.read(length) + else + body = "" + end + + if @conns > @maxconns + socket.write("Content-type: text/plain\r\n\r\n") + socket.write(@busy_msg) + else + process_request(request, body, socket) + end + end + end + + + def process_request(request, body, socket) + return if socket.closed? + cgi = SCGIFixed.new(request, body, socket) + begin + synchronize do + # unfortuneatly, the dependencies.rb file is not thread safe and will throw exceptions + # claiming that Dispatcher is not defined, or that other classes are missing. We have + # to sync the dispatch call to get around this. + Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, cgi.stdoutput) + end + rescue IOError + error("received IOError #$! when handling client. Your web server doesn't like me.") + rescue Object => rails_error + error("calling Dispatcher.dispatch", rails_error) + end + end + + + def split_body(data) + result = {} + el = data.split("\0") + i = 0 + len = el.length + while i < len + result[el[i]] = el[i+1] + i += 1 + end + + return result + end + + def status + pid = Process.pid + open("#@status_dir/scgi_rails-status.#{pid}","w") do |f| + status = { + 'time' => Time.now, 'pid' => pid, 'settings' => @settings, + 'env' => @env, 'status_dir' => @status_dir, 'started' => @started, + 'max_conns' => @maxconns, 'total_conns' => @total_conns, + 'conns' => @conns, 'errors' => @errors, 'systimes' => Process.times + } + f.write(YAML.dump(status)) + end + end +end + + +def signal_children(pidfile, signal) + if not File.exists? pidfile + log("No #{pidfile} as specified. Probably nothing running or wrong path.") + exit 1 + end + + childpids = YAML.load_file(pidfile) + childpids.each do |pid| + begin + log("Signaling pid #{pid}") + Process.kill(signal, pid) + rescue Object + log("Couldn't send #{signal} signal to #{pid} pid.") + end + end +end + + +def make_command(parent, name, desc, options) + cmd = CmdParse::Command.new(name, false ) + cmd.short_desc = desc + settings = {} + cmd.options = CmdParse::OptionParserWrapper.new do |opt| + options.each do |short, long, info, symbol| + opt.on(short, long, info) {|val| settings[symbol] = val} + end + end + cmd.set_execution_block do |args| + yield(settings, args) + end + parent.add_command(cmd) +end + + +cmd = CmdParse::CommandParser.new( true ) +cmd.program_name = "scgi_rails" +cmd.program_version = [0, 2, 1] +cmd.options = CmdParse::OptionParserWrapper.new do |opt| + opt.separator "Global options:" + opt.on("--verbose", "Be verbose when outputting info") {|t| $verbose = true } +end + +cmd.add_command( CmdParse::HelpCommand.new ) +cmd.add_command( CmdParse::VersionCommand.new ) + +make_command(cmd, 'start', "Start Rails Application", +[['-e','--env STRING','Rails environment', :env], +['-D','--[no-]debug', 'Do not fork children, stay in foreground.', :debug], +['-h','--host STRING', 'IP address to bind as server', :host], +['-p','--port NUMBER', 'Port to bind to', :port], +['-c','--children NUMBER', 'Number of children to start (not win32)', :children], +['-f','--pid-file PATH', 'Where to read the list of running children', :pid_file], +['-l','--log-file PATH', 'Use a different log from from log/scgi.log', :logfile], +['-t','--throttle NUMBER', 'Max conn/second to allow.', :conns_second], +['-m','--max-conns NUMBER', 'Max simultaneous connections before the busy message', :maxconns], +['-b','--busy-msg', 'Busy message given to clients over the max connections ("busy")', :busy_msg], +['-s','--status-dir PATH', 'Where to put the status files', :status_dir]]) do |settings, args| + scgi = SCGIProcessor.new(settings) + begin + trap("HUP") { scgi.status } + rescue Object + error("Could not setup a SIGHUP handler. You won't be able to get status.") + end + + scgi.run +end + + +make_command(cmd, 'status', "Get status from all running children", +[['-s','--status-dir PATH', 'Where to put the status files', :status_dir], +['-f','--pid-file PATH', 'Where to read the list of running children', :pid_file]]) do |settings, args| + signal_children(settings[:pid_file] || 'children.yaml', "HUP") + log("Status files for each child should show up in the configured status directory (/tmp by default).") +end + +make_command(cmd, 'stop', "Stop all running children", +[['-s','--sig SIGNAL', 'Where to put the status files', :signal], +['-n','--[no-]delete', 'Keep the children.yaml file rather than delete', :nodelete], +['-f','--pid-file PATH', 'Where to read the list of running children', :pid_file]]) do |settings, args| + pid_file = settings[:pid_file] || "children.yaml" + signal_children(pid_file, settings[:signal] || "INT") + if not settings[:nodelete] and File.exist?(pid_file) + File.unlink(pid_file) + end +end + +cmd.parse \ No newline at end of file diff --git a/script/server b/script/server new file mode 100755 index 0000000..9436fde --- /dev/null +++ b/script/server @@ -0,0 +1,3 @@ +#!/usr/bin/ruby18 +require File.dirname(__FILE__) + '/../config/boot' +require 'commands/server' \ No newline at end of file diff --git a/test/fixtures/expressions.yml b/test/fixtures/expressions.yml new file mode 100644 index 0000000..e3fa03c --- /dev/null +++ b/test/fixtures/expressions.yml @@ -0,0 +1,5 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html +first_expression: + id: 1 +another_expression: + id: 2 diff --git a/test/fixtures/filters.yml b/test/fixtures/filters.yml new file mode 100644 index 0000000..b36dd3b --- /dev/null +++ b/test/fixtures/filters.yml @@ -0,0 +1,5 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html +first_filter: + id: 1 +another_filter: + id: 2 diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml new file mode 100644 index 0000000..c884985 --- /dev/null +++ b/test/fixtures/users.yml @@ -0,0 +1,5 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html +first_user: + id: 1 +another_user: + id: 2 diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 0000000..0a4be59 --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,13 @@ +ENV["RAILS_ENV"] = "test" +require File.expand_path(File.dirname(__FILE__) + "/../config/environment") +require 'test_help' + +class Test::Unit::TestCase + # Turn off transactional fixtures if you're working with MyISAM tables in MySQL + self.use_transactional_fixtures = true + + # Instantiated fixtures are slow, but give you @david where you otherwise would need people(:david) + self.use_instantiated_fixtures = false + + # Add more helper methods to be used by all tests here... +end \ No newline at end of file diff --git a/test/unit/expression_test.rb b/test/unit/expression_test.rb new file mode 100644 index 0000000..94ff355 --- /dev/null +++ b/test/unit/expression_test.rb @@ -0,0 +1,14 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class ExpressionTest < Test::Unit::TestCase + fixtures :expressions + + def setup + @expression = Expression.find(1) + end + + # Replace this with your real tests. + def test_truth + assert_kind_of Expression, @expression + end +end diff --git a/test/unit/filter_test.rb b/test/unit/filter_test.rb new file mode 100644 index 0000000..019aec9 --- /dev/null +++ b/test/unit/filter_test.rb @@ -0,0 +1,14 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class FilterTest < Test::Unit::TestCase + fixtures :filters + + def setup + @filter = Filter.find(1) + end + + # Replace this with your real tests. + def test_truth + assert_kind_of Filter, @filter + end +end diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb new file mode 100644 index 0000000..24c6258 --- /dev/null +++ b/test/unit/user_test.rb @@ -0,0 +1,14 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class UserTest < Test::Unit::TestCase + fixtures :users + + def setup + @user = User.find(1) + end + + # Replace this with your real tests. + def test_truth + assert_kind_of User, @user + end +end diff --git a/vendor/ezcrypto-0.1.1/._README b/vendor/ezcrypto-0.1.1/._README new file mode 100644 index 0000000..a0c1410 Binary files /dev/null and b/vendor/ezcrypto-0.1.1/._README differ diff --git a/vendor/ezcrypto-0.1.1/._rakefile b/vendor/ezcrypto-0.1.1/._rakefile new file mode 100644 index 0000000..8d0ff5d Binary files /dev/null and b/vendor/ezcrypto-0.1.1/._rakefile differ diff --git a/vendor/ezcrypto-0.1.1/MIT-LICENSE b/vendor/ezcrypto-0.1.1/MIT-LICENSE new file mode 100644 index 0000000..26f55e7 --- /dev/null +++ b/vendor/ezcrypto-0.1.1/MIT-LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2004 David Heinemeier Hansson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/ezcrypto-0.1.1/README b/vendor/ezcrypto-0.1.1/README new file mode 100644 index 0000000..e360dc6 --- /dev/null +++ b/vendor/ezcrypto-0.1.1/README @@ -0,0 +1,130 @@ += EzCrypto - Easy to use Crypto for Ruby + +EzCrypto is an easy to use wrapper around the poorly documented OpenSSL ruby library. + +== Features + +* Defaults to AES 128 CBC +* Will use the systems OpenSSL library for transparent hardware crypto support +* Single class object oriented access to most commonly used features +* Ruby like + +== Simple examples + +==== To encrypt: + +Generate a key using a password and a salt. Use the keys encrypt method to encrypt a strings worth of data: + + @key=EzCrypto::Key.with_password "password", "system salt" + @encrypted=@key.encrypt "Top secret should not be revealed" + +==== To decrypt: + +Same procedure as encrypt. Generate a key using a password and a salt. Use the keys decrypt method to decrypt a strings worth of data: + + @key=EzCrypto::Key.with_password "password", "system salt" + @key.decrypt @encrypted + +==== One liners: + +These simple examples use one line each: + + @encrypted=EzCrypto::Key.encrypt_with_password "password", @salt,"Top secret should not be revealed" + + EzCrypto::Key.decrypt_with_password "password", @salt,@encrypted + +== Keys + +The only class you need to know for most uses og EzCrypto is the Key class. You don't need understand ciphers or the encryption life cycle. + +==== Generating a random key + +The most secure type of key is the randomly generated key: + + @key=EzCrypto::Key.generate + +==== Initializing a key with raw key data + +If you already have a key from some other source, you simply have to call the constructor with the raw data: + + @key=EzCrypto::Key.new @binarykey + +==== Initializing a Key with a Base64 encoded key + +As seen above you can create a key from a password. This should be used if you don't want the key to be stored on disk for example: + + @key=EzCrypto::Key.with_password "Secret password" + +==== Initializing a Key with a Base64 encoded key + +If you already have a key from some other source in the popular Base64 encoded format, you use the decode class method: + + @key=EzCrypto::Key.decode @binarykey + +==== Exporting the key + +To export or save a key use the encode method (or to_s) method for a Base64 encoded key or raw as the raw binary data. + + puts @key.encode + puts @key.raw + +The raw method could be used for storing in a database using a tinyblob column. + +== Encryption and Decryption + +EzCrypto is optimized for simple encryption and decryption of strings. There are encrypt/decrypt pairs for normal binary use as well as for Base64 encoded use. + +==== Regular raw use + +Assuming you have generated a key using one of the above methods: + + @encrypted=@key.encrypt("clear text") + @decrypted=@key.decrypt(@encrypted) + assert "clear text", @decrypted + +==== Base64 encoded use + +This uses the encrypt64 and decrypt64 methods. Otherwise it is all the same: + + @encrypted=@key.encrypt64("clear text") + @decrypted=@key.decrypt64(@encrypted) + assert "clear text", @decrypted + +== FAQ + +=== What algorithm does this use? + +It uses as the default algorithm the AES 128 bit standard. This is a very fast and highly secure algorithm specified as the national standard in the US. For more information see: + +http://en.wikipedia.org/wiki/AES + +=== Only 128 bits. Is that enough? + +While it might sound like more would make it more secure, there is really no real security advantage for most commercial applications to use more than 128 bit AES. + +=== What is Base64 encoding? + +This is the most efficient and commonly used encoding scheme for binary data. This is used amongst other things for email attachments. It is also very common to use it for encrypted data. + +=== What is a Salt? + +A salt is just a piece of data we hash in with the password to create the key. If it is a server based application you could use store a salt within your source file. The salt must be the same for both encryption and decryption. + + +== License + +Action Web Service is released under the MIT license. + + +== Support + +To contact the author, send mail to pelleb@gmail.com + +Also see my blogs at: +http://stakeventures.com and +http://neubia.com + +This project was based on code used in my project StakeItOut, where you can securely share web services with your partners. +https://stakeitout.com + +(C) 2005 Pelle Braendgaard diff --git a/vendor/ezcrypto-0.1.1/lib/ezcrypto.rb b/vendor/ezcrypto-0.1.1/lib/ezcrypto.rb new file mode 100644 index 0000000..37acdff --- /dev/null +++ b/vendor/ezcrypto-0.1.1/lib/ezcrypto.rb @@ -0,0 +1,357 @@ +require 'openssl' +require 'digest/sha2' +require 'digest/sha1' +require 'base64' + +module EzCrypto + + +=begin rdoc +The Key is the only class you need to understand for simple use. + +=== Algorithms + +The crypto algorithms default to aes-128-cbc however on any of the class methods you can change it to one of the standard openssl cipher names using the +optional :algorithm=>alg name parameter. + +Eg. + Key.new @raw, :algorithm=>"des" + Key.generate :algorithm=>"blowfish" + Key.with_password @pwd,@salt,:algorithm=>"aes256" + + +== License + +Action Web Service is released under the MIT license. + + +== Support + +To contact the author, send mail to pelleb@gmail.com + +Also see my blogs at: +http://stakeventures.com and +http://neubia.com + +This project was based on code used in my project StakeItOut, where you can securely share web services with your partners. +https://stakeitout.com + +(C) 2005 Pelle Braendgaard + +=end + + class Key + attr_reader :raw,:algorithm + +=begin rdoc +Initialize the key with raw unencoded binary key data. This needs to be at least +16 bytes long for the default aes-128 algorithm. +=end + def initialize(raw,options = {}) + @raw=raw + @algorithm=options[:algorithm]||"aes-128-cbc" + end + +=begin rdoc +Generate random key. +=end + def self.generate(options = {}) + Key.new(EzCrypto::Digester.generate_key(calculate_key_size(options[:algorithm])),options) + end + +=begin rdoc +Create key generated from the given password and salt +=end + def self.with_password(password,salt,options = {}) + Key.new(EzCrypto::Digester.get_key(password,salt,calculate_key_size(options[:algorithm])),options) + end + +=begin rdoc +Initialize the key with Base64 encoded key data. +=end + def self.decode(encoded,options = {}) + Key.new(Base64.decode64(encoded),options) + end + +=begin rdoc +Encrypts the data with the given password and a salt. Short hand for: + + key=Key.with_password(password,salt,options) + key.encrypt(data) + +=end + def self.encrypt_with_password(password,salt,data,options = {}) + key=Key.with_password(password,salt,options) + key.encrypt(data) + end + +=begin rdoc +Decrypts the data with the given password and a salt. Short hand for: + + key=Key.with_password(password,salt,options) + key.decrypt(data) + + +=end + def self.decrypt_with_password(password,salt,data,options = {}) + key=Key.with_password(password,salt,options) + key.decrypt(data) + end + +=begin rdoc +Given an algorithm this calculates the keysize. This is used by both the generate and with_password methods. This is not yet 100% complete. +=end + def self.calculate_key_size(algorithm) + if !algorithm.nil? + algorithm=~/^([[:alnum:]]+)(-(\d+))?/ + if $3 + size=($3.to_i)/8 + else + case $1 + when "bf" + size = 16 + when "blowfish" + size = 16 + when "des" + size = 8 + when "des3" + size = 24 + when "aes128" + size = 16 + when "aes192" + size = 24 + when "aes256" + size = 32 + when "rc2" + size = 16 + when "rc4" + size = 16 + else + size = 16 + end + end + end + if size.nil? + size = 16 + end + + size + end + +=begin rdoc +returns the Base64 encoded key. +=end + def encode + Base64.encode64 @raw + end + +=begin rdoc +returns the Base64 encoded key. Synonym for encode. +=end + def to_s + encode + end + +=begin rdoc +Encrypts the data and returns it in encrypted binary form. +=end + def encrypt(data) + @cipher=EzCrypto::Encrypter.new(self,"",@algorithm) + @cipher.encrypt(data) + end + +=begin rdoc +Encrypts the data and returns it in encrypted Base64 encoded form. +=end + def encrypt64(data) + Base64.encode64(encrypt(data)) + end + +=begin rdoc +Decrypts the data passed to it in binary format. +=end + def decrypt(data) + @cipher=EzCrypto::Decrypter.new(self,"",@algorithm) + @cipher.gulp(data) + rescue + puts @algorithm + throw $! + end + +=begin rdoc +Decrypts a Base64 formatted string +=end + def decrypt64(data) + decrypt(Base64.decode64(data)) + end + + + end +=begin rdoc +Abstract Wrapper around OpenSSL's Cipher object. Extended by Encrypter and Decrypter. + +You probably should be using the Key class instead. + +Warning! The interface may change. + +=end + class CipherWrapper + +=begin rdoc + +=end + def initialize(key,target,mode,algorithm) + @cipher = OpenSSL::Cipher::Cipher.new(algorithm) + if mode + @cipher.encrypt + else + @cipher.decrypt + end + @cipher.key=key.raw + @cipher.padding=1 + @target=target + @finished=false + end + +=begin rdoc +Process the givend data with the cipher. +=end + def update(data) + reset if @finished + @target<< @cipher.update(data) + end + +=begin rdoc + +=end + def <<(data) + update(data) + end + +=begin rdoc +Finishes up any last bits of data in the cipher and returns the final result. +=end + def final + @target<< @cipher.final + @finished=true + @target + end + +=begin rdoc +Processes the entire data string using update and performs a final on it returning the data. +=end + def gulp(data) + update(data) + final + end + +=begin rdoc + +=end + def reset(target="") + @target=target + @finished=false + end + end + +=begin rdoc +Wrapper around OpenSSL Cipher for Encryption use. + +You probably should be using Key instead. + +Warning! The interface may change. + +=end + class Encrypter [ :test ] + +# Run the unit tests +Rake::TestTask.new { |t| + t.libs << "test" + t.pattern = 'test/*_test.rb' + t.verbose = true +} + + +# Genereate the RDoc documentation +Rake::RDocTask.new { |rdoc| + rdoc.rdoc_dir = 'doc' + rdoc.title = "EzCrypto - Simplified Crypto Library" + rdoc.options << '--line-numbers --inline-source --main README' + rdoc.template = "#{ENV['template']}.rb" if ENV['template'] + rdoc.rdoc_files.include('README') + rdoc.rdoc_files.include('lib/ezcrypto.rb') +# rdoc.rdoc_files.include('lib/ezcrypto/*.rb') +} + + +# Create compressed packages +spec = Gem::Specification.new do |s| + s.platform = Gem::Platform::RUBY + s.name = PKG_NAME + s.summary = "Simplified encryption library." + s.description = %q{Makes it easier and safer to write crypto code.} + s.version = PKG_VERSION + + s.author = "Pelle Braendgaard" + s.email = "pelle@stakeitout.com" + s.rubyforge_project = "ezcrypto" + s.homepage = "http://ezcrypto.rubyforge.org" + + + s.has_rdoc = true + s.requirements << 'none' + s.require_path = 'lib' + + s.files = [ "rakefile", "README", "MIT-LICENSE" ] + s.files = s.files + Dir.glob( "lib/**/*" ).delete_if { |item| item.include?( "\.svn" ) } + s.files = s.files + Dir.glob( "test/**/*" ).delete_if { |item| item.include?( "\.svn" ) } +end + +Rake::GemPackageTask.new(spec) do |p| + p.gem_spec = spec + p.need_tar = true + p.need_zip = true +end + + +desc "Publish the API documentation" +task :pgem => [:package] do + Rake::SshFilePublisher.new("pelleb@rubyforge.org", "/var/www/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload +end + +desc "Publish the API documentation" +task :pdoc => [:rdoc] do + Rake::SshDirPublisher.new("pelleb@rubyforge.org", "/var/www/gforge-projects/ezcrypto", "doc").upload +end + +desc "Publish the release files to RubyForge." +task :release => [:package] do + files = ["gem", "tgz", "zip"].map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" } + + if RUBY_FORGE_PROJECT then + require 'net/http' + require 'open-uri' + + project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/" + project_data = open(project_uri) { |data| data.read } + group_id = project_data[/[?&]group_id=(\d+)/, 1] + raise "Couldn't get group id" unless group_id + + # This echos password to shell which is a bit sucky + if ENV["RUBY_FORGE_PASSWORD"] + password = ENV["RUBY_FORGE_PASSWORD"] + else + print "#{RUBY_FORGE_USER}@rubyforge.org's password: " + password = STDIN.gets.chomp + end + + login_response = Net::HTTP.start("rubyforge.org", 80) do |http| + data = [ + "login=1", + "form_loginname=#{RUBY_FORGE_USER}", + "form_pw=#{password}" + ].join("&") + http.post("/account/login.php", data) + end + + cookie = login_response["set-cookie"] + raise "Login failed" unless cookie + headers = { "Cookie" => cookie } + + release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}" + release_data = open(release_uri, headers) { |data| data.read } + package_id = release_data[/[?&]package_id=(\d+)/, 1] + raise "Couldn't get package id" unless package_id + + first_file = true + release_id = "" + + files.each do |filename| + basename = File.basename(filename) + file_ext = File.extname(filename) + file_data = File.open(filename, "rb") { |file| file.read } + + puts "Releasing #{basename}..." + + release_response = Net::HTTP.start("rubyforge.org", 80) do |http| + release_date = Time.now.strftime("%Y-%m-%d %H:%M") + type_map = { + ".zip" => "3000", + ".tgz" => "3110", + ".gz" => "3110", + ".gem" => "1400" + }; type_map.default = "9999" + type = type_map[file_ext] + boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor" + + query_hash = if first_file then + { + "group_id" => group_id, + "package_id" => package_id, + "release_name" => RELEASE_NAME, + "release_date" => release_date, + "type_id" => type, + "processor_id" => "8000", # Any + "release_notes" => "", + "release_changes" => "", + "preformatted" => "1", + "submit" => "1" + } + else + { + "group_id" => group_id, + "release_id" => release_id, + "package_id" => package_id, + "step2" => "1", + "type_id" => type, + "processor_id" => "8000", # Any + "submit" => "Add This File" + } + end + + query = "?" + query_hash.map do |(name, value)| + [name, URI.encode(value)].join("=") + end.join("&") + + data = [ + "--" + boundary, + "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"", + "Content-Type: application/octet-stream", + "Content-Transfer-Encoding: binary", + "", file_data, "" + ].join("\x0D\x0A") + + release_headers = headers.merge( + "Content-Type" => "multipart/form-data; boundary=#{boundary}" + ) + + target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php" + http.post(target + query, data, release_headers) + end + + if first_file then + release_id = release_response.body[/release_id=(\d+)/, 1] + raise("Couldn't get release id") unless release_id + end + + first_file = false + end + end +end diff --git a/vendor/ezcrypto-0.1.1/test/ezcrypto_test.rb b/vendor/ezcrypto-0.1.1/test/ezcrypto_test.rb new file mode 100644 index 0000000..cf407c7 --- /dev/null +++ b/vendor/ezcrypto-0.1.1/test/ezcrypto_test.rb @@ -0,0 +1,112 @@ +$:.unshift(File.dirname(__FILE__) + "/../lib/") + +require 'test/unit' +require 'ezcrypto' +require 'base64' + +class EzCryptoTest < Test::Unit::TestCase + + def setup + end + + def test_generate_alg_key + assert_generate_alg_key "aes-128-cbc",16 + assert_generate_alg_key "aes-192-cbc",24 + assert_generate_alg_key "aes-256-cbc",32 + assert_generate_alg_key "rc2-40-cbc",5 + assert_generate_alg_key "rc2-64-cbc",8 + assert_generate_alg_key "rc4-64" ,8 + assert_generate_alg_key "blowfish" ,16 + assert_generate_alg_key "des" ,8 + end + + def test_with_password + assert_with_password "","secret","aes-128-cbc",16 + assert_with_password "test","secret","aes-128-cbc",16 + assert_with_password "password","secret","aes-128-cbc",16 + assert_with_password "asldfad8q534j2l4j24l6j2456","secret","aes-128-cbc",16 + + assert_with_password "","secret","aes-192-cbc",24 + assert_with_password "test","secret","aes-192-cbc",24 + assert_with_password "password","secret","aes-192-cbc",24 + assert_with_password "asldfad8q534j2l4j24l6j2456","secret","aes-192-cbc",24 + + assert_with_password "","secret","aes-256-cbc",32 + assert_with_password "test","secret","aes-256-cbc",32 + assert_with_password "password","secret","aes-256-cbc",32 + assert_with_password "asldfad8q534j2l4j24l6j2456","secret","aes-256-cbc",32 + + end + + def test_encoded + 0.upto 32 do |size| + assert_encoded_keys size + end + end + + def test_encrypt + 0.upto(CLEAR_TEXT.size-1) do |size| + assert_encrypt CLEAR_TEXT[0..size] + end + end + + def test_decrypt + + 0.upto(CLEAR_TEXT.size) do |size| + assert_decrypt CLEAR_TEXT[0..size] + end + end + + def test_decrypt64 + 0.upto(CLEAR_TEXT.size) do |size| + assert_decrypt64 CLEAR_TEXT[0..size] + end + end + + def assert_key_size(size,key) + assert_equal size,key.raw.size + end + + def assert_generate_alg_key(algorithm,size) + key=EzCrypto::Key.generate :algorithm=>algorithm + assert_key_size size,key + end + + def assert_with_password(password,salt,algorithm,size) + key=EzCrypto::Key.with_password password,salt,:algorithm=>algorithm + assert_key_size size,key + assert_equal key.raw,EzCrypto::Key.with_password( password,salt,:algorithm=>algorithm).raw + end + + def assert_encoded_keys(size) + key=EzCrypto::Key.generate size + key2=EzCrypto::Key.decode(key.encode) + assert_equal key.raw, key2.raw + end + + def assert_encrypt(clear) + ALGORITHMS.each do |alg| + key=EzCrypto::Key.generate :algorithm=>alg + encrypted=key.encrypt clear + assert_not_nil encrypted + end + end + + def assert_decrypt(clear) + ALGORITHMS.each do |alg| + key=EzCrypto::Key.generate :algorithm=>alg + encrypted=key.encrypt clear + assert_not_nil encrypted + assert_equal clear,key.decrypt(encrypted) + end + end + def assert_decrypt64(clear) + key=EzCrypto::Key.generate + encrypted=key.encrypt64 clear + assert_not_nil encrypted + assert_equal clear,key.decrypt64(encrypted) + end + ALGORITHMS=["aes128","bf","blowfish","des","des3","rc4","rc2"] + CLEAR_TEXT="Lorem ipsum dolor sit amet, suspendisse id interdum mus leo id. Sapien tempus consequat nullam, platea vitae sociis sed elementum et fermentum, vel praesent eget. Sed blandit augue, molestie mus sed habitant, semper voluptatibus neque, nullam a augue. Aptent imperdiet curabitur, quam quis laoreet. Dolor magna. Quis vestibulum amet eu arcu fringilla nibh, mi urna sunt dictumst nulla, elit quisque purus eros, sem hendrerit. Vulputate tortor rhoncus ac nonummy tortor nulla. Nunc id nunc luctus ligula." +end +