-
Notifications
You must be signed in to change notification settings - Fork 0
/
lwp-example-sidebar.js.map
1 lines (1 loc) · 46.7 KB
/
lwp-example-sidebar.js.map
1
{"version":3,"sources":["lwp-example-sidebar.litcoffee"],"names":["addFormsAndCategoriesToToolbar","addMathQuillCSS","allNaturalLanguages","codeFormHierarchy","codeFormTranslators","formsAndCategories","groupToExplanation","isGroupRight","lastLanguageChoice","makeSelect","makeText","makeTextarea","markGroupRight","markGroupWith","markGroupWrong","menuItems","niceText","runTranslation","topLevelCategories","hasProp","hasOwnProperty","setAppName","addHelpMenuSourceCodeLink","window","helpAboutText","pluginsToLoad","push","allCategories","data","innerCategories","j","k","len","len1","name","ref","results","type","contents","length","indexOf","call","makeFormAction","categoriesProcessed","category","categoryToMenuItem","formToMenuItem","toMenuItem","text","onclick","after","boilerplate","editor","html","id","idStack","idToTag","nextTag","openClose","ref1","tagName","tinymce","activeEditor","selection","getRng","collapsed","exec","slice","index","Groups","nextFreeId","pop","grouperHTML","groupTypes","codexp","insertContent","set","$","getDoc","find","each","i","block","setAttribute","addClass","mathquill","groupCurrentSelection","item","menu","count","groupToolbarButtons","toggleSidebar","sidebar","splitbar","document","getElementById","splitter","get","style","display","position","editorContainer","width","registerCodeForm","validator","registerCategory","registerTranslator","form","language","output","translator","base","base1","group","child","childText","e","formName","letters","numArgs","pattern","recur","g","children","test","replace","RegExp","error","console","log","groupContentsChanged","firstTime","validate","groupDeleted","parent","explanation","Dialogs","alert","title","message","height","topLevel","languages","location","href","split","join","styleSheet","groupAsHTML","color","tooltip","imageHTML","openImageHTML","closeImageHTML","onToolbar","contentsChanged","deleted","tagContents","tagMenuItems","contextMenuItems","clear","createSidebarContent","reason","validationData","result","verbose","arg","argType","args","groupTag","options","validation","Array","setTimeout","fullScreenEditor","afterEditorReady","handleResize","mainContainer","parentNode","iframe","vp","getContainer","getContentAreaContainer","firstChild","DOM","getViewPort","clientHeight","scrollTo","x","y","orientation","limit","onDrag","resize","entry","innerHTML","val","lastSidebarContent","createElement","click","event","setRng","innerRange","padding","borderBottom","createSidebarEntryHTML","appendChild","textContent","hljs","highlightBlock","updateSidebarContent","runGeneratedJavaScript","eval","copyGeneratedCode","code","comment","apply","contentNodes","node","nodes","arguments","nodeType","hasClass","childNodes","setInterval","range","css","groupAboveSelection","openInJSFiddle","jsCode","nbsp","String","fromCharCode","0","1","2","body","submit","removeChild","option","representation","value","content"],"mappings":"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","file":"lwp-example-sidebar.js","sourcesContent":["\n# Sidebar Example Application, Lurch Web Platform\n\n## Overview\n\nTo know what's going on here, you should first have read the documenation\nfor the other example applications\n([one](https://github.com/lurchmath/lwp-example-simple),\n[two](https://github.com/lurchmath/lwp-example-complex), and\n[three](https://github.com/lurchmath/lwp-example-math)) built on the\n[Lurch Web Platform (LWP)](https://github.com/lurchmath/lurch).\n\n[See a live version of this application online here.](https://lurchmath.github.io/lwp-example-sidebar/)\n\nSet the app name with the same function we used in the simple example app.\n\n setAppName 'SidebarApp'\n\nAdd a source code link to the help menu, as in the simple example app.\n\n addHelpMenuSourceCodeLink \\\n 'lwp-example-sidebar/blob/master/lwp-example-sidebar.litcoffee'\n\nWe also change the Help/About menu item to be specific to this demo app.\n\n window.helpAboutText =\n '<p>See the fully documented <a target=\"top\"\n href=\"https://github.com/lurchmath/lwp-example-sidebar/blob/master/lwp-example-sidebar.litcoffee\"\n >source code for this demo app</a>.</p>'\n\nThis application needs the equation editor plugin, so we must tell the setup\nscript to load it, by modifying the following global variable.\n\n window.pluginsToLoad.push 'equationeditor'\n\n## Infrastructure for code forms and categories\n\nA code form is an abstract syntactic element that will be represented in the\ndocument as a group, and represented in the right sidebar as code in a\nprogramming language or text in a natural language. Examples of code forms\ninclude \"assignment statement,\" \"loop through a list,\" \"two-part conditional\nstatement,\" \"block of statements,\" and so on.\n\nA category is simply a collection of code forms or other categories that\nare topically related. Thus the set of top-level categories is a forest.\nIt will be represented in the GUI as a set of toolbar buttons with menus\nand optionally submenus whose leaf items represent code forms.\n\nBoth code forms and categories are given string names that are globally\nunique across the application. Register them with the functions below,\nwhich update the following global data structure.\n\n formsAndCategories = { }\n\nThat data structure can be converted into a set of toolbar buttons and items\nusing the following functions. First, one to compute the set of categories\nthat are not nested inside any others.\n\n topLevelCategories = ->\n allCategories = [ ]\n innerCategories = [ ]\n for own name, data of formsAndCategories\n if data.type is 'category'\n allCategories.push name\n for name in data.contents\n if name not in innerCategories\n innerCategories.push name\n ( name for name in allCategories when name not in innerCategories )\n\nNext, one to compute an array of top-level menus built recursively from\nthose categories. Note that we take measures to avoid infinite recursion\nthrough cyclic data.\n\nThe parameter is optional. If provided, it is a function mapping form names\nto actions that should be taken when those forms are chosen. If omitted,\nit creates actions that insert boilerplate code at the cursor point, or if\nthere is a selection, then wrap the selection in the given group type.\n\n codeFormHierarchy = ( makeFormAction ) ->\n categoriesProcessed = [ ]\n\nFirst, we define a function that can convert any code form to a menu (or\ntoolbar) item.\n\n formToMenuItem = ( name ) ->\n text : name\n onclick : if makeFormAction?\n -> makeFormAction name\n else\n ->\n editor = tinymce.activeEditor\n boilerplate = codeFormTranslators[name]['example']['en']\n\nIf the user has highlighed some document content, or if there is no\nboilerplate code available to insert, then just wrap the current selection\n(or the cursor) in an empty group of the given type.\n\n if not boilerplate? or \\\n not editor?.selection?.getRng()?.collapsed\n group = editor.Groups.groupCurrentSelection 'codexp'\n group.set 'tagName', name\n return\n\nThe following code inserts boilerplate content for the chosen code form. It\nexpects HTML text, plus tags of the form `<X>...</X>` for any code form name\n`X` (even if it is multiple words, unlike in normal XML). For example, if\nyou have a form called \"First name\" you can create groups of that type with\npseudo-HTML code of the form `<First name>Jane</First name>`.\n\nYou can also use `<math>LaTeX code here</math>` to insert MathQuill\ninstances containing the given LaTeX mathematics.\n\nThe following loop simply finds tags of that form and replaces them with\ntags for open and close groupers, keeping a stack of types and IDs so that\nit generates correct code.\n\n idStack = [ ]\n idToTag = { }\n html = ''\n while nextTag = /<(\\/?)([^>]+)>/.exec boilerplate\n html += boilerplate[...nextTag.index]\n if codeFormTranslators.hasOwnProperty nextTag[2]\n if nextTag[1] is ''\n openClose = 'open'\n idStack.push id = editor.Groups.nextFreeId()\n else\n openClose = 'close'\n id = idStack.pop()\n idToTag[id] = nextTag[2]\n html += grouperHTML 'codexp', openClose, id, no,\n editor.Groups.groupTypes \\\n .codexp[\"#{openClose}Image\"]\n else\n html += nextTag[0]\n after = nextTag.index + nextTag[0].length\n boilerplate = boilerplate[after...]\n html += boilerplate\n editor.insertContent html\n for own id, tagName of idToTag\n editor.Groups[id].set 'tagName', tagName\n\nThis final section of code creates MathQuill instances.\n\n ( $ editor.getDoc() ).find( '.math' )\n .each ( i, block ) ->\n block.setAttribute 'contenteditable', 'false'\n ( $ block ).addClass 'rendered-latex'\n ( $ block ).mathquill()\n\nThat completes the function that converts any code form to a menu (or\ntoolbar) item.\n\nSecond, we define a function that converts any category to a menu (or\ntoolbar) item.\n\n categoryToMenuItem = ( name ) ->\n if name in categoriesProcessed\n text : name\n menu : [ ]\n else\n categoriesProcessed.push name\n text : name\n menu : for item in formsAndCategories[name].contents\n toMenuItem item\n\nThe following function dispatches to either the function or category\nmethod given above, based on the type of its input.\n\n toMenuItem = ( name ) ->\n if formsAndCategories[name].type is 'form'\n formToMenuItem name\n else\n categoryToMenuItem name\n\nFinally, the actual work: Apply that general function to every top-level\ncategory in the hierarchy of code forms, returning the resulting list of\nmenu/toolbar items.\n\n toMenuItem category for category in topLevelCategories()\n\nNow we provide a function that adds that set of top-level menus to the app\ntoolbar. It calls the previous function to convert the form hierarchy into\na menu/toolbar hierarchy, then adds it to the toolbar.\n\n addFormsAndCategoriesToToolbar = ->\n window.groupToolbarButtons = { }\n count = 1\n for menu in codeFormHierarchy()\n menu.type = 'menubutton'\n window.groupToolbarButtons[\"category#{count++}\"] = menu\n\nIt also adds one new toolbar item, for toggling the visibility of the code\nsidebar.\n\n window.groupToolbarButtons.toggleSidebar =\n text : 'Toggle code view'\n onclick : ->\n sidebar = document.getElementById 'sidebar'\n splitbar = window.splitter.find( '.vsplitter' ).get 0\n if sidebar.style.display is 'none'\n sidebar.style.display = 'block'\n splitbar.style.display = 'block'\n splitter.position splitter.position()\n else\n sidebar.style.display = 'none'\n splitbar.style.display = 'none'\n window.editorContainer.style.width = '100%'\n\nA code form may come with an optional validator. This can be a function to\nbe run to validate the group, or if none is provided then all instances pass\nvalidation; no checks are performed. Or the validator can instead be an\narray of types (names of other code forms), each with an optional name, in\nwhich case a validation function will be created, which checks group\ncontents against this array as a function signature.\n\nValidators will take a group as input, and a boolean flag as a second\nargument, called \"verbose.\" They must return objects with these members:\n * `result`: a string, \"valid\" or \"invalid\"\n * `message`: a plain text string briefly describing the reason for the\n result\n * `verbose`: only necessary if the second argument was true, an HTML string\n describing the reason for the result in much more detail\n * Other members in the object are permitted for application-specific needs.\n\nThis function returns its first parameter, so that calls to it can be nested\ninside calls to `window.registerCategory`, defined below.\n\n window.registerCodeForm = ( name, validator ) ->\n formsAndCategories[name] =\n type : 'form'\n validator : validator\n addFormsAndCategoriesToToolbar()\n name\n\nA category is simply a name and an array of strings, the names of categories\nor code forms inside this category.\n\nThis function returns its first parameter, so that calls to it can be nested\ninside others.\n\n window.registerCategory = ( name, contents ) ->\n formsAndCategories[name] =\n type : 'category'\n contents : contents\n addFormsAndCategoriesToToolbar()\n name\n\n## Infrastructure for translators\n\nA translator maps an instance of a form to another language. It has these\nattributes.\n * form: a text string, the name of the code form that this translator can\n process, which should be registered with `registerCodeForm`, above.\n * language: a text string, globally unique, either the name of a\n programming language or [the standard code for a natural language](http://www.metamodpro.com/browser-language-codes).\n * output: a text string, one of three choices, \"code,\" \"structure,\" or\n \"explanation\", with the following meanings.\n * \"Code\" means the translator outputs code in the language given in the\n previous attribute.\n * \"Structure\" means the translator outputs HTML that can be used in the\n document to phrase the interior contents of the group accurately and\n readably.\n * \"Explanation\" means the translator outputs HTML that can be used in\n popup dialogs to help teach users the meanings of the code forms in\n the document, and will generally be more verbose than structure\n translators, and may use HTML more freely.\n * translator: a way to convert an instance of the form into the target\n language. This may be given in one of two ways.\n * It may be a function that takes two parameters, the first being the\n form instance, which is a group in the document, and the second being\n a function that can be called recursively on child groups to translate\n them. (That function will dispatch the correct code form translator\n for the child group, so that each translator does not need to figure\n out how to do so on its own.) If the first parameter is null,\n generic or boilerplate code should be generated, using `__A__`,\n `__B__`, `__C__`, and so on as parameter placeholders. Such a\n function is permitted to read and re-use data stored in a group during\n validation. If at all possible, translators should attempt to give\n output. Even if the form of the group or its inner groups is\n invalid, it would generally be better to create bad output code,\n including comments that say why it's bad and won't run, to maximize\n user feedback and understanding.\n * It may be a text string containing placeholders of the form `__A__`,\n `__B__`, `__C__`, and so on, for which the results of recursive calls\n on the child groups will be replaced.\n\nWe store translators in this global variable.\n\n codeFormTranslators = { }\n\nRegister a new translator using the following function.\n\n window.registerTranslator = ( form, language, output, translator ) ->\n codeFormTranslators[form] ?= { }\n codeFormTranslators[form][output] ?= { }\n codeFormTranslators[form][output][language] ?= translator\n\nPerform translation with the following function. The parameters are named\njust as in the explanation at the top of this section. So, for example, you\nmight call `runTranslation G, 'en', 'explanation'` or\n`runTranslation G, 'javascript', 'code'`.\n\n runTranslation = ( group, language, output ) ->\n recur = ( g ) -> runTranslation g, language, output\n\nVerify that there exists a translator of the type requested.\n\n formName = group.get 'tagName'\n if not codeFormTranslators.hasOwnProperty formName\n return \"Translation error: Form #{formName} has no translators\n registered\"\n if not codeFormTranslators[formName].hasOwnProperty output\n return \"Translation error: Form #{formName} has no translators\n of type #{output} registered\"\n if not codeFormTranslators[formName][output].hasOwnProperty language\n return \"Translation error: Form #{formName} has no #{language}\n translators of type #{output} registered\"\n translator = codeFormTranslators[formName][output][language]\n\nFor string translators, iteratively replace `__A__`-type patterns with the\nresults of recursive calls on child groups.\n\n if typeof translator is 'string'\n letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'\n numArgs = 0\n while -1 < translator.indexOf \"__#{letters[numArgs]}__\"\n numArgs++\n if group.children.length isnt numArgs\n return \"Translation error: Form #{formName} requires\n #{numArgs} parts, but contains only\n #{group.children.length}\"\n for child, index in group.children\n pattern = \"__#{letters[index]}__\"\n childText = recur child\n return childText if /^Translation error/.test childText\n translator = translator.replace RegExp( pattern, 'g' ),\n childText\n translator\n\nOtherwise the translator is a function that can be run on its own.\n\n else\n try\n translator group, recur\n catch e\n console.log 'User-defined translator error:', e\n\n## Event handlers\n\nHandler for when users edit the contents of a group: revalidate it.\n\n window.groupContentsChanged = ( group, firstTime ) ->\n window.validate group\n\nHandler for when users remove a group: revalidate the parent.\n\n window.groupDeleted = ( group ) ->\n if group.parent? then window.validate group.parent\n\nHandler for both the context menu and the tag menu of a group. It creates\nthree different items for such menus, each documented separately below.\n\n menuItems = ( group ) ->\n [\n\nFirst, a menu item for changing the type of the selected group to any other\nform type.\n\n text : 'Change this to...'\n menu : codeFormHierarchy ( formName ) ->\n group.set 'tagName', formName\n ,\n\nSecond, a menu item that asks the app to explain the meaning of the code\nform selected. This pops up a modal dialog displaying in HTML form all the\nvarious explanations of the code form on which this was invoked.\n\n text : 'Explain this...'\n onclick : ->\n explanation = ''\n for language in allNaturalLanguages()\n explanation +=\n \"<h2>Language: #{language}</h2>\\n\" + \\\n groupToExplanation group, language\n tinymce.activeEditor.Dialogs.alert\n title : 'Explanation of one structure'\n message : addMathQuillCSS explanation\n width : 600\n height : 450\n ,\n\nThird, a menu item that functions just like the previous, but it explains\nall top-level code forms in the entire document, in order. This provides an\ninterpretation of all the meaning in the document.\n\n text : 'Explain all...'\n onclick : ->\n explanation = ''\n for language in allNaturalLanguages()\n explanation += \"<h2>Language: #{language}</h2>\\n\"\n for group in tinymce.activeEditor.Groups.topLevel\n if explanation isnt '' then explanation += '<hr>'\n explanation += groupToExplanation group, language\n tinymce.activeEditor.Dialogs.alert\n title : 'Explanation of all structures'\n message : addMathQuillCSS explanation\n width : 600\n height : 450\n ]\n\nUtilities used by the functions above:\n\nGet all languages that appear in any registered \"explanation\" form, which\nshould therefore be natural languages (such as English) as opposed to\nprogramming languages (such as Python).\n\n allNaturalLanguages = ->\n languages = [ ]\n for own formName, data of codeFormTranslators\n for own language of data['explanation']\n if language not in languages then languages.push language\n languages\n\nThe following function wraps given HTML in tags that import two necessary\nCSS files for appropriate viewing of document content. The first is the\nMathQuill CSS for viewing typeset equations. The second is the CSS for the\nGroups plugin, for viewing open and close groupers.\n\n addMathQuillCSS = ( html ) ->\n currentPath = window.location.href.split( '/' )[...-1].join '/'\n \"<html>\n <head><link rel='stylesheet'\n href='#{currentPath}/eqed/mathquill.css'></head>\n <head><style>\n #{tinymce.activeEditor.Groups.styleSheet}\n </style></head>\n <body>#{html}</body>\n </html>\"\n\nConvert a group in the document into an explanation of it in the given\nnatural language.\n\n groupToExplanation = ( group, language ) ->\n \"<h4>Structure:</h4>\\n\n <p style='margin-left: 2em;'>#{group.groupAsHTML()}</p>\\n\n <h4>Explanation:</h4>\\n\n <p style='margin-left: 2em;'\n >#{runTranslation group, language, 'explanation'}</p>\\n\"\n\n## Define one group type\n\n window.groupTypes = [\n\nBasic appearance attributes for the group, which have been documented in the\nsimpler example applications linked to at the top of this source file.\n\n name : 'codexp'\n color : '#6666cc'\n text : 'Code expression'\n tooltip : 'Tag the selection'\n imageHTML : '<font color=\"#6666cc\">[ ]</font>'\n openImageHTML : '<font color=\"#6666cc\">[</font>'\n closeImageHTML : '<font color=\"#6666cc\">]</font>'\n onToolbar : no\n\nInstall event handlers, most of which are defined earlier in this file.\n\n contentsChanged : window.groupContentsChanged\n deleted : window.groupDeleted\n tagContents : ( group ) -> group.get 'tagName'\n tagMenuItems : ( group ) -> menuItems group\n contextMenuItems : ( group ) -> menuItems group\n ]\n\n## Validating groups\n\nWe will need three functions, one for marking a group as without problems,\none for marking a group as having problems (with explanations of them), and\none for detecting whether a group has problems.\n\n markGroupRight = ( group ) ->\n group.set 'valid', yes\n group.clear 'closeDecoration'\n group.clear 'closeHoverText'\n window.createSidebarContent()\n markGroupWrong = ( group, reason ) ->\n group.set 'valid', no\n group.set 'closeDecoration', '<font color=\"red\">✖</font>'\n group.set 'closeHoverText', reason\n window.createSidebarContent()\n markGroupWith = ( group, validationData ) ->\n group.set 'validationResult', validationData\n if validationData.result is 'valid'\n markGroupRight group\n else\n markGroupWrong group, validationData.message\n isGroupRight = ( group ) -> group.get 'valid'\n\nThis function validates the given group, and stores the results in the\ngroup's closing tag using one of the above functions.\n\n window.validate = ( group, verbose ) ->\n\nIf the group does not even have a children array, then it probably just\nappeared, and is still being initialized. In that case, just do validation\nin 100ms isntead of now.\n\n if not group.children\n setTimeout ( -> window.validate group ), 100\n return\n\nIf this group does not have a tag name, we cannot even tell if it belongs\nhere or not, and it cannot be converted to source code. That is a problem.\n\n if not ( groupTag = group.get 'tagName' )?\n return markGroupWith group,\n result : 'invalid'\n message : \"Each group must have a tag, but this one does\n not. Add a tag using the context menu.\"\n\nIf the group does have a tag name, run the validation routine for that code\nform, and add any problems it reports to our list of problems. We convert\narray validators into functions that check inner groups against that array\nas a function signature. Each entry in the signature must be a string\ncontaining either a single type or a slash-separated list of types (e.g.,\n\"A/B/C\") to indicate multiple options.\n\n validator = formsAndCategories[groupTag].validator\n if validator instanceof Array\n validation =\n result : 'valid'\n message : 'All inner groups have the correct types.'\n args = group.children\n if validator.length isnt args.length\n return markGroupWith group,\n result : 'invalid'\n message : \"This form needs #{validator.length} parts:\n #{validator.join ', '}.\"\n for arg, index in args\n argType = arg.get 'tagName'\n options = validator[index].split '/'\n if argType not in options\n return markGroupWith group,\n result : 'invalid'\n message : \"Part #{index+1} must be of type\n #{validator[index]}, but it is of type\n #{argType} instead.\"\n\nOr if they gave us a validator function, run it.\n\n else\n validation = validator group, verbose\n\nAnd store the result, valid or invalid, which automatically updates the\nvisual feedback.\n\n markGroupWith group, validation\n\n## GUI modifications and setup\n\nThe next two lines tell the default app setup routine to avoid filling the\nentire window, but instead to just fill one particular element, the one\nnamed. (See [index.html] for where that element is defined.)\n\n window.fullScreenEditor = no\n window.editorContainer = -> document.getElementById 'editorContainer'\n window.afterEditorReady = ( editor ) ->\n\nCreate a resize handler that will be called whenever a user drags the\nsplitter between the editor and the sidebar. This will ensure that the\neditor fills the DIV into which it's been placed.\n\n mainContainer = window.editorContainer.parentNode\n handleResize = ->\n editorContainer = editor.getContainer()\n iframe = editor.getContentAreaContainer().firstChild\n vp = tinymce.DOM.getViewPort()\n iframe.style.width = iframe.style.height =\n mainContainer.style.height = '100%'\n editorContainer.style.width = editorContainer.style.height = ''\n iframe.style.height = mainContainer.clientHeight - 2 \\\n - ( editorContainer.clientHeight - iframe.clientHeight )\n window.scrollTo vp.x, vp.y\n\nCreate the splitter, which will notice that the editor is adjacent to a\nsecond DIV defined in [index.html], and resize them appropriately.\n\n window.splitter = ( $ mainContainer ).split\n orientation : 'vertical'\n limit : 100\n position : '75%'\n onDrag : handleResize\n ( $ window ).resize handleResize\n handleResize()\n window.createSidebarContent()\n\n## Filling the sidebar with content\n\nThe main function that does so, iterating through all top-level groups in\nthe document, and calling an auxiliary function below on each. For some\nlanguages, it adds extra functionality.\n\n window.createSidebarContent = ->\n sidebar = document.getElementById 'sidebar'\n\nThe heading of the sidebar contains a selector for the output (programming)\nlanguage, and links to click to either run the code (if and only if it is\nJavaScript) or to copy the code to the clipboard.\n\n sidebar.innerHTML = '''\n <div style=\"border-bottom: solid 1px black;\n text-align: center;\">\n <p>Choose a language:\n <select onchange='updateSidebarContent();'\n id='languagePicker'>\n <option value='javascript'>JavaScript</option>\n <option value='python'>Python</option>\n <option value='r'>R</option>\n </select></p>\n <p id='runJSLink'><a href='#'\n onclick='runGeneratedJavaScript();'\n >Run this code</a></p>\n <p><a href='#' onclick='copyGeneratedCode();'\n >Copy this code</a></p>\n </div>\n '''\n ( $ '#languagePicker' ).val lastLanguageChoice\n ( $ '#runJSLink' ).get( 0 ).style.display = \\\n if lastLanguageChoice is 'javascript' then 'block' else 'none'\n\nWe now regenerate the content of the sidebar by looping through the\ntop-level groups in the document, calling `createSidebarEntryHTML` on each,\nand wrapping it in a DIV with an appropriate ID and click handler. The\nclick handler makes it so that clicking one of the generated-code DIVs\nhighlights the corresponding structure in the user's document.\n\n window.lastSidebarContent = ''\n for group in tinymce.activeEditor.Groups.topLevel\n entry = document.createElement 'div'\n entry.setAttribute 'id', \"codeForGroup#{group.id()}\"\n ( $ entry ).click group.id(), ( event ) ->\n group = tinymce.activeEditor.Groups[event.data]\n tinymce.activeEditor.selection.setRng group.innerRange()\n entry.style.padding = '1em'\n entry.style.borderBottom = 'dotted 1px black'\n entry.innerHTML = window.createSidebarEntryHTML group\n sidebar.appendChild entry\n lastSidebarContent += entry.textContent + '\\n'\n ( $ sidebar ).find( 'pre' ).each ( i, block ) ->\n hljs.highlightBlock block\n\nThe default output language is JavaScript, but whenever the user changes it,\nwe will regenerate all the contents of the sidebar based on their choice.\n\n lastLanguageChoice = 'javascript'\n window.updateSidebarContent = ->\n lastLanguageChoice = ( $ '#languagePicker' ).val()\n createSidebarContent()\n\nWhen the user clicks the \"Run\" button, it is safe to simply call the\nnotorious JavaScript `eval` in this case, because this demo app never\nspeaks to a server side, and thus any harm the user wanted to do via code\ninjection attacks could simply be done from their browser's console anyway.\n\n window.runGeneratedJavaScript = ->\n try\n eval lastSidebarContent\n catch e\n alert \"Error when running code:\\n\\n#{e.message}\"\n\nWhen the user clicks the \"Copy\" button, we place the code into a modal\ndialog and select it, so that the user can easily press Ctrl+C and then\nclose the window.\n\n window.copyGeneratedCode = ->\n tinymce.activeEditor.Dialogs.alert\n title : 'Copy the code, then close'\n width : 600\n message : \"\"\"\n <textarea id='codeToCopy'\n style='width: 100%; height: 100%;\n font-family: monospace;'\n >#{lastSidebarContent}</textarea>\n <script>\n var T = document.getElementById( 'codeToCopy' );\n T.select();\n T.focus();\n </script>\n \"\"\"\n\nThe `createSidebarContent` function uses the following to create each entry,\nbased on one given top-level group. It should encode the entirety of that\ntop-level group, and return it as HTML to be placed inside a DIV.\n\n window.createSidebarEntryHTML = ( group ) ->\n code = runTranslation group, lastLanguageChoice, 'code'\n comment = codeFormTranslators['COMMENT']['code'][lastLanguageChoice]\n result = comment.replace '__A__', niceText group.contentNodes()...\n result += '\\n' + if not /^Translation error/.test code\n code\n else\n comment.replace '__A__', code\n \"<pre class='javascript'>#{result}</pre>\"\n\nThe following utility function takes a list of HTML nodes (usually the\ncontent nodes of some group) and converts them to plain text, with special\nhandling of MathQuill instances, converting them to their LaTeX form\n(surrounded by dollar signs).\n\n niceText = ( nodes... ) ->\n result = ''\n for node in nodes\n if node?.nodeType is 3 # HTML Text node\n result += node.textContent\n else if ( $ node ).hasClass 'mathquill-rendered-math'\n result += node.childNodes[0].textContent\n else\n result += niceText node.childNodes...\n result\n\nEvery 0.1 seconds, highlight the DIV in the sidebar that corresponds to the\ncurrent cursor location, if there is such a DIV. If there isn't, highlight\nnone of them.\n\n setInterval ->\n range = tinymce.activeEditor.selection.getRng()\n ( $ sidebar ).find( 'div' ).css 'background-color', '#fff'\n if group = tinymce.activeEditor.Groups.groupAboveSelection range\n while group.parent then group = group.parent\n ( $ \"\\#codeForGroup#{group.id()}\" ).css 'background-color',\n '#eee'\n , 100\n\nThe following function used to be able to open any given JavaScript code in\na new JSFiddle. It is modeled after code by the creator of JSFiddle,\n[located here](http://jsfiddle.net/zalun/sthmj/?utm_source=website&utm_medium=embed&utm_campaign=sthmj),\nbut that code seems to no longer function (even on that fiddle), and so this\ncode is not currently used in this app. I leave it here for reference, in\ncase that fiddle gets fixed, then this can be updated to use it.\n\n window.openInJSFiddle = ( jsCode ) ->\n nbsp = String.fromCharCode 160\n jsCode = jsCode.replace RegExp( nbsp, 'g' ), ' '\n form = document.createElement 'form'\n form.setAttribute 'method', 'post'\n form.setAttribute 'action',\n 'http://jsfiddle.net/api/post/mootools/1.2/dependencies/more/'\n form.setAttribute 'target', '_blank'\n form.style.display = 'none'\n form.appendChild makeSelect 'panel_html', 0 : 'HTML'\n form.appendChild makeTextarea 'html'\n form.appendChild makeSelect 'panel_js',\n 0 : 'JavaScript'\n 1 : 'CoffeeScript'\n 2 : 'JavaScript 1.7'\n form.appendChild makeTextarea 'js', jsCode\n form.appendChild makeSelect 'panel_css', 0 : 'CSS', 1 : 'SCSS'\n form.appendChild makeTextarea 'css'\n form.appendChild makeText 'title', 'Fiddle Title Here'\n form.appendChild makeTextarea 'description',\n 'Fiddle Description Here'\n form.appendChild makeTextarea 'resources'\n form.appendChild makeText 'dtd', 'html 4'\n form.appendChild makeText 'wrap', 'l'\n document.body.appendChild form\n form.submit()\n document.body.removeChild form\n\nThe previous function uses the following utilities.\n\nCreate an HTML \"select\" element with the given value-to-text mapping.\n\n makeSelect = ( name, options ) ->\n result = document.createElement 'select'\n result.setAttribute 'name', name\n for own value, representation of options\n option = document.createElement 'option'\n option.setAttribute 'value', value\n option.innerHTML = representation\n result.appendChild option\n result\n\nCreate an HTML text area with the given content.\n\n makeTextarea = ( name, content ) ->\n result = document.createElement 'textarea'\n result.setAttribute 'name', name\n result.innerHTML = content or ''\n result\n\nCreate an HTML text input with the given content.\n\n makeText = ( name, value ) ->\n result = document.createElement 'input'\n result.setAttribute 'type', 'text'\n result.setAttribute 'name', name\n result.setAttribute 'value', value\n result\n"]}