{"id":13473351,"url":"https://github.com/jejacks0n/mercury","last_synced_at":"2025-04-10T02:18:04.556Z","repository":{"id":1487407,"uuid":"1735128","full_name":"jejacks0n/mercury","owner":"jejacks0n","description":"Mercury Editor: The Rails WYSIWYG editor that allows embedding full page editing capabilities directly inline.","archived":false,"fork":false,"pushed_at":"2023-08-15T16:11:30.000Z","size":9672,"stargazers_count":2638,"open_issues_count":73,"forks_count":531,"subscribers_count":126,"default_branch":"master","last_synced_at":"2025-04-10T02:17:53.569Z","etag":null,"topics":["deprecated-repo","javascript","mercury-editor","rails","wysiwyg-editor"],"latest_commit_sha":null,"homepage":"http://jejacks0n.github.com/mercury","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jejacks0n.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2011-05-11T20:15:37.000Z","updated_at":"2025-03-31T14:35:05.000Z","dependencies_parsed_at":"2022-07-18T16:52:52.858Z","dependency_job_id":"2145ee00-997c-4e1c-ab2e-aac0215215ef","html_url":"https://github.com/jejacks0n/mercury","commit_stats":{"total_commits":776,"total_committers":75,"mean_commits":"10.346666666666666","dds":0.2976804123711341,"last_synced_commit":"a6a7e8d3b924266aa39be73359aa5c73c81363e1"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jejacks0n%2Fmercury","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jejacks0n%2Fmercury/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jejacks0n%2Fmercury/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jejacks0n%2Fmercury/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jejacks0n","download_url":"https://codeload.github.com/jejacks0n/mercury/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248142906,"owners_count":21054672,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deprecated-repo","javascript","mercury-editor","rails","wysiwyg-editor"],"created_at":"2024-07-31T16:01:02.882Z","updated_at":"2025-04-10T02:18:04.534Z","avatar_url":"https://github.com/jejacks0n.png","language":"JavaScript","funding_links":[],"categories":["For Ruby","Rich text editor","Happy Exploring 🤘","JavaScript","HTML/CSS Tools and Frameworks"],"sub_categories":[],"readme":"# Mercury Editor\n\nMercury Editor is a fully featured editor much like TinyMCE or CKEditor, but with a different usage paradigm.  It\nexpects that an entire page is something that can be editable, and allows different types of editable regions to be\nspecified.  It displays a single toolbar for every region on the page, and uses the HTML5 contentEditable features on\nblock elements, instead of iframes, which allows for CSS to be applied in ways that many other editors can't handle.\n\nMercury has been written using CoffeeScript and jQuery for the Javascript portions, and is written on top of Rails 3.2.\n\n\n## Developer Note\n\nI've started a [new version of Mercury Editor](https://github.com/jejacks0n/mercury/tree/mercury2) with many\nimprovements. I've learned a lot in the past few years, and I've also learned how Mercury could be improved from\ncomments, feature requests, feedback etc.\n\nThe new project will take the place of this one, and the Rails portions will be moved to a new repo and will become more\nfull featured -- to serve as an example of how it can be used.  I will do what's reasonable to make this easy for folks\n(eg. moving master -\u003e mercury1, and mercury2 -\u003e master), but I don't get paid for this and I use this project as a sort\nof proving ground for various concepts and techniques, so I'd like to keep it fun and not get bogged down in version\nstuff. This means it's your responsibility to manage the transition or stick with the current version (which is no\nlonger maintained by me).\n\nThere will be a purging of pull requests and issues when the transition takes place -- probably a few months from now.\n\n\n## Awesomeness\n\nRyan Bates has created an awesome [RailsCast](http://railscasts.com/episodes/296-mercury-editor) that walks you through\ngetting Mercury Editor installed, setup and working in a Rails application.  Check it out!\n\nMercury has been added as a Featured Project on Pivotal Tracker!  If you're interested in what's planned, check out the\n[Mercury Tracker Project](https://www.pivotaltracker.com/projects/295823).\n\n\n## Browser Support\n\nMercury has been written for the future, and thus doesn't support legacy browsers or browsers that don't follow the W3C\nspecifications for content editing.  Any browser will be supported if they support the W3C specification in the future,\nbut there aren't plans currently for adding support for alternate implementations at this time.\n\nSupported Browsers:\n\n- Internet Explorer 10+\n- Chrome 10+\n- Firefox 4+\n- Safari 5+\n- Opera 11.64+\n- Mobile Safari (iOS 5+)\n\n\n## A Demo\n\nFeel free to check out [the demo](http://jejacks0n.github.com/mercury/).  We'll be adding a full walkthrough that goes\ninto detail for each of the major features.  If you would like to see how Mercury was implemented in the demo check the\n[gh-pages](https://github.com/jejacks0n/mercury/tree/gh-pages) branch, it's a useful resource to see how you can\nintegrate the Mercury bundle into a non-rails project since it's a static site.\n\n\n## The Story\n\nI was looking for a fully featured editor that didn't use iframes to edit the content, and there weren't any decent\nones.  My primary goal was to have areas that were editable, but that also allowed CSS to flow naturally.  A few have\ncropped up since then (Aloha Editor for instance), and as good as they are, none had all the features I was looking for.\n\nMercury was written to be as simple as possible, while also providing an advanced feature set.  Instead of complex\nconfiguration, we chose a mix of configuration and code simplicity, which should give you a much better chance at\ncustomizing Mercury to suit your exact needs.  This doesn't mean there's not configuration, and what's there provides\nmuch of what you'll need, but efforts were taken to keep it simple and powerful.\n\nEven though it's a great editor, Mercury Editor may not be the best for your needs (based on browser support,\nfunctionality, etc.) so here's a list of some other editors that you might want to check out:\n\n- [Aloha Editor](http://www.aloha-editor.org/)\n- [jHtmlArea](http://jhtmlarea.codeplex.com/)\n- [MarkItUp](http://markitup.jaysalvat.com/home/)\n- [TinyMCE](http://tinymce.moxiecode.com/)\n- [CKEditor](http://ckeditor.com/)\n- [NicEdit](http://nicedit.com/)\n- [Raptor Editor](http://www.raptor-editor.com/)\n\n\n## Features\n\nThe feature list is actually pretty long, so here's a short list that should be highlighted.\n\n- Previewing: Preview content while you're working to see exactly how it'll look.\n- Link Tools: Insert and edit links, including TOC/Bookmark links.\n- Media Tools: Insert and edit images, youtube videos, and vimeo videos.\n- Image Uploading: Drag images from your desktop and they'll be automatically uploaded and inserted.\n- Table Editing: Advanced table editing and creation, including support for multiple column and rows spans.\n- Snippets: Insert and edit predefined and reusable bits of markup/code using drag and drop.\n- Custom Regions: We provide Full HTML, Markdown, Snippet, Image, and Simple region types by default.\n- I18n: Built in low profile translation and internationalization system.\n\n\n## Installation\n\n### For Rails\n\nInclude the gem in your Gemfile and bundle to install the gem.\n\n    gem 'mercury-rails'\n\nYou can also get the configuration file and overrides by running the install generator.\n\n    rails generate mercury:install\n\nThis generator puts a mercury configuration file into your project in /app/assets/javascripts/mercury.js.  This file\nalso functions as a manifest using sprockets `require` to include dependencies.  The install generator can optionally\ninstall the layout and css files.\n\n#### Image Processing / Uploading\n\nMercury has a basic facility for allowing image uploads, and we provide a generator that can act as a starting point for\nyour own back end integration.  To install run the generator.\n\n    rails generate mercury:install:images\n\nFor Mongoid + MongoDB, you can use the `--orm=mongoid` option on the generator to get the appropriate model added to\nyour app.  This generator also puts paperclip (and mongoid_paperclip if needed) into your Gemfile, so make sure to\n`bundle` or make your own adjustments.\n\nIf you're using ActiveRecord, make sure to migrate your database.  You can also disable this feature entirely in the\nmercury configuration if you don't plan on allowing image uploading.\n\n#### Authentication\n\nMercury provides a generator for giving you a basic authentication implementation.  You can run this generator and write\nyour own logic into the authentication file it provides.\n\n    rails generate mercury:install:authentication\n\nThis provides a simple method for restricting the actions in the default MercuryController to only users who have the\nrequired privileges.  Since this can vary largely from application to application, it's a basic approach that assumes\nyou'll write in what you want.\n\n### For Non-Rails Environments\n\n[Download the zip file](https://github.com/downloads/jejacks0n/mercury/mercury-v0.9.0.zip), and then follow the\ninstallation instructions on the [wiki article](https://github.com/jejacks0n/mercury/wiki/Using-Mercury-without-Rails).\n\n\n## Usage\n\nThere's a glob route that captures everything beginning with `/editor`, so for instance to edit an `/about_us` page, you\nshould access it at the `/editor/about_us` path.\n\nFor performance reasons you may also want to notify Mercury when the page is ready to be initialized.  To do this just\ntrigger the initialize:frame event from within your normal application layouts.  You can do this when the DOM is ready\nto be interacted with (eg. dom:loaded, document.ready), or at the bottom of your body tag.  It's recommended that you do\nthis because it gives you some load performance improvements, but it's not required.\n\n    jQuery(parent).trigger('initialize:frame');\n\nMercury has an expectation that content regions will be on the page (not required, but probably useful).  To define\ncontent regions that Mercury will make editable you need to add a `data-mercury` attribute to an element.  This\nattribute is used to specify the region type.  Mercury provides some default region types, but you can also create your\nown.  Region types are outlined below, and the available values for the `data-mercury` attribute are:\n\n- full\n- simple\n- markdown\n- snippets\n- image (should only be applied to img tags)\n\nIt's important for saving that an id attribute *always* be set on regions, so you should always include one.\n\n    \u003cdiv id=\"primary\" data-mercury=\"full\"\u003e\n      default content\n    \u003c/div\u003e\n\nFor more advanced ways to integrate Mercury Editor with your Rails application (such as not using the /editor routing prefix) check out this\n[wiki article](https://github.com/jejacks0n/mercury/wiki/Rails-Integration-Techniques).\n\n### Using Mercury without Rails\n\nIf you're looking to use Mercury without Rails, you should start by checking this\n[wiki article](https://github.com/jejacks0n/mercury/wiki/Using-Mercury-without-Rails).\n\n\n## Region Types\n\n### Full Region\n\nFull regions are for full HTML markup and utilize the HTML5 contentEditable feature.  These are the core of what\nMercury does, and provide the most flexibility and visual representation of what the content will look like when saved.\n\n### Simple Region\n\nSimple regions are designed for plain text.  Newlines and markup are not allowed.  Simple Regions are appropriate for\ntitles, headlines, or any area where you want the content to be editable but not the style.\n\n### Markdown Region\n\nMarkdown regions are based on Markdown syntax (specifically the github flavored version), and aren't as full featured as\nthe full region type -- primarily because Markdown is meant to be simple.  To keep it simple you can't do things like\nset colors etc.  This region type is useful if you want to keep the markup clean and simple.\n\n### Snippets Region\n\nSnippet regions only allow snippets and don't have a concept of content editing within them.  Snippets can be the way to\ngo with complex markup and functionality, and are basically chunks of reusable markup that can be defined by a developer\nand placed into content regions later.  More on this below.\n\n### Image Region\n\nThe image region type should only be applied to an image tag.  It results in the image being drag-and-drop replacable.\nThis differs from the image handling in full regions, in that no content is in the area.  This works well for logos\nand images you want to display with careful layout, and do not need any content functionality.\n\n\n## Loading / Ready State\n\nWhen Mercury loads it will fire an event telling the document that it's initialized, available and ready.  You can do\nseveral things once Mercury is loaded, and we expose as many ways to do this as possible.  You can bind to the event\nusing jQuery, Prototype, or Mercury directly.  Or if you'd prefer you can just create a method and Mercury will call\nthat when it's ready.\n\n#### jQuery\n\n    jQuery(window).on('mercury:ready', function() { Mercury.saveUrl = '/content'; });\n\n#### Mercury\n\n    if (parent.Mercury) {\n      parent.Mercury.on('ready', function() { Mercury.saveUrl = '/content'; });\n    }\n\n#### Function Declaration\n\n    function onMercuryReady() { Mercury.saveUrl = '/content'; }\n\n#### Prototype\n\n    Event.observe(window, 'mercury:ready', function() { Mercury.saveUrl = '/content'; });\n\n\n## Snippets\n\nSnippets are reusable and configurable chunks of markup.  They can be defined by developers, and then placed anywhere in\ncontent regions that support them.  When you drag a snippet into a region you'll be prompted to enter options, and after\nentering options the snippet will be rendered into the page as a preview.  Snippets can be dragged around (in\nsnippets regions), edited or removed.\n\nMercury does very little to save content and snippets for you, but it does provide the ability to load snippets from\nyour own storage implementation.  Here's an example of loading existing snippet options back into Mercury using jQuery.\n\n    jQuery(window).on('mercury:ready', function() {\n      Mercury.Snippet.load({\n        snippet_1: {name: 'example', options: {'favorite_beer': \"Bells Hopslam\", 'first_name': \"Jeremy\"}}\n      });\n    });\n\nSnippet contents (when saved) are removed from the content.  Their options and their placement does come through in the\ncontent however, and you're responsible for rendering your own snippet content when the page is being rendered.  You can\nread more on the [wiki article about snippets](https://github.com/jejacks0n/mercury/wiki/Snippets).\n\n\n## Reinitializing Regions\n\nIf you're using things like history.pushState, pjax, or just simply dynamically replacing / loading new content into\nyour pages, you can reinitialize regions afterwards by using:\n\n    Mercury.trigger('reinitialize')\n\nThis will find any new regions and initialize them, leaving the existing ones intact.  There's more details that you'll\nneed to understand before taking advantage of all the possible features, but this will likely work for most cases.\n\nIn more advanced cases, you may want to load new snippets, and potentially prompt to save the contents before loading\nthe new content -- so content isn't lost.  The handling of these aspects is up to you, as Mercury can't know if an ajax\nrequest will try to dynamically replace or load new content.\n\n\n## Saving Content / Rendering Content\n\nNote: Mercury doesn't implement saving or rendering of content.  We leave this part up to you because it can vary in so\nmany ways.  You may want to implement content versioning, use a nosql data store like mongo etc. and we don't want to\nforce our opinions.\n\nMercury will submit JSON or form values back to the server on save, and this can be adjusted in the configuration.  By\ndefault it will use JSON, that JSON looks like:\n\n    {\n      \"region_name\": {\n        \"type\": \"full\",\n        \"value\": \"[contents with a snippet]\",\n        \"snippets\": {\n          \"snippet_1\": {\n            \"name\": \"example\",\n            \"options\": {\n              \"options[favorite_beer]\": \"Bells Hopslam\",\n              \"options[first_name]\": \"Jeremy\"\n            }\n          }\n        }\n      }\n    }\n\nWhere it gets saved to is also up to you.  By default it submits a post to the current url, but you can adjust this by\nsetting Mercury.saveUrl, or passing it into the Mercury.PageEditor constructor.  How you do this is dependent on how\nyou're using loading mercury (via the loader, or by using the route method).  In both situations setting Mercury.saveUrl\nis the most consistent.\n\n    jQuery(window).on('mercury:ready', function() {\n      Mercury.saveUrl = '/contents';\n    });\n\nAssuming you have a ContentsController and a RESTful route, this will make it through to the create action.  Where you\ncan store the content in whatever way you think is appropriate for your project.\n\nRendering content is up to you as well.. Now that you have content saved, you can add that content back to your pages,\nand there's a lot of ways you could approach this.  In the past I've used Nokogiri to find and replace the contents of\nregions, and do some additional handling for putting snippets back into the content.  You could also use regular\nexpressions to do this, which is probably faster, but maybe not as safe.\n\nI'm interested in what solutions people are looking for and end up using for this, so feel free to shoot me a line if\nyou write something (eg. a middleware layer, an nginx module, or just something simple to get the job done).\n\n\n## Images\n\nThe toolbar images have been created by the awesome [Mode Set](http://modeset.com/) guys (using\n[GLYPHICONS](http://www.glyphicons.com/)).  They follow a simplistic design aesthetic to minimize the complexity of\ncreating / finding your own.  You're welcome to contribute your own to the PSD that can be found within the project so\nothers can potentially build from or use your own contributions.\n\n\n## Internationalization / Translations\n\nMercury has support for the following locales.  If you'd like to contribute one, the easiest way is to fork the project,\ncreate a locale file with your translation, and submit a pull request -- that way you get full credit for your\ncontributions.\n\nSome [examples are here](https://github.com/jejacks0n/mercury/tree/master/app/assets/javascripts/mercury/locales),\nand there's more on the [wiki page](https://github.com/jejacks0n/mercury/wiki/Localization-\u0026-Translations).\n\nTranslations and contributors:\n- Arabic ([mohamagdy](https://github.com/mohamagdy))\n- Danish ([martinjlowm](https://github.com/martinjlowm))\n- German ([poke](https://github.com/poke))\n- Spanish ([javiercr](https://github.com/javiercr))\n- French ([adamantx](https://github.com/adamantx))\n- Italian ([gcastagneti](https://github.com/gcastagnet))\n- Korean ([dorajistyle](https://github.com/dorajistyle))\n- Dutch ([kieranklaassen](https://github.com/kieranklaassen))\n- Polish ([cintrzyk](https://github.com/cintrzyk))\n- Portuguese ([yakko](https://github.com/yakko))\n- Swedish ([stefanm](https://github.com/stefanm))\n- Simplified Chinese ([董劭田 DONG Shaotian](https://github.com/richarddong))\n- Hungarian ([egivandor](https://github.com/egivandor))\n- Russian ([ilyacherevkov](https://github.com/ilyacherevkov))\n\nTo add translations to your installation you'll first need to turn it on in the configuration and set the prefered\nlocale to one of those that's listed above (eg. `fr-CA`, or `pt-BR`).  All you have to do after that is include the\nlocale you want to use.  You can do this in the configuration file directly using a sprockets `require` statement.\nExamples are provided.\n\n\n## Project Details\n\n### WYSIWYG Editors Suck\n\nThey just do.  Which as I've learned, is primarily due to the browser implementations.  Don't get me wrong, what the\nbrowsers have implemented is amazing, because it's hard stuff, plain and simple.  But if you're expecting a WYSIWYG\neditor to solve all your content problems you're wrong.  A better perception is that it will solve many of them, but\nshifts some into a new area.\n\nWith that being said, Mercury tries to solve many of those issues and succeeds to a great degree, but it seems to be\nnearly impossible (impractical at least) to address everything, and the browsers don't expose enough to fix some things.\nThis is true for every editor that I've looked into as well, and will likely just take time as the browser vendors begin\nto prioritize and fix these issues.\n\nIt's important to understand this, and the details are more suited for long nerdy blog posts, so they won't be covered\nhere.\n\n### The Code and Why\n\n#### CoffeeScript\n\nMercury has been written entirely in CoffeeScript because it simplifies a lot of the patterns that are used, and allows\nfor very readable code.  The goal was to provide good readable code that could be adjusted based on need, instead of a\ncomplex configuration that makes the code harder to understand and tweak.\n\n#### jQuery\n\njQuery was used as the javascript library, but is primarily used for the selectors, traversing, and manipulating the\nDOM.  Chaining is kept to a minimum for readability, and even though much of Mercury could've been written as jQuery\nplugins, it was not.\n\n#### Rails\n\nWith the asset handling that comes bundled with Rails 3.1+, Rails Engines, and the gem tools, there really wasn't any\nother option.  The javascript from Mercury can be used by any back end system, and isn't limited to Rails.  Many of the\nfeatures do require a back end however, and those features would have to be written in whatever language you wanted\nsupport for.\n\nThe coffeescript files can be found in the repo, and I would be fully supportive of anyone who wanted to add support for\ndifferent back end frameworks or languages.  There's a server specification in the wiki that will help as well.\n\n#### Specs / Integration Tests\n\nMercury is fully tested using Jasmine (via Teabag) and Cucumber.  You can clone the project to run the full suite.\n\n    rake teabag\n    rake cucumber\n\nThe default rake task does both of these in order.\n\n\n## License\n\nLicensed under the [MIT License](http://creativecommons.org/licenses/MIT/)\n\nCopyright 2012 [Jeremy Jackson](https://github.com/jejacks0n)\n\nIcons from [GLYPHICONS](http://www.glyphicons.com/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjejacks0n%2Fmercury","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjejacks0n%2Fmercury","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjejacks0n%2Fmercury/lists"}