Passed
Pull Request — master (#3805)
by
unknown
17:20
created

themes/default/scripts/qrcode.js   F

Complexity

Total Complexity 237
Complexity/F 3.29

Size

Lines of Code 604
Function Count 72

Duplication

Duplicated Lines 10
Ratio 1.66 %

Importance

Changes 0
Metric Value
eloc 344
dl 10
loc 604
rs 2
c 0
b 0
f 0
wmc 237
mnd 165
bc 165
fnc 72
bpm 2.2916
cpm 3.2916
noi 73

12 Functions

Rating   Name   Duplication   Size   Complexity  
A qrcode.js ➔ QRCodeModel 0 8 4
B qrcode.js ➔ QR8bitByte 0 37 7
F qrcode.js ➔ _onMakeImage 0 5 17
F qrcode.js ➔ QRPolynomial 0 3 132
B qrcode.js ➔ makeSVG 0 6 6
A qrcode.js ➔ _getAndroid 0 15 3
F qrcode.js ➔ _getTypeNumber 0 35 17
B qrcode.js ➔ QRBitBuffer 0 1 7
B qrcode.js ➔ _isSupportCanvas 0 3 8
D qrcode.js ➔ _safeSetDataURI 0 34 13
C qrcode.js ➔ QRRSBlock 0 1 10
A qrcode.js ➔ _getUTF8Length 0 4 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like themes/default/scripts/qrcode.js 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
 * @fileoverview
3
 * - Using the 'QRCode for Javascript library'
4
 * - Fixed dataset of 'QRCode for Javascript library' for support full-spec.
5
 * - this library has no dependencies.
6
 * 
7
 * @author davidshimjs
8
 * @see <a href="http://www.d-project.com/" target="_blank">http://www.d-project.com/</a>
9
 * @see <a href="http://jeromeetienne.github.com/jquery-qrcode/" target="_blank">http://jeromeetienne.github.com/jquery-qrcode/</a>
10
 */
11
var QRCode;
12
13
(function () {
14
	//---------------------------------------------------------------------
15
	// QRCode for JavaScript
16
	//
17
	// Copyright (c) 2009 Kazuhiko Arase
18
	//
19
	// URL: http://www.d-project.com/
20
	//
21
	// Licensed under the MIT license:
22
	//   http://www.opensource.org/licenses/mit-license.php
23
	//
24
	// The word "QR Code" is registered trademark of 
25
	// DENSO WAVE INCORPORATED
26
	//   http://www.denso-wave.com/qrcode/faqpatent-e.html
27
	//
28
	//---------------------------------------------------------------------
29
	function QR8bitByte(data) {
30
		this.mode = QRMode.MODE_8BIT_BYTE;
31
		this.data = data;
32
		this.parsedData = [];
33
34
		// Added to support UTF-8 Characters
35
		for (var i = 0, l = this.data.length; i < l; i++) {
36
			var byteArray = [];
37
			var code = this.data.charCodeAt(i);
38
39
			if (code > 0x10000) {
40
				byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18);
41
				byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12);
42
				byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6);
43
				byteArray[3] = 0x80 | (code & 0x3F);
44
			} else if (code > 0x800) {
45
				byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12);
46
				byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6);
47
				byteArray[2] = 0x80 | (code & 0x3F);
48
			} else if (code > 0x80) {
49
				byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6);
50
				byteArray[1] = 0x80 | (code & 0x3F);
51
			} else {
52
				byteArray[0] = code;
53
			}
54
55
			this.parsedData.push(byteArray);
56
		}
57
58
		this.parsedData = Array.prototype.concat.apply([], this.parsedData);
59
60
		if (this.parsedData.length != this.data.length) {
61
			this.parsedData.unshift(191);
62
			this.parsedData.unshift(187);
63
			this.parsedData.unshift(239);
64
		}
65
	}
66
67
	QR8bitByte.prototype = {
68
		getLength: function (buffer) {
0 ignored issues
show
Unused Code introduced by
The parameter buffer 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...
69
			return this.parsedData.length;
70
		},
71
		write: function (buffer) {
72
			for (var i = 0, l = this.parsedData.length; i < l; i++) {
73
				buffer.put(this.parsedData[i], 8);
74
			}
75
		}
76
	};
77
78
	function QRCodeModel(typeNumber, errorCorrectLevel) {
79
		this.typeNumber = typeNumber;
80
		this.errorCorrectLevel = errorCorrectLevel;
81
		this.modules = null;
82
		this.moduleCount = 0;
83
		this.dataCache = null;
84
		this.dataList = [];
85
	}
86
87
	QRCodeModel.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData);this.dataCache=null;},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col){throw new Error(row+","+col);}
88
	return this.modules[row][col];},getModuleCount:function(){return this.moduleCount;},make:function(){this.makeImpl(false,this.getBestMaskPattern());},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17;this.modules=new Array(this.moduleCount);for(var row=0;row<this.moduleCount;row++){this.modules[row]=new Array(this.moduleCount);for(var col=0;col<this.moduleCount;col++){this.modules[row][col]=null;}}
0 ignored issues
show
Coding Style Best Practice introduced by
Using the Array constructor is generally discouraged. Consider using an array literal instead.
Loading history...
89
	this.setupPositionProbePattern(0,0);this.setupPositionProbePattern(this.moduleCount-7,0);this.setupPositionProbePattern(0,this.moduleCount-7);this.setupPositionAdjustPattern();this.setupTimingPattern();this.setupTypeInfo(test,maskPattern);if(this.typeNumber>=7){this.setupTypeNumber(test);}
90
	if(this.dataCache==null){this.dataCache=QRCodeModel.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);}
0 ignored issues
show
Best Practice introduced by
Comparing this.dataCache to null using the == operator is not safe. Consider using === instead.
Loading history...
91
	this.mapData(this.dataCache,maskPattern);},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}},getBestMaskPattern:function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i++){this.makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}}
0 ignored issues
show
Best Practice introduced by
Comparing r to 0 using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing i to 0 using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing c to 0 using the == operator is not safe. Consider using === instead.
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...
92
	return pattern;},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth);var cs=1;this.make();for(var row=0;row<this.modules.length;row++){var y=row*cs;for(var col=0;col<this.modules[row].length;col++){var x=col*cs;var dark=this.modules[row][col];if(dark){qr_mc.beginFill(0,100);qr_mc.moveTo(x,y);qr_mc.lineTo(x+cs,y);qr_mc.lineTo(x+cs,y+cs);qr_mc.lineTo(x,y+cs);qr_mc.endFill();}}}
93
	return qr_mc;},setupTimingPattern:function(){for(var r=8;r<this.moduleCount-8;r++){if(this.modules[r][6]!=null){continue;}
0 ignored issues
show
Best Practice introduced by
Comparing this.modules.r.6 to null using the != operator is not safe. Consider using !== instead.
Loading history...
94
	this.modules[r][6]=(r%2==0);}
0 ignored issues
show
Best Practice introduced by
Comparing r % 2 to 0 using the == operator is not safe. Consider using === instead.
Loading history...
95
	for(var c=8;c<this.moduleCount-8;c++){if(this.modules[6][c]!=null){continue;}
0 ignored issues
show
Best Practice introduced by
Comparing this.modules.6.c to null using the != operator is not safe. Consider using !== instead.
Loading history...
96
	this.modules[6][c]=(c%2==0);}},setupPositionAdjustPattern:function(){var pos=QRUtil.getPatternPosition(this.typeNumber);for(var i=0;i<pos.length;i++){for(var j=0;j<pos.length;j++){var row=pos[i];var col=pos[j];if(this.modules[row][col]!=null){continue;}
0 ignored issues
show
Best Practice introduced by
Comparing this.modules.row.col to null using the != operator is not safe. Consider using !== instead.
Loading history...
Best Practice introduced by
Comparing c % 2 to 0 using the == operator is not safe. Consider using === instead.
Loading history...
97 View Code Duplication
	for(var r=-2;r<=2;r++){for(var c=-2;c<=2;c++){if(r==-2||r==2||c==-2||c==2||(r==0&&c==0)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}}}},setupTypeNumber:function(test){var bits=QRUtil.getBCHTypeNumber(this.typeNumber);for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;}
0 ignored issues
show
Best Practice introduced by
Comparing c to 0 using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing r to 0 using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing bits >> i & 1 to 1 using the == operator is not safe. Consider using === instead.
Loading history...
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
98 View Code Duplication
	for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[i%3+this.moduleCount-8-3][Math.floor(i/3)]=mod;}},setupTypeInfo:function(test,maskPattern){var data=(this.errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<6){this.modules[i][8]=mod;}else if(i<8){this.modules[i+1][8]=mod;}else{this.modules[this.moduleCount-15+i][8]=mod;}}
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable i already seems to be declared on line 97. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
Best Practice introduced by
Comparing bits >> i & 1 to 1 using the == operator is not safe. Consider using === instead.
Loading history...
Comprehensibility Naming Best Practice introduced by
The variable mod already seems to be declared on line 97. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
99
	for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<8){this.modules[8][this.moduleCount-i-1]=mod;}else if(i<9){this.modules[8][15-i-1+1]=mod;}else{this.modules[8][15-i-1]=mod;}}
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable mod already seems to be declared on line 98. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
Comprehensibility Naming Best Practice introduced by
The variable i already seems to be declared on line 98. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
100
	this.modules[this.moduleCount-8][8]=(!test);},mapData:function(data,maskPattern){var inc=-1;var row=this.moduleCount-1;var bitIndex=7;var byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col==6)col--;while(true){for(var c=0;c<2;c++){if(this.modules[row][col-c]==null){var dark=false;if(byteIndex<data.length){dark=(((data[byteIndex]>>>bitIndex)&1)==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...
Best Practice introduced by
Comparing data.byteIndex >>> bitIndex & 1 to 1 using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing this.modules.row.col - c to null using the == operator is not safe. Consider using === instead.
Loading history...
101
	var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask){dark=!dark;}
102
	this.modules[row][col-c]=dark;bitIndex--;if(bitIndex==-1){byteIndex++;bitIndex=7;}}}
103
	row+=inc;if(row<0||this.moduleCount<=row){row-=inc;inc=-inc;break;}}}}};QRCodeModel.PAD0=0xEC;QRCodeModel.PAD1=0x11;QRCodeModel.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=new QRBitBuffer();for(var i=0;i<dataList.length;i++){var data=dataList[i];buffer.put(data.mode,4);buffer.put(data.getLength(),QRUtil.getLengthInBits(data.mode,typeNumber));data.write(buffer);}
104
	var totalDataCount=0;for(var i=0;i<rsBlocks.length;i++){totalDataCount+=rsBlocks[i].dataCount;}
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable i already seems to be declared on line 103. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
105
	if(buffer.getLengthInBits()>totalDataCount*8){throw new Error("code length overflow. ("
106
	+buffer.getLengthInBits()
107
	+">"
108
	+totalDataCount*8
109
	+")");}
110
	if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);}
111
	while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);}
0 ignored issues
show
Best Practice introduced by
Comparing buffer.getLengthInBits() % 8 to 0 using the != operator is not safe. Consider using !== instead.
Loading history...
112
	while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;}
113
	buffer.put(QRCodeModel.PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;}
114
	buffer.put(QRCodeModel.PAD1,8);}
115
	return QRCodeModel.createBytes(buffer,rsBlocks);};QRCodeModel.createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r<rsBlocks.length;r++){var dcCount=rsBlocks[r].dataCount;var ecCount=rsBlocks[r].totalCount-dcCount;maxDcCount=Math.max(maxDcCount,dcCount);maxEcCount=Math.max(maxEcCount,ecCount);dcdata[r]=new Array(dcCount);for(var i=0;i<dcdata[r].length;i++){dcdata[r][i]=0xff&buffer.buffer[i+offset];}
0 ignored issues
show
Coding Style Best Practice introduced by
Using the Array constructor is generally discouraged. Consider using an array literal instead.
Loading history...
116
	offset+=dcCount;var rsPoly=QRUtil.getErrorCorrectPolynomial(ecCount);var rawPoly=new QRPolynomial(dcdata[r],rsPoly.getLength()-1);var modPoly=rawPoly.mod(rsPoly);ecdata[r]=new Array(rsPoly.getLength()-1);for(var i=0;i<ecdata[r].length;i++){var modIndex=i+modPoly.getLength()-ecdata[r].length;ecdata[r][i]=(modIndex>=0)?modPoly.get(modIndex):0;}}
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable i already seems to be declared on line 115. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
117
	var totalCodeCount=0;for(var i=0;i<rsBlocks.length;i++){totalCodeCount+=rsBlocks[i].totalCount;}
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable i already seems to be declared on line 115. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
118
	var data=new Array(totalCodeCount);var index=0;for(var i=0;i<maxDcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<dcdata[r].length){data[index++]=dcdata[r][i];}}}
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable r already seems to be declared on line 115. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
Comprehensibility Naming Best Practice introduced by
The variable i already seems to be declared on line 115. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
119
	for(var i=0;i<maxEcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<ecdata[r].length){data[index++]=ecdata[r][i];}}}
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable r already seems to be declared on line 115. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
Comprehensibility Naming Best Practice introduced by
The variable i already seems to be declared on line 115. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
120
	return data;};var QRMode={MODE_NUMBER:1<<0,MODE_ALPHA_NUM:1<<1,MODE_8BIT_BYTE:1<<2,MODE_KANJI:1<<3};var QRErrorCorrectLevel={L:1,M:0,Q:3,H:2};var QRMaskPattern={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};var QRUtil={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:(1<<10)|(1<<8)|(1<<5)|(1<<4)|(1<<2)|(1<<1)|(1<<0),G18:(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<5)|(1<<2)|(1<<0),G15_MASK:(1<<14)|(1<<12)|(1<<10)|(1<<4)|(1<<1),getBCHTypeInfo:function(data){var d=data<<10;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)>=0){d^=(QRUtil.G15<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)));}
121
	return((data<<10)|d)^QRUtil.G15_MASK;},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0){d^=(QRUtil.G18<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)));}
122
	return(data<<12)|d;},getBCHDigit:function(data){var digit=0;while(data!=0){digit++;data>>>=1;}
0 ignored issues
show
Best Practice introduced by
Comparing data to 0 using the != operator is not safe. Consider using !== instead.
Loading history...
123
	return digit;},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1];},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2==0;case QRMaskPattern.PATTERN001:return i%2==0;case QRMaskPattern.PATTERN010:return j%3==0;case QRMaskPattern.PATTERN011:return(i+j)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2==0;case QRMaskPattern.PATTERN101:return(i*j)%2+(i*j)%3==0;case QRMaskPattern.PATTERN110:return((i*j)%2+(i*j)%3)%2==0;case QRMaskPattern.PATTERN111:return((i*j)%3+(i+j)%2)%2==0;default:throw new Error("bad maskPattern:"+maskPattern);}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i<errorCorrectLength;i++){a=a.multiply(new QRPolynomial([1,QRMath.gexp(i)],0));}
0 ignored issues
show
Best Practice introduced by
Comparing i + j % 2 to 0 using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing j % 3 to 0 using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing Math.floor(i / 2) + Math.floor(j / 3) % 2 to 0 using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing i * j % 2 + i * j % 3 % 2 to 0 using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing i * j % 2 + i * j % 3 to 0 using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing i * j % 3 + i + j % 2 % 2 to 0 using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing i + j % 3 to 0 using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing i % 2 to 0 using the == operator is not safe. Consider using === instead.
Loading history...
124 View Code Duplication
	return a;},getLengthInBits:function(mode,type){if(1<=type&&type<10){switch(mode){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw new Error("mode:"+mode);}}else if(type<27){switch(mode){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw new Error("mode:"+mode);}}else if(type<41){switch(mode){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw new Error("mode:"+mode);}}else{throw new Error("type:"+type);}},getLostPoint:function(qrCode){var moduleCount=qrCode.getModuleCount();var lostPoint=0;for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount;col++){var sameCount=0;var dark=qrCode.isDark(row,col);for(var r=-1;r<=1;r++){if(row+r<0||moduleCount<=row+r){continue;}
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
125
	for(var c=-1;c<=1;c++){if(col+c<0||moduleCount<=col+c){continue;}
126
	if(r==0&&c==0){continue;}
0 ignored issues
show
Best Practice introduced by
Comparing r to 0 using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing c to 0 using the == operator is not safe. Consider using === instead.
Loading history...
127
	if(dark==qrCode.isDark(row+r,col+c)){sameCount++;}}}
128
	if(sameCount>5){lostPoint+=(3+sameCount-5);}}}
129 View Code Duplication
	for(var row=0;row<moduleCount-1;row++){for(var col=0;col<moduleCount-1;col++){var count=0;if(qrCode.isDark(row,col))count++;if(qrCode.isDark(row+1,col))count++;if(qrCode.isDark(row,col+1))count++;if(qrCode.isDark(row+1,col+1))count++;if(count==0||count==4){lostPoint+=3;}}}
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable col already seems to be declared on line 124. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

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...
Best Practice introduced by
Comparing count to 0 using the == operator is not safe. Consider using === instead.
Loading history...
Comprehensibility Naming Best Practice introduced by
The variable row already seems to be declared on line 124. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
130 View Code Duplication
	for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount-6;col++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row,col+1)&&qrCode.isDark(row,col+2)&&qrCode.isDark(row,col+3)&&qrCode.isDark(row,col+4)&&!qrCode.isDark(row,col+5)&&qrCode.isDark(row,col+6)){lostPoint+=40;}}}
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable row already seems to be declared on line 124. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
Comprehensibility Naming Best Practice introduced by
The variable col already seems to be declared on line 124. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
131 View Code Duplication
	for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount-6;row++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row+1,col)&&qrCode.isDark(row+2,col)&&qrCode.isDark(row+3,col)&&qrCode.isDark(row+4,col)&&!qrCode.isDark(row+5,col)&&qrCode.isDark(row+6,col)){lostPoint+=40;}}}
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable row already seems to be declared on line 124. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
Comprehensibility Naming Best Practice introduced by
The variable col already seems to be declared on line 124. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
132
	var darkCount=0;for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount;row++){if(qrCode.isDark(row,col)){darkCount++;}}}
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable col already seems to be declared on line 124. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
Comprehensibility Naming Best Practice introduced by
The variable row already seems to be declared on line 124. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
133
	var ratio=Math.abs(100*darkCount/moduleCount/moduleCount-50)/5;lostPoint+=ratio*10;return lostPoint;}};var QRMath={glog:function(n){if(n<1){throw new Error("glog("+n+")");}
134
	return QRMath.LOG_TABLE[n];},gexp:function(n){while(n<0){n+=255;}
135
	while(n>=256){n-=255;}
136
	return QRMath.EXP_TABLE[n];},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(var i=0;i<8;i++){QRMath.EXP_TABLE[i]=1<<i;}
137
	for(var i=8;i<256;i++){QRMath.EXP_TABLE[i]=QRMath.EXP_TABLE[i-4]^QRMath.EXP_TABLE[i-5]^QRMath.EXP_TABLE[i-6]^QRMath.EXP_TABLE[i-8];}
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable i already seems to be declared on line 136. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
138
	for(var i=0;i<255;i++){QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]]=i;}
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable i already seems to be declared on line 136. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
139
	function QRPolynomial(num,shift){if(num.length==undefined){throw new Error(num.length+"/"+shift);}
0 ignored issues
show
Best Practice introduced by
Comparing num.length to undefined using the == operator is not safe. Consider using === instead.
Loading history...
140
	var offset=0;while(offset<num.length&&num[offset]==0){offset++;}
0 ignored issues
show
Best Practice introduced by
Comparing num.offset to 0 using the == operator is not safe. Consider using === instead.
Loading history...
141
	this.num=new Array(num.length-offset+shift);for(var i=0;i<num.length-offset;i++){this.num[i]=num[i+offset];}}
142
	QRPolynomial.prototype={get:function(index){return this.num[index];},getLength:function(){return this.num.length;},multiply:function(e){var num=new Array(this.getLength()+e.getLength()-1);for(var i=0;i<this.getLength();i++){for(var j=0;j<e.getLength();j++){num[i+j]^=QRMath.gexp(QRMath.glog(this.get(i))+QRMath.glog(e.get(j)));}}
143
	return new QRPolynomial(num,0);},mod:function(e){if(this.getLength()-e.getLength()<0){return this;}
144
	var ratio=QRMath.glog(this.get(0))-QRMath.glog(e.get(0));var num=new Array(this.getLength());for(var i=0;i<this.getLength();i++){num[i]=this.get(i);}
0 ignored issues
show
Coding Style Best Practice introduced by
Using the Array constructor is generally discouraged. Consider using an array literal instead.
Loading history...
145
	for(var i=0;i<e.getLength();i++){num[i]^=QRMath.gexp(QRMath.glog(e.get(i))+ratio);}
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable i already seems to be declared on line 144. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
146
	return new QRPolynomial(num,0).mod(e);}};function QRRSBlock(totalCount,dataCount){this.totalCount=totalCount;this.dataCount=dataCount;}
147
	QRRSBlock.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];QRRSBlock.getRSBlocks=function(typeNumber,errorCorrectLevel){var rsBlock=QRRSBlock.getRsBlockTable(typeNumber,errorCorrectLevel);if(rsBlock==undefined){throw new Error("bad rs block @ typeNumber:"+typeNumber+"/errorCorrectLevel:"+errorCorrectLevel);}
0 ignored issues
show
Best Practice introduced by
Comparing rsBlock to undefined using the == operator is not safe. Consider using === instead.
Loading history...
148
	var length=rsBlock.length/3;var list=[];for(var i=0;i<length;i++){var count=rsBlock[i*3+0];var totalCount=rsBlock[i*3+1];var dataCount=rsBlock[i*3+2];for(var j=0;j<count;j++){list.push(new QRRSBlock(totalCount,dataCount));}}
149
	return list;};QRRSBlock.getRsBlockTable=function(typeNumber,errorCorrectLevel){switch(errorCorrectLevel){case QRErrorCorrectLevel.L:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+0];case QRErrorCorrectLevel.M:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+1];case QRErrorCorrectLevel.Q:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+2];case QRErrorCorrectLevel.H:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+3];default:return undefined;}};function QRBitBuffer(){this.buffer=[];this.length=0;}
150
	QRBitBuffer.prototype={get:function(index){var bufIndex=Math.floor(index/8);return((this.buffer[bufIndex]>>>(7-index%8))&1)==1;},put:function(num,length){for(var i=0;i<length;i++){this.putBit(((num>>>(length-i-1))&1)==1);}},getLengthInBits:function(){return this.length;},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex){this.buffer.push(0);}
0 ignored issues
show
Best Practice introduced by
Comparing num >>> length - i - 1 & 1 to 1 using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing this.buffer.bufIndex >>> 7 - index % 8 & 1 to 1 using the == operator is not safe. Consider using === instead.
Loading history...
151
	if(bit){this.buffer[bufIndex]|=(0x80>>>(this.length%8));}
152
	this.length++;}};var QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]];
153
	
154
	function _isSupportCanvas() {
155
		return typeof CanvasRenderingContext2D != "undefined";
0 ignored issues
show
Bug introduced by
The variable CanvasRenderingContext2D seems to be never declared. If this is a global, consider adding a /** global: CanvasRenderingContext2D */ 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...
156
	}
157
	
158
	// android 2.x doesn't support Data-URI spec
159
	function _getAndroid() {
160
		var android = false;
161
		var sAgent = navigator.userAgent;
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...
162
		
163
		if (/android/i.test(sAgent)) { // android
164
			android = true;
165
			var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i);
166
			
167
			if (aMat && aMat[1]) {
168
				android = parseFloat(aMat[1]);
169
			}
170
		}
171
		
172
		return android;
173
	}
174
	
175
	var svgDrawer = (function() {
176
177
		var Drawing = function (el, htOption) {
178
			this._el = el;
179
			this._htOption = htOption;
180
		};
181
182
		Drawing.prototype.draw = function (oQRCode) {
183
			var _htOption = this._htOption;
184
			var _el = this._el;
185
			var nCount = oQRCode.getModuleCount();
186
			var nWidth = Math.floor(_htOption.width / nCount);
0 ignored issues
show
Unused Code introduced by
The variable nWidth seems to be never used. Consider removing it.
Loading history...
187
			var nHeight = Math.floor(_htOption.height / nCount);
0 ignored issues
show
Unused Code introduced by
The variable nHeight seems to be never used. Consider removing it.
Loading history...
188
189
			this.clear();
190
191
			function makeSVG(tag, attrs) {
192
				var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
193
				for (var k in attrs)
194
					if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]);
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...
195
				return el;
196
			}
197
198
			var svg = makeSVG("svg" , {'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 'width': '100%', 'height': '100%', 'fill': _htOption.colorLight});
199
			svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
200
			_el.appendChild(svg);
201
202
			svg.appendChild(makeSVG("rect", {"fill": _htOption.colorLight, "width": "100%", "height": "100%"}));
203
			svg.appendChild(makeSVG("rect", {"fill": _htOption.colorDark, "width": "1", "height": "1", "id": "template"}));
204
205
			for (var row = 0; row < nCount; row++) {
206
				for (var col = 0; col < nCount; col++) {
207
					if (oQRCode.isDark(row, col)) {
208
						var child = makeSVG("use", {"x": String(row), "y": String(col)});
209
						child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template")
210
						svg.appendChild(child);
211
					}
212
				}
213
			}
214
		};
215
		Drawing.prototype.clear = function () {
216
			while (this._el.hasChildNodes())
217
				this._el.removeChild(this._el.lastChild);
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...
218
		};
219
		return Drawing;
220
	})();
221
222
	var useSVG = document.documentElement.tagName.toLowerCase() === "svg";
223
224
	// Drawing in DOM by using Table tag
225
	var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function () {
226
		var Drawing = function (el, htOption) {
227
			this._el = el;
228
			this._htOption = htOption;
229
		};
230
			
231
		/**
232
		 * Draw the QRCode
233
		 * 
234
		 * @param {QRCode} oQRCode
235
		 */
236
		Drawing.prototype.draw = function (oQRCode) {
237
            var _htOption = this._htOption;
238
            var _el = this._el;
239
			var nCount = oQRCode.getModuleCount();
240
			var nWidth = Math.floor(_htOption.width / nCount);
241
			var nHeight = Math.floor(_htOption.height / nCount);
242
			var aHTML = ['<table style="border:0;border-collapse:collapse;">'];
243
			
244
			for (var row = 0; row < nCount; row++) {
245
				aHTML.push('<tr>');
246
				
247
				for (var col = 0; col < nCount; col++) {
248
					aHTML.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:' + nWidth + 'px;height:' + nHeight + 'px;background-color:' + (oQRCode.isDark(row, col) ? _htOption.colorDark : _htOption.colorLight) + ';"></td>');
249
				}
250
				
251
				aHTML.push('</tr>');
252
			}
253
			
254
			aHTML.push('</table>');
255
			_el.innerHTML = aHTML.join('');
256
			
257
			// Fix the margin values as real size.
258
			var elTable = _el.childNodes[0];
259
			var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2;
260
			var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2;
261
			
262
			if (nLeftMarginTable > 0 && nTopMarginTable > 0) {
263
				elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px";	
264
			}
265
		};
266
		
267
		/**
268
		 * Clear the QRCode
269
		 */
270
		Drawing.prototype.clear = function () {
271
			this._el.innerHTML = '';
272
		};
273
		
274
		return Drawing;
275
	})() : (function () { // Drawing in Canvas
276
		function _onMakeImage() {
277
			this._elImage.src = this._elCanvas.toDataURL("image/png");
278
			this._elImage.style.display = "block";
279
			this._elCanvas.style.display = "none";			
280
		}
281
		
282
		// Android 2.1 bug workaround
283
		// http://code.google.com/p/android/issues/detail?id=5141
284
		if (this._android && this._android <= 2.1) {
285
	    	var factor = 1 / window.devicePixelRatio;
286
	        var drawImage = CanvasRenderingContext2D.prototype.drawImage; 
0 ignored issues
show
Bug introduced by
The variable CanvasRenderingContext2D seems to be never declared. If this is a global, consider adding a /** global: CanvasRenderingContext2D */ 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...
287
	    	CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) {
0 ignored issues
show
Unused Code introduced by
The parameter dh 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...
288
	    		if (("nodeName" in image) && /img/i.test(image.nodeName)) {
289
		        	for (var i = arguments.length - 1; i >= 1; i--) {
290
		            	arguments[i] = arguments[i] * factor;
291
		        	}
292
	    		} else if (typeof dw == "undefined") {
293
	    			arguments[1] *= factor;
294
	    			arguments[2] *= factor;
295
	    			arguments[3] *= factor;
296
	    			arguments[4] *= factor;
297
	    		}
298
	    		
299
	        	drawImage.apply(this, arguments); 
300
	    	};
301
		}
302
		
303
		/**
304
		 * Check whether the user's browser supports Data URI or not
305
		 * 
306
		 * @private
307
		 * @param {Function} fSuccess Occurs if it supports Data URI
308
		 * @param {Function} fFail Occurs if it doesn't support Data URI
309
		 */
310
		function _safeSetDataURI(fSuccess, fFail) {
311
            var self = this;
312
            self._fFail = fFail;
313
            self._fSuccess = fSuccess;
314
315
            // Check it just once
316
            if (self._bSupportDataURI === null) {
317
                var el = document.createElement("img");
318
                var fOnError = function() {
319
                    self._bSupportDataURI = false;
320
321
                    if (self._fFail) {
322
                        self._fFail.call(self);
323
                    }
324
                };
325
                var fOnSuccess = function() {
326
                    self._bSupportDataURI = true;
327
328
                    if (self._fSuccess) {
329
                        self._fSuccess.call(self);
330
                    }
331
                };
332
333
                el.onabort = fOnError;
334
                el.onerror = fOnError;
335
                el.onload = fOnSuccess;
336
                el.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data.
337
                return;
0 ignored issues
show
Unused Code introduced by
This return has no effect and can be removed.
Loading history...
338
            } else if (self._bSupportDataURI === true && self._fSuccess) {
339
                self._fSuccess.call(self);
340
            } else if (self._bSupportDataURI === false && self._fFail) {
341
                self._fFail.call(self);
342
            }
343
		};
344
		
345
		/**
346
		 * Drawing QRCode by using canvas
347
		 * 
348
		 * @constructor
349
		 * @param {HTMLElement} el
350
		 * @param {Object} htOption QRCode Options 
351
		 */
352
		var Drawing = function (el, htOption) {
353
    		this._bIsPainted = false;
354
    		this._android = _getAndroid();
355
		
356
			this._htOption = htOption;
357
			this._elCanvas = document.createElement("canvas");
358
			this._elCanvas.width = htOption.width;
359
			this._elCanvas.height = htOption.height;
360
			el.appendChild(this._elCanvas);
361
			this._el = el;
362
			this._oContext = this._elCanvas.getContext("2d");
363
			this._bIsPainted = false;
364
			this._elImage = document.createElement("img");
365
			this._elImage.alt = "Scan me!";
366
			this._elImage.style.display = "none";
367
			this._el.appendChild(this._elImage);
368
			this._bSupportDataURI = null;
369
		};
370
			
371
		/**
372
		 * Draw the QRCode
373
		 * 
374
		 * @param {QRCode} oQRCode 
375
		 */
376
		Drawing.prototype.draw = function (oQRCode) {
377
            var _elImage = this._elImage;
378
            var _oContext = this._oContext;
379
            var _htOption = this._htOption;
380
            
381
			var nCount = oQRCode.getModuleCount();
382
			var nWidth = _htOption.width / nCount;
383
			var nHeight = _htOption.height / nCount;
384
			var nRoundedWidth = Math.round(nWidth);
385
			var nRoundedHeight = Math.round(nHeight);
386
387
			_elImage.style.display = "none";
388
			this.clear();
389
			
390
			for (var row = 0; row < nCount; row++) {
391
				for (var col = 0; col < nCount; col++) {
392
					var bIsDark = oQRCode.isDark(row, col);
393
					var nLeft = col * nWidth;
394
					var nTop = row * nHeight;
395
					_oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;
396
					_oContext.lineWidth = 1;
397
					_oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;					
398
					_oContext.fillRect(nLeft, nTop, nWidth, nHeight);
399
					
400
					// 안티 앨리어싱 방지 처리
401
					_oContext.strokeRect(
402
						Math.floor(nLeft) + 0.5,
403
						Math.floor(nTop) + 0.5,
404
						nRoundedWidth,
405
						nRoundedHeight
406
					);
407
					
408
					_oContext.strokeRect(
409
						Math.ceil(nLeft) - 0.5,
410
						Math.ceil(nTop) - 0.5,
411
						nRoundedWidth,
412
						nRoundedHeight
413
					);
414
				}
415
			}
416
			
417
			this._bIsPainted = true;
418
		};
419
			
420
		/**
421
		 * Make the image from Canvas if the browser supports Data URI.
422
		 */
423
		Drawing.prototype.makeImage = function () {
424
			if (this._bIsPainted) {
425
				_safeSetDataURI.call(this, _onMakeImage);
426
			}
427
		};
428
			
429
		/**
430
		 * Return whether the QRCode is painted or not
431
		 * 
432
		 * @return {Boolean}
433
		 */
434
		Drawing.prototype.isPainted = function () {
435
			return this._bIsPainted;
436
		};
437
		
438
		/**
439
		 * Clear the QRCode
440
		 */
441
		Drawing.prototype.clear = function () {
442
			this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height);
443
			this._bIsPainted = false;
444
		};
445
		
446
		/**
447
		 * @private
448
		 * @param {Number} nNumber
449
		 */
450
		Drawing.prototype.round = function (nNumber) {
451
			if (!nNumber) {
452
				return nNumber;
453
			}
454
			
455
			return Math.floor(nNumber * 1000) / 1000;
456
		};
457
		
458
		return Drawing;
459
	})();
460
	
461
	/**
462
	 * Get the type by string length
463
	 * 
464
	 * @private
465
	 * @param {String} sText
466
	 * @param {Number} nCorrectLevel
467
	 * @return {Number} type
468
	 */
469
	function _getTypeNumber(sText, nCorrectLevel) {			
470
		var nType = 1;
471
		var length = _getUTF8Length(sText);
472
		
473
		for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) {
474
			var nLimit = 0;
475
			
476
			switch (nCorrectLevel) {
477
				case QRErrorCorrectLevel.L :
478
					nLimit = QRCodeLimitLength[i][0];
479
					break;
480
				case QRErrorCorrectLevel.M :
481
					nLimit = QRCodeLimitLength[i][1];
482
					break;
483
				case QRErrorCorrectLevel.Q :
484
					nLimit = QRCodeLimitLength[i][2];
485
					break;
486
				case QRErrorCorrectLevel.H :
487
					nLimit = QRCodeLimitLength[i][3];
488
					break;
489
			}
490
			
491
			if (length <= nLimit) {
492
				break;
493
			} else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
494
				nType++;
495
			}
496
		}
497
		
498
		if (nType > QRCodeLimitLength.length) {
499
			throw new Error("Too long data");
500
		}
501
		
502
		return nType;
503
	}
504
505
	function _getUTF8Length(sText) {
506
		var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a');
507
		return replacedText.length + (replacedText.length != sText ? 3 : 0);
508
	}
509
	
510
	/**
511
	 * @class QRCode
512
	 * @constructor
513
	 * @example 
514
	 * new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie");
515
	 *
516
	 * @example
517
	 * var oQRCode = new QRCode("test", {
518
	 *    text : "http://naver.com",
519
	 *    width : 128,
520
	 *    height : 128
521
	 * });
522
	 * 
523
	 * oQRCode.clear(); // Clear the QRCode.
524
	 * oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode.
525
	 *
526
	 * @param {HTMLElement|String} el target element or 'id' attribute of element.
527
	 * @param {Object|String} vOption
528
	 * @param {String} vOption.text QRCode link data
529
	 * @param {Number} [vOption.width=256]
530
	 * @param {Number} [vOption.height=256]
531
	 * @param {String} [vOption.colorDark="#000000"]
532
	 * @param {String} [vOption.colorLight="#ffffff"]
533
	 * @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H] 
534
	 */
535
	QRCode = function (el, vOption) {
536
		this._htOption = {
537
			width : 256, 
538
			height : 256,
539
			typeNumber : 4,
540
			colorDark : "#000000",
541
			colorLight : "#ffffff",
542
			correctLevel : QRErrorCorrectLevel.H
543
		};
544
		
545
		if (typeof vOption === 'string') {
546
			vOption	= {
547
				text : vOption
548
			};
549
		}
550
		
551
		// Overwrites options
552
		if (vOption) {
553
			for (var i in vOption) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
554
				this._htOption[i] = vOption[i];
555
			}
556
		}
557
		
558
		if (typeof el == "string") {
559
			el = document.getElementById(el);
560
		}
561
562
		if (this._htOption.useSVG) {
563
			Drawing = svgDrawer;
564
		}
565
		
566
		this._android = _getAndroid();
567
		this._el = el;
568
		this._oQRCode = null;
569
		this._oDrawing = new Drawing(this._el, this._htOption);
570
		
571
		if (this._htOption.text) {
572
			this.makeCode(this._htOption.text);	
573
		}
574
	};
575
	
576
	/**
577
	 * Make the QRCode
578
	 * 
579
	 * @param {String} sText link data
580
	 */
581
	QRCode.prototype.makeCode = function (sText) {
582
		this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel);
583
		this._oQRCode.addData(sText);
584
		this._oQRCode.make();
585
		this._el.title = sText;
586
		this._oDrawing.draw(this._oQRCode);			
587
		this.makeImage();
588
	};
589
	
590
	/**
591
	 * Make the Image from Canvas element
592
	 * - It occurs automatically
593
	 * - Android below 3 doesn't support Data-URI spec.
594
	 * 
595
	 * @private
596
	 */
597
	QRCode.prototype.makeImage = function () {
598
		if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) {
599
			this._oDrawing.makeImage();
600
		}
601
	};
602
	
603
	/**
604
	 * Clear the QRCode
605
	 */
606
	QRCode.prototype.clear = function () {
607
		this._oDrawing.clear();
608
	};
609
	
610
	/**
611
	 * @name QRCode.CorrectLevel
612
	 */
613
	QRCode.CorrectLevel = QRErrorCorrectLevel;
614
})();
615