tagcanvas.js ➔ TagCanvas   F
last analyzed

Complexity

Conditions 87

Size

Total Lines 131
Code Lines 110

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 87
eloc 110
dl 0
loc 131
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like tagcanvas.js ➔ TagCanvas often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/**
2
 * Copyright (C) 2010-2015 Graham Breach
3
 *
4
 * This program is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU Lesser General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public License
15
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
 */
17
/**
18
 * TagCanvas 2.9
19
 * For more information, please contact <[email protected]>
20
 */
21
(function(){
22
"use strict";
23
var i, j, abs = Math.abs, sin = Math.sin, cos = Math.cos, max = Math.max,
24
  min = Math.min, ceil = Math.ceil, sqrt = Math.sqrt, pow = Math.pow,
25
  hexlookup3 = {}, hexlookup2 = {}, hexlookup1 = {
26
  0:"0,",   1:"17,",  2:"34,",  3:"51,",  4:"68,",  5:"85,",
27
  6:"102,", 7:"119,", 8:"136,", 9:"153,", a:"170,", A:"170,",
28
  b:"187,", B:"187,", c:"204,", C:"204,", d:"221,", D:"221,",
29
  e:"238,", E:"238,", f:"255,", F:"255,"
30
  }, Oproto, Tproto, TCproto, Mproto, Vproto, TSproto, TCVproto,
31
  doc = document, ocanvas, handlers = {};
32
for(i = 0; i < 256; ++i) {
33
  j = i.toString(16);
34
  if(i < 16)
35
    j = '0' + j;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
36
  hexlookup2[j] = hexlookup2[j.toUpperCase()] = i.toString() + ',';
37
}
38
function Defined(d) {
39
  return typeof d != 'undefined';
40
}
41
function IsObject(o) {
42
  return typeof o == 'object' && o != null;
0 ignored issues
show
Best Practice introduced by
Comparing o to null using the != operator is not safe. Consider using !== instead.
Loading history...
43
}
44
function Clamp(v, mn, mx) {
45
  return isNaN(v) ? mx : min(mx, max(mn, v));
46
}
47
function Nop() {
48
  return false;
49
}
50
function TimeNow() {
51
  return new Date().valueOf();
52
}
53
function SortList(l, f) {
54
  var nl = [], tl = l.length, i;
55
  for(i = 0; i < tl; ++i)
56
    nl.push(l[i]);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
57
  nl.sort(f);
58
  return nl;
59
}
60
function Shuffle(a) {
61
  var i = a.length-1, t, p;
62
  while(i) {
63
    p = ~~(Math.random()*i);
64
    t = a[i];
65
    a[i] = a[p];
66
    a[p] = t;
67
    --i;
68
  }
69
}
70
function Vector(x, y, z) {
71
  this.x = x;
72
  this.y = y;
73
  this.z = z;
74
}
75
Vproto = Vector.prototype;
76
Vproto.length = function() {
77
  return sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
78
};
79
Vproto.dot = function(v) {
80
  return this.x * v.x + this.y * v.y + this.z * v.z;
81
};
82
Vproto.cross = function(v) {
83
  var x = this.y * v.z - this.z * v.y,
84
    y = this.z * v.x - this.x * v.z,
85
    z = this.x * v.y - this.y * v.x;
86
  return new Vector(x, y, z);
87
};
88
Vproto.angle = function(v) {
89
  var dot = this.dot(v), ac;
90
  if(dot == 0)
0 ignored issues
show
Best Practice introduced by
Comparing dot to 0 using the == operator is not safe. Consider using === instead.
Loading history...
91
    return Math.PI / 2.0;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
92
  ac = dot / (this.length() * v.length());
93
  if(ac >= 1)
94
    return 0;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
95
  if(ac <= -1)
96
    return Math.PI;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
97
  return Math.acos(ac);
98
};
99
Vproto.unit = function() {
100
  var l = this.length();
101
  return new Vector(this.x / l, this.y / l, this.z / l);
102
};
103
function MakeVector(lg, lt) {
104
  lt = lt * Math.PI / 180;
105
  lg = lg * Math.PI / 180;
106
  var x = sin(lg) * cos(lt), y = -sin(lt), z = -cos(lg) * cos(lt);
107
  return new Vector(x, y, z);
108
}
109
function Matrix(a) {
110
  this[1] = {1: a[0],  2: a[1],  3: a[2]};
111
  this[2] = {1: a[3],  2: a[4],  3: a[5]};
112
  this[3] = {1: a[6],  2: a[7],  3: a[8]};
113
}
114
Mproto = Matrix.prototype;
115
Matrix.Identity = function() {
116
  return new Matrix([1,0,0, 0,1,0, 0,0,1]);
117
};
118
Matrix.Rotation = function(angle, u) {
119
  var sina = sin(angle), cosa = cos(angle), mcos = 1 - cosa;
120
  return new Matrix([
121
    cosa + pow(u.x, 2) * mcos, u.x * u.y * mcos - u.z * sina, u.x * u.z * mcos + u.y * sina,
122
    u.y * u.x * mcos + u.z * sina, cosa + pow(u.y, 2) * mcos, u.y * u.z * mcos - u.x * sina,
123
    u.z * u.x * mcos - u.y * sina, u.z * u.y * mcos + u.x * sina, cosa + pow(u.z, 2) * mcos
124
  ]);
125
}
126
Mproto.mul = function(m) {
127
  var a = [], i, j, mmatrix = (m.xform ? 1 : 0);
128
  for(i = 1; i <= 3; ++i)
129
    for(j = 1; j <= 3; ++j) {
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
130
      if(mmatrix)
131
        a.push(this[i][1] * m[1][j] +
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
132
          this[i][2] * m[2][j] +
133
          this[i][3] * m[3][j]);
134
      else
135
        a.push(this[i][j] * m);
136
    }
137
  return new Matrix(a);
138
};
139
Mproto.xform = function(p) {
140
  var a = {}, x = p.x, y = p.y, z = p.z;
141
  a.x = x * this[1][1] + y * this[2][1] + z * this[3][1];
142
  a.y = x * this[1][2] + y * this[2][2] + z * this[3][2];
143
  a.z = x * this[1][3] + y * this[2][3] + z * this[3][3];
144
  return a;
145
};
146 View Code Duplication
function PointsOnSphere(n,xr,yr,zr,magic) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
147
  var i, y, r, phi, pts = [], off = 2/n, inc;
148
  inc = Math.PI * (3 - sqrt(5) + (parseFloat(magic) ? parseFloat(magic) : 0));
149
  for(i = 0; i < n; ++i) {
150
    y = i * off - 1 + (off / 2);
151
    r = sqrt(1 - y*y);
152
    phi = i * inc;
153
    pts.push([cos(phi) * r * xr, y * yr, sin(phi) * r * zr]);
154
  }
155
  return pts;
156
}
157 View Code Duplication
function Cylinder(n,o,xr,yr,zr,magic) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
158
  var phi, pts = [], off = 2/n, inc, i, j, k, l;
159
  inc = Math.PI * (3 - sqrt(5) + (parseFloat(magic) ? parseFloat(magic) : 0));
160
  for(i = 0; i < n; ++i) {
161
    j = i * off - 1 + (off / 2);
162
    phi = i * inc;
163
    k = cos(phi);
164
    l = sin(phi);
165
    pts.push(o ? [j * xr, k * yr, l * zr] : [k * xr, j * yr, l * zr]);
166
  }
167
  return pts;
168
}
169
function Ring(o, n, xr, yr, zr, j) {
170
  var phi, pts = [], inc = Math.PI * 2 / n, i, k, l;
171
  for(i = 0; i < n; ++i) {
172
    phi = i * inc;
173
    k = cos(phi);
174
    l = sin(phi);
175
    pts.push(o ? [j * xr, k * yr, l * zr] : [k * xr, j * yr, l * zr]);
176
  }
177
  return pts;
178
}
179
function PointsOnCylinderV(n,xr,yr,zr,m) { return Cylinder(n, 0, xr, yr, zr, m) }
180
function PointsOnCylinderH(n,xr,yr,zr,m) { return Cylinder(n, 1, xr, yr, zr, m) }
181
function PointsOnRingV(n, xr, yr, zr, offset) {
182
  offset = isNaN(offset) ? 0 : offset * 1;
183
  return Ring(0, n, xr, yr, zr, offset);
184
}
185
function PointsOnRingH(n, xr, yr, zr, offset) {
186
  offset = isNaN(offset) ? 0 : offset * 1;
187
  return Ring(1, n, xr, yr, zr, offset);
188
}
189
function CentreImage(t) {
190
  var i = new Image;
0 ignored issues
show
Bug introduced by
The variable Image seems to be never declared. If this is a global, consider adding a /** global: Image */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
191
  i.onload = function() {
192
    var dx = i.width / 2, dy = i.height / 2;
193
    t.centreFunc = function(c, w, h, cx, cy) {
194
      c.setTransform(1, 0, 0, 1, 0, 0);
195
      c.globalAlpha = 1;
196
      c.drawImage(i, cx - dx, cy - dy);
197
    };
198
  };
199
  i.src = t.centreImage;
200
}
201
function SetAlpha(c,a) {
202
  var d = c, p1, p2, ae = (a*1).toPrecision(3) + ')';
203
  if(c[0] === '#') {
204
    if(!hexlookup3[c])
205
      if(c.length === 4)
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
206
        hexlookup3[c] = 'rgba(' + hexlookup1[c[1]] + hexlookup1[c[2]] + hexlookup1[c[3]];
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
207
      else
208
        hexlookup3[c] = 'rgba(' + hexlookup2[c.substr(1,2)] + hexlookup2[c.substr(3,2)] + hexlookup2[c.substr(5,2)];
209
    d = hexlookup3[c] + ae;
210
  } else if(c.substr(0,4) === 'rgb(' || c.substr(0,4) === 'hsl(') {
211
    d = (c.replace('(','a(').replace(')', ',' + ae));
212
  } else if(c.substr(0,5) === 'rgba(' || c.substr(0,5) === 'hsla(') {
213
    p1 = c.lastIndexOf(',') + 1, p2 = c.indexOf(')');
0 ignored issues
show
Comprehensibility introduced by
Usage of the sequence operator is discouraged, since it may lead to obfuscated code.

The sequence or comma operator allows the inclusion of multiple expressions where only is permitted. The result of the sequence is the value of the last expression.

This operator is most often used in for statements.

Used in another places it can make code hard to read, especially when people do not realize it even exists as a seperate operator.

This check looks for usage of the sequence operator in locations where it is not necessary and could be replaced by a series of expressions or statements.

var a,b,c;

a = 1, b = 1,  c= 3;

could just as well be written as:

var a,b,c;

a = 1;
b = 1;
c = 3;

To learn more about the sequence operator, please refer to the MDN.

Loading history...
214
    a *= parseFloat(c.substring(p1,p2));
215
    d = c.substr(0,p1) + a.toPrecision(3) + ')';
216
  }
217
  return d;
218
}
219
function NewCanvas(w,h) {
220
  // if using excanvas, give up now
221
  if(window.G_vmlCanvasManager)
222
    return null;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
223
  var c = doc.createElement('canvas');
224
  c.width = w;
225
  c.height = h;
226
  return c;
227
}
228
// I think all browsers pass this test now...
229
function ShadowAlphaBroken() {
230
  var cv = NewCanvas(3,3), c, i;
231
  if(!cv)
232
    return false;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
233
  c = cv.getContext('2d');
234
  c.strokeStyle = '#000';
235
  c.shadowColor = '#fff';
236
  c.shadowBlur = 3;
237
  c.globalAlpha = 0;
238
  c.strokeRect(2,2,2,2);
239
  c.globalAlpha = 1;
240
  i = c.getImageData(2,2,1,1);
241
  cv = null;
0 ignored issues
show
Unused Code introduced by
The assignment to cv seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
242
  return (i.data[0] > 0);
243
}
244
function SetGradient(c, l, o, g) {
245
  var gd = c.createLinearGradient(0, 0, l, 0), i;
246
  for(i in g)
247
    gd.addColorStop(1 - i, g[i]);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
248
  c.fillStyle = gd;
249
  c.fillRect(0, o, l, 1);
250
}
251
function FindGradientColour(tc, p, r) {
252
  var l = 1024, h = 1, gl = tc.weightGradient, cv, c, i, d;
253
  if(tc.gCanvas) {
254
    c = tc.gCanvas.getContext('2d');
255
    h = tc.gCanvas.height;
256
  } else {
257
    if(IsObject(gl[0]))
258
      h = gl.length;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
259
    else
260
      gl = [gl];
261
    tc.gCanvas = cv = NewCanvas(l, h);
262
    if(!cv)
263
      return null;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
264
    c = cv.getContext('2d');
265
    for(i = 0; i < h; ++i)
266
      SetGradient(c, l, i, gl[i]);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
267
  }
268
  r = max(min(r || 0, h - 1), 0);
269
  d = c.getImageData(~~((l - 1) * p), r, 1, 1).data;
270
  return 'rgba(' + d[0] + ',' + d[1] + ',' + d[2] + ',' + (d[3]/255) + ')';
271
}
272
function TextSet(ctxt, font, colour, strings, padx, pady, shadowColour,
273
  shadowBlur, shadowOffsets, maxWidth, widths, align) {
274
  var xo = padx + (shadowBlur || 0) +
275
    (shadowOffsets.length && shadowOffsets[0] < 0 ? abs(shadowOffsets[0]) : 0),
276
    yo = pady + (shadowBlur || 0) +
277
    (shadowOffsets.length && shadowOffsets[1] < 0 ? abs(shadowOffsets[1]) : 0), i, xc;
278
  ctxt.font = font;
279
  ctxt.textBaseline = 'top';
280
  ctxt.fillStyle = colour;
281
  shadowColour && (ctxt.shadowColor = shadowColour);
282
  shadowBlur && (ctxt.shadowBlur = shadowBlur);
283
  shadowOffsets.length && (ctxt.shadowOffsetX = shadowOffsets[0],
0 ignored issues
show
Comprehensibility introduced by
Usage of the sequence operator is discouraged, since it may lead to obfuscated code.

The sequence or comma operator allows the inclusion of multiple expressions where only is permitted. The result of the sequence is the value of the last expression.

This operator is most often used in for statements.

Used in another places it can make code hard to read, especially when people do not realize it even exists as a seperate operator.

This check looks for usage of the sequence operator in locations where it is not necessary and could be replaced by a series of expressions or statements.

var a,b,c;

a = 1, b = 1,  c= 3;

could just as well be written as:

var a,b,c;

a = 1;
b = 1;
c = 3;

To learn more about the sequence operator, please refer to the MDN.

Loading history...
284
    ctxt.shadowOffsetY = shadowOffsets[1]);
285
  for(i = 0; i < strings.length; ++i) {
286
    xc = 0;
287
    if(widths) {
288
      if('right' == align) {
289
        xc = maxWidth - widths[i];
290
      } else if('centre' == align) {
291
        xc = (maxWidth - widths[i]) / 2;
292
      }
293
    }
294
    ctxt.fillText(strings[i], xo + xc, yo);
295
    yo += parseInt(font);
296
  }
297
}
298
function RRect(c, x, y, w, h, r, s) {
299
  if(r) {
300
    c.beginPath();
301
    c.moveTo(x, y + h - r);
302
    c.arcTo(x, y, x + r, y, r);
303
    c.arcTo(x + w, y, x + w, y + r, r);
304
    c.arcTo(x + w, y + h, x + w - r, y + h, r);
305
    c.arcTo(x, y + h, x, y + h - r, r);
306
    c.closePath();
307
    c[s ? 'stroke' : 'fill']();
308
  } else {
309
    c[s ? 'strokeRect' : 'fillRect'](x, y, w, h);
310
  }
311
}
312
function TextCanvas(strings, font, w, h, maxWidth, stringWidths, align, valign,
313
  scale) {
314
  this.strings = strings;
315
  this.font = font;
316
  this.width = w;
317
  this.height = h;
318
  this.maxWidth = maxWidth;
319
  this.stringWidths = stringWidths;
320
  this.align = align;
321
  this.valign = valign;
322
  this.scale = scale;
323
}
324
TCVproto = TextCanvas.prototype;
325
TCVproto.SetImage = function(image, w, h, position, padding, align, valign,
326
  scale) {
327
  this.image = image;
328
  this.iwidth = w * this.scale;
329
  this.iheight = h * this.scale;
330
  this.ipos = position;
331
  this.ipad = padding * this.scale;
332
  this.iscale = scale;
333
  this.ialign = align;
334
  this.ivalign = valign;
335
};
336
TCVproto.Align = function(size, space, a) {
337
  var pos = 0;
338
  if(a == 'right' || a == 'bottom')
339
    pos = space - size;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
340
  else if(a != 'left' && a != 'top')
341
    pos = (space - size) / 2;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
342
  return pos;
343
};
344
TCVproto.Create = function(colour, bgColour, bgOutline, bgOutlineThickness,
345
  shadowColour, shadowBlur, shadowOffsets, padding, radius) {
346
  var cv, cw, ch, c, x1, x2, y1, y2, offx, offy, ix, iy, iw, ih, rr,
347
    sox = abs(shadowOffsets[0]), soy = abs(shadowOffsets[1]), shadowcv, shadowc;
348
  padding = max(padding, sox + shadowBlur, soy + shadowBlur);
349
  x1 = 2 * (padding + bgOutlineThickness);
350
  y1 = 2 * (padding + bgOutlineThickness);
351
  cw = this.width + x1;
352
  ch = this.height + y1;
353
  offx = offy = padding + bgOutlineThickness;
354
355
  if(this.image) {
356
    ix = iy = padding + bgOutlineThickness;
357
    iw = this.iwidth;
358
    ih = this.iheight;
359
    if(this.ipos == 'top' || this.ipos == 'bottom') {
360
      if(iw < this.width)
361
        ix += this.Align(iw, this.width, this.ialign);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
362
      else
363
        offx += this.Align(this.width, iw, this.align);
364
      if(this.ipos == 'top')
365
        offy += ih + this.ipad;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
366
      else
367
        iy += this.height + this.ipad;
368
      cw = max(cw, iw + x1);
369
      ch += ih + this.ipad;
370
    } else {
371
      if(ih < this.height)
372
        iy += this.Align(ih, this.height, this.ivalign);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
373
      else
374
        offy += this.Align(this.height, ih, this.valign);
375
      if(this.ipos == 'right')
376
        ix += this.width + this.ipad;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
377
      else
378
        offx += iw + this.ipad;
379
      cw += iw + this.ipad;
380
      ch = max(ch, ih + y1);
381
    }
382
  }
383
384
  cv = NewCanvas(cw, ch);
385
  if(!cv)
386
    return null;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
387
  x1 = y1 = bgOutlineThickness / 2;
388
  x2 = cw - bgOutlineThickness;
389
  y2 = ch - bgOutlineThickness;
390
  rr = min(radius, x2 / 2, y2 / 2);
391
  c = cv.getContext('2d');
392
  if(bgColour) {
393
    c.fillStyle = bgColour;
394
    RRect(c, x1, y1, x2, y2, rr);
395
  }
396
  if(bgOutlineThickness) {
397
    c.strokeStyle = bgOutline;
398
    c.lineWidth = bgOutlineThickness;
399
    RRect(c, x1, y1, x2, y2, rr, true);
400
  }
401
  if(shadowBlur || sox || soy) {
402
    // use a transparent canvas to draw on
403
    shadowcv = NewCanvas(cw, ch);
404
    if(shadowcv) {
405
      shadowc = c;
406
      c = shadowcv.getContext('2d');
407
    }
408
  }
409
410
  // don't use TextSet shadow support because it adds space for shadow
411
  TextSet(c, this.font, colour, this.strings, offx, offy, 0, 0, [],
412
    this.maxWidth, this.stringWidths, this.align);
413
414
  if(this.image)
415
    c.drawImage(this.image, ix, iy, iw, ih);
0 ignored issues
show
Bug introduced by
The variable ix does not seem to be initialized in case this.image on line 355 is false. Are you sure the function drawImage handles undefined variables?
Loading history...
Bug introduced by
The variable ih does not seem to be initialized in case this.image on line 355 is false. Are you sure the function drawImage handles undefined variables?
Loading history...
Bug introduced by
The variable iy does not seem to be initialized in case this.image on line 355 is false. Are you sure the function drawImage handles undefined variables?
Loading history...
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
Bug introduced by
The variable iw does not seem to be initialized in case this.image on line 355 is false. Are you sure the function drawImage handles undefined variables?
Loading history...
416
417
  if(shadowc) {
418
    // draw the text and image with the added shadow
419
    c = shadowc;
420
    shadowColour && (c.shadowColor = shadowColour);
421
    shadowBlur && (c.shadowBlur = shadowBlur);
422
    c.shadowOffsetX = shadowOffsets[0];
423
    c.shadowOffsetY = shadowOffsets[1];
424
    c.drawImage(shadowcv, 0, 0);
0 ignored issues
show
Bug introduced by
The variable shadowcv does not seem to be initialized in case shadowBlur || sox || soy on line 401 is false. Are you sure the function drawImage handles undefined variables?
Loading history...
425
  }
426
  return cv;
427
};
428
function ExpandImage(i, w, h) {
429
  var cv = NewCanvas(w, h), c;
430
  if(!cv)
431
    return null;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
432
  c = cv.getContext('2d');
433
  c.drawImage(i, (w - i.width) / 2, (h - i.height) / 2);
434
  return cv;
435
}
436
function ScaleImage(i, w, h) {
437
  var cv = NewCanvas(w, h), c;
438
  if(!cv)
439
    return null;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
440
  c = cv.getContext('2d');
441
  c.drawImage(i, 0, 0, w, h);
442
  return cv;
443
}
444
function AddBackgroundToImage(i, w, h, scale, colour, othickness, ocolour,
445
  padding, radius, ofill) {
446
  var cw = w + ((2 * padding) + othickness) * scale,
447
    ch = h + ((2 * padding) + othickness) * scale,
448
    cv = NewCanvas(cw, ch), c, x1, y1, x2, y2, ocanvas, cc, rr;
449
  if(!cv)
450
    return null;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
451
  othickness *= scale;
452
  radius *= scale;
453
  x1 = y1 = othickness / 2;
454
  x2 = cw - othickness;
455
  y2 = ch - othickness;
456
  padding = (padding * scale) + x1; // add space for outline
457
  c = cv.getContext('2d');
458
  rr = min(radius, x2 / 2, y2 / 2);
459
  if(colour) {
460
    c.fillStyle = colour;
461
    RRect(c, x1, y1, x2, y2, rr);
462
  }
463
  if(othickness) {
464
    c.strokeStyle = ocolour;
465
    c.lineWidth = othickness;
466
    RRect(c, x1, y1, x2, y2, rr, true);
467
  }
468
469
  if(ofill) {
470
    // use compositing to colour in the image and border
471
    ocanvas = NewCanvas(cw, ch);
472
    cc = ocanvas.getContext('2d');
473
    cc.drawImage(i, padding, padding, w, h);
474
    cc.globalCompositeOperation = 'source-in';
475
    cc.fillStyle = ocolour;
476
    cc.fillRect(0, 0, cw, ch);
477
    cc.globalCompositeOperation = 'destination-over';
478
    cc.drawImage(cv, 0, 0);
479
    cc.globalCompositeOperation = 'source-over';
480
    c.drawImage(ocanvas, 0, 0);
481
  } else {
482
    c.drawImage(i, padding, padding, i.width, i.height);
483
  }
484
  return {image: cv, width: cw / scale, height: ch / scale};
485
}
486
/**
487
 * Rounds off the corners of an image
488
 */
489
function RoundImage(i, r, iw, ih, s) {
490
  var cv, c, r1 = parseFloat(r), l = max(iw, ih);
491
  cv = NewCanvas(iw, ih);
492
  if(!cv)
493
    return null;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
494
  if(r.indexOf('%') > 0)
495
    r1 = l * r1 / 100;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
496
  else
497
    r1 = r1 * s;
498
  c = cv.getContext('2d');
499
  c.globalCompositeOperation = 'source-over';
500
  c.fillStyle = '#fff';
501
  if(r1 >= l/2) {
502
    r1 = min(iw,ih) / 2;
503
    c.beginPath();
504
    c.moveTo(iw/2,ih/2);
505
    c.arc(iw/2,ih/2,r1,0,2*Math.PI,false);
506
    c.fill();
507
    c.closePath();
508
  } else {
509
    r1 = min(iw/2,ih/2,r1);
510
    RRect(c, 0, 0, iw, ih, r1, true);
511
    c.fill();
512
  }
513
  c.globalCompositeOperation = 'source-in';
514
  c.drawImage(i, 0, 0, iw, ih);
515
  return cv;
516
}
517
/**
518
 * Creates a new canvas containing the image and its shadow
519
 * Returns an object containing the image and its dimensions at z=0
520
 */
521
function AddShadowToImage(i, w, h, scale, sc, sb, so) {
522
  var sw = abs(so[0]), sh = abs(so[1]),
523
    cw = w + (sw > sb ? sw + sb : sb * 2) * scale,
524
    ch = h + (sh > sb ? sh + sb : sb * 2) * scale,
525
    xo = scale * ((sb || 0) + (so[0] < 0 ? sw : 0)),
526
    yo = scale * ((sb || 0) + (so[1] < 0 ? sh : 0)), cv, c;
527
  cv = NewCanvas(cw, ch);
528
  if(!cv)
529
    return null;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
530
  c = cv.getContext('2d');
531
  sc && (c.shadowColor = sc);
532
  sb && (c.shadowBlur = sb * scale);
533
  so && (c.shadowOffsetX = so[0] * scale, c.shadowOffsetY = so[1] * scale);
0 ignored issues
show
Comprehensibility introduced by
Usage of the sequence operator is discouraged, since it may lead to obfuscated code.

The sequence or comma operator allows the inclusion of multiple expressions where only is permitted. The result of the sequence is the value of the last expression.

This operator is most often used in for statements.

Used in another places it can make code hard to read, especially when people do not realize it even exists as a seperate operator.

This check looks for usage of the sequence operator in locations where it is not necessary and could be replaced by a series of expressions or statements.

var a,b,c;

a = 1, b = 1,  c= 3;

could just as well be written as:

var a,b,c;

a = 1;
b = 1;
c = 3;

To learn more about the sequence operator, please refer to the MDN.

Loading history...
534
  c.drawImage(i, xo, yo, w, h);
535
  return {image: cv, width: cw / scale, height: ch / scale};
536
}
537
function FindTextBoundingBox(s,f,ht) {
538
  var w = parseInt(s.toString().length * ht), h = parseInt(ht * 2 * s.length),
539
    cv = NewCanvas(w,h), c, idata, w1, h1, x, y, i, ex;
540
  if(!cv)
541
    return null;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
542
  c = cv.getContext('2d');
543
  c.fillStyle = '#000';
544
  c.fillRect(0,0,w,h);
545
  TextSet(c,ht + 'px ' + f,'#fff',s,0,0,0,0,[],'centre')
546
547
  idata = c.getImageData(0,0,w,h);
548
  w1 = idata.width; h1 = idata.height;
549
  ex = {
550
    min: { x: w1, y: h1 },
551
    max: { x: -1, y: -1 }
552
  };
553
  for(y = 0; y < h1; ++y) {
554
    for(x = 0; x < w1; ++x) {
555
      i = (y * w1 + x) * 4;
556
      if(idata.data[i+1] > 0) {
557
        if(x < ex.min.x) ex.min.x = x;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
558
        if(x > ex.max.x) ex.max.x = x;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
559
        if(y < ex.min.y) ex.min.y = y;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
560
        if(y > ex.max.y) ex.max.y = y;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
561
      }
562
    }
563
  }
564
  // device pixels might not be css pixels
565
  if(w1 != w) {
566
    ex.min.x *= (w / w1);
567
    ex.max.x *= (w / w1);
568
  }
569
  if(h1 != h) {
570
    ex.min.y *= (w / h1);
571
    ex.max.y *= (w / h1);
572
  }
573
574
  cv = null;
0 ignored issues
show
Unused Code introduced by
The assignment to cv seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
575
  return ex;
576
}
577
function FixFont(f) {
578
  return "'" + f.replace(/(\'|\")/g,'').replace(/\s*,\s*/g, "', '") + "'";
579
}
580
function AddHandler(h,f,e) {
581
  e = e || doc;
582
  if(e.addEventListener)
583
    e.addEventListener(h,f,false);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
584
  else
585
    e.attachEvent('on' + h, f);
586
}
587
function RemoveHandler(h,f,e) {
588
  e = e || doc;
589
  if(e.removeEventListener)
590
    e.removeEventListener(h, f);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
591
  else
592
    e.detachEvent('on' + h, f);
593
}
594
function AddImage(i, o, t, tc) {
595
  var s = tc.imageScale, mscale, ic, bc, oc, iw, ih;
596
  // image not loaded, wait for image onload
597
  if(!o.complete)
598
    return AddHandler('load',function() { AddImage(i,o,t,tc); }, o);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
599
  if(!i.complete)
600
    return AddHandler('load',function() { AddImage(i,o,t,tc); }, i);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
601
602
  // Yes, this does look like nonsense, but it makes sure that both the
603
  // width and height are actually set and not just calculated. This is
604
  // required to keep proportional sizes when the images are hidden, so
605
  // the images can be used again for another cloud.
606
  o.width = o.width;
607
  o.height = o.height;
608
609
  if(s) {
610
    i.width = o.width * s;
611
    i.height = o.height * s;
612
  }
613
  // the standard width of the image, with imageScale applied
614
  t.iw = i.width;
615
  t.ih = i.height;
616
  if(tc.txtOpt) {
617
    ic = i;
0 ignored issues
show
Unused Code introduced by
The assignment to variable ic seems to be never used. Consider removing it.
Loading history...
618
    mscale = tc.zoomMax * tc.txtScale;
619
    iw = t.iw * mscale;
620
    ih = t.ih * mscale;
621
    if(iw < o.naturalWidth || ih < o.naturalHeight) {
622
      ic = ScaleImage(i, iw, ih);
623
      if(ic)
624
        t.fimage = ic;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
625
    } else {
626
      iw = t.iw;
627
      ih = t.ih;
628
      mscale = 1;
629
    }
630
    if(parseFloat(tc.imageRadius))
631
      t.image = t.fimage = i = RoundImage(t.image, tc.imageRadius, iw, ih, mscale);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
632
    if(!t.HasText()) {
633
      if(tc.shadow) {
634
        ic = AddShadowToImage(t.image, iw, ih, mscale, tc.shadow, tc.shadowBlur,
635
          tc.shadowOffset);
636
        if(ic) {
637
          t.fimage = ic.image;
638
          t.w = ic.width;
639
          t.h = ic.height;
640
        }
641
      }
642
      if(tc.bgColour || tc.bgOutlineThickness) {
643
        bc = tc.bgColour == 'tag' ? GetProperty(t.a, 'background-color') :
644
          tc.bgColour;
645
        oc = tc.bgOutline == 'tag' ? GetProperty(t.a, 'color') :
646
          (tc.bgOutline || tc.textColour);
647
        iw = t.fimage.width;
648
        ih = t.fimage.height;
649
        if(tc.outlineMethod == 'colour') {
650
          // create the outline version first, using the current image state
651
          ic = AddBackgroundToImage(t.fimage, iw, ih, mscale, bc,
652
            tc.bgOutlineThickness, t.outline.colour, tc.padding, tc.bgRadius, 1);
653
          if(ic)
654
            t.oimage = ic.image;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
655
        }
656
        ic = AddBackgroundToImage(t.fimage, iw, ih, mscale, bc,
657
          tc.bgOutlineThickness, oc, tc.padding, tc.bgRadius);
658
        if(ic) {
659
          t.fimage = ic.image;
660
          t.w = ic.width;
661
          t.h = ic.height;
662
        }
663
      }
664
      if(tc.outlineMethod == 'size') {
665
        if(tc.outlineIncrease > 0) {
666
          t.iw += 2 * tc.outlineIncrease;
667
          t.ih += 2 * tc.outlineIncrease;
668
          iw = mscale * t.iw;
669
          ih = mscale * t.ih;
670
          ic = ScaleImage(t.fimage, iw, ih);
671
          t.oimage = ic;
672
          t.fimage = ExpandImage(t.fimage, t.oimage.width, t.oimage.height);
673
        } else {
674
          iw = mscale * (t.iw + (2 * tc.outlineIncrease));
675
          ih = mscale * (t.ih + (2 * tc.outlineIncrease));
676
          ic = ScaleImage(t.fimage, iw, ih);
677
          t.oimage = ExpandImage(ic, t.fimage.width, t.fimage.height);
678
        }
679
      }
680
    }
681
  }
682
  t.Init();
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
683
}
684
function GetProperty(e,p) {
685
  var dv = doc.defaultView, pc = p.replace(/\-([a-z])/g,function(a){return a.charAt(1).toUpperCase()});
686
  return (dv && dv.getComputedStyle && dv.getComputedStyle(e,null).getPropertyValue(p)) ||
687
    (e.currentStyle && e.currentStyle[pc]);
688
}
689
function FindWeight(a, wFrom, tHeight) {
690
  var w = 1, p;
691
  if(wFrom) {
692
    w = 1 * (a.getAttribute(wFrom) || tHeight);
693
  } else if(p = GetProperty(a,'font-size')) {
694
    w = (p.indexOf('px') > -1 && p.replace('px','') * 1) ||
695
      (p.indexOf('pt') > -1 && p.replace('pt','') * 1.25) ||
696
      p * 3.3;
697
  }
698
  return w;
699
}
700
function EventToCanvasId(e) {
701
  return e.target && Defined(e.target.id) ? e.target.id :
702
    e.srcElement.parentNode.id;
703
}
704
function EventXY(e, c) {
705
  var xy, p, xmul = parseInt(GetProperty(c, 'width')) / c.width,
706
    ymul = parseInt(GetProperty(c, 'height')) / c.height;
707
  if(Defined(e.offsetX)) {
708
    xy = {x: e.offsetX, y: e.offsetY};
709
  } else {
710
    p = AbsPos(c.id);
711
    if(Defined(e.changedTouches))
712
      e = e.changedTouches[0];
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
713
    if(e.pageX)
714
      xy = {x: e.pageX - p.x, y: e.pageY - p.y};
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
715
  }
716
  if(xy && xmul && ymul) {
717
    xy.x /= xmul;
718
    xy.y /= ymul;
719
  }
720
  return xy;
0 ignored issues
show
Bug introduced by
The variable xy does not seem to be initialized in case e.pageX on line 713 is false. Are you sure this can never be the case?
Loading history...
721
}
722
function MouseOut(e) {
723
  var cv = e.target || e.fromElement.parentNode, tc = TagCanvas.tc[cv.id];
724
  if(tc) {
725
   tc.mx = tc.my = -1;
726
   tc.UnFreeze();
727
   tc.EndDrag();
728
  }
729
}
730
function MouseMove(e) {
731
  var i, t = TagCanvas, tc, p, tg = EventToCanvasId(e);
732
  for(i in t.tc) {
733
    tc = t.tc[i];
734
    if(tc.tttimer) {
735
      clearTimeout(tc.tttimer);
736
      tc.tttimer = null;
737
    }
738
  }
739
  if(tg && t.tc[tg]) {
740
    tc = t.tc[tg];
741
    if(p = EventXY(e, tc.canvas)) {
742
      tc.mx = p.x;
743
      tc.my = p.y;
744
      tc.Drag(e, p);
745
    }
746
    tc.drawn = 0;
747
  }
748
}
749
function MouseDown(e) {
750
  var t = TagCanvas, cb = doc.addEventListener ? 0 : 1,
751
    tg = EventToCanvasId(e);
752
  if(tg && e.button == cb && t.tc[tg]) {
753
    t.tc[tg].BeginDrag(e);
754
  }
755
}
756
function MouseUp(e) {
757
  var t = TagCanvas, cb = doc.addEventListener ? 0 : 1,
758
    tg = EventToCanvasId(e), tc;
759
  if(tg && e.button == cb && t.tc[tg]) {
760
    tc = t.tc[tg];
761
    MouseMove(e);
762
    if(!tc.EndDrag() && !tc.touchState)
763
      tc.Clicked(e);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
764
  }
765
}
766
function TouchDown(e) {
767
  var tg = EventToCanvasId(e), tc = (tg && TagCanvas.tc[tg]), p;
768
  if(tc && e.changedTouches) {
769
    if(e.touches.length == 1 && tc.touchState == 0) {
0 ignored issues
show
Best Practice introduced by
Comparing e.touches.length to 1 using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing tc.touchState to 0 using the == operator is not safe. Consider using === instead.
Loading history...
770
      tc.touchState = 1;
771
      tc.BeginDrag(e);
772
      if(p = EventXY(e, tc.canvas)) {
773
        tc.mx = p.x;
774
        tc.my = p.y;
775
        tc.drawn = 0;
776
      }
777
    } else if(e.targetTouches.length == 2 && tc.pinchZoom) {
778
      tc.touchState = 3;
779
      tc.EndDrag();
780
      tc.BeginPinch(e);
781
    } else {
782
      tc.EndDrag();
783
      tc.EndPinch();
784
      tc.touchState = 0;
785
    }
786
  }
787
}
788
function TouchUp(e) {
789
  var tg = EventToCanvasId(e), tc = (tg && TagCanvas.tc[tg]);
790
  if(tc && e.changedTouches) {
791
    switch(tc.touchState) {
792
    case 1:
793
      tc.Draw();
794
      tc.Clicked();
795
      break;
796
    case 2:
797
      tc.EndDrag();
798
      break;
799
    case 3:
800
      tc.EndPinch();
801
    }
802
    tc.touchState = 0;
803
  }
804
}
805
function TouchMove(e) {
806
  var i, t = TagCanvas, tc, p, tg = EventToCanvasId(e);
807
  for(i in t.tc) {
808
    tc = t.tc[i];
809
    if(tc.tttimer) {
810
      clearTimeout(tc.tttimer);
811
      tc.tttimer = null;
812
    }
813
  }
814
  tc = (tg && t.tc[tg]);
815
  if(tc && e.changedTouches && tc.touchState) {
816
    switch(tc.touchState) {
817
    case 1:
818
    case 2:
819
      if(p = EventXY(e, tc.canvas)) {
820
        tc.mx = p.x;
821
        tc.my = p.y;
822
        if(tc.Drag(e, p))
823
          tc.touchState = 2;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
824
      }
825
      break;
826
    case 3:
827
      tc.Pinch(e);
828
    }
829
    tc.drawn = 0;
830
  }
831
}
832
function MouseWheel(e) {
833
  var t = TagCanvas, tg = EventToCanvasId(e);
834
  if(tg && t.tc[tg]) {
835
    e.cancelBubble = true;
836
    e.returnValue = false;
837
    e.preventDefault && e.preventDefault();
838
    t.tc[tg].Wheel((e.wheelDelta || e.detail) > 0);
839
  }
840
}
841
function Scroll(e) {
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
842
  var i, t = TagCanvas;
843
  clearTimeout(t.scrollTimer);
844
  for(i in t.tc) {
845
    t.tc[i].Pause();
846
  }
847
  t.scrollTimer = setTimeout(function() {
848
    var i, t = TagCanvas;
849
    for(i in t.tc) {
850
      t.tc[i].Resume();
851
    }
852
  }, t.scrollPause);
853
}
854
function DrawCanvas() {
855
  DrawCanvasRAF(TimeNow());
856
}
857
function DrawCanvasRAF(t) {
858
  var tc = TagCanvas.tc, i;
859
  TagCanvas.NextFrame(TagCanvas.interval);
860
  t = t || TimeNow();
861
  for(i in tc)
862
    tc[i].Draw(t);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
863
}
864
function AbsPos(id) {
865
  var e = doc.getElementById(id), r = e.getBoundingClientRect(),
866
    dd = doc.documentElement, b = doc.body, w = window,
867
    xs = w.pageXOffset || dd.scrollLeft,
868
    ys = w.pageYOffset || dd.scrollTop,
869
    xo = dd.clientLeft || b.clientLeft,
870
    yo = dd.clientTop || b.clientTop;
871
  return { x: r.left + xs - xo, y: r.top + ys - yo };
872
}
873
function Project(tc,p1,sx,sy) {
874
  var m = tc.radius * tc.z1 / (tc.z1 + tc.z2 + p1.z);
875
  return {
876
    x: p1.x * m * sx,
877
    y: p1.y * m * sy,
878
    z: p1.z,
879
    w: (tc.z1 - p1.z) / tc.z2
880
  };
881
}
882
/**
883
 * @constructor
884
 * for recursively splitting tag contents on <br> tags
885
 */
886
function TextSplitter(e) {
887
  this.e = e;
888
  this.br = 0;
889
  this.line = [];
890
  this.text = [];
891
  this.original = e.innerText || e.textContent;
892
}
893
TSproto = TextSplitter.prototype;
894
TSproto.Empty = function() {
895
  for(var i = 0; i < this.text.length; ++i)
896
    if(this.text[i].length)
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
897
      return false;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
898
  return true;
899
};
900
TSproto.Lines = function(e) {
901
  var r = e ? 1 : 0, cn, cl, i;
902
  e = e || this.e;
903
  cn = e.childNodes;
904
  cl = cn.length;
905
906
  for(i = 0; i < cl; ++i) {
907
    if(cn[i].nodeName == 'BR') {
908
      this.text.push(this.line.join(' '));
909
      this.br = 1;
910
    } else if(cn[i].nodeType == 3) {
911
      if(this.br) {
912
        this.line = [cn[i].nodeValue];
913
        this.br = 0;
914
      } else {
915
        this.line.push(cn[i].nodeValue);
916
      }
917
    } else {
918
      this.Lines(cn[i]);
919
    }
920
  }
921
  r || this.br || this.text.push(this.line.join(' '));
922
  return this.text;
923
};
924
TSproto.SplitWidth = function(w, c, f, h) {
925
  var i, j, words, text = [];
926
  c.font = h + 'px ' + f;
927
  for(i = 0; i < this.text.length; ++i) {
928
    words = this.text[i].split(/\s+/);
929
    this.line = [words[0]];
930
    for(j = 1; j < words.length; ++j) {
931
      if(c.measureText(this.line.join(' ') + ' ' + words[j]).width > w) {
932
        text.push(this.line.join(' '));
933
        this.line = [words[j]];
934
      } else {
935
        this.line.push(words[j]);
936
      }
937
    }
938
    text.push(this.line.join(' '));
939
  }
940
  return this.text = text;
941
};
942
/**
943
 * @constructor
944
 */
945
function Outline(tc,t) {
946
  this.ts = null;
947
  this.tc = tc;
948
  this.tag = t;
949
  this.x = this.y = this.w = this.h = this.sc = 1;
950
  this.z = 0;
951
  this.pulse = 1;
952
  this.pulsate = tc.pulsateTo < 1;
953
  this.colour = tc.outlineColour;
954
  this.adash = ~~tc.outlineDash;
955
  this.agap = ~~tc.outlineDashSpace || this.adash;
956
  this.aspeed = tc.outlineDashSpeed * 1;
957
  if(this.colour == 'tag')
958
    this.colour = GetProperty(t.a, 'color');
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
959
  else if(this.colour == 'tagbg')
960
    this.colour = GetProperty(t.a, 'background-color');
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
961
  this.Draw = this.pulsate ? this.DrawPulsate : this.DrawSimple;
962
  this.radius = tc.outlineRadius | 0;
963
  this.SetMethod(tc.outlineMethod);
964
}
965
Oproto = Outline.prototype;
966
Oproto.SetMethod = function(om) {
967
  var methods = {
968
    block: ['PreDraw','DrawBlock'],
969
    colour: ['PreDraw','DrawColour'],
970
    outline: ['PostDraw','DrawOutline'],
971
    classic: ['LastDraw','DrawOutline'],
972
    size: ['PreDraw','DrawSize'],
973
    none: ['LastDraw']
974
  }, funcs = methods[om] || methods.outline;
975
  if(om == 'none') {
976
    this.Draw = function() { return 1; }
977
  } else {
978
    this.drawFunc = this[funcs[1]];
979
  }
980
  this[funcs[0]] = this.Draw;
981
};
982
Oproto.Update = function(x,y,w,h,sc,z,xo,yo) {
983
  var o = this.tc.outlineOffset, o2 = 2 * o;
984
  this.x = sc * x + xo - o;
985
  this.y = sc * y + yo - o;
986
  this.w = sc * w + o2;
987
  this.h = sc * h + o2;
988
  this.sc = sc; // used to determine frontmost
989
  this.z = z;
990
};
991
Oproto.Ants = function(c) {
992
  if(!this.adash)
993
    return;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
994
  var l = this.adash, g = this.agap, s = this.aspeed, length = l + g,
995
    l1 = 0, l2 = l, g1 = g, g2 = 0, seq = 0, ants;
996
  if(s) {
997
    seq = abs(s) * (TimeNow() - this.ts) / 50;
998
    if(s < 0)
999
      seq = 8.64e6 - seq;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1000
    s = ~~seq % length;
1001
  }
1002
  if(s) {
1003
    if(l >= s) {
1004
      l1 = l - s;
1005
      l2 = s;
1006
    } else {
1007
      g1 = length - s;
1008
      g2 = g - g1;
1009
    }
1010
    ants = [l1, g1, l2, g2];
1011
  } else {
1012
    ants = [l,g];
1013
  }
1014
  c.setLineDash(ants);
1015
}
1016
Oproto.DrawOutline = function(c,x,y,w,h,colour) {
1017
  var r = min(this.radius, h/2, w/2);
1018
  c.strokeStyle = colour;
1019
  this.Ants(c);
1020
  RRect(c, x, y, w, h, r, true);
1021
};
1022
Oproto.DrawSize = function(c,x,y,w,h,colour,tag,x1,y1) {
1023
  var tw = tag.w, th = tag.h, m, i, sc;
1024
  if(this.pulsate) {
1025
    if(tag.image)
1026
      sc = (tag.image.height + this.tc.outlineIncrease) / tag.image.height;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1027
    else
1028
      sc = tag.oscale;
1029
    i = tag.fimage || tag.image;
1030
    m = 1 + ((sc - 1) * (1-this.pulse));
1031
    tag.h *= m;
1032
    tag.w *= m;
1033
  } else {
1034
    i = tag.oimage;
1035
  }
1036
  tag.alpha = 1;
1037
  tag.Draw(c, x1, y1, i);
1038
  tag.h = th;
1039
  tag.w = tw;
1040
  return 1;
1041
};
1042
Oproto.DrawColour = function(c,x,y,w,h,colour,tag,x1,y1) {
1043
  if(tag.oimage) {
1044
    if(this.pulse < 1) {
1045
      tag.alpha = 1 - pow(this.pulse, 2);
1046
      tag.Draw(c, x1, y1, tag.fimage);
1047
      tag.alpha = this.pulse;
1048
    } else {
1049
      tag.alpha = 1;
1050
    }
1051
    tag.Draw(c, x1, y1, tag.oimage);
1052
    return 1;
1053
  }
1054
  return this[tag.image ? 'DrawColourImage' : 'DrawColourText'](c,x,y,w,h,colour,tag,x1,y1);
1055
};
1056
Oproto.DrawColourText = function(c,x,y,w,h,colour,tag,x1,y1) {
1057
  var normal = tag.colour;
1058
  tag.colour = colour;
1059
  tag.alpha = 1;
1060
  tag.Draw(c,x1,y1);
1061
  tag.colour = normal;
1062
  return 1;
1063
};
1064
Oproto.DrawColourImage = function(c,x,y,w,h,colour,tag,x1,y1) {
1065
  var ccanvas = c.canvas, fx = ~~max(x,0), fy = ~~max(y,0),
1066
    fw = min(ccanvas.width - fx, w) + .5|0, fh = min(ccanvas.height - fy,h) + .5|0, cc;
1067
  if(ocanvas)
1068
    ocanvas.width = fw, ocanvas.height = fh;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
Comprehensibility introduced by
Usage of the sequence operator is discouraged, since it may lead to obfuscated code.

The sequence or comma operator allows the inclusion of multiple expressions where only is permitted. The result of the sequence is the value of the last expression.

This operator is most often used in for statements.

Used in another places it can make code hard to read, especially when people do not realize it even exists as a seperate operator.

This check looks for usage of the sequence operator in locations where it is not necessary and could be replaced by a series of expressions or statements.

var a,b,c;

a = 1, b = 1,  c= 3;

could just as well be written as:

var a,b,c;

a = 1;
b = 1;
c = 3;

To learn more about the sequence operator, please refer to the MDN.

Loading history...
1069
  else
1070
    ocanvas = NewCanvas(fw, fh);
1071
  if(!ocanvas)
1072
    return this.SetMethod('outline'); // if using IE and images, give up!
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1073
  cc = ocanvas.getContext('2d');
1074
1075
  cc.drawImage(ccanvas,fx,fy,fw,fh,0,0,fw,fh);
1076
  c.clearRect(fx,fy,fw,fh);
1077
  if(this.pulsate) {
1078
    tag.alpha = 1 - pow(this.pulse, 2);
1079
  } else {
1080
    tag.alpha = 1;
1081
  }
1082
  tag.Draw(c,x1,y1);
1083
  c.setTransform(1,0,0,1,0,0);
1084
  c.save();
1085
  c.beginPath();
1086
  c.rect(fx,fy,fw,fh);
1087
  c.clip();
1088
  c.globalCompositeOperation = 'source-in';
1089
  c.fillStyle = colour;
1090
  c.fillRect(fx,fy,fw,fh);
1091
  c.restore();
1092
  c.globalAlpha = 1;
1093
  c.globalCompositeOperation = 'destination-over';
1094
  c.drawImage(ocanvas,0,0,fw,fh,fx,fy,fw,fh);
1095
  c.globalCompositeOperation = 'source-over';
1096
  return 1;
1097
};
1098
Oproto.DrawBlock = function(c,x,y,w,h,colour) {
1099
  var r = min(this.radius, h/2, w/2);
1100
  c.fillStyle = colour;
1101
  RRect(c, x, y, w, h, r);
1102
};
1103
Oproto.DrawSimple = function(c, tag, x1, y1, ga, useGa) {
1104
  var t = this.tc;
1105
  c.setTransform(1,0,0,1,0,0);
1106
  c.strokeStyle = this.colour;
1107
  c.lineWidth = t.outlineThickness;
1108
  c.shadowBlur = c.shadowOffsetX = c.shadowOffsetY = 0;
1109
  c.globalAlpha = useGa ? ga : 1;
1110
  return this.drawFunc(c,this.x,this.y,this.w,this.h,this.colour,tag,x1,y1);
1111
};
1112
Oproto.DrawPulsate = function(c, tag, x1, y1) {
1113
  var diff = TimeNow() - this.ts, t = this.tc,
1114
    ga = t.pulsateTo + ((1 - t.pulsateTo) *
1115
    (0.5 + (cos(2 * Math.PI * diff / (1000 * t.pulsateTime)) / 2)));
1116
  this.pulse = ga = TagCanvas.Smooth(1,ga);
1117
  return this.DrawSimple(c, tag, x1, y1, ga, 1);
1118
};
1119
Oproto.Active = function(c,x,y) {
1120
  var a = (x >= this.x && y >= this.y &&
1121
    x <= this.x + this.w && y <= this.y + this.h);
1122
  if(a) {
1123
    this.ts = this.ts || TimeNow();
1124
  } else {
1125
    this.ts = null;
1126
  }
1127
  return a;
1128
};
1129
Oproto.PreDraw = Oproto.PostDraw = Oproto.LastDraw = Nop;
1130
/**
1131
 * @constructor
1132
 */
1133
function Tag(tc, text, a, v, w, h, col, bcol, bradius, boutline, bothickness,
1134
  font, padding, original) {
1135
  this.tc = tc;
1136
  this.image = null;
1137
  this.text = text;
1138
  this.text_original = original;
1139
  this.line_widths = [];
1140
  this.title = a.title || null;
1141
  this.a = a;
1142
  this.position = new Vector(v[0], v[1], v[2]);
1143
  this.x = this.y = this.z = 0;
1144
  this.w = w;
1145
  this.h = h;
1146
  this.colour = col || tc.textColour;
1147
  this.bgColour = bcol || tc.bgColour;
1148
  this.bgRadius = bradius | 0;
1149
  this.bgOutline = boutline || this.colour;
1150
  this.bgOutlineThickness = bothickness | 0;
1151
  this.textFont = font || tc.textFont;
1152
  this.padding = padding | 0;
1153
  this.sc = this.alpha = 1;
1154
  this.weighted = !tc.weight;
1155
  this.outline = new Outline(tc,this);
1156
}
1157
Tproto = Tag.prototype;
1158
Tproto.Init = function(e) {
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1159
  var tc = this.tc;
1160
  this.textHeight = tc.textHeight;
1161
  if(this.HasText()) {
1162
    this.Measure(tc.ctxt,tc);
1163
  } else {
1164
    this.w = this.iw;
1165
    this.h = this.ih;
1166
  }
1167
1168
  this.SetShadowColour = tc.shadowAlpha ? this.SetShadowColourAlpha : this.SetShadowColourFixed;
1169
  this.SetDraw(tc);
1170
};
1171
Tproto.Draw = Nop;
1172
Tproto.HasText = function() {
1173
  return this.text && this.text[0].length > 0;
1174
};
1175
Tproto.EqualTo = function(e) {
1176
  var i = e.getElementsByTagName('img');
1177
  if(this.a.href != e.href)
1178
    return 0;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1179
  if(i.length)
1180
    return this.image.src == i[0].src;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1181
  return (e.innerText || e.textContent) == this.text_original;
1182
};
1183
Tproto.SetImage = function(i) {
1184
  this.image = this.fimage = i;
1185
};
1186
Tproto.SetDraw = function(t) {
1187
  this.Draw = this.fimage ? (t.ie > 7 ? this.DrawImageIE : this.DrawImage) : this.DrawText;
1188
  t.noSelect && (this.CheckActive = Nop);
1189
};
1190
Tproto.MeasureText = function(c) {
1191
  var i, l = this.text.length, w = 0, wl;
1192
  for(i = 0; i < l; ++i) {
1193
    this.line_widths[i] = wl = c.measureText(this.text[i]).width;
1194
    w = max(w, wl);
1195
  }
1196
  return w;
1197
};
1198
Tproto.Measure = function(c,t) {
1199
  var extents = FindTextBoundingBox(this.text, this.textFont, this.textHeight),
1200
    s, th, f, soff, cw, twidth, theight, img, tcv;
1201
  // add the gap at the top to the height to make equal gap at bottom
1202
  theight = extents ? extents.max.y + extents.min.y : this.textHeight;
1203
  c.font = this.font = this.textHeight + 'px ' + this.textFont;
1204
  twidth = this.MeasureText(c);
1205
  if(t.txtOpt) {
1206
    s = t.txtScale;
1207
    th = s * this.textHeight;
1208
    f = th + 'px ' + this.textFont;
1209
    soff = [s * t.shadowOffset[0], s * t.shadowOffset[1]];
1210
    c.font = f;
1211
    cw = this.MeasureText(c);
1212
    tcv = new TextCanvas(this.text, f, cw + s, (s * theight) + s, cw,
1213
      this.line_widths, t.textAlign, t.textVAlign, s);
1214
1215
    if(this.image)
1216
      tcv.SetImage(this.image, this.iw, this.ih, t.imagePosition, t.imagePadding,
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1217
        t.imageAlign, t.imageVAlign, t.imageScale);
1218
1219
    img = tcv.Create(this.colour, this.bgColour, this.bgOutline,
1220
      s * this.bgOutlineThickness, t.shadow, s * t.shadowBlur, soff,
1221
      s * this.padding, s * this.bgRadius);
1222
1223
    // add outline image using highlight colour
1224
    if(t.outlineMethod == 'colour') {
1225
      this.oimage = tcv.Create(this.outline.colour, this.bgColour, this.outline.colour,
1226
        s * this.bgOutlineThickness, t.shadow, s * t.shadowBlur, soff,
1227
        s * this.padding, s * this.bgRadius);
1228
1229
    } else if(t.outlineMethod == 'size') {
1230
      extents = FindTextBoundingBox(this.text, this.textFont,
1231
        this.textHeight + t.outlineIncrease);
1232
      th = extents.max.y + extents.min.y;
1233
      f = (s * (this.textHeight + t.outlineIncrease)) + 'px ' + this.textFont;
1234
      c.font = f;
1235
      cw = this.MeasureText(c);
1236
1237
      tcv = new TextCanvas(this.text, f, cw + s, (s * th) + s, cw,
1238
        this.line_widths, t.textAlign, t.textVAlign, s);
1239
      if(this.image)
1240
        tcv.SetImage(this.image, this.iw + t.outlineIncrease,
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1241
          this.ih + t.outlineIncrease, t.imagePosition, t.imagePadding,
1242
          t.imageAlign, t.imageVAlign, t.imageScale);
1243
1244
      this.oimage = tcv.Create(this.colour, this.bgColour, this.bgOutline,
1245
        s * this.bgOutlineThickness, t.shadow, s * t.shadowBlur, soff,
1246
        s * this.padding, s * this.bgRadius);
1247
1248
      this.oscale = this.oimage.width / img.width;
1249
      if(t.outlineIncrease > 0)
1250
        img = ExpandImage(img, this.oimage.width, this.oimage.height);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1251
      else
1252
        this.oimage = ExpandImage(this.oimage, img.width, img.height);
1253
    }
1254
    if(img) {
1255
      this.fimage = img;
1256
      twidth = this.fimage.width / s;
1257
      theight = this.fimage.height / s;
1258
    }
1259
    this.SetDraw(t);
1260
    t.txtOpt = !!this.fimage;
1261
  }
1262
  this.h = theight;
1263
  this.w = twidth;
1264
};
1265
Tproto.SetFont = function(f, c, bc, boc) {
1266
  this.textFont = f;
1267
  this.colour = c;
1268
  this.bgColour = bc;
1269
  this.bgOutline = boc;
1270
  this.Measure(this.tc.ctxt, this.tc);
1271
};
1272
Tproto.SetWeight = function(w) {
1273
  var tc = this.tc, modes = tc.weightMode.split(/[, ]/), m, s, wl = w.length;
1274
  if(!this.HasText())
1275
    return;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1276
  this.weighted = true;
1277
  for(s = 0; s < wl; ++s) {
1278
    m = modes[s] || 'size';
1279
    if('both' == m) {
1280
      this.Weight(w[s], tc.ctxt, tc, 'size', tc.min_weight[s],
1281
        tc.max_weight[s], s);
1282
      this.Weight(w[s], tc.ctxt, tc, 'colour', tc.min_weight[s],
1283
        tc.max_weight[s], s);
1284
    } else {
1285
      this.Weight(w[s], tc.ctxt, tc, m, tc.min_weight[s], tc.max_weight[s], s);
1286
    }
1287
  }
1288
  this.Measure(tc.ctxt, tc);
1289
};
1290
Tproto.Weight = function(w, c, t, m, wmin, wmax, wnum) {
1291
  w = isNaN(w) ? 1 : w;
1292
  var nweight = (w - wmin) / (wmax - wmin);
1293
  if('colour' == m)
1294
    this.colour = FindGradientColour(t, nweight, wnum);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1295
  else if('bgcolour' == m)
1296
    this.bgColour = FindGradientColour(t, nweight, wnum);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1297
  else if('bgoutline' == m)
1298
    this.bgOutline = FindGradientColour(t, nweight, wnum);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1299
  else if('outline' == m)
1300
    this.outline.colour = FindGradientColour(t, nweight, wnum);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1301
  else if('size' == m) {
1302
    if(t.weightSizeMin > 0 && t.weightSizeMax > t.weightSizeMin) {
1303
      this.textHeight = t.weightSize *
1304
        (t.weightSizeMin + (t.weightSizeMax - t.weightSizeMin) * nweight);
1305
    } else {
1306
      // min textHeight of 1
1307
      this.textHeight = max(1, w * t.weightSize);
1308
    }
1309
  }
1310
};
1311
Tproto.SetShadowColourFixed = function(c,s,a) {
0 ignored issues
show
Unused Code introduced by
The parameter a is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1312
  c.shadowColor = s;
1313
};
1314
Tproto.SetShadowColourAlpha = function(c,s,a) {
1315
  c.shadowColor = SetAlpha(s, a);
1316
};
1317
Tproto.DrawText = function(c,xoff,yoff) {
1318
  var t = this.tc, x = this.x, y = this.y, s = this.sc, i, xl;
1319
  c.globalAlpha = this.alpha;
1320
  c.fillStyle = this.colour;
1321
  t.shadow && this.SetShadowColour(c,t.shadow,this.alpha);
1322
  c.font = this.font;
1323
  x += xoff / s;
1324
  y += (yoff / s) - (this.h / 2);
1325
  for(i = 0; i < this.text.length; ++i) {
1326
    xl = x;
1327
    if('right' == t.textAlign) {
1328
      xl += this.w / 2 - this.line_widths[i];
1329
    } else if('centre' == t.textAlign) {
1330
      xl -= this.line_widths[i] / 2;
1331
    } else {
1332
      xl -= this.w / 2;
1333
    }
1334
    c.setTransform(s, 0, 0, s, s * xl, s * y);
1335
    c.fillText(this.text[i], 0, 0);
1336
    y += this.textHeight;
1337
  }
1338
};
1339
Tproto.DrawImage = function(c,xoff,yoff,im) {
1340
  var x = this.x, y = this.y, s = this.sc,
1341
    i = im || this.fimage, w = this.w, h = this.h, a = this.alpha,
1342
    shadow = this.shadow;
1343
  c.globalAlpha = a;
1344
  shadow && this.SetShadowColour(c,shadow,a);
1345
  x += (xoff / s) - (w / 2);
1346
  y += (yoff / s) - (h / 2);
1347
  c.setTransform(s, 0, 0, s, s * x, s * y);
1348
  c.drawImage(i, 0, 0, w, h);
1349
};
1350
Tproto.DrawImageIE = function(c,xoff,yoff) {
1351
  var i = this.fimage, s = this.sc,
1352
    w = i.width = this.w*s, h = i.height = this.h * s,
1353
    x = (this.x*s) + xoff - (w/2), y = (this.y*s) + yoff - (h/2);
1354
  c.setTransform(1,0,0,1,0,0);
1355
  c.globalAlpha = this.alpha;
1356
  c.drawImage(i, x, y);
1357
};
1358
Tproto.Calc = function(m,a) {
1359
  var pp, t = this.tc, mnb = t.minBrightness,
1360
    mxb = t.maxBrightness, r = t.max_radius;
1361
  pp = m.xform(this.position);
1362
  this.xformed = pp;
1363
  pp = Project(t, pp, t.stretchX, t.stretchY);
1364
  this.x = pp.x;
1365
  this.y = pp.y;
1366
  this.z = pp.z;
1367
  this.sc = pp.w;
1368
  this.alpha = a * Clamp(mnb + (mxb - mnb) * (r - this.z) / (2 * r), 0, 1);
1369
  return this.xformed;
1370
};
1371
Tproto.UpdateActive = function(c, xoff, yoff) {
1372
  var o = this.outline, w = this.w, h = this.h,
1373
    x = this.x - w/2, y = this.y - h/2;
1374
  o.Update(x, y, w, h, this.sc, this.z, xoff, yoff);
1375
  return o;
1376
};
1377
Tproto.CheckActive = function(c,xoff,yoff) {
1378
  var t = this.tc, o = this.UpdateActive(c, xoff, yoff);
1379
  return o.Active(c, t.mx, t.my) ? o : null;
1380
};
1381
Tproto.Clicked = function(e) {
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
1382
  var a = this.a, t = a.target, h = a.href, evt;
1383
  if(t != '' && t != '_self') {
1384
    if(self.frames[t]) {
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
1385
      self.frames[t].document.location = h;
1386
    } else{
1387
      try {
1388
        if(top.frames[t]) {
0 ignored issues
show
Bug introduced by
The variable top seems to be never declared. If this is a global, consider adding a /** global: top */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
1389
          top.frames[t].document.location = h;
1390
          return;
1391
        }
1392
      } catch(err) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
1393
        // different domain/port/protocol?
1394
      }
1395
      window.open(h, t);
1396
    }
1397
    return;
1398
  }
1399
  if(doc.createEvent) {
1400
    evt = doc.createEvent('MouseEvents');
1401
    evt.initMouseEvent('click', 1, 1, window, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, null);
1402
    if(!a.dispatchEvent(evt))
1403
      return;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1404
  } else if(a.fireEvent) {
1405
    if(!a.fireEvent('onclick'))
1406
      return;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1407
  }
1408
  doc.location = h;
1409
};
1410
/**
1411
 * @constructor
1412
 */
1413
function TagCanvas(cid,lctr,opt) {
1414
  var i, p, c = doc.getElementById(cid), cp = ['id','class','innerHTML'], raf;
1415
1416
  if(!c) throw 0;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1417
  if(Defined(window.G_vmlCanvasManager)) {
1418
    c = window.G_vmlCanvasManager.initElement(c);
1419
    this.ie = parseFloat(navigator.appVersion.split('MSIE')[1]);
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
1420
  }
1421
  if(c && (!c.getContext || !c.getContext('2d').fillText)) {
1422
    p = doc.createElement('DIV');
1423
    for(i = 0; i < cp.length; ++i)
1424
      p[cp[i]] = c[cp[i]];
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1425
    c.parentNode.insertBefore(p,c);
1426
    c.parentNode.removeChild(c);
1427
    throw 0;
1428
  }
1429
  for(i in TagCanvas.options)
1430
    this[i] = opt && Defined(opt[i]) ? opt[i] :
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1431
      (Defined(TagCanvas[i]) ? TagCanvas[i] : TagCanvas.options[i]);
1432
1433
  this.canvas = c;
1434
  this.ctxt = c.getContext('2d');
1435
  this.z1 = 250 / max(this.depth, 0.001);
1436
  this.z2 = this.z1 / this.zoom;
1437
  this.radius = min(c.height, c.width) * 0.0075; // fits radius of 100 in canvas
1438
  this.max_radius = 100;
1439
  this.max_weight = [];
1440
  this.min_weight = [];
1441
  this.textFont = this.textFont && FixFont(this.textFont);
1442
  this.textHeight *= 1;
1443
  this.imageRadius = this.imageRadius.toString();
1444
  this.pulsateTo = Clamp(this.pulsateTo, 0, 1);
1445
  this.minBrightness = Clamp(this.minBrightness, 0, 1);
1446
  this.maxBrightness = Clamp(this.maxBrightness, this.minBrightness, 1);
1447
  this.ctxt.textBaseline = 'top';
1448
  this.lx = (this.lock + '').indexOf('x') + 1;
1449
  this.ly = (this.lock + '').indexOf('y') + 1;
1450
  this.frozen = this.dx = this.dy = this.fixedAnim = this.touchState = 0;
1451
  this.fixedAlpha = 1;
1452
  this.source = lctr || cid;
1453
  this.repeatTags = min(64, ~~this.repeatTags);
1454
  this.minTags = min(200, ~~this.minTags);
1455
  if(~~this.scrollPause > 0)
1456
    TagCanvas.scrollPause = ~~this.scrollPause;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1457
  else
1458
    this.scrollPause = 0;
1459
  if(this.minTags > 0 && this.repeatTags < 1 && (i = this.GetTags().length))
1460
    this.repeatTags = ceil(this.minTags / i) - 1;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1461
  this.transform = Matrix.Identity();
1462
  this.startTime = this.time = TimeNow();
1463
  this.mx = this.my = -1;
1464
  this.centreImage && CentreImage(this);
1465
  this.Animate = this.dragControl ? this.AnimateDrag : this.AnimatePosition;
1466
  this.animTiming = (typeof TagCanvas[this.animTiming] == 'function' ?
1467
    TagCanvas[this.animTiming] : TagCanvas.Smooth);
1468
  if(this.shadowBlur || this.shadowOffset[0] || this.shadowOffset[1]) {
1469
    // let the browser translate "red" into "#ff0000"
1470
    this.ctxt.shadowColor = this.shadow;
1471
    this.shadow = this.ctxt.shadowColor;
1472
    this.shadowAlpha = ShadowAlphaBroken();
1473
  } else {
1474
    delete this.shadow;
1475
  }
1476
  this.Load();
1477
  if(lctr && this.hideTags) {
1478
    (function(t) {
1479
    if(TagCanvas.loaded)
1480
      t.HideTags();
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1481
    else
1482
      AddHandler('load', function() { t.HideTags(); }, window);
1483
    })(this);
1484
  }
1485
1486
  this.yaw = this.initial ? this.initial[0] * this.maxSpeed : 0;
1487
  this.pitch = this.initial ? this.initial[1] * this.maxSpeed : 0;
1488
  if(this.tooltip) {
1489
    this.ctitle = c.title;
1490
    c.title = '';
1491
    if(this.tooltip == 'native') {
1492
      this.Tooltip = this.TooltipNative;
1493
    } else {
1494
      this.Tooltip = this.TooltipDiv;
1495
      if(!this.ttdiv) {
1496
        this.ttdiv = doc.createElement('div');
1497
        this.ttdiv.className = this.tooltipClass;
1498
        this.ttdiv.style.position = 'absolute';
1499
        this.ttdiv.style.zIndex = c.style.zIndex + 1;
1500
        AddHandler('mouseover',function(e){e.target.style.display='none';},this.ttdiv);
1501
        doc.body.appendChild(this.ttdiv);
1502
      }
1503
    }
1504
  } else {
1505
    this.Tooltip = this.TooltipNone;
1506
  }
1507
  if(!this.noMouse && !handlers[cid]) {
1508
    handlers[cid] = [
1509
      ['mousemove', MouseMove],
1510
      ['mouseout', MouseOut],
1511
      ['mouseup', MouseUp],
1512
      ['touchstart', TouchDown],
1513
      ['touchend', TouchUp],
1514
      ['touchcancel', TouchUp],
1515
      ['touchmove', TouchMove]
1516
    ];
1517
    if(this.dragControl) {
1518
      handlers[cid].push(['mousedown', MouseDown]);
1519
      handlers[cid].push(['selectstart', Nop]);
1520
    }
1521
    if(this.wheelZoom) {
1522
      handlers[cid].push(['mousewheel', MouseWheel]);
1523
      handlers[cid].push(['DOMMouseScroll', MouseWheel]);
1524
    }
1525
    if(this.scrollPause) {
1526
      handlers[cid].push(['scroll', Scroll, window]);
1527
    }
1528
    for(i = 0; i < handlers[cid].length; ++i) {
1529
      p = handlers[cid][i];
1530
      AddHandler(p[0], p[1], p[2] ? p[2] : c);
1531
    }
1532
  }
1533
  if(!TagCanvas.started) {
1534
    raf = window.requestAnimationFrame = window.requestAnimationFrame ||
1535
      window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||
1536
      window.msRequestAnimationFrame;
1537
    TagCanvas.NextFrame = raf ? TagCanvas.NextFrameRAF :
1538
      TagCanvas.NextFrameTimeout;
1539
    TagCanvas.interval = this.interval;
1540
    TagCanvas.NextFrame(this.interval);
1541
    TagCanvas.started = 1;
1542
  }
1543
}
1544
TCproto = TagCanvas.prototype;
1545
TCproto.SourceElements = function() {
1546
  if(doc.querySelectorAll)
1547
    return doc.querySelectorAll('#' + this.source);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1548
  return [doc.getElementById(this.source)];
1549
};
1550
TCproto.HideTags = function() {
1551
  var el = this.SourceElements(), i;
1552
  for(i = 0; i < el.length; ++i)
1553
    el[i].style.display = 'none';
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1554
};
1555
TCproto.GetTags = function() {
1556
  var el = this.SourceElements(), etl, tl = [], i, j, k;
1557
  for(k = 0; k <= this.repeatTags; ++k) {
1558
    for(i = 0; i < el.length; ++i) {
1559
      etl = el[i].getElementsByTagName('a');
1560
      for(j = 0; j < etl.length; ++j) {
1561
        tl.push(etl[j]);
1562
      }
1563
    }
1564
  }
1565
  return tl;
1566
};
1567
TCproto.Message = function(text) {
1568
  var tl = [], i, p, tc = text.split(''), a, t, x, z;
1569
  for(i = 0; i < tc.length; ++i) {
1570
    if(tc[i] != ' ') {
1571
      p = i - tc.length / 2;
1572
      a = doc.createElement('A');
1573
      a.href = '#';
1574
      a.innerText = tc[i];
1575
      x = 100 * sin(p / 9);
1576
      z = -100 * cos(p / 9);
1577
      t = new Tag(this, tc[i], a, [x,0,z], 2, 18, '#000', '#fff', 0, 0, 0,
1578
        'monospace', 2, tc[i]);
1579
      t.Init();
1580
      tl.push(t);
1581
    }
1582
  }
1583
  return tl;
1584
};
1585
TCproto.CreateTag = function(e) {
1586
  var im, i, t, txt, ts, font, bc, boc, p = [0, 0, 0];
1587
  if('text' != this.imageMode) {
1588
    im = e.getElementsByTagName('img');
1589
    if(im.length) {
1590
      i = new Image;
0 ignored issues
show
Bug introduced by
The variable Image seems to be never declared. If this is a global, consider adding a /** global: Image */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
1591
      i.src = im[0].src;
1592
1593
      if(!this.imageMode) {
1594
        t = new Tag(this, "", e, p, 0, 0);
1595
        t.SetImage(i);
1596
        //t.Init();
1597
        AddImage(i, im[0], t, this);
1598
        return t;
1599
      }
1600
    }
1601
  }
1602
  if('image' != this.imageMode) {
1603
    ts = new TextSplitter(e);
1604
    txt = ts.Lines();
1605
    if(!ts.Empty()) {
1606
      font = this.textFont || FixFont(GetProperty(e,'font-family'));
1607
      if(this.splitWidth)
1608
        txt = ts.SplitWidth(this.splitWidth, this.ctxt, font, this.textHeight);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1609
1610
      bc = this.bgColour == 'tag' ? GetProperty(e, 'background-color') :
1611
        this.bgColour;
1612
      boc = this.bgOutline == 'tag' ? GetProperty(e, 'color') : this.bgOutline;
1613
    } else {
1614
      ts = null;
1615
    }
1616
  }
1617
  if(ts || i) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if ts || i is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
1618
    t = new Tag(this, txt, e, p, 2, this.textHeight + 2,
0 ignored issues
show
Bug introduced by
The variable txt does not seem to be initialized in case "image" != this.imageMode on line 1602 is false. Are you sure this can never be the case?
Loading history...
1619
      this.textColour || GetProperty(e,'color'), bc, this.bgRadius,
0 ignored issues
show
Bug introduced by
The variable bc seems to not be initialized for all possible execution paths.
Loading history...
1620
      boc, this.bgOutlineThickness, font, this.padding, ts && ts.original);
0 ignored issues
show
Bug introduced by
The variable boc seems to not be initialized for all possible execution paths.
Loading history...
Bug introduced by
The variable font seems to not be initialized for all possible execution paths.
Loading history...
1621
    if(i) {
1622
      t.SetImage(i);
1623
      AddImage(i, im[0], t, this);
0 ignored issues
show
Bug introduced by
The variable im does not seem to be initialized in case "text" != this.imageMode on line 1587 is false. Are you sure this can never be the case?
Loading history...
1624
    } else {
1625
      t.Init();
1626
    }
1627
    return t;
1628
  }
1629
};
1630
TCproto.UpdateTag = function(t, a) {
1631
  var colour = this.textColour || GetProperty(a, 'color'),
1632
    font = this.textFont || FixFont(GetProperty(a, 'font-family')),
1633
    bc = this.bgColour == 'tag' ? GetProperty(a, 'background-color') :
1634
      this.bgColour, boc = this.bgOutline == 'tag' ? GetProperty(a, 'color') :
1635
      this.bgOutline;
1636
  t.a = a;
1637
  t.title = a.title;
1638
  if(t.colour != colour || t.textFont != font || t.bgColour != bc ||
1639
    t.bgOutline != boc)
1640
    t.SetFont(font, colour, bc, boc);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1641
};
1642
TCproto.Weight = function(tl) {
1643
  var ll = tl.length, w, i, s, weights = [], valid,
1644
    wfrom = this.weightFrom ? this.weightFrom.split(/[, ]/) : [null],
1645
    wl = wfrom.length;
1646
  for(i = 0; i < ll; ++i) {
1647
    weights[i] = [];
1648
    for(s = 0; s < wl; ++s) {
1649
      w = FindWeight(tl[i].a, wfrom[s], this.textHeight);
1650
      if(!this.max_weight[s] || w > this.max_weight[s])
1651
        this.max_weight[s] = w;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1652
      if(!this.min_weight[s] || w < this.min_weight[s])
1653
        this.min_weight[s] = w;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1654
      weights[i][s] = w;
1655
    }
1656
  }
1657
  for(s = 0; s < wl; ++s) {
1658
    if(this.max_weight[s] > this.min_weight[s])
1659
      valid = 1;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1660
  }
1661
  if(valid) {
1662
    for(i = 0; i < ll; ++i) {
1663
      tl[i].SetWeight(weights[i]);
1664
    }
1665
  }
1666
};
1667
TCproto.Load = function() {
1668
  var tl = this.GetTags(), taglist = [], shape, t,
1669
    shapeArgs, rx, ry, rz, vl, i, tagmap = [], pfuncs = {
1670
      sphere: PointsOnSphere,
1671
      vcylinder: PointsOnCylinderV,
1672
      hcylinder: PointsOnCylinderH,
1673
      vring: PointsOnRingV,
1674
      hring: PointsOnRingH
1675
    };
1676
1677
  if(tl.length) {
1678
    tagmap.length = tl.length;
1679
    for(i = 0; i < tl.length; ++i)
1680
      tagmap[i] = i;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1681
    this.shuffleTags && Shuffle(tagmap);
1682
    rx = 100 * this.radiusX;
1683
    ry = 100 * this.radiusY;
1684
    rz = 100 * this.radiusZ;
1685
    this.max_radius = max(rx, max(ry, rz));
1686
1687
    for(i = 0; i < tl.length; ++i) {
1688
      t = this.CreateTag(tl[tagmap[i]]);
1689
      if(t)
1690
        taglist.push(t);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1691
    }
1692
    this.weight && this.Weight(taglist, true);
1693
1694
    if(this.shapeArgs) {
1695
      this.shapeArgs[0] = taglist.length;
1696
    } else {
1697
      shapeArgs = this.shape.toString().split(/[(),]/);
1698
      shape = shapeArgs.shift();
1699
      if(typeof window[shape] === 'function')
1700
        this.shape = window[shape];
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1701
      else
1702
        this.shape = pfuncs[shape] || pfuncs.sphere;
1703
      this.shapeArgs = [taglist.length, rx, ry, rz].concat(shapeArgs);
1704
    }
1705
    vl = this.shape.apply(this, this.shapeArgs);
1706
    this.listLength = taglist.length;
1707
    for(i = 0; i < taglist.length; ++i)
1708
      taglist[i].position = new Vector(vl[i][0], vl[i][1], vl[i][2]);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1709
  }
1710
  if(this.noTagsMessage && !taglist.length) {
1711
    i = (this.imageMode && this.imageMode != 'both' ? this.imageMode + ' ': '');
0 ignored issues
show
Complexity Coding Style introduced by
You seem to be assigning a new value to the loop variable i here. Please check if this was indeed your intention. Even if it was, consider using another kind of loop instead.
Loading history...
1712
    taglist = this.Message('No ' + i + 'tags');
1713
  }
1714
  this.taglist = taglist;
1715
};
1716
TCproto.Update = function() {
1717
  var tl = this.GetTags(), newlist = [],
1718
    taglist = this.taglist, found,
1719
    added = [], removed = [], vl, ol, nl, i, j;
1720
1721
  if(!this.shapeArgs)
1722
    return this.Load();
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1723
1724
  if(tl.length) {
1725
    nl = this.listLength = tl.length;
1726
    ol = taglist.length;
1727
1728
    // copy existing list, populate "removed"
1729
    for(i = 0; i < ol; ++i) {
1730
      newlist.push(taglist[i]);
1731
      removed.push(i);
1732
    }
1733
1734
    // find added and removed tags
1735
    for(i = 0; i < nl; ++i) {
1736
      for(j = 0, found = 0; j < ol; ++j) {
1737
        if(taglist[j].EqualTo(tl[i])) {
1738
          this.UpdateTag(newlist[j], tl[i]);
1739
          found = removed[j] = -1;
1740
        }
1741
      }
1742
      if(!found)
1743
        added.push(i);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1744
    }
1745
1746
    // clean out found tags from removed list
1747
    for(i = 0, j = 0; i < ol; ++i) {
1748
      if(removed[j] == -1)
1749
        removed.splice(j,1);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1750
      else
1751
        ++j;
1752
    }
1753
1754
    // insert new tags in gaps where old tags removed
1755
    if(removed.length) {
1756
      Shuffle(removed);
1757
      while(removed.length && added.length) {
1758
        i = removed.shift();
0 ignored issues
show
Complexity Coding Style introduced by
You seem to be assigning a new value to the loop variable i here. Please check if this was indeed your intention. Even if it was, consider using another kind of loop instead.
Loading history...
1759
        j = added.shift();
1760
        newlist[i] = this.CreateTag(tl[j]);
1761
      }
1762
1763
      // remove any more (in reverse order)
1764
      removed.sort(function(a,b) {return a-b});
1765
      while(removed.length) {
1766
        newlist.splice(removed.pop(), 1);
1767
      }
1768
    }
1769
1770
    // add any extra tags
1771
    j = newlist.length / (added.length + 1);
1772
    i = 0;
0 ignored issues
show
Complexity Coding Style introduced by
You seem to be assigning a new value to the loop variable i here. Please check if this was indeed your intention. Even if it was, consider using another kind of loop instead.
Loading history...
1773
    while(added.length) {
1774
      newlist.splice(ceil(++i * j), 0, this.CreateTag(tl[added.shift()]));
1775
    }
1776
1777
    // assign correct positions to tags
1778
    this.shapeArgs[0] = nl = newlist.length;
1779
    vl = this.shape.apply(this, this.shapeArgs);
1780
    for(i = 0; i < nl; ++i)
1781
      newlist[i].position = new Vector(vl[i][0], vl[i][1], vl[i][2]);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1782
1783
    // reweight tags
1784
    this.weight && this.Weight(newlist);
1785
  }
1786
  this.taglist = newlist;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
1787
};
1788
TCproto.SetShadow = function(c) {
1789
  c.shadowBlur = this.shadowBlur;
1790
  c.shadowOffsetX = this.shadowOffset[0];
1791
  c.shadowOffsetY = this.shadowOffset[1];
1792
};
1793
TCproto.Draw = function(t) {
1794
  if(this.paused)
1795
    return;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
1796
  var cv = this.canvas, cw = cv.width, ch = cv.height, max_sc = 0,
1797
    tdelta = (t - this.time) * TagCanvas.interval / 1000,
1798
    x = cw / 2 + this.offsetX, y = ch / 2 + this.offsetY, c = this.ctxt,
1799
    active, a, i, aindex = -1, tl = this.taglist, l = tl.length,
1800
    frontsel = this.frontSelect, centreDrawn = (this.centreFunc == Nop), fixed;
1801
  this.time = t;
1802
  if(this.frozen && this.drawn)
1803
    return this.Animate(cw,ch,tdelta);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1804
  fixed = this.AnimateFixed();
1805
  c.setTransform(1,0,0,1,0,0);
1806
  for(i = 0; i < l; ++i)
1807
    tl[i].Calc(this.transform, this.fixedAlpha);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1808
  tl = SortList(tl, function(a,b) {return b.z-a.z});
1809
1810
  if(fixed && this.fixedAnim.active) {
1811
    active = this.fixedAnim.tag.UpdateActive(c, x, y);
1812
  } else {
1813
    this.active = null;
1814
    for(i = 0; i < l; ++i) {
1815
      a = this.mx >= 0 && this.my >= 0 && this.taglist[i].CheckActive(c, x, y);
1816
      if(a && a.sc > max_sc && (!frontsel || a.z <= 0)) {
1817
        active = a;
1818
        aindex = i;
1819
        active.tag = this.taglist[i];
1820
        max_sc = a.sc;
1821
      }
1822
    }
1823
    this.active = active;
0 ignored issues
show
Bug introduced by
The variable active seems to not be initialized for all possible execution paths.
Loading history...
1824
  }
1825
1826
  this.txtOpt || (this.shadow && this.SetShadow(c));
1827
  c.clearRect(0,0,cw,ch);
1828
  for(i = 0; i < l; ++i) {
1829
    if(!centreDrawn && tl[i].z <= 0) {
1830
      // run the centreFunc if the next tag is at the front
1831
      try { this.centreFunc(c, cw, ch, x, y); }
1832
      catch(e) {
1833
        alert(e);
0 ignored issues
show
Debugging Code Best Practice introduced by
The alert UI element is often considered obtrusive and is generally only used as a temporary measure. Consider replacing it with another UI element.
Loading history...
1834
        // don't run it again
1835
        this.centreFunc = Nop;
1836
      }
1837
      centreDrawn = true;
1838
    }
1839
1840
    if(!(active && active.tag == tl[i] && active.PreDraw(c, tl[i], x, y)))
1841
      tl[i].Draw(c, x, y);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1842
    active && active.tag == tl[i] && active.PostDraw(c);
1843
  }
1844
  if(this.freezeActive && active) {
1845
    this.Freeze();
1846
  } else {
1847
    this.UnFreeze();
1848
    this.drawn = (l == this.listLength);
1849
  }
1850
  if(this.fixedCallback) {
1851
    this.fixedCallback(this,this.fixedCallbackTag);
1852
    this.fixedCallback = null;
1853
  }
1854
  fixed || this.Animate(cw, ch, tdelta);
1855
  active && active.LastDraw(c);
1856
  cv.style.cursor = active ? this.activeCursor : '';
1857
  this.Tooltip(active,this.taglist[aindex]);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
1858
};
1859
TCproto.TooltipNone = function() { };
1860
TCproto.TooltipNative = function(active,tag) {
1861
  if(active)
1862
    this.canvas.title = tag && tag.title ? tag.title : '';
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1863
  else
1864
    this.canvas.title = this.ctitle;
1865
};
1866
TCproto.SetTTDiv = function(title, tag) {
1867
  var tc = this, s = tc.ttdiv.style;
1868
  if(title != tc.ttdiv.innerHTML)
1869
    s.display = 'none';
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1870
  tc.ttdiv.innerHTML = title;
1871
  tag && (tag.title = tc.ttdiv.innerHTML);
1872
  if(s.display == 'none' && ! tc.tttimer) {
1873
    tc.tttimer = setTimeout(function() {
1874
      var p = AbsPos(tc.canvas.id);
1875
      s.display = 'block';
1876
      s.left = p.x + tc.mx + 'px';
1877
      s.top = p.y + tc.my + 24 + 'px';
1878
      tc.tttimer = null;
1879
    }, tc.tooltipDelay);
1880
  }
1881
};
1882
TCproto.TooltipDiv = function(active,tag) {
1883
  if(active && tag && tag.title) {
1884
    this.SetTTDiv(tag.title, tag);
1885
  } else if(!active && this.mx != -1 && this.my != -1 && this.ctitle.length) {
1886
    this.SetTTDiv(this.ctitle);
1887
  } else {
1888
    this.ttdiv.style.display = 'none';
1889
  }
1890
};
1891
TCproto.Transform = function(tc, p, y) {
1892
  if(p || y) {
1893
    var sp = sin(p), cp = cos(p), sy = sin(y), cy = cos(y),
1894
      ym = new Matrix([cy,0,sy, 0,1,0, -sy,0,cy]),
1895
      pm = new Matrix([1,0,0, 0,cp,-sp, 0,sp,cp]);
1896
    tc.transform = tc.transform.mul(ym.mul(pm));
1897
  }
1898
};
1899
TCproto.AnimateFixed = function() {
1900
  var fa, t1, angle, m, d;
1901
  if(this.fadeIn) {
1902
    t1 = TimeNow() - this.startTime;
1903
    if(t1 >= this.fadeIn) {
1904
      this.fadeIn = 0;
1905
      this.fixedAlpha = 1;
1906
    } else {
1907
      this.fixedAlpha = t1 / this.fadeIn;
1908
    }
1909
  }
1910
  if(this.fixedAnim) {
1911
    if(!this.fixedAnim.transform)
1912
      this.fixedAnim.transform = this.transform;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1913
    fa = this.fixedAnim, t1 = TimeNow() - fa.t0, angle = fa.angle,
0 ignored issues
show
Comprehensibility introduced by
Usage of the sequence operator is discouraged, since it may lead to obfuscated code.

The sequence or comma operator allows the inclusion of multiple expressions where only is permitted. The result of the sequence is the value of the last expression.

This operator is most often used in for statements.

Used in another places it can make code hard to read, especially when people do not realize it even exists as a seperate operator.

This check looks for usage of the sequence operator in locations where it is not necessary and could be replaced by a series of expressions or statements.

var a,b,c;

a = 1, b = 1,  c= 3;

could just as well be written as:

var a,b,c;

a = 1;
b = 1;
c = 3;

To learn more about the sequence operator, please refer to the MDN.

Loading history...
1914
      m, d = this.animTiming(fa.t, t1);
0 ignored issues
show
Bug introduced by
The variable m seems to be never initialized.
Loading history...
1915
    this.transform = fa.transform;
1916
    if(t1 >= fa.t) {
1917
      this.fixedCallbackTag = fa.tag;
1918
      this.fixedCallback = fa.cb;
1919
      this.fixedAnim = this.yaw = this.pitch = 0;
1920
    } else {
1921
      angle *= d;
1922
    }
1923
    m = Matrix.Rotation(angle, fa.axis);
1924
    this.transform = this.transform.mul(m);
1925
    return (this.fixedAnim != 0);
0 ignored issues
show
Best Practice introduced by
Comparing this.fixedAnim to 0 using the != operator is not safe. Consider using !== instead.
Loading history...
1926
  }
1927
  return false;
1928
};
1929
TCproto.AnimatePosition = function(w, h, t) {
1930
  var tc = this, x = tc.mx, y = tc.my, s, r;
1931
  if(!tc.frozen && x >= 0 && y >= 0 && x < w && y < h) {
1932
    s = tc.maxSpeed, r = tc.reverse ? -1 : 1;
0 ignored issues
show
Comprehensibility introduced by
Usage of the sequence operator is discouraged, since it may lead to obfuscated code.

The sequence or comma operator allows the inclusion of multiple expressions where only is permitted. The result of the sequence is the value of the last expression.

This operator is most often used in for statements.

Used in another places it can make code hard to read, especially when people do not realize it even exists as a seperate operator.

This check looks for usage of the sequence operator in locations where it is not necessary and could be replaced by a series of expressions or statements.

var a,b,c;

a = 1, b = 1,  c= 3;

could just as well be written as:

var a,b,c;

a = 1;
b = 1;
c = 3;

To learn more about the sequence operator, please refer to the MDN.

Loading history...
1933
    tc.lx || (tc.yaw = ((x * 2 * s / w) - s) * r * t);
1934
    tc.ly || (tc.pitch = ((y * 2 * s / h) - s) * -r * t);
1935
    tc.initial = null;
1936
  } else if(!tc.initial) {
1937
    if(tc.frozen && !tc.freezeDecel)
1938
      tc.yaw = tc.pitch = 0;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1939
    else
1940
      tc.Decel(tc);
1941
  }
1942
  this.Transform(tc, tc.pitch, tc.yaw);
1943
};
1944
TCproto.AnimateDrag = function(w, h, t) {
1945
  var tc = this, rs = 100 * t * tc.maxSpeed / tc.max_radius / tc.zoom;
1946
  if(tc.dx || tc.dy) {
1947
    tc.lx || (tc.yaw = tc.dx * rs / tc.stretchX);
1948
    tc.ly || (tc.pitch = tc.dy * -rs / tc.stretchY);
1949
    tc.dx = tc.dy = 0;
1950
    tc.initial = null;
1951
  } else if(!tc.initial) {
1952
    tc.Decel(tc);
1953
  }
1954
  this.Transform(tc, tc.pitch, tc.yaw);
1955
};
1956
TCproto.Freeze = function() {
1957
  if(!this.frozen) {
1958
    this.preFreeze = [this.yaw, this.pitch];
1959
    this.frozen = 1;
1960
    this.drawn = 0;
1961
  }
1962
};
1963
TCproto.UnFreeze = function() {
1964
  if(this.frozen) {
1965
    this.yaw = this.preFreeze[0];
1966
    this.pitch = this.preFreeze[1];
1967
    this.frozen = 0;
1968
  }
1969
};
1970
TCproto.Decel = function(tc) {
1971
  var s = tc.minSpeed, ay = abs(tc.yaw), ap = abs(tc.pitch);
1972
  if(!tc.lx && ay > s)
1973
    tc.yaw = ay > tc.z0 ? tc.yaw * tc.decel : 0;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1974
  if(!tc.ly && ap > s)
1975
    tc.pitch = ap > tc.z0 ? tc.pitch * tc.decel : 0;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1976
};
1977
TCproto.Zoom = function(r) {
1978
  this.z2 = this.z1 * (1/r);
1979
  this.drawn = 0;
1980
};
1981
TCproto.Clicked = function(e) {
1982
  var a = this.active;
1983
  try {
1984
    if(a && a.tag)
1985
      if(this.clickToFront === false || this.clickToFront === null)
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1986
        a.tag.Clicked(e);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1987
      else
1988
        this.TagToFront(a.tag, this.clickToFront, function() {
1989
          a.tag.Clicked(e);
1990
        }, true);
1991
  } catch(ex) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
1992
  }
1993
};
1994
TCproto.Wheel = function(i) {
1995
  var z = this.zoom + this.zoomStep * (i ? 1 : -1);
1996
  this.zoom = min(this.zoomMax,max(this.zoomMin,z));
1997
  this.Zoom(this.zoom);
1998
};
1999
TCproto.BeginDrag = function(e) {
2000
  this.down = EventXY(e, this.canvas);
2001
  e.cancelBubble = true;
2002
  e.returnValue = false;
2003
  e.preventDefault && e.preventDefault();
2004
};
2005
TCproto.Drag = function(e, p) {
2006
  if(this.dragControl && this.down) {
2007
    var t2 = this.dragThreshold * this.dragThreshold,
2008
      dx = p.x - this.down.x, dy = p.y - this.down.y;
2009
    if(this.dragging || dx * dx + dy * dy > t2) {
2010
      this.dx = dx;
2011
      this.dy = dy;
2012
      this.dragging = 1;
2013
      this.down = p;
2014
    }
2015
  }
2016
  return this.dragging;
2017
};
2018
TCproto.EndDrag = function() {
2019
  var res = this.dragging;
2020
  this.dragging = this.down = null;
2021
  return res;
2022
};
2023
function PinchDistance(e) {
2024
  var t1 = e.targetTouches[0], t2 = e.targetTouches[1];
2025
  return sqrt(pow(t2.pageX - t1.pageX, 2) + pow(t2.pageY - t1.pageY, 2));
2026
}
2027
TCproto.BeginPinch = function(e) {
2028
  this.pinched = [PinchDistance(e), this.zoom];
2029
  e.preventDefault && e.preventDefault();
2030
};
2031
TCproto.Pinch = function(e) {
2032
  var z, d, p = this.pinched;
2033
  if(!p)
2034
    return;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
2035
  d = PinchDistance(e);
2036
  z = p[1] * d / p[0];
2037
  this.zoom = min(this.zoomMax,max(this.zoomMin,z));
2038
  this.Zoom(this.zoom);
2039
};
2040
TCproto.EndPinch = function(e) {
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
2041
  this.pinched = null;
2042
};
2043
TCproto.Pause = function() { this.paused = true; };
2044
TCproto.Resume = function() { this.paused = false; };
2045
TCproto.SetSpeed = function(i) {
2046
  this.initial = i;
2047
  this.yaw = i[0] * this.maxSpeed;
2048
  this.pitch = i[1] * this.maxSpeed;
2049
};
2050
TCproto.FindTag = function(t) {
2051
  if(!Defined(t))
2052
    return null;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
2053
  Defined(t.index) && (t = t.index);
2054
  if(!IsObject(t))
2055
    return this.taglist[t];
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
2056
  var srch, tgt, i;
2057
  if(Defined(t.id))
2058
    srch = 'id', tgt = t.id;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
Comprehensibility introduced by
Usage of the sequence operator is discouraged, since it may lead to obfuscated code.

The sequence or comma operator allows the inclusion of multiple expressions where only is permitted. The result of the sequence is the value of the last expression.

This operator is most often used in for statements.

Used in another places it can make code hard to read, especially when people do not realize it even exists as a seperate operator.

This check looks for usage of the sequence operator in locations where it is not necessary and could be replaced by a series of expressions or statements.

var a,b,c;

a = 1, b = 1,  c= 3;

could just as well be written as:

var a,b,c;

a = 1;
b = 1;
c = 3;

To learn more about the sequence operator, please refer to the MDN.

Loading history...
2059
  else if(Defined(t.text))
2060
    srch = 'innerText', tgt = t.text;
0 ignored issues
show
Comprehensibility introduced by
Usage of the sequence operator is discouraged, since it may lead to obfuscated code.

The sequence or comma operator allows the inclusion of multiple expressions where only is permitted. The result of the sequence is the value of the last expression.

This operator is most often used in for statements.

Used in another places it can make code hard to read, especially when people do not realize it even exists as a seperate operator.

This check looks for usage of the sequence operator in locations where it is not necessary and could be replaced by a series of expressions or statements.

var a,b,c;

a = 1, b = 1,  c= 3;

could just as well be written as:

var a,b,c;

a = 1;
b = 1;
c = 3;

To learn more about the sequence operator, please refer to the MDN.

Loading history...
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
2061
2062
  for(i = 0; i < this.taglist.length; ++i)
2063
    if(this.taglist[i].a[srch] == tgt)
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
Bug introduced by
The variable srch does not seem to be initialized in case Defined(t.text) on line 2059 is false. Are you sure this can never be the case?
Loading history...
Bug introduced by
The variable tgt does not seem to be initialized in case Defined(t.text) on line 2059 is false. Are you sure this can never be the case?
Loading history...
2064
      return this.taglist[i];
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
2065
};
2066
TCproto.RotateTag = function(tag, lt, lg, time, callback, active) {
2067
  var t = tag.Calc(this.transform, 1), v1 = new Vector(t.x, t.y, t.z),
2068
    v2 = MakeVector(lg, lt), angle = v1.angle(v2), u = v1.cross(v2).unit();
2069
  if(angle == 0) {
0 ignored issues
show
Best Practice introduced by
Comparing angle to 0 using the == operator is not safe. Consider using === instead.
Loading history...
2070
    this.fixedCallbackTag = tag;
2071
    this.fixedCallback = callback;
2072
  } else {
2073
    this.fixedAnim = {
2074
      angle: -angle,
2075
      axis: u,
2076
      t: time,
2077
      t0: TimeNow(),
2078
      cb: callback,
2079
      tag: tag,
2080
      active: active
2081
    };
2082
  }
2083
};
2084
TCproto.TagToFront = function(tag, time, callback, active) {
2085
  this.RotateTag(tag, 0, 0, time, callback, active);
2086
};
2087
TagCanvas.Start = function(id,l,o) {
2088
  TagCanvas.Delete(id);
2089
  TagCanvas.tc[id] = new TagCanvas(id,l,o);
2090
};
2091
function tccall(f,id) {
2092
  TagCanvas.tc[id] && TagCanvas.tc[id][f]();
2093
}
2094
TagCanvas.Linear = function(t, t0) { return t0 / t; }
2095
TagCanvas.Smooth = function(t, t0) { return 0.5 - cos(t0 * Math.PI / t) / 2; }
2096
TagCanvas.Pause = function(id) { tccall('Pause',id); };
2097
TagCanvas.Resume = function(id) { tccall('Resume',id); };
2098
TagCanvas.Reload = function(id) { tccall('Load',id); };
2099
TagCanvas.Update = function(id) { tccall('Update',id); };
2100
TagCanvas.SetSpeed = function(id, speed) {
2101
  if(IsObject(speed) && TagCanvas.tc[id] &&
2102
    !isNaN(speed[0]) && !isNaN(speed[1])) {
2103
    TagCanvas.tc[id].SetSpeed(speed);
2104
    return true;
2105
  }
2106
  return false;
2107
};
2108
TagCanvas.TagToFront = function(id, options) {
2109
  if(!IsObject(options))
2110
    return false;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
2111
  options.lat = options.lng = 0;
2112
  return TagCanvas.RotateTag(id, options);
2113
};
2114
TagCanvas.RotateTag = function(id, options) {
2115
  if(IsObject(options) && TagCanvas.tc[id]) {
2116
    if(isNaN(options.time))
2117
      options.time = 500;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
2118
    var tt = TagCanvas.tc[id].FindTag(options);
2119
    if(tt) {
2120
      TagCanvas.tc[id].RotateTag(tt, options.lat, options.lng,
2121
        options.time, options.callback, options.active);
2122
      return true;
2123
    }
2124
  }
2125
  return false;
2126
};
2127
TagCanvas.Delete = function(id) {
2128
  var i, c;
2129
  if(handlers[id]) {
2130
    c = doc.getElementById(id);
2131
    if(c) {
2132
      for(i = 0; i < handlers[id].length; ++i)
2133
        RemoveHandler(handlers[id][i][0], handlers[id][i][1], c);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
2134
    }
2135
  }
2136
  delete handlers[id];
2137
  delete TagCanvas.tc[id];
2138
};
2139
TagCanvas.NextFrameRAF = function() {
2140
  requestAnimationFrame(DrawCanvasRAF);
2141
};
2142
TagCanvas.NextFrameTimeout = function(iv) {
2143
  setTimeout(DrawCanvas, iv);
2144
};
2145
TagCanvas.tc = {};
2146
TagCanvas.options = {
2147
z1: 20000,
2148
z2: 20000,
2149
z0: 0.0002,
2150
freezeActive: true,
2151
freezeDecel: false,
2152
activeCursor: 'pointer',
2153
pulsateTo: 1,
2154
pulsateTime: 3,
2155
reverse: false,
2156
depth: 0.5,
2157
maxSpeed: 0.05,
2158
minSpeed: 0,
2159
decel: 0.95,
2160
interval: 20,
2161
minBrightness: 0.1,
2162
maxBrightness: 1,
2163
outlineColour: '',
2164
outlineThickness: 2,
2165
outlineOffset: 5,
2166
outlineMethod: 'outline',
2167
outlineRadius: 0,
2168
textColour: ['#222', '#000'],
2169
textHeight: 15,
2170
textFont: 'Helvetica, Arial, sans-serif',
2171
shadow: '#111',
2172
shadowBlur: 1,
2173
shadowOffset: [0.1,0.1],
2174
initial: null,
2175
hideTags: false,
2176
zoom: 0,
2177
weight: false,
2178
weightMode: 'size',
2179
weightFrom: null,
2180
weightSize: 1,
2181
weightSizeMin: null,
2182
weightSizeMax: null,
2183
weightGradient: {0:'#f00', 0.33:'#ff0', 0.66:'#0f0', 1:'#00f'},
2184
txtOpt: true,
2185
txtScale: 2,
2186
frontSelect: false,
2187
wheelZoom: true,
2188
zoomMin: 0.8,
2189
zoomMax: 0.8,
2190
zoomStep: 0.05,
2191
shape: 'sphere',
2192
lock: null,
2193
tooltip: null,
2194
tooltipDelay: 300,
2195
tooltipClass: 'tctooltip',
2196
radiusX: 1,
2197
radiusY: 1,
2198
radiusZ: 1,
2199
stretchX: 1,
2200
stretchY: 1,
2201
offsetX: 0,
2202
offsetY: 0,
2203
shuffleTags: false,
2204
noSelect: false,
2205
noMouse: false,
2206
imageScale: 1,
2207
paused: false,
2208
dragControl: false,
2209
dragThreshold: 4,
2210
centreFunc: Nop,
2211
splitWidth: 0,
2212
animTiming: 'Smooth',
2213
clickToFront: false,
2214
fadeIn: 0,
2215
padding: 0,
2216
bgColour: null,
2217
bgRadius: 0,
2218
bgOutline: null,
2219
bgOutlineThickness: 0,
2220
outlineIncrease: 4,
2221
textAlign: 'centre',
2222
textVAlign: 'middle',
2223
imageMode: null,
2224
imagePosition: null,
2225
imagePadding: 2,
2226
imageAlign: 'centre',
2227
imageVAlign: 'middle',
2228
noTagsMessage: true,
2229
centreImage: null,
2230
pinchZoom: false,
2231
repeatTags: 0,
2232
minTags: 0,
2233
imageRadius: 0,
2234
scrollPause: false,
2235
outlineDash: 0,
2236
outlineDashSpace: 0,
2237
outlineDashSpeed: 1
2238
};
2239
for(i in TagCanvas.options) TagCanvas[i] = TagCanvas.options[i];
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
Complexity Coding Style introduced by
You seem to be assigning a new value to the loop variable i here. Please check if this was indeed your intention. Even if it was, consider using another kind of loop instead.
Loading history...
2240
window.TagCanvas = TagCanvas;
2241
// set a flag for when the window has loaded
2242
AddHandler('load',function(){TagCanvas.loaded=1},window);
2243
})();
2244