Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code editor not working if ace loaded via requirejs. #173

Closed
SplicePHP opened this issue Mar 25, 2015 · 14 comments
Closed

Code editor not working if ace loaded via requirejs. #173

SplicePHP opened this issue Mar 25, 2015 · 14 comments

Comments

@SplicePHP
Copy link

If you load ace with requirejs prior to loading jsoneditor you get this error:
WARNING: Cannot load code editor, Ace library not loaded. Falling back to plain text editor
This happens even if I shim jsoneditor to load 'ace/ace' in its deps.
I have multiple instances of ace running on my project and need jsoneditor to be able to run on every page in a toolbar as a page registry variable manager.
I have stripped down an example to the bare nuts and bolts to illustrate the error below.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Project</title>
        <link href="css/style.css" rel="stylesheet" type="text/css"/>
        <link href="js/lib/jsoneditor/jsoneditor.min.css" rel="stylesheet" type="text/css"/>
        <script src="js/lib/require.js" type="text/javascript"></script>
        <script>
            requirejs.config({
                baseUrl: 'js/lib',
                paths: {
                    jsoneditor: 'jsoneditor/jsoneditor.min'
                },
                shim: {
                    jsoneditor: {
                        exports: ['JSONEditor'],
                        deps: ["ace"]
                    }
                }
            });
        </script>
    </head>
    <body>
        <pre id="editor">function foo(items) {
            var i;
                for (i = 0; i &lt; items.length; i++) {
                    alert("Ace Rocks " + items[i]);
                }
            }
        </pre>
        <div id="container"></div>
        <script>
            require(['ace/ace'], function () {
//                ace.require("ace/config").set("packaged", false);
                var editor = ace.edit("editor");
                editor.setTheme("ace/theme/twilight");
                editor.getSession().setMode("ace/mode/javascript");
            });
            require(['ace/ace'],function(ace){
                require(['jquery', 'jsoneditor'], function ($, JSONEditor, ace) {
                    var container = $('#container');
                    var editor = new JSONEditor(container[0], {modes: ['code', 'form', 'text', 'tree', 'view'], mode: "code"});
                    // set json
                    var json = {
                        "Array": [1, 2, 3],
                        "Boolean": true,
                        "Null": null,
                        "Number": 123,
                        "Object": {"a": "b", "c": "d"},
                        "String": "Hello World"
                    };
                    editor.set(json);
                    // get json
                    var json = editor.get();
                });
            });
        </script>
    </body>
</html>

This is a simple index.php file with an ace build, jquery file and jsoneditor located in js/lib.

Getting this working is of extreme importance to me since I can't finish any of my current projects until this is resolved and I am already way way overdue on delivery on all of them.
Any help would be greatly appreciated.

@josdejong
Copy link
Owner

Which version of JSONEditor are you using? (There is quite a breaking change in v4.0, which now has Ace editor embedded by default)

@SplicePHP
Copy link
Author

I am using the latest git master build

@josdejong
Copy link
Owner

So is there any need left to load ace editor separately? It's embedded in JSONEditor. There is a require.js example which works just fine if you switch to mode code.

@SplicePHP
Copy link
Author

Unfortunately it has to be loaded via requirejs. There are other widgets that use ace as well. For example I have an CKEditor widget that uses ace for creating twig templates. If I have both on the same page a conflict emerges. This widget gets used quite a lot. I also need to use requirejs to load ace since the system uses a lot of ajax. This makes it impossible for me to know exactly which scripts will be loaded on a given page since the content is dynamically generated as scripts are loaded as they are needed.

@SplicePHP
Copy link
Author

I quickly create a repo with the bare bones example for you to download if you are interested in seeing the error.

@josdejong
Copy link
Owner

Ok thanks

@SplicePHP
Copy link
Author

Here you go: https://github.com/SplicePHP/error-ace

@josdejong
Copy link
Owner

I think your issue is similar to this one: #166 (comment), and will be largely resolved when JSONEditor allows overriding the ace editor.

As a quick hack, you can change the code testing for availability of Ace such that it uses the global ace instance when missing, like:

      if (this.mode == 'code') {
        // verify whether Ace editor is available and supported
        if (typeof ace === 'undefined') {
          ace = window.ace;
        }
        if (typeof ace === 'undefined') {
          this.mode = 'text';
          util.log('WARNING: Cannot load code editor, Ace library not loaded. ' +
              'Falling back to plain text editor');
        }
      }

code: https://github.com/SplicePHP/error-ace/blob/master/js/lib/jsoneditor/jsoneditor.js#L1140-L1147

All you have to do then is move the files that the global ace then tries to load (like the custom theme of JSONEditor) to the right folder where Ace expects them.

@SplicePHP
Copy link
Author

Thanks, I will try this and see if I can make it play nice.

@SplicePHP
Copy link
Author

Okay, I finally got it to play nice.
Took a hell of a lot of trial an error.
There are a couple of important things to note though:
For some reason the library ace/src-min does not work with requirejs.
ace/src-min-noconflict does work however.
When loading other ace scripts via require you have to do it like this:

require(['ace/ace'], function () {
    var editor = ace.edit("editor");
    editor.setTheme("ace/theme/twilight");
    editor.getSession().setMode("ace/mode/javascript");
});

it is very important that you don't call require like this:

require(['ace/ace'], function (ace) {

This will cause a conflict.

My working requirejs config looks like this:

            requirejs = {
                baseUrl: 'js',
                paths: {
                    jsoneditor: 'jsoneditor/jsoneditor',
                    ace: 'ace/src-min-noconflict'
                },
                shim: {
                    jsoneditor: {
                        deps: ['ace/ace'],
                        exports: 'JSONEditor'
                    }
                }
            };

Adding the following lines to jsoneditor got it working as suggested above.

        if (typeof ace === 'undefined') {
          ace = window.ace;
        }

In addition I added this to +-line 1224 to remove the scrolling notice from the console.
(It might be a good idea to add this to the core library in addition to the above mentioned hack)

editor.$blockScrolling = Infinity;

It is also important to add the json template to the requirejs ace directory.

Everything seems to be working flawlessly now.

Thanks for the help
You saved my life by pointing me in the right direction.

@SplicePHP
Copy link
Author

For anyone who has the same problem.
I have updated the git repo with the two libs working together via requirejs on:
https://github.com/SplicePHP/error-ace

@josdejong
Copy link
Owner

Thanks for your update, glad you got it working.

It might be a good idea to add this to the core library in addition to the above mentioned hack

Yes that will be very handy. It's on the list (see #166 (comment)).

@josdejong
Copy link
Owner

I've just released v4.2.0, which has a new option ace, allowing you to pass a custom instance of Ace instead of the embedded one.

@SplicePHP
Copy link
Author

Thanks for the update.

PS. If anyone is using a custom version of ace, it is still a good idea to do a custom build of jsoneditor with ace omitted completely. This will dramatically decrease the size of the jsoneditor script. Ace is a big library and one should avoid loading it multiple times if possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants