jejacks0n / mercury Goto Github PK
View Code? Open in Web Editor NEWMercury Editor: The Rails WYSIWYG editor that allows embedding full page editing capabilities directly inline.
Home Page: http://jejacks0n.github.com/mercury
License: Other
Mercury Editor: The Rails WYSIWYG editor that allows embedding full page editing capabilities directly inline.
Home Page: http://jejacks0n.github.com/mercury
License: Other
When I'm working inside a table cell, and I try to upload an image, I seem to get weird behavior with regards to the place of insertion.
It seems, when you first create a table with a few cells, that each cell has a whitespace in it. Not sure if this is the case, but at least it's possible to move the cursor one position to the right and/or left inside a cell, without leaving that cell, making it clear that there is some kind of character in there (nbsp maybe?).
When you move the cursor to the utmost right of the cell, and drag an image over the page, the image is actually inserted inside the next cell. If you move the cursor to the utmost left of the cell, the image is inserted correctly in the current cell.
Any thoughts on this?
If someone has an android tablet that they'd like to check it on that would be awesome too.
I am receiving this error when using the load_mercury.js
file in Safari 5.1 with mercury-rails 0.2.3 or the git head. Version 0.2.0 seems to work without this error.
Mercury.PageEditor failed to load: RangeError: Maximum call stack size exceeded.
Here are the steps to reproduce:
mercury-rails
gem to Gemfilebundle
rails generate mercury:install
rake mercury_engine:install:migrations
rake db:migrate
Add load_mercury.js
to the layout file.
<%= javascript_include_tag "application", "mercury_loader" %>
Add a mercury region.
<div id="page_content" class="mercury-region" data-type="editable">
...
</div>
Visiting the page with that div shows that error. Is there something I'm missing?
BTW, the /editor
way of loading seems to work.
When a file is dropped onto the mercury editable region, the file is opened in standard way and not being handled by mercury.
Windows/Chrome
originally created by: jakubmisek
I tried the following:
<% @options = params[:options] || {} %>
<%= semantic_form_for 'options', { :html => { :style => 'width: 600px' } } do |f| %>
<div class="mercury-modal-pane-container">
<div class="mercury-modal-pane">
<%= f.inputs 'Options' do %>
<%= f.input :campaign_id, :required => true, :as => :select,
:collection => { "Google Adwords" => 1, "Facebook Ad" => 2, "No Referrer" => 3 },
:input_html => { :value => @options[:campaign_id] || 1, :allow_blank => true } %>
<% end %>
</div>
</div>
<div class="mercury-modal-controls">
<%= f.buttons do %>
<%= f.commit_button 'Insert Subscription Form' %>
<% end %>
</div>
<% end %>
And get the following error:
Rendered mercury/snippets/subscription_options.html.erb (5.8ms)
Completed 500 Internal Server Error in 9ms
ActionView::Template::Error (undefined method 'campaign_id' for {}:Hash):
4: <div class="mercury-modal-pane-container">
5: <div class="mercury-modal-pane">
6: <%= f.inputs 'Options' do %>
7: <%= f.input :campaign_id, :required => true, :as => :select,
8: :collection => { "Google Adwords" => 1, "Facebook Ad" => 2, "No Referrer" => 3 },
9: :input_html => { :value => @options[:campaign_id] || 1, :allow_blank => true } %>
10:
app/views/mercury/snippets/subscription_options.html.erb:7:in 'block (2 levels) in _app_views_mercury_snippets_subscription_options_html_erb___2314300290869354519_70344109546800'
app/views/mercury/snippets/subscription_options.html.erb:6:in 'block in _app_views_mercury_snippets_subscription_options_html_erb___2314300290869354519_70344109546800'
app/views/mercury/snippets/subscription_options.html.erb:2:in _app_views_mercury_snippets_subscription_options_html_erb___2314300290869354519_70344109546800'
Ultimately I'd like the collection to come from database but I was trying to take baby steps and it failed here. How do I construct an option parameter that provides a drop down select? I have Formtastic included in the Gemfile and if I use just normal text box inputs it works fine.
I'm currently using history.pushState() functionality in order to indicate current location of ajax-loaded html page chunks.
When I enable Mercury (and only when I enable Mercury) on the page from which I come to the current section (by using ajax and history API), history.pushState() stops working. The JS console does not report any error or warning, but the location string remains unchanged.
User agent:
Mozilla/5.0 (X11; Linux x86_64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1
In Chrome line
15078 selection = this.selection().selection.collapseToStart();
sometimes results in an INVALID_STATE_ERR: DOM Exception 11
I can reproduce this, for content-editable regions that are based on a textarea in a hidden div (see http://groups.google.com/group/django-feincms/browse_thread/thread/9db5707478a012a2#msg_e557224633c56597 )
Since I don't think the call to collapseToStart is absolutely required, I placed it in a try/catch, to ignore the problem.
I was wondering, is it possible to load part of the editor on the server, instead of on the client? I ask this because I have an app where the editor is always visible (and can't be disabled) when logged in as an admin. But right now, when an admin loads a page, the page first shows up in a single frame, without the editor, after which the editor reloads the page with the editor loaded and the page stuck in an iframe.
This significantly increases loading times for each page (which is somewhat annoying) but I'd also like to be able to do things with the _top
frame, like adding other admin commands (not related to the editor), without having them being stuck in the original page iframe.
I will probably have more time to look into this next week, but I just wanted to throw this out there as a nice feature to have in CMS systems.
Ever since I've updated to the latest master (which uses htmlClean instead of my overly-simplified implementation to clean pasted text) I am getting markup inside the text that should be filtered but isn't.
I tested this with allowing spans and divs without any attributes, and when pasting html code, it actually kept the style attribute which messed up the entire layout.
Not sure what is going on here, but I thought it was worth mentioning as this clearly doesn't work as expected.
I also checked to make sure my config was being read, and it was, because using the text
option for santize
resulted in only text being pasted.
Currently it just stacks. This should be true for all the different wrapping types of methods.
Based on the changes in baluptons fork, I believe that providing more region types by default would be beneficial.
These are outlined by his work:
plain_html
(no formatting ability)simple_html
(basic formatting -- bold, italic, underline, links etc)rich_html
(full editing)I sometimes notice that I get invalid warning about a change in the content when in fact nothing has changed. I simply navigate to a page, Mercury automatically selects the first found contenteditable
element and then when I try to reload the page it warns for changes.
This can get quite annoying since it means it keeps showing the warning when browsing a full website which uses Mercury (while logged in).
While working with the upload feature I noticed it not working (and not giving any errors) in Safari 5.1.1
. After digging around I noticed @supported()
returned false
because window.fileReader
returns false
.
After Googling I found this url which explains the issue: http://castlesblog.com/2010/july/13/html5-drag-drop-upload
I haven't implemented a fix or workaround yet, but I just wanted to let you know in advance.
also see: http://caniuse.com/filereader
How easy is it to configure and use this application inside an asp.net mvc application? Is Mercury all compiled into Js without reference to Ruby?
This is on v 0.2.3.
$ rake mercury_engine:install:migrations
NOTE: Migration 20110526035601_create_images.rb from mercury_engine has been skipped. Migration with the same name already exists.
Given I have a region that scrolls
When I put the cursor in an anchor tag so that the tooltip shows
And I scroll the region
Then the tooltip should move with the link
To ensure what you get is expected - quicker than manual testing :)
Current you can insert images fine, and drag them around, but there doesn't appear to be a way to resize them.
What are the current plans for this? As this is a pretty important thing :)
While testing copy/pasting from Word everything seemed to work perfectly. However, when diving into the HTML I noticed I had img tags in there that didn't show any actual images. It seems the img src is set to a local path using <img src="file:///C:/DOCUME~1/Anne/Local%20Settings/Temp/10/msohtmlclip1/01/clip_image002.gif">
. It would be nice if we checked the src of every pasted image if it starts with file://
and simply remove the tag if that's the case.
A more elegant solution would obviously be that we find that file and upload it, but I highly doubt that is even possible due to security reasons.
Address: http://jejacks0n.github.com/mercury/
Pop-up with: Region type is malformed, no data-type provided, or "Editable" is unknown. This opens two times than normal web displays.
Opera
Ver. 11.51
Win32 - Windows 7 64b
I didn't want to make a pull request out of this yet, but I hacked the current uploader to allow for documents to be uploaded:
Basically it extends the current functionality by checking if the uploaded file is an image, and if it isn't, use the new code.
src
set to response.document.img
, on the server side I then check for the mime type and pass back the appropriate image url, for example a small PDF image, or Word image.This needs a lot of work, and it would be best to extract this out into a separate image uploader and document uploader (because the image previewing feature (during uploading) now shows a broken image), but I don't think I am comfortable with the code yet to do this and I definitely won't have the time for the next few weeks.
Anyway, here is the snippet:
if ['image/jpeg', 'image/gif', 'image/png'].indexOf(@file.type) > -1
Mercury.trigger('action', {action: 'insertImage', value: {src: response.document.url}})
else
attrs = {href: response.document.url}
content = jQuery('<img>', {src: response.document.img})
selection = Mercury.region.selection()
if selection.range.collapsed is false
if selection.commonAncestor && selection.commonAncestor(true).find('img').length > 0
content = selection.commonAncestor(true).find('img')[0]
else
content = selection.fragment.textContent
container = selection.commonAncestor(true).closest('a') if selection && selection.commonAncestor
if container && container.length
Mercury.trigger('action', {action: 'replaceLink', value: {tagName: 'a', attrs: attrs, content: content}, node: container.get(0)})
else
Mercury.trigger('action', {action: 'insertLink', value: {tagName: 'a', attrs: attrs, content: content}})
Why mercury inserts a
when pressing enter? A new paragraph would be better...
I was working in Google Chrome on a webpage, and I had the following content in an editable div:
I wanted to make the two divs into one (without using the html editor), and so I placed my cursor at the start of the second div, and hit backspace. This was the result:
Not only was my second div placed somewhere in the middle of the content of the first div, a lot of weird Apple-style-span
spans where added to the content.
To make matters worse, these new elements include a lot of whitespace and can't be removed by hitting backspace. If you position the mouse cursor behind one of these whitespace elements, and hit backspace, the characters before the element get removed, which are actually a few positions away from the current cursor position.
Ever noticed this? And any idea if this can be solved in Mercury or if this is a (pretty severe) bug in the browsers?
In /assets/javascripts/mercury.js:
// ## Snippet Options and Preview
//
// When a user drags a snippet onto the page they'll be prompted to enter options for the given snippet. The server
// is expected to respond with a form. Once the user submits this form, an Ajax request is sent to the server with
// the options provided; this preview request is expected to respond with the rendered markup for the snippet.
//
// Name will be replaced with the snippet name (eg. example)
snippets: {
method: 'POST',
optionsUrl: '/mercury/snippets/:name/options.html',
previewUrl: '/mercury/snippets/:name/preview.html'
},
the snippets config appears to be ignored.
I am required to place my preview and options in the /app/views/mercury/snippets directory and to call them mysnippet.html (or mysnippet.html.erb) and mysnippet_options.html (or mysnippet_options.html.erb).
I get the following error if I place my preview and options views in a named snippet directory under snippets:
ActionView::MissingTemplate (Missing template mercury/snippets/mysnippet_options with {:handlers=>[:erb, :builder, :coffee], :formats=>[:html], :locale=>[:en, :en]}. Searched in:
* "/Volumes/Code/meetdom/prototype1/app/views"
* "/Users/Dom/.rvm/gems/ruby-1.9.2-p290@rails31/bundler/gems/mercury-bbb80cf2caec/app/views"
):
I think it would be a good idea to move the table buttons outside the toolbar, as they take up almost 33% of the space in the toolbar and are probably only active less than 20% of the time.
I would suggest not adding a new row for this, but instead make some kind of hover toolbar that shows up above a table when the cursor is moved inside that table. This way we declutter the interface and only bother the end-user with an extra interface when it's needed.
On a different note: I'd like to be able to hide the statusbar as well. I can see it being valuable to more technical users, but to a lot of "Word" users, it doesn't add any extra value and only uses valuable pixels.
--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/371853-move-table-buttons-out-of-main-toolbar-and-hover-on-top-of-table?utm_campaign=plugin&utm_content=tracker%2F134071&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F134071&utm_medium=issues&utm_source=github).I noticed that the modal window for uploads hides as soon as it's done uploading the file to the server. I think it would be better to actually wait for the server to come back with a response before hiding the modal window. The reasoning behind this is that I in my situation, the file is actually uploaded to the server first, some data is saved into the database, after which the file is uploaded again to Amazon S3. The server only fires back the JSON after the upload is completed, but the upload window is removed even if no response is given yet.
This results in confusion with the end user, and can actually break things if the user starts moving the cursor around or moves out of the region, in which case the image can't be inserted when the server actually returns the JSON.
I know it would be better to handle the uploading of the file on the server through a background process, but I haven't implemented this yet and even then the window would disappear but no image would show up because it's still being uploaded to S3.
I checked uploader.js.coffee, but couldn't find a quick fix for this, so just putting this out here in case anyone knows an easy fix.
I love the feature that mimics word/pages which allow for the tab
character to indent/outdent list items. However, what I don't like (even though it's probably the same in full-featured text editors) is that the final shift + tab
can move the element out of the list. This can result in all kinds of weirdness and sometimes reapplying the list attribute to the line does not return it to the exact state it was in before. The only way to get things back to normal is through the undo
command.
I think it would be better to disable the shift + tab
character completely when at the top of the list tree.
Also, while on the subject, the tab inside list
function is also partially broken: When placing the cursor before the first character in a list item and hitting tab triggers both the indentation of the current list item, but also inserts a list item below the current one.
It would be nice if a double click on an image doesn't show the insert media
model, but instead introduces a new modal in which the user can edit the double-clicked image.
Things like alt
tag, width
, height
and a link
for the image could be modified here. With regards to the image dimensions, I think it would be a good idea to have some kind of lock aspect ratio
switch for this feature.
I was wondering if it would be a good idea to make tabbing inside tables actually switch to the next cell (and add a new row if in the last cell), this is consistent with text editors if I recall correctly. It breaks the assumption that tab always inserts a tab (two spaces), but we could make shift-tab still insert the two spaces (or use shift-tab for the cell-switching).
Just a thought I had while working inside a table and intuitively hitting tab to go to the next cell, only to see it not working (yet).
Hello I need to be able to control the snippets locations from a config variable.
Is this possible now?
When there is no text selected, only cursor stays inside some word ... formatting (such as clicking on Bold, Underlined, ...) should affect the whole word. Currently nothing happens.
originally posted by: jakubmisek
Firstly, thanks for a truly interesting project :-)
With the GIT revision cf66224 I found that Image objects converted to JSON does not match the server specification on the Wiki. The specification says:
{"image":{"url":"/system/images/1/original/imagename.jpg?1309022763"}}
Which also seems to be expected by JavaScript client code.
But I found the nested image object to be missing after succefully uploading an image resulting in an JavaScript popup.
I tested by adding a to_json to the Image class:
def as_json(options = {})
{
:image => { :url => self.url }
}
end
And that works.
Rails version: 3.1.1.rc1
I've been working on reducing the toolbar to a single row of (small) buttons, instead of the large row on top, and the smaller row(s) below that. While working on doing this, I noticed it's not as easy as I hoped, because some rows disable themselves completely when no region was focused, even though I only wanted to have a few buttons disabled and keep the rest active.
Maybe this is something to look into, especially since screen real-estate is quite important on smaller devises (like the Macbook Air), and having this huge toolbar on top feels very wrong (and windows-like, if you don't mind me saying).
when you have a form on a page that is enriched with Mercury, and you post the form, Mercury returns a
"Mercury.PageEditor failed to load: " + error + "\n\nPlease try refreshing."
alert.
when navigating things go OK, but posting data result in this problem. I guess because the iFrame is not updated with the new content.
I haven't found any solution or work-around for this problem.
Added auth to the test Mercury app today. Have been using Devise for this. Perhaps my implementation is incorrect?
$(document).ready(function(){
<% if @model.content_snippets %>
<% @model.snippet_array.each do |s| %>
top.Mercury.Snippet.load({<%= s.gsub('=>', ':').html_safe %>});
<% end %>
<% @model.snippet_name_array.each do |s| %>
// This destroys our session from devise, I have no idea why
//top.Mercury.Snippet.all[<%= s.gsub('snippet_', '') %>].loadPreview($('[data-snippet="<%= s %>"]'));
<% end %>
<% end %>
});
The offending line is:
top.Mercury.Snippet.all[<%= s.gsub('snippet_', '') %>].loadPreview($('[data-snippet="<%= s %>"]'));
Shutting everything down for the day and just ran across the issue. Haven't looked into the Mercury code yet, will do that first thing in the morning. Starting the issue now, in-case you happen to use Devise, or you can see an obvious error in the way I'm trying to use snippets.
Dennis
When you edit an inserted image (double click) the image url contains the right url.... But if the align is not "none", the url field styas empty...
Really the mercury editor should be it's own project, and be included as a submodule or something into the rails cms.
Bundler could not find compatible versions for gem "rails":
In Gemfile:
mercury-rails depends on
rails (= 3.1.0.rc4)
rails (3.1.0.rc5)
copy something, and then mash on command/ctrl+p, and you'll see other content being duplicated.
When an image is uploaded there will also is also an csrf-header set, however this is not done when saving content with the PageEditor.
I adjusted the save method as follows to accomplish this:
Mercury.PageEditor.prototype.save = function() {
var data, url, _ref, _ref2;
url = (_ref = (_ref2 = this.saveUrl) != null ? _ref2 : Mercury.saveURL) != null ? _ref : this.iframeSrc();
data = this.serialize();
var headers = {};
headers[Mercury.csrfTag] = Mercury.csrfToken;
Mercury.log('saving', data);
if (this.options.saveStyle !== 'form') {
data = jQuery.toJSON(data);
}
return jQuery.ajax(url, {
type: 'POST',
headers: headers,
data: {
content: data
},
success: __bind(function() {
return Mercury.changes = false;
}, this),
error: __bind(function() {
return alert("Mercury was unable to save to the url: " + url);
}, this)
});
};
Please note that I am also using a parameter for the tag-name: csrfTag, since Django uses another tag-name than RoR
for the image upload, I use:
xhr.setRequestHeader(Mercury.csrfTag, Mercury.csrfToken);
currently I simply set the token like this:
if (token = jQuery('meta[name="csrf-token"]').attr('content')) {
Mercury.csrfToken = token;
Mercury.csrfTag = 'X-CSRFToken';
}
I tried setting the saveStyle option to 'form' to debug some weird behavior while saving Mercury data on a rails app running in production, but it seems like saveStyle is never passed in the pageEditor initialization.
At first I wanted to use the ?saveStyle=form
option, but I couldn't, because I use sprockets and it doesn't allow for any params to be added to filenames, so instead I injected it directly in the default options block in mercury.js, like:
var options = {
// A path or url from which the javascripts and css should be loaded.
src: '/assets',
saveStyle: 'form',
// A value defined in the packages above. Development is used by default. If you want to provide your own package
// you can just define one before including this script.
pack: 'development'
};
but the content was never submitted as form data. In the end I uncommented line 156
in page_editor.js.coffee to make it work, any thoughts on this?
Whenever I try to put a link inside a region, and I click the Insert link
button, the browser actually refreshes with the current GET params:
http://www.test.dev/?link%5Btext%5D=Jean&link_type=external_url &link%5Bexternal_url%5D=www.test.dev&link%5Bnew_bookmark%5D= &link%5Btarget%5D=&link%5Bpopup_width%5D= &link%5Bpopup_height%5D=&commit=Insert+Link
Seems like a weird issue, I haven't looked into this yet, but throwing it out here anyway.
$ git clone https://github.com/jejacks0n/mercury.git
$ cd mercury
$ bundle install
$ rails server
Then going to http://0.0.0.0:3000/ results in http://awesomescreenshot.com/070f8yy29
I tried to use Mercury with Rails 3.1.rc4 and it spills out a lot of syntax error messages.
One example is the route:
root to: "application#show"
I think it should be:
root :to => "application#show"
There are a lot of syntax errors like this one. It this a real issue? Does it work in any other rails version?
Putting this here to see if anybody else is seeing this issue.. I rolled back several commits (back to 4d75478) and it still does it.. the weird thing is that it's working on the demo page for me.
This works in chrome, but not safari (latest on osx 10.6 and 10.7)
in mercury.js for toolbars:
close: ['Close', 'Exit the editor'],
and then in my css:
.mercury-primary-toolbar .mercury-close-button em, .mercury-expander-button[data-button="close"] em {
background-image:url('/assets/close_button.png');
background-position: 50% 2px !important;
}
as a matter of fact, even if I .mercury-close-button { background-color: red !important } it won't show up in safari
Had to modify toolbar.css under mercury gem's vendor assets to be able to show the background image in safari.
I can see the styles loaded from my css under resources in the inspect window for safari, but the dom css inspector doesn't show the styles as applying to the class.
I've seen similar things before when missing a ; on a style declaration, where chrome will keep on chugging but safari won't load any css for that selector after the omission.
Just looking through your css quickly, I didn't notice anything glaringly obvious. What do you suggest is the best way to go about working around this issue for now?
Dennis
By the way, great job on mercury, it's a pleasure to use.
If file upload fails, user should see the notification for longer time.
Also the Error thrown by the upload handler is not displayed to the user.
originally created by: jakubmisek
PageEditor.prototype.resize initializes the global property Mercury.displayRect
however, resize isn't always called before Mercury.displayRect is used!
For instance initializeInterface.toolbar() is called which apparently triggers the creation of tooltips for all links in your content, which reads Mercury.displayRect.top (but since Mercury.displayRect is not set, it crashes)
This is the danger of using global properties. I would prefer to use a getTop() method, which calculates the top when desired. I haven't got a clue, when to call the pageEditor.resize method
The example above happens when I edit the following content:
<ul class="things">
<li><a href="test"><img src="/media/medialibrary/2011/08test-mini.jpg">Test</a></li>
<li><a href="test"><img src="/media/medialibrary/2011/08test-mini.jpg">Test</a></li>
<li><img src="/media/medialibrary/2011/08test-mini.jpg">Test</li>
</ul>
resulting in this stacktrace:
jQuery.extend.position() at mercury.js:14108jQuery.extend.update() at mercury.js:14102jQuery.extend.appear() at mercury.js:14092jQuery.extend.show() at mercury.js:14045Mercury.tooltip() at mercury.js:14032Mercury.Regions.Editable.Editable.bindEvents.element.bind.__bind.event.originalEvent.dataTransfer.dropEffect() at mercury.js:14876__bind() at mercury.js:14816jQuery.event.handle() at mercury.js:2894jQuery.event.add.elemData.handle.eventHandle() at mercury.js:2528jQuery.event.trigger() at mercury.js:2822jQuery.fn.extend.trigger() at mercury.js:3434jQuery.jQuery.extend.each() at mercury.js:670jQuery.jQuery.fn.jQuery.each() at mercury.js:294jQuery.fn.extend.trigger() at mercury.js:3433jQuery.extend.trigger() at mercury.js:11820Mercury.Regions.Editable.Editable.focus() at mercury.js:15081Mercury.PageEditor.PageEditor.initializeRegions() at mercury.js:11999Mercury.PageEditor.PageEditor.initializeFrame() at mercury.js:11971Mercury.PageEditor.PageEditor.initializeInterface.toolbar() at mercury.js:11942__bind() at mercury.js:11903jQuery.event.handle() at mercury.js:2894jQuery.event.add.elemData.handle.eventHandle() at mercury.js:2528
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.