Using Ace together with a database - issues with text formatting

793 views
Skip to first unread message

Peter Savnik

unread,
Oct 5, 2017, 1:15:22 PM10/5/17
to Ajax.org Cloud9 Editor (Ace)
Hi 

I want to use Ace to enable my users to type in a small script in the webbrowser. The script is then stored in a database. 
The problem is that i can not get the text formatting to work properly with multi-line code.
To be completely honest i'm not sure if i'm doing something wrong with Ace or i do it wrong in the post/fetching the data. 

I'm using nodejs with express as a webserver and ejs to create my views. 

My Ace editor script looks like this:
 
<script>
   
var textarea = $('#code');
   
var editor = ace.edit("editor");
    editor
.setTheme("ace/theme/github");
    editor
.getSession().setMode("ace/mode/javascript");
    editor
.getSession().on('change', function () {
       textarea
.val(editor.getSession().getValue());
   
});


    editor
.getSession().setValue('<%= event_trigger.code %>');
    textarea
.val(editor.getSession().getValue());</script>  

<%= event_trigger.code %> is the ejs way to put in the raw data from my database(postgre).
To display the data i use a div tag and a hidden textarea to put the data in a form. Whenever the code is changed in the editor it will update the textarea.

<textarea class="form-control" rows="5" id="code" name="code" style="display: none;"></textarea>
   
<div id="editor">
   
</div>

I have made a button to save the data. On click on the button i use a ajax script to send the data:

<script type="text/javascript">
  $
("#saveCode").click(function(){


    $
.ajax({
      type
: "POST",
      async
: true,
      url
: "/checkins/saveTriggerCode",
      data
: JSON.stringify({
        id
: $("#eventTriggerId").val(),
        code
: $("#code").val()
     
}),
      dataType
: "json",
      contentType
: "application/x-www-form-urlencoded; charset=utf-8",
        success
: function (msg)
               
{ $.toast({
                  heading
: 'Success',
                  text
: 'Device information updated',
                  showHideTransition
: 'slide',
                  position
: 'top-right',
                  icon
: 'success'})},
        error
: function (err)
       
{
          console
.log({err})
          $
.toast({
          heading
: 'Error',
          text
: 'Code update failed \n ' + err.status,
          showHideTransition
: 'slide',
          position
: 'top-right',
          icon
: 'error'})}
   
});
 
});
</script>

In this case the line formatting is simply lost. 
If i replace application/x-www-form-urlencoded; with application/json;
the formatting is kept in the database but when i need to display the code from the database the "\n" character causes the inserted code in editor.getSession().setValue('<%= event_trigger.code %>'); to be multi-line hence resulting in a console error.

Harutyun Amirjanyan

unread,
Oct 5, 2017, 2:03:24 PM10/5/17
to ace-d...@googlegroups.com
This question is not really related to ace, and is more about ejs.
You need to use application/json contentType, otherwise you are discarding new line characters (and some others),

Multiline strings cause problems because you are not escaping them string properly when putting into script tag from ejs

In cloud9 we use https://github.com/c9/core/blob/b6148761dcc4c88918cdc5946d1f5e543d654aab/plugins/c9.vfs.standalone/views/standalone.html.ejs#L32
for a similar issue

That is: add a new ejs filter  

    ejs.filters.JSONToJS = function(obj, indent) {
        return JSON.stringify(obj, null, indent).replace(/<\/?script|[\u2028\u2029\ud800-\uDFFF\ufeff]/ig, function(a) {
            var h =  a.charCodeAt(0).toString(16);
            return (h.length == 2 ? "\\x" : "\\u") + h + a.substr(1);
        });
    };
    
and instead of 

    editor.getSession().setValue('<%= event_trigger.code %>');

use 

    editor.session.setValue(<%-: event_trigger.code | JSONToJS  %>);

note how the filter escapes closing script tag, unicode line terminators, invalid unicode sequences and bom character, which can not appear in the middle of the string and  json.stringify handles the addition of quotes and escaping newlines.

if you prefer to not use filter syntax, or use an old version of ejs

    editor.session.setValue(<%-  ejs.JSONToJS (event_trigger.code) %>);

should also work


--
You received this message because you are subscribed to the Google Groups "Ajax.org Cloud9 Editor (Ace)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ace-discuss+unsubscribe@googlegroups.com.
To post to this group, send email to ace-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/ace-discuss.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages