I am embedding Ace locally offline and so am not using the hosted package and am subject to the same origin policy.
How do you tell ace to look in a particular folder for it's source of modes, themes and workers?
You used to be able to use:
editor.config.set("modePath", "Scripts/Ace");
editor.config.set("workerPath", "Scripts/Ace");
editor.config.set("themePath", "Scripts/Ace");
But that doesn't work in the latest version.
How can this be achieved?
Thanks in advance
I had a similar issue and you can actually let Ace know what's the base folder path this way:
ace.config.set("basePath", "/Scripts/Ace");
This work with the latest version I have, v1.1.3
The simple way to achieve the same thing is to embed all scripts from the Ace source folder into the web page manually, excluding the worker-xxx.js files. This is still a bodge though.
The answer from #rorofromfrance solve my problem of the base folder path on loading Ace script on the fly:
$.getScript($('#js')[0].href, function() {
$('.theme').change(function() {draw.change();});
$.getScript("/ace/src-min/ace.js", function() {
if (!editor) {ace.config.set("basePath", "/ace/src-min"); draw.editor();};
$.getScript("/underscore/underscore-min.js", function() {
editor.getSession().on('change', _.debounce(function() {draw.diagram();}, 100));
$.getScript("/tensorflow/tf.min.js", function() {
$.ajax({
type: "GET",
dataType: "xml",
url: "/sitemap.xml",
success: draw.getJSON(xml)
});
});
});
});
});
I have a similar requirement in a current project of mine.
I created an Angular project with all the files bundles in a single directory without access to node_modules in runtime, using a remote package for the ace basePath was out of the question.
Then I stumbled upon the Ace embedding guide and it clued me that I can import the relevant modes and themes straight from my dependencies and just use new instead of a path string.
https://ajaxorg.github.io/ace-api-docs/index.html#embedding-ace
from the docs:
var JavaScriptMode = ace.require("ace/mode/javascript").Mode;
editor.session.setMode(new JavaScriptMode());
So I just imported the mode and theme I went and provided them straight to Ace
import DraculaTheme from "ace-builds/src-noconflict/theme-dracula";
import JavaScriptMode from "ace-builds/src-noconflict/mode-javascript";
const aceEditor = ace.edit(this.editor.nativeElement);
aceEditor.session.setValue("function greet() {\n\tconsole.log('hello world');\n}\n");
aceEditor.setTheme(DraculaTheme);
aceEditor.session.setMode(new JavaScriptMode.Mode());
Notice that I didn't set any basePath !!!
Related
I ran into a problem where when I call my mirage_smokes.json file using the require.js module, the script searches for mirage_smokes.json.js to no avail. (Obviously, the .js extension is not supposed to be there)
function getData() {
require(['../JSON/mirage_smokes.json'], function(data) {
document.getElementById(testJSON).innerHTML = data.number;
});
}
What could be causing the bug?
RequireJS defaults to javascript files and will automatically add the extension to the end of your filename. So, you must tell RequireJS that you are looking for a JSON file by using this syntax:
require(['json!yourfile.json'], function(data) {
...
})
Alternatively, since RequireJS adds the extension to the end of the filename for you, you can leave off the .json extension if you wish:
require(['json!yourfile'], function(data) {
...
})
I have to setup a, most of the time, offline installation of Node-RED and need to use the "Chart.js" Library in a template node. Currently my working approach is to copy the Chart.js dictory to node-red-dashboard/dist/js and import it with <script src= "js/chart.js/dist/Chart.min.js"></script>. But when I want to update the dashboard I need to copy everything again. So it would be nice to have a permanent Solution for this.
I tryed two other approaches until now. For both I installed Chart.js to the .node-red dictory.
First I tryed it like this:
var canvas = document.getElementById('myChart').getContext('2d');
var ChartJs = require('Chart.js');
var chart = new ChartJs(canvas, {... }
in a script tag (... stands for the working chart code that is not edited), but it didn't work aswell as to put
functionGlobalContext: {chartjs:require('Chart.js')} into settings.js and change require('Chart.js') to global.get('chartjs')
Does anyone here has an Idea to solve this properly? Unfortunately the node throws no Error to the console so I don't get an idea whats wrong here.
Thanks in advance for every hint or solution,
manni
When I want to use any 3rd party charting library in my node-red dashboard, I put 2 ui_template nodes into my flow:
under "Template Type" select the "Added to site <head> section" and add the link to the library's url:
<script src="url/to/library.js"></script>
(which in your offline case would be a local url)
use the library's exported objects directly within the template, without using require, such as:
<div id="myChart"></div>
<script>
var canvas = document.getElementById('myChart').getContext('2d');
var chart = new ChartJs(canvas, { ... }
</script>
The trick is to have your local node-red instance serve the ChartJS library through a local url. For that, first add this require path line to the settings.js file, before the exports section:
// The `https` setting requires the `fs` module. Uncomment the following
// to make it available:
var fs = require("fs");
var path = require ("path");
then, uncomment the httpStatic section below that, within the exports:
// When httpAdminRoot is used to move the UI to a different root path, the
// following property can be used to identify a directory of static content
// that should be served at http://localhost:1880/.
httpStatic: path.join(__dirname, 'public'),
(you can use any directory name, in place of public) The __dirname references the node-red server's working directory, usually .node-red under your home directory.
Create this new public directory, copy the ChartJS files under it, and restart node-red. At startup, you should see a line in the console log showing the path to your new static file location:
5 Feb 12:12:23 - [info] Settings file : C:\NODE\node_red_ui\settings.js
5 Feb 12:12:23 - [info] HTTP Static : C:\NODE\node_red_ui\public
5 Feb 12:12:23 - [info] User directory : C:\NODE\node_red_ui
Now you can serve the local file public\scripts\abc.js using the local url
http://localhost:1880/scripts/abc.js
This way, npm updates to the dashboard code will not overwrite your static files.
Simple question here, but I found no useful resource. Is templating possible in Electron? Using Jade or Handlebars to display dynamic templates? I know there is .loadURL() that takes a static html file.
Is dynamic possible?
Thanks.
You could give electron-pug a chance. https://github.com/yan-foto/electron-pug
You can register a new buffer protocol via protocol.registerBufferProtocol.
main.js
var electron = require('electron');
var app = electron.app;
var protocol = electron.protocol;
var BrowserWindow = electron.BrowserWindow;
var pug = require('pug');
var window;
app.on('ready', function () {
// Define the `pug` scheme
protocol.registerBufferProtocol('pug', function (request, callback) {
var url = path.normalize(request.url.substr(7));
var content = pug.renderFile(url);
callback({
mimeType: 'text/html',
data: new Buffer(content)
});
});
window = new BrowserWindow({width: 600, height: 600});
// Load your file using the `pug` protocol
window.loadURL(url.format({
pathname: path.join(__dirname, 'index.pug'),
protocol: 'pug:',
slashes: true
}));
});
index.pug
html
head
title My title
body
h1 Hello world!
It would certainly be possible to use Jade or Handlebars for dynamic templating by running a local server in the Electron main process. I would not recommend this however, as it is kind of backwards. Electron is primarily a front end framework and while running a local server is good for some things, templating is not really one of them.
Most people use a frontend JS framework like Angular or React.
Probably too late to add here but thought it might be worthwhile. I have added a package to deal with adding views from any renderer and handle asset paths. So far I have just added the ejs renderer but plan on adding pug and haml as additional default renderers, but it is easy to extend and add your own as well. The package is called electron-view-renderer https://www.npmjs.com/package/electron-view-renderer
Hopefully this can help someone like it did our team. It is in its infancy, so all comments and contributions welcome
U can use ejs-electron to achieve the same purpose. U can check it out on github & simply install it as follows:
npm i ejs-electron --save
Just require it in ur main js file
I'm using requireJS to load scripts. It has this detail in the docs:
The path that is used for a module name should not include the .js
extension, since the path mapping could be for a directory.
In my app, I map all of my script files in a config path, because they're dynamically generated at runtime (my scripts start life as things like order.js but become things like order.min.b25a571965d02d9c54871b7636ca1c5e.js (this is a hash of the file contents, for cachebusting purposes).
In some cases, require will add a second .js extension to the end of these paths. Although I generate the dynamic paths on the server side and then populate the config path, I have to then write some extra javascript code to remove the .js extension from the problematic files.
Reading the requireJS docs, I really don't understand why you'd ever want the path mapping to be used for a directory. Does this mean it's possible to somehow load an entire directory's worth of files in one call? I don't get it.
Does anybody know if it's possible to just force require to stop adding .js to file paths so I don't have to hack around it?
thanks.
UPDATE: added some code samples as requested.
This is inside my HTML file (it's a Scala project so we can't write these variables directly into a .js file):
foo.js.modules = {
order : '#Static("javascripts/order.min.js")',
reqwest : 'http://5.foo.appspot.com/js/libs/reqwest',
bean : 'http://4.foo.appspot.com/js/libs/bean.min',
detect : 'order!http://4.foo.appspot.com/js/detect/detect.js',
images : 'order!http://4.foo.appspot.com/js/detect/images.js',
basicTemplate : '#Static("javascripts/libs/basicTemplate.min.js")',
trailExpander : '#Static("javascripts/libs/trailExpander.min.js")',
fetchDiscussion : '#Static("javascripts/libs/fetchDiscussion.min.js")'
mostPopular : '#Static("javascripts/libs/mostPopular.min.js")'
};
Then inside my main.js:
requirejs.config({
paths: foo.js.modules
});
require([foo.js.modules.detect, foo.js.modules.images, "bean"],
function(detect, images, bean) {
// do stuff
});
In the example above, I have to use the string "bean" (which refers to the require path) rather than my direct object (like the others use foo.js.modules.bar) otherwise I get the extra .js appended.
Hope this makes sense.
If you don't feel like adding a dependency on noext, you can also just append a dummy query string to the path to prevent the .js extension from being appended, as in:
require.config({
paths: {
'signalr-hubs': '/signalr/hubs?noext'
}
});
This is what the noext plugin does.
requirejs' noext plugin:
Load scripts without appending ".js" extension, useful for dynamic scripts...
Documentation
check the examples folder. All the info you probably need will be inside comments or on the example code itself.
Basic usage
Put the plugins inside the baseUrl folder (usually same folder as the main.js file) or create an alias to the plugin location:
require.config({
paths : {
//create alias to plugins (not needed if plugins are on the baseUrl)
async: 'lib/require/async',
font: 'lib/require/font',
goog: 'lib/require/goog',
image: 'lib/require/image',
json: 'lib/require/json',
noext: 'lib/require/noext',
mdown: 'lib/require/mdown',
propertyParser : 'lib/require/propertyParser',
markdownConverter : 'lib/Markdown.Converter'
}
});
//use plugins as if they were at baseUrl
define([
'image!awsum.jpg',
'json!data/foo.json',
'noext!js/bar.php',
'mdown!data/lorem_ipsum.md',
'async!http://maps.google.com/maps/api/js?sensor=false',
'goog!visualization,1,packages:[corechart,geochart]',
'goog!search,1',
'font!google,families:[Tangerine,Cantarell]'
], function(awsum, foo, bar, loremIpsum){
//all dependencies are loaded (including gmaps and other google apis)
}
);
I am using requirejs server side with node.js. The noext plugin does not work for me. I suspect this is because it tries to add ?noext to a url and we have filenames instead of urls serverside.
I need to name my files .njs or .model to separate them from static .js files. Hopefully the author will update requirejs to not force automatic .js file extension conventions on the users.
Meanwhile here is a quick patch to disable this behavior.
To apply this patch (against version 2.1.15 of node_modules/requirejs/bin/r.js) :
Save in a file called disableAutoExt.diff or whatever and open a terminal
cd path/to/node_modules/
patch -p1 < path/to/disableAutoExt.diff
add disableAutoExt: true, to your requirejs.config: requirejs.config({disableAutoExt: true,});
Now we can do require(["test/index.njs", ...] ... and get back to work.
Save this patch in disableAutoExt.diff :
--- mod/node_modules/requirejs/bin/r.js 2014-09-07 20:54:07.000000000 -0400
+++ node_modules/requirejs/bin/r.js 2014-12-11 09:33:21.000000000 -0500
## -1884,6 +1884,10 ##
//Delegates to req.load. Broken out as a separate function to
//allow overriding in the optimizer.
load: function (id, url) {
+ if (config.disableAutoExt && url.match(/\..*\.js$/)) {
+ url = url.replace(/\.js$/, '');
+ }
+
req.load(context, id, url);
},
The patch simply adds the following around line 1887 to node_modules/requirejs/bin/r.js:
if (config.disableAutoExt && url.match(/\..*\.js$/)) {
url = url.replace(/\.js$/, '');
}
UPDATE: Improved patch by moving url change deeper in the code so it no longer causes a hang after calling undef on a module. Needed undef because:
To disable caching of modules when developing with node.js add this to your main app file:
requirejs.onResourceLoad = function(context, map)
{
requirejs.undef(map.name);
};
Update I want to avoid compiling the templates client-side, and have them compile during my local ant build process. Perhaps something like loading jQuery and jQuery templates into rhino, passing the $.template() function the contents of each .jst file in turn, and building a "templates.js" which should contain:
$.template['model-view'] = resultingFunction.toString();
// 1 for each .jst file
This way, I can maintain each template in a seperate file, and avoid having all clients redundantly compile the same template.
I'm using jQuery templates, and was hoping to separate them out into their own files (eg. model-view.jst) that are compiled into functions when the project is built and made available in the jQuery .tmpl() scope for later use.
For example, given the file model-view.jst
<li>${name}</li>
This file and all other .jst files should be picked up on build, compiled into a function that can later be used anywhere in the program like so:
$.tmpl('model-view', {
name: 'Matt'
});
I solved this problem using Node.js and coffeescript by making directory of partial templated into executable, pre-compiled functions. Hope this helps.
https://github.com/wookiehangover/jquery-tmpl-jst
I let you decide if you like it or not :)
in you common js library define this function:
function loadTemplate(templateName) {
$.ajax({
url: templateName + '.jst',
success: function(data) {
$.template(templateName, data);
}});
}
Then in you master hml file <head></head> section you can add:
<script type="text/javascript">loadTemplate('model-view');</script>
<script type="text/javascript">loadTemplate('another-model-view');</script>
so you can use anywhere in your code
$.tmpl('model-view', your-data)
$.tmpl('another-model-view', your-data)
Hope it helps