123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423 |
- /**
- * @license Licensed under the Apache License, Version 2.0 (the "License"):
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * @fileoverview Ardublockly JavaScript for the Blockly resources and bindings.
- */
- 'use strict';
- /** Create a namespace for the application. */
- var Ardublockly = Ardublockly || {};
- /**
- * Blockly main workspace.
- * @type Blockly.WorkspaceSvg
- */
- Ardublockly.workspace = null;
- /**
- * Blockly workspace toolbox XML.
- * @type Element
- */
- Ardublockly.xmlTree = null;
- Ardublockly.injectBlockly = function (blocklyEl, toolboxXml, blocklyPath) {
- // Remove any trailing slashes in the blockly path
- if (blocklyPath.substr(-1) === '/') {
- blocklyPath = blocklyPath.slice(0, -1);
- }
- // Ardublockly.xmlTree = Blockly.Xml.textToDom(toolboxXml);
- // The Toolbox menu language is edited directly from the XML nodes.
- Ardublockly.updateToolboxLanguage(toolboxXml);
- Ardublockly.workspace = Blockly.inject(blocklyEl, {
- collapse: true,
- comments: true,
- css: true,
- disable: true,
- grid: false,
- maxBlocks: Infinity,
- media: blocklyPath + '/media/',
- rtl: false,
- scrollbars: true,
- sounds: true,
- toolbox: Ardublockly.xmlTree,
- trashcan: true,
- zoom: {
- controls: true,
- wheel: false,
- startScale: 1.0,
- maxScale: 2,
- minScale: 0.2,
- scaleSpeed: 1.2
- }
- });
- };
- /** Binds the event listeners relevant to Blockly. */
- Ardublockly.bindBlocklyEventListeners = function () {
- blockpy.components.editor.blockly.addChangeListener(Ardublockly.renderContent);
- // Ensure the Blockly workspace resizes accordingly
- window.addEventListener('resize',
- function () { Blockly.asyncSvgResize(blockpy.components.editor.blockly); }, false);
- };
- /** @return {!string} Generated Arduino code from the Blockly workspace. */
- Ardublockly.generateArduino = function () {
- return Blockly.Python.workspaceToCode(blockpy.components.editor.blockly);
- };
- /** @return {!string} Generated XML code from the Blockly workspace. */
- Ardublockly.generateXml = function () {
- var xmlDom = Blockly.Xml.workspaceToDom(blockpy.components.editor.blockly);
- //add tag for different mode
- var tag = CCB.mode ? "main" : "wifi"
- var xmlText = tag + "$" + Blockly.Xml.domToPrettyText(xmlDom);
- return xmlText;
- };
- Ardublockly.loadXmlBlockFile = function (xmlFile, cbSuccess, cbError) {
- var request = Ardublockly.ajaxRequest();
- var requestCb = function () {
- if (request.readyState == 4) {
- if (request.status == 200) {
- var result_xml = request.responseText;
- //if file has tag(main/wifi)
- if (request.responseText.indexOf('$') == 4) {
- result_xml = request.responseText.substr(5);
- }
- var success = Ardublockly.replaceBlocksfromXml(result_xml);
- cbSuccess(success);
- } else {
- cbError();
- }
- }
- };
- try {
- request.open('GET', xmlFile, true);
- request.onreadystatechange = requestCb;
- request.send(null);
- } catch (e) {
- cbError();
- }
- };
- Ardublockly.replaceBlocksfromXml = function (blocksXml) {
- var xmlDom = null;
- try {
- xmlDom = Blockly.Xml.textToDom(blocksXml);
- } catch (e) {
- return false;
- }
- blockpy.components.editor.blockly.clear();
- var sucess = false;
- if (xmlDom) {
- sucess = Ardublockly.loadBlocksfromXmlDom(xmlDom);
- }
- return sucess;
- };
- /**
- * Parses the XML from its argument input to generate and add blocks to the
- * Blockly workspace.
- * @param {!string} blocksXmlDom String of XML DOM code for the blocks.
- * @return {!boolean} Indicates if the XML into blocks parse was successful.
- */
- Ardublockly.loadBlocksfromXmlDom = function (blocksXmlDom) {
- // try {
- // Blockly.Xml.domToWorkspace(blocksXmlDom, blockpy.components.editor.blockly);
- // } catch (e) {
- // return false;
- // }
- // return true;
- Blockly.Xml.domToWorkspace(blocksXmlDom, blockpy.components.editor.blockly);
- return !Blockly.Xml.getLoadingXmlErr();
- };
- /**
- * Save blocks into session storage. Note that MSIE 11 does not support
- * sessionStorage on file:// URLs.
- */
- Ardublockly.saveSessionStorageBlocks = function () {
- if (window.sessionStorage) {
- var xml = Blockly.Xml.workspaceToDom(blockpy.components.editor.blockly);
- var text = Blockly.Xml.domToText(xml);
- window.sessionStorage.loadOnceBlocks = text;
- }
- };
- /** Load blocks saved on session storage and deletes them from storage. */
- Ardublockly.loadSessionStorageBlocks = function () {
- try {
- var loadOnce = window.sessionStorage.loadOnceBlocks;
- } catch (e) {
- // Firefox sometimes throws a SecurityError when accessing sessionStorage.
- // Restarting Firefox fixes this, so it looks like a bug.
- var loadOnce = null;
- }
- if (loadOnce) {
- delete window.sessionStorage.loadOnceBlocks;
- var xml = Blockly.Xml.textToDom(loadOnce);
- Blockly.Xml.domToWorkspace(xml, blockpy.components.editor.blockly);
- }
- };
- /**
- * Save blocks into local storage. Note that MSIE 11 does not support
- * LocalStorage on file:// URLs.
- */
- Ardublockly.saveLocalStorageBlocks = function () {
- if (window.sessionStorage) {
- var xml = Blockly.Xml.workspaceToDom(blockpy.components.editor.blockly);
- var text = Blockly.Xml.domToText(xml);
- window.localStorage.loadOnceBlocks = text;
- }
- };
- /** Load blocks saved on loacl storage and deletes them from storage. */
- Ardublockly.loadLocalStorageBlocks = function () {
- try {
- var loadOnce = window.localStorage.loadOnceBlocks;
- } catch (e) {
- // Firefox sometimes throws a SecurityError when accessing sessionStorage.
- // Restarting Firefox fixes this, so it looks like a bug.
- var loadOnce = null;
- }
- if (loadOnce) {
- delete window.localStorage.loadOnceBlocks;
- var xml = Blockly.Xml.textToDom(loadOnce);
- Blockly.Xml.domToWorkspace(xml, blockpy.components.editor.blockly);
- }
- };
- /** Discard all blocks from the workspace. */
- Ardublockly.discardAllBlocks = function () {
- var blockCount = blockpy.components.editor.blockly.getAllBlocks().length;
- var is_delete = false;
- if (blockCount == 1) {
- blockpy.components.editor.blockly.clear();
- Ardublockly.renderContent();
- } else if (blockCount > 1) {
- Ardublockly.alertMessage(
- Ardublockly.getLocalStr('discardBlocksTitle'),
- Ardublockly.getLocalStr('discardBlocksBody').replace('%1', blockCount),
- true,
- function () {
- blockpy.components.editor.blockly.clear();
- Ardublockly.renderContent();
- });
- }
- };
- /** @return {!boolean} Indicates if the Blockly workspace has blocks. */
- Ardublockly.isWorkspaceEmpty = function () {
- return blockpy.components.editor.blockly.getAllBlocks().length ? false : true;
- };
- /**
- * Changes the Arduino board profile if different from the currently set one.
- * @param {string} newBoard Name of the new profile to set.
- */
- Ardublockly.changeBlocklyArduinoBoard = function (newBoard) {
- if (Blockly.Python.Boards.selected !== Blockly.Python.Boards[newBoard]) {
- Blockly.Python.Boards.changeBoard(blockpy.components.editor.blockly, newBoard);
- }
- };
- /** Update the toolbox categories language. */
- Ardublockly.updateToolboxLanguage = function (data) {
- var categories = ['catLogic', 'catLoops', 'catMath', 'catText',
- 'catVariables', 'catDefine', 'catFunctions', 'catInputOutput',
- 'catTime', 'catAudio', 'catMotors', 'catComms', 'catFASTLED', 'catTouch', 'catHCI',
- 'catENV', 'catMOTOR', 'catROBOT', 'catLists', 'catMOTION', 'catMainWifi',
- 'catCloudData', 'catWifiClient', 'catWifiWebServices', 'catWifiComms', 'catNetwork', 'catEasyMode', 'catBlynk', "ExtendedFunction"
- ];
- Ardublockly.xmlTree = Blockly.Xml.textToDom(data)
- var categoryNodes = Ardublockly.xmlTree.getElementsByTagName('category');
- for (var i = 0, cat; cat = categoryNodes[i]; i++) {
- var catId = cat.getAttribute('id');
- var catText = Ardublockly.getLocalStr(catId);
- if (catText) {
- cat.setAttribute('name', catText);
- }
- }
- };
- /**
- * Adds a category to the current toolbox.
- * @param {!string} categoryTitle Toolbox category title.
- * @param {!Element} categoryDom Toolbox category to add add the end of tree.
- */
- Ardublockly.addToolboxCategory = function (categoryTitle, categoryDom) {
- categoryDom.id = 'cat' + categoryTitle.replace(/\s+/g, '');
- categoryDom.setAttribute('name', categoryTitle);
- Ardublockly.xmlTree.appendChild(document.createElement('sep'));
- Ardublockly.xmlTree.appendChild(categoryDom);
- blockpy.components.editor.blockly.updateToolbox(Ardublockly.xmlTree);
- };
- /**
- * Removes a category to the current toolbox.
- * @param {!String} categoryTitle Toolbox category name to remove from tree.
- */
- Ardublockly.removeToolboxCategory = function (categoryTitle) {
- var categoryId = 'cat' + categoryTitle.replace(/\s+/g, '');
- var categoryNodes = Ardublockly.xmlTree.getElementsByTagName('category');
- for (var i = 0; i < categoryNodes.length; i++) {
- if (categoryNodes[i].getAttribute('id') === categoryId) {
- var previousNode = categoryNodes[i].previousElementSibling;
- Ardublockly.xmlTree.removeChild(categoryNodes[i]);
- if (previousNode && previousNode.nodeName == 'sep') {
- Ardublockly.xmlTree.removeChild(previousNode);
- }
- }
- }
- blockpy.components.editor.blockly.updateToolbox(Ardublockly.xmlTree);
- };
- /** Closes the toolbox block container sub-menu. */
- Ardublockly.blocklyCloseToolbox = function () {
- blockpy.components.editor.blockly.toolbox_.flyout_.hide();
- };
- /** @return {!integer} The width of the blockly workspace toolbox. */
- Ardublockly.blocklyToolboxWidth = function () {
- return blockpy.components.editor.blockly.toolbox_.width;
- };
- /** @return {!boolean} Indicates if a block is currently being dragged. */
- Ardublockly.blocklyIsDragging = function () {
- return (Blockly.dragMode_ != 0) ? true : false;
- };
- Ardublockly.blocklyCut = function () {
- if (Blockly.selected) {
- Blockly.copy_(Blockly.selected);
- Blockly.selected.dispose(true, true);
- }
- };
- Ardublockly.blocklyCopy = function () {
- if (Blockly.selected) {
- Blockly.copy_(Blockly.selected);
- }
- };
- Ardublockly.blocklyPaste = function () {
- if (Blockly.clipboardXml_) {
- Blockly.hideChaff();
- Blockly.clipboardSource_.paste(Blockly.clipboardXml_);
- }
- };
- Ardublockly.blocklyDelete = function () {
- if (Blockly.selected && Blockly.selected.isDeletable()) {
- Blockly.hideChaff();
- Blockly.selected.dispose(true, true);
- }
- };
- /** @return {XMLHttpRequest} An XML HTTP Request multi-browser compatible. */
- Ardublockly.ajaxRequest = function () {
- var request;
- try {
- // Firefox, Chrome, IE7+, Opera, Safari
- request = new XMLHttpRequest();
- } catch (e) {
- try {
- // IE6 and earlier
- request = new ActiveXObject('Msxml2.XMLHTTP');
- } catch (e) {
- try {
- request = new ActiveXObject('Microsoft.XMLHTTP');
- } catch (e) {
- throw 'Your browser does not support AJAX';
- request = null;
- }
- }
- }
- return request;
- };
- /**
- * get a workspace snapshot on blocks
- * handle with blocks imgs with onload function twice
- * in order to convert img into base64 format data for download
- * @param {String} name name of pic to store as
- */
- Ardublockly.workspace_capture = async function (name) {
- let _header = window.location.protocol + "//"
- let _href = window.location.origin + "/";
- let ws = blockpy.components.editor.blockly.svgBlockCanvas_.cloneNode(true);
- ws.removeAttribute("width");
- ws.removeAttribute("height");
- ws.removeAttribute("transform");
- let styleElem = document.createElementNS("http://www.w3.org/2000/svg", "style");
- styleElem.textContent = Blockly.Css.CONTENT.join('');
- ws.insertBefore(styleElem, ws.firstChild);
- let bbox = blockpy.components.editor.blockly.svgBlockCanvas_.getBBox();
- let canvas = document.createElement("canvas");
- // canvas.width = Math.ceil(bbox.width + 120);
- // canvas.height = Math.ceil(bbox.height + 50);
- canvas.width = Math.ceil(Math.abs(bbox.x) + bbox.width + 120);
- canvas.height = Math.ceil(Math.abs(bbox.y) + bbox.height + 50);
- canvas.appendChild(ws);
- let ctx = canvas.getContext("2d");
- let xml = new XMLSerializer().serializeToString(ws);
- let test = /xlink:href="[a-zA-z]+:\/\/[^\s]*"/g;
- let test1 = /xlink:href="[^\s]*"/g;
- let arr = xml.match(test1)
- if (arr != null) {
- let loadImage = function () {
- return new Promise((resolve) => {
- let length = arr.length;
- let count = 0;
- for (let i = 0; i < length; i++) {
- let dataURL;
- let canvas_inline = document.createElement("canvas");
- let ctx1 = canvas_inline.getContext("2d");
- let image_item = new Image();
- image_item.setAttribute("src", _header + arr[i].replace("xlink:href=\"", _href).replace("\"", ""));
- image_item.onload = function () {
- //convert image to base64
- canvas_inline.width = image_item.width;
- canvas_inline.height = image_item.height;
- ctx1.drawImage(image_item, 0, 0);
- dataURL = canvas_inline.toDataURL("image/png", 1);
- xml = xml.replace(arr[i], "xlink:href=\"" + dataURL + "\"");
- count++;
- }
- }
- let timer = setInterval(() => {
- if (count == length) {
- return resolve(true);
- clearInterval(timer);
- }
- });
- });
- }
- await loadImage();
- }
- xml = '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="' + canvas.width + '" height="' + canvas.height + '" viewBox="' + bbox.x + ' ' + bbox.y + ' ' + canvas.width + ' ' + canvas.height + '"><rect width="100%" height="100%" fill="white"></rect>' + xml + '</svg>';
- var img = new Image();
- img.setAttribute("src", 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(xml))));
- img.onload = function () {
- ctx.drawImage(img, 5, 5);
- var canvasdata = canvas.toDataURL("image/png", 1);
- var a = document.createElement("a");
- a.download = name + ".png";
- a.href = canvasdata;
- document.body.appendChild(a);
- a.click();
- }
- }
|