/* global $ */ import { Parser, HtmlRenderer, Node } from 'commonmark' import { emojiIndex } from 'emoji-mart' import { escapeRegExp } from 'lodash' const emojiToShortcodes = {} Object.keys(emojiIndex.emojis).forEach(key => { const emoji = emojiIndex.emojis[key] emojiToShortcodes[emoji.native] = emoji.colons }) const Util = { // helper function to determine how many lines are needed // Line Splitter Function // copyright Stephen Chapman, 19th April 2006 // you may copy this code but please keep the copyright notice as well splitLine: function(st, n) { var b = '' var s = st || '' while (s.length > n) { var c = s.substring(0, n) var d = c.lastIndexOf(' ') var e = c.lastIndexOf('\n') if (e !== -1) d = e if (d === -1) d = n b += c.substring(0, d) + '\n' s = s.substring(d + 1) } return b + s }, nowDateFormatted: function(date = new Date(Date.now())) { const month = (date.getMonth() + 1) < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1) const day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate() const year = date.getFullYear() return month + '/' + day + '/' + year }, decodeEntities: function(desc) { let temp = document.createElement('p') temp.innerHTML = desc // browser handles the topics let str = temp.textContent || temp.innerText temp = null // delete the element return str }, // decodeEntities getDistance: function(p1, p2) { return Math.sqrt(Math.pow((p2.x - p1.x), 2) + Math.pow((p2.y - p1.y), 2)) }, // Try using Visualize.mGraph coordsToPixels: function(mGraph, coords) { if (mGraph) { const canvas = mGraph.canvas const s = canvas.getSize() const p = canvas.getPos() const ox = canvas.translateOffsetX const oy = canvas.translateOffsetY const sx = canvas.scaleOffsetX const sy = canvas.scaleOffsetY return { x: (coords.x / (1 / sx)) + p.x + s.width / 2 + ox, y: (coords.y / (1 / sy)) + p.y + s.height / 2 + oy } } else { return { x: 0, y: 0 } } }, // Try using Visualize.mGraph pixelsToCoords: function(mGraph, pixels) { if (mGraph) { const canvas = mGraph.canvas const s = canvas.getSize() const p = canvas.getPos() const ox = canvas.translateOffsetX const oy = canvas.translateOffsetY const sx = canvas.scaleOffsetX const sy = canvas.scaleOffsetY return { x: (pixels.x - p.x - s.width / 2 - ox) * (1 / sx), y: (pixels.y - p.y - s.height / 2 - oy) * (1 / sy) } } else { return { x: 0, y: 0 } } }, getPastelColor: function(opts = {}) { const rseed = opts.rseed === undefined ? Math.random() : opts.rseed const gseed = opts.gseed === undefined ? Math.random() : opts.gseed const bseed = opts.bseed === undefined ? Math.random() : opts.bseed var r = (Math.round(rseed * 127) + 127).toString(16) var g = (Math.round(gseed * 127) + 127).toString(16) var b = (Math.round(bseed * 127) + 127).toString(16) return Util.colorLuminance('#' + r + g + b, -0.4) }, // darkens a hex value by 'lum' percentage colorLuminance: function(hex, lum) { // validate hex string hex = String(hex).replace(/[^0-9a-f]/gi, '') if (hex.length < 6) { hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2] } lum = lum || 0 // convert to decimal and change luminosity var rgb = '#' for (let i = 0; i < 3; i++) { let c = parseInt(hex.substr(i * 2, 2), 16) c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16) rgb += ('00' + c).substr(c.length) } return rgb }, openLink: function(url) { var win = (url !== '') ? window.open(url, '_blank') : 'empty' if (win) { // Browser has allowed it to be opened return true } else { // Browser has blocked it window.alert('Please allow popups in order to open the link') return false } }, mdToHTML: text => { const safeText = text || '' const parsed = new Parser().parse(safeText) // remove images to avoid http content in https context const walker = parsed.walker() for (let event = walker.next(); event = walker.next(); event) { const node = event.node if (node.type === 'image') { const imageAlt = node.firstChild.literal const imageSrc = node.destination const textNode = new Node('text', node.sourcepos) textNode.literal = `![${imageAlt}](${imageSrc})` node.insertBefore(textNode) node.unlink() // remove the image, replacing it with markdown walker.resumeAt(textNode, false) } } // use safe: true to filter xss return new HtmlRenderer({ safe: true }).render(parsed) }, logCanvasAttributes: function(canvas) { const fakeMgraph = { canvas } return { scaleX: canvas.scaleOffsetX, scaleY: canvas.scaleOffsetY, centreCoords: Util.pixelsToCoords(fakeMgraph, { x: canvas.canvases[0].size.width / 2, y: canvas.canvases[0].size.height / 2 }) } }, resizeCanvas: function(canvas) { // Store the current canvas attributes, i.e. scale and map-coordinate at the centre of the user's screen const oldAttr = Util.logCanvasAttributes(canvas) // Resize the canvas to fill the new window size. Based on how JIT works, this also resets the map back to scale 1 and tranlations = 0 canvas.resize($(window).width(), $(window).height()) // Return the map to the original scale, and then put the previous central map-coordinate back to the centre of user's newly resized screen canvas.scale(oldAttr.scaleX, oldAttr.scaleY) const newAttr = Util.logCanvasAttributes(canvas) canvas.translate(newAttr.centreCoords.x - oldAttr.centreCoords.x, newAttr.centreCoords.y - oldAttr.centreCoords.y) }, removeEmoji: function(withEmoji) { let text = withEmoji Object.keys(emojiIndex.emojis).forEach(key => { const emoji = emojiIndex.emojis[key] text = text.replace(new RegExp(escapeRegExp(emoji.native), 'g'), emoji.colons) }) return text }, addEmoji: function(withoutEmoji, opts = { emoticons: true }) { let text = withoutEmoji Object.keys(emojiIndex.emojis).forEach(key => { const emoji = emojiIndex.emojis[key] text = text.replace(new RegExp(escapeRegExp(emoji.colons), 'g'), emoji.native) }) if (opts.emoticons) { Object.keys(emojiIndex.emoticons).forEach(emoticon => { const key = emojiIndex.emoticons[emoticon] const emoji = emojiIndex.emojis[key] text = text.replace(new RegExp(escapeRegExp(emoticon), 'g'), emoji.native) }) } return text }, isTester: function(currentUser) { return ['connorturland@gmail.com', 'devin@callysto.com', 'chessscholar@gmail.com', 'solaureum@gmail.com', 'ishanshapiro@gmail.com'].indexOf(currentUser.get('email')) > -1 }, zoomOnPoint: function(graph, ans, zoomPoint) { var s = graph.canvas.getSize(), p = graph.canvas.getPos(), ox = graph.canvas.translateOffsetX, oy = graph.canvas.translateOffsetY, sx = graph.canvas.scaleOffsetX, sy = graph.canvas.scaleOffsetY; var pointerCoordX = (zoomPoint.x - p.x - s.width / 2 - ox) * (1 / sx), pointerCoordY = (zoomPoint.y - p.y - s.height / 2 - oy) * (1 / sy); //This translates the canvas to be centred over the zoomPoint, then the canvas is zoomed as intended. graph.canvas.translate(-pointerCoordX,-pointerCoordY); graph.canvas.scale(ans, ans); //Get the canvas attributes again now that is has changed s = graph.canvas.getSize(), p = graph.canvas.getPos(), ox = graph.canvas.translateOffsetX, oy = graph.canvas.translateOffsetY, sx = graph.canvas.scaleOffsetX, sy = graph.canvas.scaleOffsetY; var newX = (zoomPoint.x - p.x - s.width / 2 - ox) * (1 / sx), newY = (zoomPoint.y - p.y - s.height / 2 - oy) * (1 / sy); //Translate the canvas to put the pointer back over top the same coordinate it was over before graph.canvas.translate(newX-pointerCoordX,newY-pointerCoordY); } } export default Util