123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750 |
- 'use strict';
- goog.provide('Blockly.utils');
- goog.require('Blockly.Touch');
- goog.require('goog.dom');
- goog.require('goog.events.BrowserFeature');
- goog.require('goog.math.Coordinate');
- goog.require('goog.userAgent');
- Blockly.addClass_ = function(element, className) {
- var classes = element.getAttribute('class') || '';
- if ((' ' + classes + ' ').indexOf(' ' + className + ' ') == -1) {
- if (classes) {
- classes += ' ';
- }
- element.setAttribute('class', classes + className);
- }
- };
- Blockly.removeClass_ = function(element, className) {
- var classes = element.getAttribute('class');
- if ((' ' + classes + ' ').indexOf(' ' + className + ' ') != -1) {
- var classList = classes.split(/\s+/);
- for (var i = 0; i < classList.length; i++) {
- if (!classList[i] || classList[i] == className) {
- classList.splice(i, 1);
- i--;
- }
- }
- if (classList.length) {
- element.setAttribute('class', classList.join(' '));
- } else {
- element.removeAttribute('class');
- }
- }
- };
- Blockly.hasClass_ = function(element, className) {
- var classes = element.getAttribute('class');
- return (' ' + classes + ' ').indexOf(' ' + className + ' ') != -1;
- };
- Blockly.bindEventWithChecks_ = function(node, name, thisObject, func,
- opt_noCaptureIdentifier) {
- var handled = false;
- var wrapFunc = function(e) {
- var captureIdentifier = !opt_noCaptureIdentifier;
-
-
- var events = Blockly.Touch.splitEventByTouches(e);
- for (var i = 0, event; event = events[i]; i++) {
- if (captureIdentifier && !Blockly.Touch.shouldHandleEvent(event)) {
- continue;
- }
- Blockly.Touch.setClientFromTouch(event);
- if (thisObject) {
- func.call(thisObject, event);
- } else {
- func(event);
- }
- handled = true;
- }
- };
- node.addEventListener(name, wrapFunc, false);
- var bindData = [[node, name, wrapFunc]];
-
- if (name in Blockly.Touch.TOUCH_MAP) {
- var touchWrapFunc = function(e) {
- wrapFunc(e);
-
- if (handled) {
- e.preventDefault();
- }
- };
- for (var i = 0, eventName;
- eventName = Blockly.Touch.TOUCH_MAP[name][i]; i++) {
- node.addEventListener(eventName, touchWrapFunc, false);
- bindData.push([node, eventName, touchWrapFunc]);
- }
- }
- return bindData;
- };
- Blockly.bindEvent_ = function(node, name, thisObject, func) {
- var wrapFunc = function(e) {
- if (thisObject) {
- func.call(thisObject, e);
- } else {
- func(e);
- }
- };
- node.addEventListener(name, wrapFunc, false);
- var bindData = [[node, name, wrapFunc]];
-
- if (name in Blockly.Touch.TOUCH_MAP) {
- var touchWrapFunc = function(e) {
-
- if (e.changedTouches.length == 1) {
-
- var touchPoint = e.changedTouches[0];
- e.clientX = touchPoint.clientX;
- e.clientY = touchPoint.clientY;
- }
- wrapFunc(e);
-
- e.preventDefault();
- };
- for (var i = 0, eventName;
- eventName = Blockly.Touch.TOUCH_MAP[name][i]; i++) {
- node.addEventListener(eventName, touchWrapFunc, false);
- bindData.push([node, eventName, touchWrapFunc]);
- }
- }
- return bindData;
- };
- Blockly.unbindEvent_ = function(bindData) {
- while (bindData.length) {
- var bindDatum = bindData.pop();
- var node = bindDatum[0];
- var name = bindDatum[1];
- var func = bindDatum[2];
- node.removeEventListener(name, func, false);
- }
- return func;
- };
- Blockly.noEvent = function(e) {
-
- e.preventDefault();
- e.stopPropagation();
- };
- Blockly.isTargetInput_ = function(e) {
- return e.target.type == 'textarea' || e.target.type == 'text' ||
- e.target.type == 'number' || e.target.type == 'email' ||
- e.target.type == 'password' || e.target.type == 'search' ||
- e.target.type == 'tel' || e.target.type == 'url' ||
- e.target.isContentEditable;
- };
- Blockly.getRelativeXY_ = function(element) {
- var xy = new goog.math.Coordinate(0, 0);
-
- var x = element.getAttribute('x');
- if (x) {
- xy.x = parseInt(x, 10);
- }
- var y = element.getAttribute('y');
- if (y) {
- xy.y = parseInt(y, 10);
- }
-
- var transform = element.getAttribute('transform');
- var r = transform && transform.match(Blockly.getRelativeXY_.XY_REGEXP_);
- if (r) {
- xy.x += parseFloat(r[1]);
- if (r[3]) {
- xy.y += parseFloat(r[3]);
- }
- }
- return xy;
- };
- Blockly.getRelativeXY_.XY_REGEXP_ =
- /translate\(\s*([-+\d.e]+)([ ,]\s*([-+\d.e]+)\s*\))?/;
- Blockly.getSvgXY_ = function(element, workspace) {
- var x = 0;
- var y = 0;
- var scale = 1;
- if (goog.dom.contains(workspace.getCanvas(), element) ||
- goog.dom.contains(workspace.getBubbleCanvas(), element)) {
-
- scale = workspace.scale;
- }
- do {
-
- var xy = Blockly.getRelativeXY_(element);
- if (element == workspace.getCanvas() ||
- element == workspace.getBubbleCanvas()) {
-
- scale = 1;
- }
- x += xy.x * scale;
- y += xy.y * scale;
- element = element.parentNode;
- } while (element && element != workspace.getParentSvg());
- return new goog.math.Coordinate(x, y);
- };
- Blockly.createSvgElement = function(name, attrs, parent, opt_workspace) {
- var e = (
- document.createElementNS(Blockly.SVG_NS, name));
- for (var key in attrs) {
- e.setAttribute(key, attrs[key]);
- }
-
-
-
- if (document.body.runtimeStyle) {
- e.runtimeStyle = e.currentStyle = e.style;
- }
- if (parent) {
- parent.appendChild(e);
- }
- return e;
- };
- Blockly.isRightButton = function(e) {
- if (e.ctrlKey && goog.userAgent.MAC) {
-
-
- return true;
- }
- return e.button == 2;
- };
- Blockly.convertCoordinates = function(x, y, toSvg, svg) {
- if (toSvg) {
- x -= window.scrollX || window.pageXOffset;
- y -= window.scrollY || window.pageYOffset;
- }
- var svgPoint = svg.createSVGPoint();
- svgPoint.x = x;
- svgPoint.y = y;
- var matrix = svg.getScreenCTM();
- if (toSvg) {
- matrix = matrix.inverse();
- }
- var xy = svgPoint.matrixTransform(matrix);
- if (!toSvg) {
- xy.x += window.scrollX || window.pageXOffset;
- xy.y += window.scrollY || window.pageYOffset;
- }
- return xy;
- };
- Blockly.mouseToSvg = function(e, svg, matrix) {
- var svgPoint = svg.createSVGPoint();
- svgPoint.x = e.clientX;
- svgPoint.y = e.clientY;
- if (!matrix) {
- matrix = svg.getScreenCTM().inverse();
- }
- return svgPoint.matrixTransform(matrix);
- };
- Blockly.shortestStringLength = function(array) {
- if (!array.length) {
- return 0;
- }
- var len = array[0].length;
- for (var i = 1; i < array.length; i++) {
- len = Math.min(len, array[i].length);
- }
- return len;
- };
- Blockly.commonWordPrefix = function(array, opt_shortest) {
- if (!array.length) {
- return 0;
- } else if (array.length == 1) {
- return array[0].length;
- }
- var wordPrefix = 0;
- var max = opt_shortest || Blockly.shortestStringLength(array);
- for (var len = 0; len < max; len++) {
- var letter = array[0][len];
- for (var i = 1; i < array.length; i++) {
- if (letter != array[i][len]) {
- return wordPrefix;
- }
- }
- if (letter == ' ') {
- wordPrefix = len + 1;
- }
- }
- for (var i = 1; i < array.length; i++) {
- var letter = array[i][len];
- if (letter && letter != ' ') {
- return wordPrefix;
- }
- }
- return max;
- };
- Blockly.commonWordSuffix = function(array, opt_shortest) {
- if (!array.length) {
- return 0;
- } else if (array.length == 1) {
- return array[0].length;
- }
- var wordPrefix = 0;
- var max = opt_shortest || Blockly.shortestStringLength(array);
- for (var len = 0; len < max; len++) {
- var letter = array[0].substr(-len - 1, 1);
- for (var i = 1; i < array.length; i++) {
- if (letter != array[i].substr(-len - 1, 1)) {
- return wordPrefix;
- }
- }
- if (letter == ' ') {
- wordPrefix = len + 1;
- }
- }
- for (var i = 1; i < array.length; i++) {
- var letter = array[i].charAt(array[i].length - len - 1);
- if (letter && letter != ' ') {
- return wordPrefix;
- }
- }
- return max;
- };
- Blockly.isNumber = function(str) {
- return !!str.match(/^\s*-?\d+(\.\d+)?\s*$/);
- };
- Blockly.utils.tokenizeInterpolation = function(message) {
- var tokens = [];
- var chars = message.split('');
- chars.push('');
-
-
-
-
- var state = 0;
- var buffer = [];
- var number = null;
- for (var i = 0; i < chars.length; i++) {
- var c = chars[i];
- if (state == 0) {
- if (c == '%') {
- state = 1;
- } else {
- buffer.push(c);
- }
- } else if (state == 1) {
- if (c == '%') {
- buffer.push(c);
- state = 0;
- } else if ('0' <= c && c <= '9') {
- state = 2;
- number = c;
- var text = buffer.join('');
- if (text) {
- tokens.push(text);
- }
- buffer.length = 0;
- } else {
- buffer.push('%', c);
- state = 0;
- }
- } else if (state == 2) {
- if ('0' <= c && c <= '9') {
- number += c;
- } else {
- tokens.push(parseInt(number, 10));
- i--;
- state = 0;
- }
- }
- }
- var text = buffer.join('');
- if (text) {
- tokens.push(text);
- }
- return tokens;
- };
- Blockly.genUid = function() {
- var length = 20;
- var soupLength = Blockly.genUid.soup_.length;
- var id = [];
- for (var i = 0; i < length; i++) {
- id[i] = Blockly.genUid.soup_.charAt(Math.random() * soupLength);
- }
- return id.join('');
- };
- Blockly.genUid.soup_ = '!#$%()*+,-./:;=?@[]^_`{|}~' +
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
- Blockly.utils.wrap = function(text, limit) {
- var lines = text.split('\n');
- for (var i = 0; i < lines.length; i++) {
- lines[i] = Blockly.utils.wrap_line_(lines[i], limit);
- }
- return lines.join('\n');
- };
- Blockly.utils.wrap_line_ = function(text, limit) {
- if (text.length <= limit) {
-
- return text;
- }
-
- var words = text.trim().split(/\s+/);
-
- for (var i = 0; i < words.length; i++) {
- if (words[i].length > limit) {
- limit = words[i].length;
- }
- }
- var lastScore;
- var score = -Infinity;
- var lastText;
- var lineCount = 1;
- do {
- lastScore = score;
- lastText = text;
-
-
- var wordBreaks = [];
-
- var steps = words.length / lineCount;
- var insertedBreaks = 1;
- for (var i = 0; i < words.length - 1; i++) {
- if (insertedBreaks < (i + 1.5) / steps) {
- insertedBreaks++;
- wordBreaks[i] = true;
- } else {
- wordBreaks[i] = false;
- }
- }
- wordBreaks = Blockly.utils.wrapMutate_(words, wordBreaks, limit);
- score = Blockly.utils.wrapScore_(words, wordBreaks, limit);
- text = Blockly.utils.wrapToText_(words, wordBreaks);
- lineCount++;
- } while (score > lastScore);
- return lastText;
- };
- Blockly.utils.wrapScore_ = function(words, wordBreaks, limit) {
-
-
- var lineLengths = [0];
- var linePunctuation = [];
- for (var i = 0; i < words.length; i++) {
- lineLengths[lineLengths.length - 1] += words[i].length;
- if (wordBreaks[i] === true) {
- lineLengths.push(0);
- linePunctuation.push(words[i].charAt(words[i].length - 1));
- } else if (wordBreaks[i] === false) {
- lineLengths[lineLengths.length - 1]++;
- }
- }
- var maxLength = Math.max.apply(Math, lineLengths);
- var score = 0;
- for (var i = 0; i < lineLengths.length; i++) {
-
-
- score -= Math.pow(Math.abs(limit - lineLengths[i]), 1.5) * 2;
-
-
- score -= Math.pow(maxLength - lineLengths[i], 1.5);
-
-
- if ('.?!'.indexOf(linePunctuation[i]) != -1) {
- score += limit / 3;
- } else if (',;)]}'.indexOf(linePunctuation[i]) != -1) {
- score += limit / 4;
- }
- }
-
-
-
-
- if (lineLengths.length > 1 && lineLengths[lineLengths.length - 1] <=
- lineLengths[lineLengths.length - 2]) {
- score += 0.5;
- }
- return score;
- };
- Blockly.utils.wrapMutate_ = function(words, wordBreaks, limit) {
- var bestScore = Blockly.utils.wrapScore_(words, wordBreaks, limit);
- var bestBreaks;
-
- for (var i = 0; i < wordBreaks.length - 1; i++) {
- if (wordBreaks[i] == wordBreaks[i + 1]) {
- continue;
- }
- var mutatedWordBreaks = [].concat(wordBreaks);
- mutatedWordBreaks[i] = !mutatedWordBreaks[i];
- mutatedWordBreaks[i + 1] = !mutatedWordBreaks[i + 1];
- var mutatedScore =
- Blockly.utils.wrapScore_(words, mutatedWordBreaks, limit);
- if (mutatedScore > bestScore) {
- bestScore = mutatedScore;
- bestBreaks = mutatedWordBreaks;
- }
- }
- if (bestBreaks) {
-
- return Blockly.utils.wrapMutate_(words, bestBreaks, limit);
- }
-
- return wordBreaks;
- };
- Blockly.utils.wrapToText_ = function(words, wordBreaks) {
- var text = [];
- for (var i = 0; i < words.length; i++) {
- text.push(words[i]);
- if (wordBreaks[i] !== undefined) {
- text.push(wordBreaks[i] ? '\n' : ' ');
- }
- }
- return text.join('');
- };
|