/** * Copyright JS Foundation and other contributors, http://js.foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. **/ var RED = (function() { function appendNodeConfig(nodeConfig,done) { done = done || function(){}; var m = //.exec(nodeConfig.trim()); var moduleId; if (m) { moduleId = m[1]; } else { moduleId = "unknown"; } try { var hasDeferred = false; var nodeConfigEls = $("
"+nodeConfig+"
"); nodeConfigEls.find("script").each(function(i,el) { var srcUrl = $(el).attr('src'); if (srcUrl && !/^\s*(https?:|\/|\.)/.test(srcUrl)) { $(el).remove(); var newScript = document.createElement("script"); newScript.onload = function() { $("body").append(nodeConfigEls); done() } $('body').append(newScript); newScript.src = RED.settings.apiRootUrl+srcUrl; hasDeferred = true; } }) if (!hasDeferred) { $("body").append(nodeConfigEls); done(); } } catch(err) { RED.notify(RED._("notification.errors.failedToAppendNode",{module:moduleId, error:err.toString()}),{ type: "error", timeout: 10000 }); console.log("["+moduleId+"] "+err.toString()); done(); } } function loadNodeList() { $.ajax({ headers: { "Accept":"application/json" }, cache: false, url: 'nodes', success: function(data) { RED.nodes.setNodeList(data); RED.i18n.loadNodeCatalogs(function() { loadIconList(loadNodes); }); } }); } function loadIconList(done) { $.ajax({ headers: { "Accept":"application/json" }, cache: false, url: 'icons', success: function(data) { RED.nodes.setIconSets(data); if (done) { done(); } } }); } function loadNodes() { $.ajax({ headers: { "Accept":"text/html" }, cache: false, url: 'nodes', success: function(data) { var configs = data.trim().split(/(?=)/); var stepConfig = function() { if (configs.length === 0) { $("body").i18n(); $("#palette > .palette-spinner").hide(); $(".palette-scroll").removeClass("hide"); $("#palette-search").removeClass("hide"); loadFlows(function() { if (RED.settings.theme("projects.enabled",false)) { RED.projects.refresh(function(activeProject) { RED.sidebar.info.refresh() if (!activeProject) { // Projects enabled but no active project RED.menu.setDisabled('menu-item-projects-open',true); RED.menu.setDisabled('menu-item-projects-settings',true); if (activeProject === false) { // User previously decline the migration to projects. } else { // null/undefined RED.projects.showStartup(); } } completeLoad(); }); } else { // Projects disabled by the user RED.sidebar.info.refresh() completeLoad(); } }); } else { var config = configs.shift(); appendNodeConfig(config,stepConfig); } } stepConfig(); } }); } function loadFlows(done) { $.ajax({ headers: { "Accept":"application/json", }, cache: false, url: 'flows', success: function(nodes) { if (nodes) { var currentHash = window.location.hash; RED.nodes.version(nodes.rev); RED.nodes.import(nodes.flows); RED.nodes.dirty(false); RED.view.redraw(true); if (/^#flow\/.+$/.test(currentHash)) { RED.workspaces.show(currentHash.substring(6)); } } done(); } }); } function completeLoad() { var persistentNotifications = {}; RED.comms.subscribe("notification/#",function(topic,msg) { var parts = topic.split("/"); var notificationId = parts[1]; if (notificationId === "runtime-deploy") { // handled in ui/deploy.js return; } if (notificationId === "node") { // handled below return; } if (notificationId === "project-update") { RED.nodes.clear(); RED.history.clear(); RED.view.redraw(true); RED.projects.refresh(function() { loadFlows(function() { var project = RED.projects.getActiveProject(); var message = { "change-branch": RED._("notification.project.change-branch", {project: project.git.branches.local}), "merge-abort": RED._("notification.project.merge-abort"), "loaded": RED._("notification.project.loaded", {project: msg.project}), "updated": RED._("notification.project.updated", {project: msg.project}), "pull": RED._("notification.project.pull", {project: msg.project}), "revert": RED._("notification.project.revert", {project: msg.project}), "merge-complete": RED._("notification.project.merge-complete") }[msg.action]; RED.notify("

"+message+"

"); RED.sidebar.info.refresh() }); }); return; } if (msg.text) { msg.default = msg.text; var text = RED._(msg.text,msg); var options = { type: msg.type, fixed: msg.timeout === undefined, timeout: msg.timeout, id: notificationId } if (notificationId === "runtime-state") { if (msg.error === "missing-types") { text+=""; if (!!RED.projects.getActiveProject()) { options.buttons = [ { text: RED._("notification.label.manage-project-dep"), click: function() { persistentNotifications[notificationId].hideNotification(); RED.projects.settings.show('deps'); } } ] // } else if (RED.settings.theme('palette.editable') !== false) { } else { options.buttons = [ { text: RED._("common.label.close"), click: function() { persistentNotifications[notificationId].hideNotification(); } } ] } } else if (msg.error === "credentials_load_failed") { if (RED.settings.theme("projects.enabled",false)) { // projects enabled if (RED.user.hasPermission("projects.write")) { options.buttons = [ { text: "Setup credentials", click: function() { persistentNotifications[notificationId].hideNotification(); RED.projects.showCredentialsPrompt(); } } ] } } else { options.buttons = [ { text: "Close", click: function() { persistentNotifications[notificationId].hideNotification(); } } ] } } else if (msg.error === "missing_flow_file") { if (RED.user.hasPermission("projects.write")) { options.buttons = [ { text: "Setup project files", click: function() { persistentNotifications[notificationId].hideNotification(); RED.projects.showFilesPrompt(); } } ] } } else if (msg.error === "missing_package_file") { if (RED.user.hasPermission("projects.write")) { options.buttons = [ { text: "Create default package file", click: function() { persistentNotifications[notificationId].hideNotification(); RED.projects.createDefaultPackageFile(); } } ] } } else if (msg.error === "project_empty") { if (RED.user.hasPermission("projects.write")) { options.buttons = [ { text: "No thanks", click: function() { persistentNotifications[notificationId].hideNotification(); } }, { text: "Create default project files", click: function() { persistentNotifications[notificationId].hideNotification(); RED.projects.createDefaultFileSet(); } } ] } } else if (msg.error === "git_merge_conflict") { RED.nodes.clear(); RED.sidebar.versionControl.refresh(true); if (RED.user.hasPermission("projects.write")) { options.buttons = [ { text: "Show merge conflicts", click: function() { persistentNotifications[notificationId].hideNotification(); RED.sidebar.versionControl.showLocalChanges(); } } ] } } } if (!persistentNotifications.hasOwnProperty(notificationId)) { persistentNotifications[notificationId] = RED.notify(text,options); } else { persistentNotifications[notificationId].update(text,options); } } else if (persistentNotifications.hasOwnProperty(notificationId)) { persistentNotifications[notificationId].close(); delete persistentNotifications[notificationId]; } }); RED.comms.subscribe("status/#",function(topic,msg) { var parts = topic.split("/"); var node = RED.nodes.node(parts[1]); if (node) { if (msg.hasOwnProperty("text")) { if (msg.text[0] !== ".") { msg.text = node._(msg.text.toString(),{defaultValue:msg.text.toString()}); } } node.status = msg; node.dirty = true; RED.view.redraw(); } }); RED.comms.subscribe("notification/node/#",function(topic,msg) { var i,m; var typeList; var info; if (topic == "notification/node/added") { var addedTypes = []; msg.forEach(function(m) { var id = m.id; RED.nodes.addNodeSet(m); addedTypes = addedTypes.concat(m.types); RED.i18n.loadNodeCatalog(id, function() { $.get('nodes/'+id, function(data) { appendNodeConfig(data); }); }); }); if (addedTypes.length) { typeList = ""; RED.notify(RED._("palette.event.nodeAdded", {count:addedTypes.length})+typeList,"success"); } loadIconList(); } else if (topic == "notification/node/removed") { for (i=0;i
  • ")+"
  • "; RED.notify(RED._("palette.event.nodeRemoved", {count:m.types.length})+typeList,"success"); } } loadIconList(); } else if (topic == "notification/node/enabled") { if (msg.types) { info = RED.nodes.getNodeSet(msg.id); if (info.added) { RED.nodes.enableNodeSet(msg.id); typeList = ""; RED.notify(RED._("palette.event.nodeEnabled", {count:msg.types.length})+typeList,"success"); } else { $.get('nodes/'+msg.id, function(data) { appendNodeConfig(data); typeList = ""; RED.notify(RED._("palette.event.nodeAdded", {count:msg.types.length})+typeList,"success"); }); } } } else if (topic == "notification/node/disabled") { if (msg.types) { RED.nodes.disableNodeSet(msg.id); typeList = ""; RED.notify(RED._("palette.event.nodeDisabled", {count:msg.types.length})+typeList,"success"); } } else if (topic == "node/upgraded") { RED.notify(RED._("palette.event.nodeUpgraded", {module:msg.module,version:msg.version}),"success"); RED.nodes.registry.setModulePendingUpdated(msg.module,msg.version); } // Refresh flow library to ensure any examples are updated RED.library.loadFlowLibrary(); }); } function showAbout() { $.get('red/about', function(data) { var aboutHeader = '
    '+ ''+ '
    '; RED.sidebar.info.set(aboutHeader+marked(data)); RED.sidebar.info.show(); }); } function loadEditor() { var menuOptions = []; if (RED.settings.theme("projects.enabled",false)) { menuOptions.push({id:"menu-item-projects-menu",label:"Projects",options:[ {id:"menu-item-projects-new",label:"New",disabled:false,onselect:"core:new-project"}, {id:"menu-item-projects-open",label:"Open",disabled:false,onselect:"core:open-project"}, {id:"menu-item-projects-settings",label:"Project Settings",disabled:false,onselect:"core:show-project-settings"} ]}); } menuOptions.push({id:"menu-item-view-menu",label:RED._("menu.label.view.view"),options:[ // {id:"menu-item-view-show-grid",setting:"view-show-grid",label:RED._("menu.label.view.showGrid"),toggle:true,onselect:"core:toggle-show-grid"}, // {id:"menu-item-view-snap-grid",setting:"view-snap-grid",label:RED._("menu.label.view.snapGrid"),toggle:true,onselect:"core:toggle-snap-grid"}, // {id:"menu-item-status",setting:"node-show-status",label:RED._("menu.label.displayStatus"),toggle:true,onselect:"core:toggle-status", selected: true}, //null, // {id:"menu-item-bidi",label:RED._("menu.label.view.textDir"),options:[ // {id:"menu-item-bidi-default",toggle:"text-direction",label:RED._("menu.label.view.defaultDir"),selected: true, onselect:function(s) { if(s){RED.text.bidi.setTextDirection("")}}}, // {id:"menu-item-bidi-ltr",toggle:"text-direction",label:RED._("menu.label.view.ltr"), onselect:function(s) { if(s){RED.text.bidi.setTextDirection("ltr")}}}, // {id:"menu-item-bidi-rtl",toggle:"text-direction",label:RED._("menu.label.view.rtl"), onselect:function(s) { if(s){RED.text.bidi.setTextDirection("rtl")}}}, // {id:"menu-item-bidi-auto",toggle:"text-direction",label:RED._("menu.label.view.auto"), onselect:function(s) { if(s){RED.text.bidi.setTextDirection("auto")}}} // ]}, // null, {id:"menu-item-sidebar",label:RED._("menu.label.sidebar.show"),toggle:true,onselect:"core:toggle-sidebar", selected: true}, null ]}); menuOptions.push(null); menuOptions.push({id:"menu-item-import",label:RED._("menu.label.import"),options:[ {id:"menu-item-import-clipboard",label:RED._("menu.label.clipboard"),onselect:"core:show-import-dialog"}, {id:"menu-item-import-library",label:RED._("menu.label.library"),options:[]} ]}); menuOptions.push({id:"menu-item-export",label:RED._("menu.label.export"),options:[ {id:"menu-item-export-clipboard",label:RED._("menu.label.clipboard"),onselect:"core:show-export-dialog"}, {id:"menu-item-export-library",label:RED._("menu.label.library"),disabled:true,onselect:"core:library-export"} ]}); menuOptions.push(null); menuOptions.push({id:"menu-item-search",label:RED._("menu.label.search"),onselect:"core:search"}); menuOptions.push(null); menuOptions.push({id:"menu-item-config-nodes",label:RED._("menu.label.displayConfig"),onselect:"core:show-config-tab"}); menuOptions.push({id:"menu-item-workspace",label:RED._("menu.label.flows"),options:[ {id:"menu-item-workspace-add",label:RED._("menu.label.add"),onselect:"core:add-flow"}, {id:"menu-item-workspace-edit",label:RED._("menu.label.rename"),onselect:"core:edit-flow"}, {id:"menu-item-workspace-delete",label:RED._("menu.label.delete"),onselect:"core:remove-flow"} ]}); menuOptions.push({id:"menu-item-subflow",label:RED._("menu.label.subflows"), options: [ {id:"menu-item-subflow-create",label:RED._("menu.label.createSubflow"),onselect:"core:create-subflow"}, {id:"menu-item-subflow-convert",label:RED._("menu.label.selectionToSubflow"),disabled:true,onselect:"core:convert-to-subflow"}, ]}); menuOptions.push(null); if (RED.settings.theme('palette.editable') !== false) { menuOptions.push({id:"menu-item-edit-palette",label:RED._("menu.label.editPalette"),onselect:"core:manage-palette"}); menuOptions.push(null); } menuOptions.push({id:"menu-item-user-settings",label:RED._("menu.label.settings"),onselect:"core:show-user-settings"}); menuOptions.push(null); menuOptions.push({id:"menu-item-keyboard-shortcuts",label:RED._("menu.label.keyboardShortcuts"),onselect:"core:show-help"}); menuOptions.push({id:"menu-item-help", label: RED.settings.theme("menu.menu-item-help.label",RED._("menu.label.help")), href: RED.settings.theme("menu.menu-item-help.url","http://nodered.org/docs") }); menuOptions.push({id:"menu-item-node-red-version", label:"v"+RED.settings.version, onselect: "core:show-about" }); RED.view.init(); RED.userSettings.init(); RED.user.init(); RED.library.init(); RED.keyboard.init(); RED.palette.init(); if (RED.settings.theme('palette.editable') !== false) { RED.palette.editor.init(); } else { console.log("Palette editor disabled"); } RED.sidebar.init(); if (RED.settings.theme("projects.enabled",false)) { RED.projects.init(); } else { console.log("Projects disabled"); } RED.subflow.init(); RED.workspaces.init(); RED.clipboard.init(); RED.search.init(); RED.editor.init(); RED.diff.init(); RED.menu.init({id:"btn-sidemenu",options: menuOptions}); RED.deploy.init(RED.settings.theme("deployButton",null)); RED.notifications.init(); RED.actions.add("core:show-about", showAbout); RED.nodes.init(); RED.comms.connect(); $("#main-container").show(); $(".header-toolbar").show(); loadNodeList(); } var initialised = false; function init(options) { if (initialised) { throw new Error("RED already initialised"); } initialised = true; ace.require("ace/ext/language_tools"); options = options || {}; options.apiRootUrl = options.apiRootUrl || ""; if (options.apiRootUrl && !/\/$/.test(options.apiRootUrl)) { options.apiRootUrl = options.apiRootUrl+"/"; } RED.i18n.init(options, function() { RED.settings.init(options, loadEditor); }) } return { init: init } })();