UNPKG

pxt-core-own

Version:

Microsoft MakeCode, also known as Programming Experience Toolkit (PXT), provides Blocks / JavaScript tools and editors

266 lines (247 loc) 9.9 kB
function handleEnterKey(e) { var charCode = (typeof e.which == "number") ? e.which : e.keyCode if (charCode === 13 || charCode === 32) { // Enter or Space key e.preventDefault(); e.currentTarget.click(); } } function describePlural(value, unit) { return value + " " + unit + (value == 1 ? "" : "s") } function describetime(now, other) { var seconds = now - other if (isNaN(seconds)) return "" var timeString if (seconds < 0) return "now" else if (seconds < 10) return "a few seconds ago" else if (seconds < 60) return " " + describePlural(Math.floor(seconds), "second") + " ago" else if (seconds < 2 * 60) return "a minute ago" else if (seconds < 60 * 60) return " " + describePlural(Math.floor(seconds / 60), "minute") + " ago" else if (seconds < 2 * 60 * 60) return "an hour ago"; else if (seconds < 60 * 60 * 24) return " " + describePlural(Math.floor(seconds / 60 / 60), "hour") + " ago" else if (seconds < 60 * 60 * 24 * 30) return " " + describePlural(Math.floor(seconds / 60 / 60 / 24), "day") + " ago" else if (seconds < 60 * 60 * 24 * 365) return " " + describePlural(Math.floor(seconds / 60 / 60 / 24 / 30), "month") + " ago" else return " " + describePlural(Math.floor(seconds / 60 / 60 / 24 / 365), "year") + " ago" } function isIE() { return /trident/i.test(navigator.userAgent); } function dirAuto($el) { if ($el) { if (!isIE()) $el.attr('dir', 'auto'); else { var dir = /^[\s\.;:(+0-9]*[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]/i.test($el.text()) ? "rtl" : "ltr"; $el.attr('dir', dir); } } return $el; } function searchSubmit(form) { if (pxt && pxt.tickEvent) pxt.tickEvent("docs.search", { 'source': form.id }, { interactiveConsent: true }) } function scrollActiveHeaderIntoView() { var activeHeaders = document.getElementsByClassName("header active"); for (var i = 0; i < activeHeaders.length; ++i) { var activeHeader = activeHeaders.item(i); if (activeHeader.scrollIntoView) activeHeader.scrollIntoView() } } function setupSidebar() { // do not use pxt.appTarget in this function $('#togglesidebar').on('keydown', handleEnterKey); $('.ui.sidebar') .sidebar({ dimPage: false, onShow: function () { togglesidebar.setAttribute("aria-expanded", "true"); document.getElementsByClassName("sidebar").item(0).getElementsByClassName("focused").item(0).focus(); scrollActiveHeaderIntoView(); }, onHidden: function () { togglesidebar.setAttribute("aria-expanded", "false"); } }) .sidebar( 'attach events', '#togglesidebar' ); $('.ui.dropdown') .dropdown(); $('.ui.accordion') .accordion({ closeNested: true, selector: { trigger: '.title .icon' } }); var accordions = document.getElementsByClassName("ui accordion"); for (var i = 0; i < accordions.length; i++) { var nodes = accordions.item(i).getElementsByClassName("title"); for (var j = 0; j < nodes.length; j++) { var hrefNode = nodes.item(j).getElementsByTagName("a").item(0); var iNode = nodes.item(j).getElementsByTagName("i").item(0); iNode.onclick = function (e) { if (hrefNode.hasAttribute("aria-expanded") && hrefNode.getAttribute("aria-expanded") === "true") { hrefNode.setAttribute("aria-expanded", "false"); } else { hrefNode.setAttribute("aria-expanded", "true"); } }; hrefNode.onkeydown = function (e) { var charCode = (typeof e.which == "number") ? e.which : e.keyCode if (charCode === 39) { // Right key $(e.target.parentElement.parentElement).accordion("open", 0); e.target.setAttribute("aria-expanded", "true"); } else if (charCode === 37) { // Left key $(e.target.parentElement.parentElement).accordion("close", 0); e.target.setAttribute("aria-expanded", "false"); } }; } } var searchIcons = document.getElementsByClassName("search link icon"); for (var i = 0; i < searchIcons.length; i++) { searchIcons.item(i).onkeydown = handleEnterKey; } scrollActiveHeaderIntoView(); } function setupSemantic() { // do not use pxt.appTarget in this function // don't show related videos $.fn.embed.settings.sources.youtube.url = '//www.youtube.com/embed/{id}?rel=0' //This is an adapted version of the original template code in Semantic UI $.fn.embed.settings.templates.placeholder = function (image, icon) { var html = ''; if (icon) { html += '<i class="' + icon + ' icon"></i>'; } if (image) { //Remove the timestamp from the YouTube source URL image = image.replace(/\#t=([0-9]+m)?([0-9]+s)?/, ""); html += '<img class="placeholder" src="' + image + '">'; } return html; }; //Again, this is a slightly modified version of the original Semantic UI source to support timestamped YouTube videos $.fn.embed.settings.templates.iframe = function (url, parameters) { var src = url; //The following if statement is all that is different from the original implementation var matches = src.match(/\#t=(([0-9]+)m)?(([0-9]+)s)?/); if (matches) { var minutes = matches[2] != undefined ? parseInt(matches[2]) : 0; var seconds = matches[4] != undefined ? parseInt(matches[4]) : 0; var param = "start=" + (minutes * 60 + seconds).toString(); if (parameters) { parameters = param + "&" + parameters; } else { parameters = param; } src = src.replace(/\#t=([0-9]+m)?([0-9]+s)?/, ""); } if (parameters) { src += (/\?/.test(url) ? '&' : '?') + parameters; } return '' + '<iframe src="' + src + '"' + ' width="100%" height="100%"' + ' frameborder="0" scrolling="no" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>' ; }; $('.ui.embed').embed(); $('.md-video-link').on("click", function () { var name = $(this).data("playerurl") || $(this).data("videosrc"); $(this).find("img").remove(); $(this).find("svg").remove(); var outer = $('<div />', { "class": 'embed-responsive embed-responsive-16by9' }); outer.appendTo($(this)); $('<iframe>', { class: 'embed-responsive-item', src: name, frameborder: 0, scrolling: 'no' }).appendTo(outer); }); $('#printbtn').on("click", function () { window.print(); }) if (/browsers$/i.test(window.location.href)) $('.ui.footer').append($('<div class="ui center aligned small container"/>').text('user agent: ' + navigator.userAgent)) } function setupBlocklyAsync() { let promise = Promise.resolve(); if (pxt.appTarget.appTheme && pxt.appTarget.appTheme.extendFieldEditors) { let opts = {}; promise = promise.then(function () { return pxt.BrowserUtils.loadScriptAsync("fieldeditors.js") }).then(function () { return pxt.editor.initFieldExtensionsAsync(opts) }).then(function (res) { if (res.fieldEditors) res.fieldEditors.forEach(function (fi) { pxt.blocks.registerFieldEditor(fi.selector, fi.editor, fi.validator); }) }) } // backward compatibility: load editor if (pxt.appTarget.versions && pxt.semver.strcmp(pxt.appTarget.versions.pxt, "3.9.0") < 0 && pxt.appTarget.appTheme && pxt.appTarget.appTheme.extendEditor) { let opts = {}; promise = promise.then(function () { return pxt.BrowserUtils.loadScriptAsync(pxt.webConfig.commitCdnUrl + "editor.js") }).then(function () { return pxt.editor.initExtensionsAsync(opts) }).then(function (res) { if (res.fieldEditors) res.fieldEditors.forEach(function (fi) { pxt.blocks.registerFieldEditor(fi.selector, fi.editor, fi.validator); }) }) } return promise; } function renderSnippets() { var path = window.location.href.split('/').pop().split(/[?#]/)[0]; ksRunnerReady(function () { setupBlocklyAsync() .then(function () { return pxt.runner.renderAsync({ snippetClass: 'lang-blocks', signatureClass: 'lang-sig', blocksClass: 'lang-block', staticPythonClass: 'lang-spy', shuffleClass: 'lang-shuffle', simulatorClass: 'lang-sim', linksClass: 'lang-cards', namespacesClass: 'lang-namespaces', codeCardClass: 'lang-codecard', packageClass: 'lang-package', projectClass: 'lang-project', snippetReplaceParent: true, simulator: true, showEdit: true, hex: true, hexName: path }); }).done(); }); } $(document).ready(function () { setupSidebar(); setupSemantic(); renderSnippets(); });