From e7ba46a9ca3e110abd9db4581b19d9f69eaf42d9 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 2 Aug 2013 15:55:35 +0000 Subject: [PATCH 001/218] chore(rest) "){" -> ") {" --- lib/server/rest.js | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/server/rest.js b/lib/server/rest.js index 2be9152b..e323f287 100644 --- a/lib/server/rest.js +++ b/lib/server/rest.js @@ -30,12 +30,12 @@ */ exports.api = function(pParams){ var lRet = main.checkParams(pParams); - if(lRet){ + if (lRet) { var lAPIURL = main.config.api_url, p = pParams; lRet = Util.isContainStr(p.name, lAPIURL); - if( lRet ){ + if (lRet) { p.name = Util.removeStrOneTime(p.name, lAPIURL); sendData( pParams); } @@ -92,14 +92,15 @@ } function onFS(pParams){ - var p, lError, lWriteStream, lSize, lQuery, + var p, lError, lReadStream, lWriteStream, lSize, lQuery, lRet = main.checkParams(pParams); - if(lRet){ + + if (lRet){ p = pParams, lQuery = main.getQuery(p.request); - p.name = Util.removeStrOneTime(p.name, CloudFunc.FS) || '/'; - switch(p.request.method){ + + switch (p.request.method){ case 'GET': if( Util.strCmp(lQuery, 'size') ) dir.getSize(p.name, function(pErr, pSize){ @@ -113,10 +114,10 @@ }); else fs.stat(p.name, function(pError, pStat){ - if(!pError) - if( pStat.isDirectory() ) + if (!pError) + if (pStat.isDirectory()) main.commander.getDirContent(p.name, function(pError, pData){ - if(!pError){ + if (!pError){ p.name += '.json'; p.data = Util.stringifyJSON(pData); main.sendResponse(p); @@ -134,8 +135,8 @@ case 'PUT': if (lQuery === 'dir') - fs.mkdir(p.name, function(pError){ - if(!pError) + fs.mkdir(p.name, function(pError) { + if (!pError) main.sendResponse(pParams, 'Folder ' + p.name + ' created.'); else main.sendError(pParams, pError); From 57329e4472c97cad14b3c2eef8f93c720fb77ada Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 2 Aug 2013 15:57:04 +0000 Subject: [PATCH 002/218] feature(rest) add zip --- lib/server/rest.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/server/rest.js b/lib/server/rest.js index e323f287..4bb9f9ab 100644 --- a/lib/server/rest.js +++ b/lib/server/rest.js @@ -18,6 +18,7 @@ path = main.path, Util = main.util, CloudFunc = main.cloudfunc, + zlib = main.zlib, dir = main.dir, OK = 200, Header = main.generateHeaders({ @@ -141,7 +142,26 @@ else main.sendError(pParams, pError); }); - else { + else if (lQuery === 'zip') { + lReadStream = fs.createReadStream(p.name); + lWriteStream = fs.createWriteStream(p.name + '.zip'); + + lError = function(pError) { + main.sendError(pParams, pError); + }; + + lWriteStream.on('error', lError); + lReadStream.on('error', lError); + + lWriteStream.on('open', function() { + lReadStream.pipe(zlib.createGzip()).pipe(lWriteStream); + //p.request.pipe(process.stdout); + lReadStream.on('end', function() { + var lName = path.basename(p.name) + '.zip'; + main.sendResponse(pParams, 'save: ok("' + lName +'")'); + }); + }); + } else { lWriteStream = fs.createWriteStream(p.name); lError = function(pError) { From c2055bbbf06e2b300071fff0f319d0ab6b4a7cdb Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 2 Aug 2013 19:00:18 +0300 Subject: [PATCH 003/218] doc(readme) "=" -> "-" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aa364275..d29075d8 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ There is a short list: - **F6** - rename/move - **F7** - new dir - **F8, Delete** - remove current file -- **F9** = menu +- **F9** - menu - **Ctrl + r** - reload dir content - **Ctrl + d** - clear local cache (wich contains dir contents) - **Alt + q** - disable key bindings From 217acccda379aa9f9da5705bc12742b9fb46530e Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 2 Aug 2013 18:25:25 +0000 Subject: [PATCH 004/218] refactor(rest) zip --- ChangeLog | 5 +++++ lib/server/rest.js | 48 ++++++++++++++++++++-------------------------- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1f8aebfe..5a12a908 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2012.*.*, v0.3.1 +feature: +* (rest) add zip + + 2012.07.01, v0.3.0 * Changed jquery cdn to one with https suport jquery.com -> google cdn. diff --git a/lib/server/rest.js b/lib/server/rest.js index 4bb9f9ab..5b20c4f9 100644 --- a/lib/server/rest.js +++ b/lib/server/rest.js @@ -93,7 +93,7 @@ } function onFS(pParams){ - var p, lError, lReadStream, lWriteStream, lSize, lQuery, + var p, lError, lMsg, lName, lZlib, lZipStream, lReadStream, lWriteStream, lSize, lQuery, lRet = main.checkParams(pParams); if (lRet){ @@ -142,11 +142,23 @@ else main.sendError(pParams, pError); }); - else if (lQuery === 'zip') { - lReadStream = fs.createReadStream(p.name); - lWriteStream = fs.createWriteStream(p.name + '.zip'); + else { + lName = p.name; - lError = function(pError) { + if (lQuery === 'zip') { + lZlib = zlib.createGzip(); + lReadStream = fs.createReadStream(lName); + lReadStream = lReadStream.pipe(lZlib); + lName += '.' + lQuery; + lMsg = lQuery; + } else { + lReadStream = p.request; + lMsg = 'save'; + } + + lWriteStream = fs.createWriteStream(lName); + + lError = function(pError) { main.sendError(pParams, pError); }; @@ -154,29 +166,11 @@ lReadStream.on('error', lError); lWriteStream.on('open', function() { - lReadStream.pipe(zlib.createGzip()).pipe(lWriteStream); - //p.request.pipe(process.stdout); + lReadStream.pipe(lWriteStream); + lReadStream.on('end', function() { - var lName = path.basename(p.name) + '.zip'; - main.sendResponse(pParams, 'save: ok("' + lName +'")'); - }); - }); - } else { - lWriteStream = fs.createWriteStream(p.name); - - lError = function(pError) { - main.sendError(pParams, pError); - }; - - lWriteStream.on('error', lError); - p.request.on('error', lError); - - lWriteStream.on('open', function() { - p.request.pipe(lWriteStream); - //p.request.pipe(process.stdout); - p.request.on('end', function() { - var lName = path.basename(p.name); - main.sendResponse(pParams, 'save: ok("' + lName +'")'); + lName = path.basename(lName); + main.sendResponse(pParams, lMsg + ': ok("' + lName +'")'); }); }); } From 4eaca18dd3f0af193308aeca4717686340635c8c Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 2 Aug 2013 18:28:09 +0000 Subject: [PATCH 005/218] chore(rest) "deleted" -> "delete: ok" --- lib/server/rest.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/server/rest.js b/lib/server/rest.js index 5b20c4f9..42570cc9 100644 --- a/lib/server/rest.js +++ b/lib/server/rest.js @@ -142,6 +142,7 @@ else main.sendError(pParams, pError); }); + else { lName = p.name; @@ -179,7 +180,7 @@ if(lQuery === 'dir') fs.rmdir(p.name, function(pError){ if(!pError) - main.sendResponse(pParams, 'Folder ' + p.name + ' deleted.'); + main.sendResponse(pParams, 'delete: ok("' + p.name + '")'); else main.sendError(pParams, pError); }); @@ -213,7 +214,7 @@ fs.unlink(d.name, log); if(lAssync === n && !p.error) - main.sendResponse(pParams, 'Files deleted: ' + pBody); + main.sendResponse(pParams, 'delete: ok("' + pBody + '")'); } } @@ -229,7 +230,7 @@ }else fs.unlink(p.name, function(pError){ if(!pError) - main.sendResponse(pParams, 'File ' + p.name + ' delete.'); + main.sendResponse(pParams, 'delete: ok(' + p.name + '")'); else main.sendError(pParams, pError); }); From 2478fb6ad82497e39bc09ef3375ae5355854e201 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 5 Aug 2013 09:01:32 +0000 Subject: [PATCH 006/218] doc(readme) fix date --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d29075d8..0386d174 100644 --- a/README.md +++ b/README.md @@ -264,9 +264,9 @@ so to get it you should type a couple more commands: Version history --------------- -- *2012.07.01*, **[v0.3.0](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.3.0.zip)** -- *2012.04.22*, **[v0.2.0](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.2.0.zip)** -- *2012.03.01*, **[v0.1.9](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.1.9.zip)** +- *2013.07.01*, **[v0.3.0](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.3.0.zip)** +- *2013.04.22*, **[v0.2.0](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.2.0.zip)** +- *2013.03.01*, **[v0.1.9](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.1.9.zip)** - *2012.12.12*, **[v0.1.8](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.1.8.zip)** - *2012.10.01*, **[v0.1.7](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.1.7.zip)** - *2012.08.24*, **[v0.1.6](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.1.6.zip)** From e595243c3525d5805bf37da1d8dd38bb798b6d9e Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 5 Aug 2013 14:01:56 +0000 Subject: [PATCH 007/218] feature(css) .cmd-button: add transition --- css/style.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/css/style.css b/css/style.css index 840ba253..18ddf969 100644 --- a/css/style.css +++ b/css/style.css @@ -106,17 +106,20 @@ body { text-overflow: ellipsis; overflow: hidden; outline: 0; + transition: ease 0.1s; white-space: nowrap; width: 8%; } .cmd-button:hover { border: 1.5px solid rgb(0,0,0); + transition: ease 0.5s; } .cmd-button:active { color: white; background-color: rgb(49,123,249); + transition: ease 0.1s; } .clear-cache { From 04ee992d1c5607f532d98076a10767e4a481ea59 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 5 Aug 2013 14:03:33 +0000 Subject: [PATCH 008/218] style(css) .path-icon: add " " --- css/style.css | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/css/style.css b/css/style.css index 18ddf969..2a39869f 100644 --- a/css/style.css +++ b/css/style.css @@ -44,17 +44,16 @@ body { } .path-icon { - position: relative; - top: 3px; - left: -4px; - display: inline-block; - /* размер иконки и позиция на png-файле*/ - width: 15px; - height: 15px; - font-family:'FoundationIconsGeneralEnclosed'; - font-size:30px; - color: #46A4C3;/*#55BF3F; green*/ - text-shadow:black 0 2px 1px; + position : relative; + top : 3px; + left : -4px; + display : inline-block; + width : 15px; + height : 15px; + font-family :'FoundationIconsGeneralEnclosed'; + font-size :30px; + color : #46A4C3;/*#55BF3F; green*/ + text-shadow :black 0 2px 1px; } .path-icon:hover { cursor:pointer; From 49c41f9452812f1475c9270115d899689424b086 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 5 Aug 2013 17:07:14 +0300 Subject: [PATCH 009/218] chore(readme) A -> a --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0386d174..10acd342 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ There is a short list: - **Ctrl + d** - clear local cache (wich contains dir contents) - **Alt + q** - disable key bindings - **Alt + s** - get all key bindings back -- **Ctrl + A** - select all files in a panel +- **Ctrl + a** - select all files in a panel - **up, down, enter** - filesystem navigation - **Tab** - move thru panels - **Page Up** - up on one page From 2af2cf83e50d069ebd8060f6dd9d1838dc1ef3bd Mon Sep 17 00:00:00 2001 From: coderaiser Date: Tue, 6 Aug 2013 11:50:56 +0000 Subject: [PATCH 010/218] chore(css) .panel: mv margin, padding to style.css --- css/reset.css | 9 --------- css/style.css | 2 ++ 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/css/reset.css b/css/reset.css index f6003d74..9a0cb0f5 100644 --- a/css/reset.css +++ b/css/reset.css @@ -37,15 +37,6 @@ a:focus { outline: thin dotted; } /* Improve readability when focused and hovered in all browsers: h5bp.com/h */ a:hover, a:active { outline: 0; } -/* changed ul to panel, it using only in this case for now, and will css - * processing cost 33% with name of tag, so it should be match faster - */ -.panel{ - /* removed default margins */ - padding: 20px; - margin: 0; -} - /* * 1. Display hand cursor for clickable form elements * 2. Allow styling of clickable form elements in iOS diff --git a/css/style.css b/css/style.css index 2a39869f..24dbf4df 100644 --- a/css/style.css +++ b/css/style.css @@ -198,6 +198,8 @@ body { width: 46%; overflow-y: auto; border: 1.5px solid rgba(49, 123, 249, .40); + margin: 0; + padding: 20px; } #keyspanel{ text-align: center; From dd05252eff62f74ae49402d7f561adf032de1bd9 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Tue, 6 Aug 2013 12:32:47 +0000 Subject: [PATCH 011/218] refactor(css) path-icon: rm font-family, font-size --- css/style.css | 2 -- 1 file changed, 2 deletions(-) diff --git a/css/style.css b/css/style.css index 24dbf4df..f0b31006 100644 --- a/css/style.css +++ b/css/style.css @@ -50,8 +50,6 @@ body { display : inline-block; width : 15px; height : 15px; - font-family :'FoundationIconsGeneralEnclosed'; - font-size :30px; color : #46A4C3;/*#55BF3F; green*/ text-shadow :black 0 2px 1px; } From fc98e1ec5034ea46508258debae646f27ac4953e Mon Sep 17 00:00:00 2001 From: coderaiser Date: Tue, 6 Aug 2013 12:42:24 +0000 Subject: [PATCH 012/218] refactor(css) rm !important --- css/style.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/css/style.css b/css/style.css index f0b31006..b1362d92 100644 --- a/css/style.css +++ b/css/style.css @@ -260,7 +260,7 @@ a:hover, a:active { /* responsive design */ @media only screen and (max-width: 600px){ .panel{ - width:94% !important; + width:94%; } /* если правая панель не помещаеться - прячем её */ #right{ @@ -356,7 +356,7 @@ a:hover, a:active { } @media only screen and (min-width: 601px) and (max-width: 785px){ .panel{ - width:94% !important; + width:94%; } #right{ display:none; @@ -369,7 +369,7 @@ a:hover, a:active { @media only screen and (min-width:786px) and (max-width: 1155px){ .panel{ - width:94% !important; + width:94%; } /* если правая панель не помещаеться - прячем её */ #right{ From e10419afb6b354216e619dea79d9d4b40390f5db Mon Sep 17 00:00:00 2001 From: coderaiser Date: Tue, 6 Aug 2013 13:00:45 +0000 Subject: [PATCH 013/218] fix(css) .icon: {width, height: 16px -> 15.5px} --- css/style.css | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/css/style.css b/css/style.css index b1362d92..ac3978cf 100644 --- a/css/style.css +++ b/css/style.css @@ -62,12 +62,11 @@ body { text-shadow:black 0 0 1px; } .icon { - display:inline-block; - width:16px; - height:16px; - margin-left:0.5%; - /* font-family: 'GeneralFoundicons'; */ - font-family: 'Fontello'; + display : inline-block; + font-family : 'Fontello'; + height : 15.5px; + margin-left : 0.5%; + width : 15.5px; } .error::before { position: relative; From 17eb39256273753b2cb9700ec0193961e53e94a3 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Tue, 6 Aug 2013 14:10:22 +0000 Subject: [PATCH 014/218] feature(shell) add log --- shell/log.sh | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100755 shell/log.sh diff --git a/shell/log.sh b/shell/log.sh new file mode 100755 index 00000000..7f79a617 --- /dev/null +++ b/shell/log.sh @@ -0,0 +1,9 @@ +#!/bin/sh +if test -z $1 + then + echo "log.sh " + else + git log $1..HEAD --pretty=format:"* %s" --grep feature + git log $1..HEAD --pretty=format:"* %s" --grep fix + git log $1..HEAD --pretty=format:"* %s" --grep refactor +fi \ No newline at end of file From 75573d12a5061838f0d95d58f1fbd36e201be435 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Tue, 6 Aug 2013 14:32:46 +0000 Subject: [PATCH 015/218] chore(css) .current-file: border -> box-shadow --- css/style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/css/style.css b/css/style.css index ac3978cf..ecdc5f96 100644 --- a/css/style.css +++ b/css/style.css @@ -181,7 +181,7 @@ body { /* фон файла, на котором курсор*/ .current-file { - border: 1.5px solid rgba(49, 123, 249, .40); + box-shadow: inset 0 0 2px rgb(49, 123, 249); } .selected-file, .selected-file .name > a{ From 44eaad8461adc9eb0ef41fafc59a8cda623302f1 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Tue, 6 Aug 2013 14:37:10 +0000 Subject: [PATCH 016/218] style(css) add " ", "\n" --- css/style.css | 64 ++++++++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 36 deletions(-) diff --git a/css/style.css b/css/style.css index ecdc5f96..afb5bcf0 100644 --- a/css/style.css +++ b/css/style.css @@ -53,14 +53,17 @@ body { color : #46A4C3;/*#55BF3F; green*/ text-shadow :black 0 2px 1px; } + .path-icon:hover { cursor:pointer; } + .path-icon:active { position: relative; top: 4px; text-shadow:black 0 0 1px; -} +} + .icon { display : inline-block; font-family : 'Fontello'; @@ -68,6 +71,7 @@ body { margin-left : 0.5%; width : 15.5px; } + .error::before { position: relative; font-size: 14px; @@ -75,6 +79,7 @@ body { cursor :default; content: '\2757'; } + .loading { position:relative; top:1px; @@ -179,7 +184,6 @@ body { float:left; } -/* фон файла, на котором курсор*/ .current-file { box-shadow: inset 0 0 2px rgb(49, 123, 249); } @@ -198,34 +202,23 @@ body { margin: 0; padding: 20px; } + #keyspanel{ text-align: center; } -/* информация о файлах и папках*/ .name { float: left; width: 35%; - /* если длина имени файла больше 16 символов - * отрезаем лишнее, оставляя лишь 16, - * и добавляем две точки и тайтл - */ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } + .size { float:left; width:16%; - /* Ставим отступ, что бы - * size не налазил на uid - * (owner) - */ margin-right: 27px; - /* Ставим выравнивание, - * что бы размер был в - * одной ровной колонке - */ text-align: right; } .mode { @@ -233,23 +226,21 @@ body { width: 23%; } -/* changin ul to panel for high speed parsing*/ -.panel, li{ - list-style-type:none; - /* making cursor just arrow, - * not text editing cursor - */ - cursor:default; +.panel, li { + list-style-type: none; + cursor: default; } -button{ + +button { width:10%; } -a{ + +a { text-decoration:none; } a:hover, a:active { - color: #06e; - cursor:pointer; + color : #06e; + cursor: pointer; } /* Если размер окна очень маленький @@ -257,12 +248,12 @@ a:hover, a:active { * друг-под-другом */ /* responsive design */ -@media only screen and (max-width: 600px){ - .panel{ +@media only screen and (max-width: 600px) { + .panel { width:94%; } /* если правая панель не помещаеться - прячем её */ - #right{ + #right { display:none; } /* текущий файл под курсором */ @@ -310,7 +301,8 @@ a:hover, a:active { /* убираем заголовок*/ .fm_header { display:none; - } + } + .mode,.size,.owner { /* располагаем элементы * один под другим @@ -353,11 +345,11 @@ a:hover, a:active { width: 20%; } } -@media only screen and (min-width: 601px) and (max-width: 785px){ - .panel{ +@media only screen and (min-width: 601px) and (max-width: 785px) { + .panel { width:94%; } - #right{ + #right { display:none; } @@ -366,12 +358,12 @@ a:hover, a:active { } } -@media only screen and (min-width:786px) and (max-width: 1155px){ - .panel{ +@media only screen and (min-width:786px) and (max-width: 1155px) { + .panel { width:94%; } /* если правая панель не помещаеться - прячем её */ - #right{ + #right { display:none; } From 4c89ec346b0acccd02dcac3847c8269e753c3b0a Mon Sep 17 00:00:00 2001 From: coderaiser Date: Tue, 6 Aug 2013 14:40:39 +0000 Subject: [PATCH 017/218] feature(css) .current-file: add transition --- css/style.css | 1 + 1 file changed, 1 insertion(+) diff --git a/css/style.css b/css/style.css index afb5bcf0..d71b8634 100644 --- a/css/style.css +++ b/css/style.css @@ -186,6 +186,7 @@ body { .current-file { box-shadow: inset 0 0 2px rgb(49, 123, 249); + transition: ease 0.05s; } .selected-file, .selected-file .name > a{ From 47288f0f6ec484f06a7ff50b39f4ead9ee85634d Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 8 Aug 2013 10:10:21 +0000 Subject: [PATCH 018/218] style(rest) "){" -> ") {" --- lib/server/rest.js | 449 +++++++++++++++++++++++---------------------- 1 file changed, 226 insertions(+), 223 deletions(-) diff --git a/lib/server/rest.js b/lib/server/rest.js index 42570cc9..df19b415 100644 --- a/lib/server/rest.js +++ b/lib/server/rest.js @@ -1,9 +1,9 @@ /* RESTfull module */ -(function(){ +(function() { 'use strict'; - if(!global.cloudcmd) + if (!global.cloudcmd) return console.log( '# rest.js' + '\n' + '# -----------' + '\n' + @@ -29,8 +29,9 @@ * rest interface * @pParams {request, responce} */ - exports.api = function(pParams){ + exports.api = function(pParams) { var lRet = main.checkParams(pParams); + if (lRet) { var lAPIURL = main.config.api_url, p = pParams; @@ -50,7 +51,7 @@ * @param pRes * @param pData */ - function send(pParams){ + function send(pParams) { var lRes = pParams.response, lData = pParams.data; @@ -63,12 +64,12 @@ * * @param pParams {command, method, body, requrest, response} */ - function sendData(pParams){ + function sendData(pParams) { var p, lRet = main.checkParams(pParams); if(lRet){ - p = pParams; - + p = pParams; lRet = Util.isContainStrAtBegin(p.name, CloudFunc.FS); + if (lRet) onFS(pParams); else { @@ -92,7 +93,7 @@ return lRet; } - function onFS(pParams){ + function onFS(pParams) { var p, lError, lMsg, lName, lZlib, lZipStream, lReadStream, lWriteStream, lSize, lQuery, lRet = main.checkParams(pParams); @@ -101,143 +102,144 @@ lQuery = main.getQuery(p.request); p.name = Util.removeStrOneTime(p.name, CloudFunc.FS) || '/'; - switch (p.request.method){ - case 'GET': - if( Util.strCmp(lQuery, 'size') ) - dir.getSize(p.name, function(pErr, pSize){ - if (!pErr){ - lSize = CloudFunc.getShortSize(pSize); - Util.log(lSize); - main.sendResponse(p, lSize); - } - else - main.sendError(p, pErr); - }); - else - fs.stat(p.name, function(pError, pStat){ - if (!pError) - if (pStat.isDirectory()) - main.commander.getDirContent(p.name, function(pError, pData){ - if (!pError){ - p.name += '.json'; - p.data = Util.stringifyJSON(pData); - main.sendResponse(p); - } - else - main.sendError(p, pError); - }); - else - main.sendFile(p); - else - main.sendError(p, pError); - - }); - break; - - case 'PUT': - if (lQuery === 'dir') - fs.mkdir(p.name, function(pError) { - if (!pError) - main.sendResponse(pParams, 'Folder ' + p.name + ' created.'); - else - main.sendError(pParams, pError); - }); - - else { - lName = p.name; - - if (lQuery === 'zip') { - lZlib = zlib.createGzip(); - lReadStream = fs.createReadStream(lName); - lReadStream = lReadStream.pipe(lZlib); - lName += '.' + lQuery; - lMsg = lQuery; - } else { - lReadStream = p.request; - lMsg = 'save'; + switch (p.request.method) { + case 'GET': + if( Util.strCmp(lQuery, 'size') ) + dir.getSize(p.name, function(pErr, pSize) { + if (!pErr){ + lSize = CloudFunc.getShortSize(pSize); + Util.log(lSize); + main.sendResponse(p, lSize); } - - lWriteStream = fs.createWriteStream(lName); - - lError = function(pError) { - main.sendError(pParams, pError); - }; - - lWriteStream.on('error', lError); - lReadStream.on('error', lError); - - lWriteStream.on('open', function() { - lReadStream.pipe(lWriteStream); - - lReadStream.on('end', function() { - lName = path.basename(lName); - main.sendResponse(pParams, lMsg + ': ok("' + lName +'")'); - }); - }); - } - break; - case 'DELETE': - if(lQuery === 'dir') - fs.rmdir(p.name, function(pError){ - if(!pError) - main.sendResponse(pParams, 'delete: ok("' + p.name + '")'); - else - main.sendError(pParams, pError); - }); - else if(lQuery === 'files'){ - getBody(p.request, function(pBody){ - var lFiles = Util.parseJSON(pBody), - n = lFiles.length, - lDir = p.name, - log = Util.retExec(Util.log), - lAssync = 0; - - function stat(pStat){ - var lRet = Util.checkObjTrue(pStat, 'params') && - Util.checkObjTrue(pStat.params, 'name'); - - if(lRet){ - var p = pStat, - d = p.params; - - ++lAssync; - - if( p.error ){ - main.sendError(pParams, p.error); - Util.log(p.error); + else + main.sendError(p, pErr); + }); + else + fs.stat(p.name, function(pError, pStat) { + if (!pError) + if (pStat.isDirectory()) + main.commander.getDirContent(p.name, function(pError, pData) { + if (!pError){ + p.name += '.json'; + p.data = Util.stringifyJSON(pData); + main.sendResponse(p); } else - if(p.data.isDirectory()) - fs.rmdir(d.name, log); - - else if(p.data.isFile()) - fs.unlink(d.name, log); - - if(lAssync === n && !p.error) - main.sendResponse(pParams, 'delete: ok("' + pBody + '")'); - } - } - - - for(var i = 0; i < n; i ++){ - var lName = lDir + lFiles[i]; - Util.log(lName); - fs.stat(lName, Util.call(stat, { - name: lName - })); - } - }); - }else - fs.unlink(p.name, function(pError){ - if(!pError) - main.sendResponse(pParams, 'delete: ok(' + p.name + '")'); + main.sendError(p, pError); + }); else - main.sendError(pParams, pError); - }); + main.sendFile(p); + else + main.sendError(p, pError); + + }); + break; + + case 'PUT': + if (lQuery === 'dir') + fs.mkdir(p.name, function(pError) { + if (!pError) + main.sendResponse(pParams, 'Folder ' + p.name + ' created.'); + else + main.sendError(pParams, pError); + }); + + else { + lName = p.name; - break; + if (lQuery === 'zip') { + lZlib = zlib.createGzip(); + lReadStream = fs.createReadStream(lName); + lReadStream = lReadStream.pipe(lZlib); + lName += '.' + lQuery; + lMsg = lQuery; + } else { + lReadStream = p.request; + lMsg = 'save'; + } + + lWriteStream = fs.createWriteStream(lName); + + lError = function(pError) { + main.sendError(pParams, pError); + }; + + lWriteStream.on('error', lError); + lReadStream.on('error', lError); + + lWriteStream.on('open', function() { + lReadStream.pipe(lWriteStream); + + lReadStream.on('end', function() { + lName = path.basename(lName); + main.sendResponse(pParams, lMsg + ': ok("' + lName +'")'); + }); + }); } + break; + case 'DELETE': + if (lQuery === 'dir') + fs.rmdir(p.name, function(pError){ + if (!pError) + main.sendResponse(pParams, 'delete: ok("' + p.name + '")'); + else + main.sendError(pParams, pError); + }); + else if (lQuery === 'files'){ + getBody(p.request, function(pBody) { + var lFiles = Util.parseJSON(pBody), + n = lFiles.length, + lDir = p.name, + log = Util.retExec(Util.log), + lAssync = 0; + + function stat(pStat){ + var lRet = Util.checkObjTrue(pStat, 'params') && + Util.checkObjTrue(pStat.params, 'name'); + + if (lRet) { + var p = pStat, + d = p.params; + + ++lAssync; + + if (p.error){ + main.sendError(pParams, p.error); + Util.log(p.error); + } + else + if (p.data.isDirectory()) + fs.rmdir(d.name, log); + + else if (p.data.isFile()) + fs.unlink(d.name, log); + + if (lAssync === n && !p.error) + main.sendResponse(pParams, 'delete: ok("' + pBody + '")'); + } + } + + + for(var i = 0; i < n; i ++) { + var lName = lDir + lFiles[i]; + Util.log(lName); + fs.stat(lName, Util.call(stat, { + name: lName + })); + } + }); + }else + fs.unlink(p.name, function(pError) { + if (!pError) + main.sendResponse(pParams, 'delete: ok(' + p.name + '")'); + else + main.sendError(pParams, pError); + }); + + break; + } } + return lRet; } @@ -246,40 +248,41 @@ * * @param pParams {command, method, body, requrest, response} */ - function onGET(pParams){ + function onGET(pParams) { var lRet = main.checkParams(pParams); if(lRet){ var p = pParams, lCmd = p.command; switch(lCmd){ - case '': - p.data = { - info: 'Cloud Commander API v1' - }; - send(p); - break; + case '': + p.data = { + info: 'Cloud Commander API v1' + }; + send(p); + break; + + case 'proxy': - case 'proxy': - - break; - - case 'zip': - main.sendFile(pParams); - break; - - case 'kill': - p.data = { - mesage: 'Cloud Commander was killed' - }; - send(p); - break; - default: - p.data = { - error: 'command not found' - }; - send(p); - break; + break; + + case 'zip': + main.sendFile(pParams); + break; + + case 'kill': + p.data = { + mesage: 'Cloud Commander was killed' + }; + send(p); + break; + + default: + p.data = { + error: 'command not found' + }; + send(p); + break; } } @@ -291,72 +294,72 @@ * * @param pParams {command, method, body, requrest, response} */ - function onPUT(pParams){ + function onPUT(pParams) { var lRet = main.checkParams(pParams, ['body']); - if(lRet){ + if (lRet) { var p = pParams, lCmd = p.command, lFiles = Util.parseJSON(p.body); - console.log(p.body); - switch(lCmd){ - case 'auth': - main.auth(p.body, function(pTocken){ - send({ - response: p.response, - data: pTocken - }); + + switch(lCmd) { + case 'auth': + main.auth(p.body, function(pTocken){ + send({ + response: p.response, + data: pTocken }); - break; - - case 'cmd': - main.child_process.exec(p.body, function(pError, pStdout, pStderr){ - var lError = pError || pStderr; - if(!lError) - main.sendResponse(pParams, pStdout); + }); + break; + + case 'cmd': + main.child_process.exec(p.body, function(pError, pStdout, pStderr) { + var lError = pError || pStderr; + if (!lError) + main.sendResponse(pParams, pStdout); + else + main.sendError(pParams, lError); + }); + break; + + case 'mv': + if( Util.checkObjTrue(lFiles, ['from', 'to']) ) + fs.rename(lFiles.from, lFiles.to, function(pError){ + if(!pError) + main.sendResponse(pParams); else - main.sendError(pParams, lError); + main.sendError(pParams, pError); }); - break; - - case 'mv': - if( Util.checkObjTrue(lFiles, ['from', 'to']) ) - fs.rename(lFiles.from, lFiles.to, function(pError){ - if(!pError) - main.sendResponse(pParams); - else - main.sendError(pParams, pError); - }); - else - main.sendError(pParams, p.data); - break; - - case 'cp': - if( Util.checkObjTrue(lFiles, ['from', 'to']) ){ - var l = lFiles, - lReadStream = fs.createReadStream(l.from), - lWriteStream = fs.createWriteStream(l.to), - - lError = function(pError){ - main.sendError(pParams, pError); - }; - - lWriteStream.on('error', lError); - lReadStream.on('error', lError); - - lReadStream.on('end', function(){ - main.sendResponse(pParams, 'copied to: ' + l.to); - }); + else + main.sendError(pParams, p.data); + break; + + case 'cp': + if (Util.checkObjTrue(lFiles, ['from', 'to'])) { + var l = lFiles, + lReadStream = fs.createReadStream(l.from), + lWriteStream = fs.createWriteStream(l.to), - lReadStream.pipe(lWriteStream); - } - else - main.sendError(pParams, p.data); - break; - default: - send(pParams); - break; + lError = function(pError){ + main.sendError(pParams, pError); + }; + + lWriteStream.on('error', lError); + lReadStream.on('error', lError); + + lReadStream.on('end', function(){ + main.sendResponse(pParams, 'copied to: ' + l.to); + }); + + lReadStream.pipe(lWriteStream); } + else + main.sendError(pParams, p.data); + break; + default: + send(pParams); + break; } + } return lRet; } @@ -367,10 +370,10 @@ * @param pReq * @param pCallBack */ - function getBody(pReq, pCallBack){ + function getBody(pReq, pCallBack) { var lBody = ''; - pReq.on('data', function(chunk){ + pReq.on('data', function(chunk) { lBody += chunk.toString(); }); From c718abb3185f03db7c2b421ba327e4247d6e3b3a Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 8 Aug 2013 10:23:19 +0000 Subject: [PATCH 019/218] style(key) "){" -> ") {" --- lib/client/key.js | 478 +++++++++++++++++++++++----------------------- 1 file changed, 239 insertions(+), 239 deletions(-) diff --git a/lib/client/key.js b/lib/client/key.js index a0de62e3..e1bfdd75 100644 --- a/lib/client/key.js +++ b/lib/client/key.js @@ -78,253 +78,252 @@ var CloudCmd, Util, DOM; /* если клавиши можно обрабатывать*/ if(Binded){ switch(lKeyCode){ - case Key.TAB: - /* changing parent panel of curent-file */ - var lPanel = DOM.getPanel(), - lId = lPanel.id; - - lTabPanel[lId] = lCurrent; - - lPanel = DOM.getPanel({active:false}); + case Key.TAB: + /* changing parent panel of curent-file */ + var lPanel = DOM.getPanel(), lId = lPanel.id; - - if(lTabPanel[lId]) - DOM.setCurrentFile(lTabPanel[lId]); - else{ - var lFirstFileOnList = DOM.getByTag('li', lPanel)[2]; - - DOM.setCurrentFile(lFirstFileOnList); - } - - DOM.preventDefault(pEvent);//запрет на дальнейшее действие - break; - case Key.INSERT: - DOM.setSelectedFile( lCurrent ); - DOM.setCurrentFile( lCurrent.nextSibling ); - break; + lTabPanel[lId] = lCurrent; - case Key.DELETE: - if(lShift){ - var lUrl = DOM.getCurrentPath(lCurrent); + lPanel = DOM.getPanel({active:false}); + lId = lPanel.id; + + if(lTabPanel[lId]) + DOM.setCurrentFile(lTabPanel[lId]); + else{ + var lFirstFileOnList = DOM.getByTag('li', lPanel)[2]; - if( DOM.isCurrentIsDir(lCurrent) ) - lUrl += '?dir'; - - DOM.RESTfull.delete(lUrl, function(){ - DOM.deleteCurrent(lCurrent); - }); - } - else - DOM.promptDeleteSelected(lCurrent); - break; + DOM.setCurrentFile(lFirstFileOnList); + } - case Key.F1: - Util.exec(CloudCmd.Help); - DOM.preventDefault(pEvent); - break; - - case Key.F2: - DOM.renameCurrent(lCurrent); - break; + DOM.preventDefault(pEvent);//запрет на дальнейшее действие + break; + + case Key.INSERT: + DOM.setSelectedFile( lCurrent ); + DOM.setCurrentFile( lCurrent.nextSibling ); + break; + + case Key.DELETE: + if(lShift){ + var lUrl = DOM.getCurrentPath(lCurrent); - case Key.F3: - Util.exec(CloudCmd.View); - DOM.preventDefault(pEvent); - break; - - case Key.F4: - Util.exec(CloudCmd.Edit); - DOM.preventDefault(pEvent); - break; - - case Key.F5: - DOM.copyCurrent(lCurrent); - DOM.preventDefault(pEvent); - break; - - case Key.F6: - DOM.moveCurrent(lCurrent); - DOM.preventDefault(pEvent); - break; - - case Key.F7: - DOM.promptNewDir(); - break; - - case Key.F8: - DOM.promptDeleteSelected(lCurrent); - break; - - case Key.F: - DOM.promptDeleteCurrent(lCurrent); - break; - - case Key.F9: - Util.exec(CloudCmd.Menu); - DOM.preventDefault(pEvent); - break; - - case Key.TRA: - DOM.Images.showLoad({top: true}); - Util.exec(CloudCmd.Console); - break; + if( DOM.isCurrentIsDir(lCurrent) ) + lUrl += '?dir'; - case Key.SPACE: - var lSelected = DOM.isSelected(lCurrent), - lDir = DOM.isCurrentIsDir(lCurrent), - lName = DOM.getCurrentName(lCurrent); - - if(!lDir || lName === '..') - lSelected = true; - - Util.ifExec(lSelected, function(){ - DOM.setSelectedFile(lCurrent); - }, function(pCallBack){ - DOM.loadCurrentSize(pCallBack, lCurrent); + DOM.RESTfull.delete(lUrl, function(){ + DOM.deleteCurrent(lCurrent); }); - - - DOM.preventDefault(pEvent); - break; - - /* навигация по таблице файлов * - * если нажали клавишу вверх * - * выделяем предыдущую строку */ - case Key.UP: - if(lShift) - DOM.setSelectedFile(lCurrent); - - DOM.setCurrentFile( lCurrent.previousSibling ); - DOM.preventDefault( pEvent ); - break; - - /* если нажали клавишу в низ * - * выделяем следующую строку */ - case Key.DOWN: - if(lShift) - DOM.setSelectedFile(lCurrent); - - DOM.setCurrentFile( lCurrent.nextSibling ); - DOM.preventDefault( pEvent ); - break; - - /* если нажали клавишу Home * - * переходим к самому верхнему * - * элементу */ - case Key.HOME: - DOM.setCurrentFile( lCurrent.parentElement.firstChild ); - DOM.preventDefault(pEvent); - break; - - /* если нажали клавишу End - * выделяем последний элемент */ - case Key.END: - DOM.setCurrentFile( lCurrent.parentElement.lastElementChild ); - DOM.preventDefault( pEvent ); - break; - - /* если нажали клавишу page down - * проматываем экран */ - case Key.PAGE_DOWN: - DOM.scrollByPages( DOM.getPanel(), 1 ); - - for(i=0; i<30; i++){ - if(!lCurrent.nextSibling) break; - - lCurrent = lCurrent.nextSibling; - } - DOM.setCurrentFile(lCurrent); - DOM.preventDefault(pEvent); - break; - - /* если нажали клавишу page up проматываем экран */ - case Key.PAGE_UP: - DOM.scrollByPages( DOM.getPanel(), -1 ); - - var lC = lCurrent, - tryCatch = function(pCurrentFile){ - Util.tryCatch(function(){ - return pCurrentFile - .previousSibling - .previousSibling - .previousSibling - .previousSibling; - }); - }; - - for(i = 0; i < 30; i++){ - if(!lC.previousSibling || tryCatch(lC) ) break; - - lC = lC.previousSibling; - } - DOM.setCurrentFile(lC); - DOM.preventDefault(pEvent); - break; - - /* открываем папку*/ - case Key.ENTER: - if( DOM.isCurrentIsDir() ) - Util.exec( CloudCmd.loadDir() ); - break; - - case Key.A: - if(pEvent.ctrlKey){ - var lParent = lCurrent.parentElement, - lNodes = lParent.childNodes; - - /* not path and fm_header */ - for(i = 2, n = lNodes.length; i < n; i++) - DOM.setSelectedFile( lNodes[i] ); - - DOM.preventDefault(pEvent); - } - - break; - - /* - * обновляем страницу, - * загружаем содержимое каталога - * при этом данные берём всегда с - * сервера, а не из кэша - * (обновляем кэш) - */ - case Key.R: - if(lCtrl){ - Util.log('+r pressed\n' + - 'reloading page...\n' + - 'press +q to remove all key-handlers'); - - CloudCmd.refresh(); - DOM.preventDefault(pEvent); - } + } + else + DOM.promptDeleteSelected(lCurrent); + break; + + case Key.F1: + Util.exec(CloudCmd.Help); + DOM.preventDefault(pEvent); + break; + + case Key.F2: + DOM.renameCurrent(lCurrent); break; - /* чистим кэш */ - case Key.D: - if(lCtrl){ - Util.log('+d pressed\n' + - 'clearing cache...\n' + - 'press +q to remove all key-handlers'); - - DOM.Cache.clear(); - DOM.preventDefault(); - } - break; + case Key.F3: + Util.exec(CloudCmd.View); + DOM.preventDefault(pEvent); + break; - /* убираем все обработчики - * нажатий клавиш */ - case Key.Q: - if(lAlt){ - Util.log('+q pressed\n' + - '+r reload key-handerl - removed' + - '+s clear cache key-handler - removed'+ - 'press +s to to set them'); - - /* обработчик нажатий клавиш снят*/ - Binded = false; - DOM.preventDefault(pEvent); - } + case Key.F4: + Util.exec(CloudCmd.Edit); + DOM.preventDefault(pEvent); + break; + + case Key.F5: + DOM.copyCurrent(lCurrent); + DOM.preventDefault(pEvent); + break; + + case Key.F6: + DOM.moveCurrent(lCurrent); + DOM.preventDefault(pEvent); + break; + + case Key.F7: + DOM.promptNewDir(); + break; + + case Key.F8: + DOM.promptDeleteSelected(lCurrent); + break; + + case Key.F: + DOM.promptDeleteCurrent(lCurrent); + break; + + case Key.F9: + Util.exec(CloudCmd.Menu); + DOM.preventDefault(pEvent); + + break; + + case Key.TRA: + DOM.Images.showLoad({top: true}); + Util.exec(CloudCmd.Console); + + break; + + case Key.SPACE: + var lSelected = DOM.isSelected(lCurrent), + lDir = DOM.isCurrentIsDir(lCurrent), + lName = DOM.getCurrentName(lCurrent); + + if (!lDir || lName === '..') + lSelected = true; + + Util.ifExec(lSelected, function() { + DOM.setSelectedFile(lCurrent); + }, function(pCallBack) { + DOM.loadCurrentSize(pCallBack, lCurrent); + }); + + + DOM.preventDefault(pEvent); + break; + + /* навигация по таблице файлов * + * если нажали клавишу вверх * + * выделяем предыдущую строку */ + case Key.UP: + if (lShift) + DOM.setSelectedFile(lCurrent); + + DOM.setCurrentFile( lCurrent.previousSibling ); + DOM.preventDefault( pEvent ); + break; + + /* если нажали клавишу в низ - выделяем следующую строку */ + case Key.DOWN: + if (lShift) + DOM.setSelectedFile(lCurrent); + + DOM.setCurrentFile( lCurrent.nextSibling ); + DOM.preventDefault( pEvent ); + break; + + /* если нажали клавишу Home * + * переходим к самому верхнему * + * элементу */ + case Key.HOME: + DOM.setCurrentFile( lCurrent.parentElement.firstChild ); + DOM.preventDefault(pEvent); + break; + + /* если нажали клавишу End выделяем последний элемент */ + case Key.END: + DOM.setCurrentFile( lCurrent.parentElement.lastElementChild ); + DOM.preventDefault( pEvent ); + break; + + /* если нажали клавишу page down проматываем экран */ + case Key.PAGE_DOWN: + DOM.scrollByPages( DOM.getPanel(), 1 ); + + for (i = 0; i < 30; i++) { + + if (!lCurrent.nextSibling) + break; + + lCurrent = lCurrent.nextSibling; + } + DOM.setCurrentFile(lCurrent); + DOM.preventDefault(pEvent); + break; + + /* если нажали клавишу page up проматываем экран */ + case Key.PAGE_UP: + DOM.scrollByPages(DOM.getPanel(), -1); + + var lC = lCurrent, + tryCatch = function(pCurrentFile){ + Util.tryCatch(function(){ + return pCurrentFile + .previousSibling + .previousSibling + .previousSibling + .previousSibling; + }); + }; + + for (i = 0; i < 30; i++){ + if (!lC.previousSibling || tryCatch(lC) ) break; + + lC = lC.previousSibling; + } + + DOM.setCurrentFile(lC); + DOM.preventDefault(pEvent); + break; + + /* открываем папку*/ + case Key.ENTER: + if (DOM.isCurrentIsDir()) + Util.exec( CloudCmd.loadDir() ); + break; + + case Key.A: + if (pEvent.ctrlKey) { + var lParent = lCurrent.parentElement, + lNodes = lParent.childNodes; + + /* not path and fm_header */ + for (i = 2, n = lNodes.length; i < n; i++) + DOM.setSelectedFile( lNodes[i] ); + + DOM.preventDefault(pEvent); + } + break; + + /* + * обновляем страницу, + * загружаем содержимое каталога + * при этом данные берём всегда с + * сервера, а не из кэша + * (обновляем кэш) + */ + case Key.R: + if (lCtrl) { + Util.log('+r pressed\n' + + 'reloading page...\n' + + 'press +q to remove all key-handlers'); + + CloudCmd.refresh(); + DOM.preventDefault(pEvent); + } + break; + + /* чистим кэш */ + case Key.D: + if (lCtrl) { + Util.log('+d pressed\n' + + 'clearing cache...\n' + + 'press +q to remove all key-handlers'); + + DOM.Cache.clear(); + DOM.preventDefault(); + } + break; + + /* убираем все обработчики нажатий клавиш */ + case Key.Q: + if (lAlt) { + Util.log('+q pressed\n' + + '+r reload key-handerl - removed' + + '+s clear cache key-handler - removed'+ + 'press +s to to set them'); + + Binded = false; + DOM.preventDefault(pEvent); + } break; } } @@ -335,10 +334,11 @@ var CloudCmd, Util, DOM; else if(lKeyCode === Key.S && lAlt){ /* обрабатываем нажатия на клавиши*/ Binded = true; - Util.log('+s pressed\n' + - '+r reload key-handerl - set\n' + - '+s clear cache key-handler - set\n' + + Util.log('+s pressed \n' + + '+r reload key-handerl - set \n' + + '+s clear cache key-handler - set \n' + 'press +q to remove them'); + DOM.preventDefault(pEvent); } } From dd8adbe731ffec7b5188badcb8e03f98ee2f6b3c Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 9 Aug 2013 08:22:25 +0000 Subject: [PATCH 020/218] chore(util) "){" -> ") {" --- lib/util.js | 210 ++++++++++++++++++++++++++-------------------------- 1 file changed, 105 insertions(+), 105 deletions(-) diff --git a/lib/util.js b/lib/util.js index 3077c7a3..e083adfa 100644 --- a/lib/util.js +++ b/lib/util.js @@ -5,7 +5,7 @@ var Util, exports; Util = exports || {}; -(function(Util){ +(function(Util) { 'use strict'; var Scope = exports ? global : window; @@ -14,7 +14,7 @@ Util = exports || {}; * @param {function} pFunction * @param {object} pContext */ - Util.bind = function(pFunction, pContext){ + Util.bind = function(pFunction, pContext) { var lRet; if ( Util.isFunction(pFunction) ) @@ -30,8 +30,8 @@ Util = exports || {}; * @param pFunc * @param pParams */ - Util.call = function(pFunc, pParams){ - function lFunc(pError, pData){ + Util.call = function(pFunc, pParams) { + function lFunc(pError, pData) { Util.exec(pFunc, { error : pError, data : pData, @@ -48,7 +48,7 @@ Util = exports || {}; * @param pName - получает имя файла * @param pExt - расширение */ - Util.checkExtension = function(pName, pExt){ + Util.checkExtension = function(pName, pExt) { var lRet = false, lLength = pName.length; /* длина имени*/ @@ -61,8 +61,8 @@ Util = exports || {}; /* если pExt - расширение pName */ lRet = lExtSub === pExt.length; - }else if (Util.isObject(pExt) && pExt.length){ - for(var i=0; i < pName.length; i++){ + }else if (Util.isObject(pExt) && pExt.length) { + for(var i=0; i < pName.length; i++) { lRet = Util.checkExtension(pName, pExt[i]); if (lRet) @@ -81,17 +81,17 @@ Util = exports || {}; * @param pPropArr * @param pTrueArr */ - Util.checkObj = function(pObj, pPropArr, pTrueArr){ + Util.checkObj = function(pObj, pPropArr, pTrueArr) { var lRet, i, n; - if ( pObj ){ + if ( pObj ) { lRet = Util.isArray(pPropArr); - if (lRet){ + if (lRet) { n = pPropArr.length; - for (i = 0; i < n; i++){ + for (i = 0; i < n; i++) { var lProp = pPropArr[i]; lRet = pObj.hasOwnProperty( lProp ); - if (!lRet){ + if (!lRet) { Util.logError(lProp + ' not in Obj!'); Util.log(pObj); break; @@ -113,18 +113,18 @@ Util = exports || {}; * @param pPropArr * @param pTrueArr */ - Util.checkObjTrue = function(pObj, pTrueArr){ + Util.checkObjTrue = function(pObj, pTrueArr) { var lRet, lTrueArr, i, n; - if ( pObj ){ + if ( pObj ) { lTrueArr = Util.isArray(pTrueArr) ? pTrueArr : [pTrueArr]; n = lTrueArr.length; - for(i = 0; i < n; i++){ + for(i = 0; i < n; i++) { var lProp = lTrueArr[i]; lRet = pObj[lProp]; - if ( !lRet){ + if ( !lRet) { Util.logError(lProp + ' not true!'); Util.log(pObj); break; @@ -142,13 +142,13 @@ Util = exports || {}; * @param pToObj * @param pProps */ - Util.copyObj = function(pFromObj, pToObj, pProps){ + Util.copyObj = function(pFromObj, pToObj, pProps) { var lRet; if ( !pToObj ) lRet = pToObj = {}; - function copy(pI){ + function copy(pI) { var lName = pProps ? pProps[pI] : pI, lValue = pFromObj[lName]; @@ -156,7 +156,7 @@ Util = exports || {}; pToObj[lName] = pFromObj[lName]; } - if ( Util.isObject(pFromObj) ){ + if ( Util.isObject(pFromObj) ) { if (!pProps) Util.forIn(pFromObj, copy); else @@ -168,11 +168,11 @@ Util = exports || {}; return lRet; }; - Util.convertArrToObj = function(pArrKeys, pArrVal){ + Util.convertArrToObj = function(pArrKeys, pArrVal) { var i, n, lName, lRet; - if (pArrKeys && pArrVal){ - for(i = 0, n = pArrKeys; i < n; i++){ + if (pArrKeys && pArrVal) { + for(i = 0, n = pArrKeys; i < n; i++) { lName = pArrKeys[i]; lRet[lName] = pArrVal[i]; } @@ -187,14 +187,14 @@ Util = exports || {}; * @pTarget * @pObj */ - Util.extend = function(pTarget, PObj){ + Util.extend = function(pTarget, PObj) { var i, n, lObj, lRet = Util.isObject(pTarget) ? pTarget : {}; if ( Util.isArray(PObj) ) for(i = 0, n = PObj.length; i < n; i++) lRet = Util.extend(pTarget, PObj[i]); - else if (PObj){ + else if (PObj) { lObj = Util.isFunction(PObj) ? new PObj() : PObj; for(i in lObj) @@ -210,8 +210,8 @@ Util = exports || {}; * @pTarget * @pObj */ - Util.extendProto = function(pObj){ - var lRet, F = function(){}; + Util.extendProto = function(pObj) { + var lRet, F = function() {}; F.prototype = Util.extend({}, pObj); lRet = new F(); @@ -223,9 +223,9 @@ Util = exports || {}; * @param pN * @param pFunc */ - Util.for = function(pI, pN, pFunc){ + Util.for = function(pI, pN, pFunc) { if (Util.isFunction(pFunc)) - for(var i = pI, n = pN; i < n; i++){ + for(var i = pI, n = pN; i < n; i++) { if (pFunc(i)) break; } @@ -235,7 +235,7 @@ Util = exports || {}; * @param pObj * @param pFunc */ - Util.forIn = function(pObj, pFunc){ + Util.forIn = function(pObj, pFunc) { if (Util.isFunction(pFunc)) for(var lName in pObj) if (pFunc(lName)) @@ -246,7 +246,7 @@ Util = exports || {}; * @param pN * @param pFunc */ - Util.fori = function(pN, pFunc){ + Util.fori = function(pN, pFunc) { var lRet = Util.for(0, pN, pFunc); return lRet; @@ -255,10 +255,10 @@ Util = exports || {}; /** * @pJSON */ - Util.parseJSON = function(pJSON){ + Util.parseJSON = function(pJSON) { var lRet; - Util.tryCatch(function(){ + Util.tryCatch(function() { lRet = JSON.parse(pJSON); }); @@ -268,10 +268,10 @@ Util = exports || {}; /** * pObj */ - Util.stringifyJSON = function(pObj){ + Util.stringifyJSON = function(pObj) { var lRet; - Util.tryCatchLog(function(){ + Util.tryCatchLog(function() { lRet = JSON.stringify(pObj, null, 4); }); @@ -284,12 +284,12 @@ Util = exports || {}; * @param pStr1 * @param pStr2 */ - Util.strCmp = function (pStr1, pStr2){ + Util.strCmp = function(pStr1, pStr2) { var lRet = Util.isString(pStr1); - if (lRet){ + if (lRet) { if ( Util.isArray(pStr2) ) - for(var i = 0, n = pStr2.length; i < n; i++){ + for(var i = 0, n = pStr2.length; i < n; i++) { lRet = Util.strCmp( pStr1, pStr2[i] ); if (lRet) @@ -310,12 +310,12 @@ Util = exports || {}; * @param pStr2 */ - Util.isContainStr = function(pStr1, pStr2){ + Util.isContainStr = function(pStr1, pStr2) { var lRet = Util.isString(pStr1); - if ( lRet ){ + if ( lRet ) { if ( Util.isArray(pStr2) ) - for(var i = 0, n = pStr2.length; i < n; i++){ + for(var i = 0, n = pStr2.length; i < n; i++) { lRet = Util.isContainStr( pStr1, pStr2[i] ); if (lRet) @@ -333,10 +333,10 @@ Util = exports || {}; * @param pStr1 * @param pStr2 */ - Util.isContainStrAtBegin = function(pStr1, pStr2){ + Util.isContainStrAtBegin = function(pStr1, pStr2) { var lRet; - if ( Util.isString(pStr1) && Util.isString(pStr2) ){ + if ( Util.isString(pStr1) && Util.isString(pStr2) ) { var lLength = pStr2.length, lSubStr = pStr1.substring(0, lLength); @@ -350,7 +350,7 @@ Util = exports || {}; * function log pArg if it's not empty * @param pArg */ - Util.log = function(){ + Util.log = function() { var lArg = arguments, lConsole = Scope.console, lDate = '[' + Util.getDate() + '] ', @@ -386,11 +386,11 @@ Util = exports || {}; * function log pArg if it's not empty * @param pArg */ - Util.logError = function(pArg){ + Util.logError = function(pArg) { var lConsole = Scope.console, lDate = '[' + Util.getDate() + '] '; - if (lConsole && pArg){ + if (lConsole && pArg) { var lMsg = pArg.message; if ( lMsg ) lDate += pArg.message + ' '; @@ -406,11 +406,11 @@ Util = exports || {}; * @param pFunc_a {Array} - array of functions * @param pData - not necessarily */ - Util.loadOnLoad = function(pFunc_a, pData){ + Util.loadOnLoad = function(pFunc_a, pData) { if ( Util.isArray(pFunc_a) && pFunc_a.length) { var lFunc_a = pFunc_a.slice(), lFunc = lFunc_a.pop(), - lCallBack = function(pData){ + lCallBack = function(pData) { return Util.loadOnLoad(lFunc_a, pData); }; @@ -429,14 +429,14 @@ Util = exports || {}; * @param pStr * @param pSubStr */ - Util.removeStr = function(pStr, pSubStr){ + Util.removeStr = function(pStr, pSubStr) { var lRet = Util.isString(pStr) && pSubStr; if ( lRet ) { var n = pSubStr.length; if ( Util.isArray(pSubStr) ) - Util.fori(n, function(i){ + Util.fori(n, function(i) { lRet = pStr = Util.replaceStr(pStr, pSubStr[i], ''); }); else @@ -453,14 +453,14 @@ Util = exports || {}; * @param pStr * @param pSubStr */ - Util.removeStrOneTime = function(pStr, pSubStr){ + Util.removeStrOneTime = function(pStr, pSubStr) { var lRet = Util.isString(pStr) && pSubStr; if ( lRet ) { var n = pSubStr.length; if ( Util.isArray(pSubStr) ) - Util.fori(n, function(i){ + Util.fori(n, function(i) { lRet = pStr = pStr.replace(pSubStr[i], ''); }); else @@ -479,7 +479,7 @@ Util = exports || {}; * @pTo */ - Util.replaceStr = function(pStr, pFrom, pTo){ + Util.replaceStr = function(pStr, pFrom, pTo) { var lRet = pStr; if (pStr && pFrom) { @@ -505,7 +505,7 @@ Util = exports || {}; * @pTempl * @pView */ - Util.render = function(pTempl, pView){ + Util.render = function(pTempl, pView) { var lRet = Util.ownRender(pTempl, pView, ['{', '}']); return lRet; @@ -517,7 +517,7 @@ Util = exports || {}; * @pView * @pSymbols */ - Util.ownRender = function(pTempl, pView, pSymbols){ + Util.ownRender = function(pTempl, pView, pSymbols) { if (!pSymbols) pSymbols = ['{', '}']; @@ -528,7 +528,7 @@ Util = exports || {}; lFirstChar = pSymbols[0]; lSecondChar = pSymbols[1] || lFirstChar; - for(var lVar in pView){ + for(var lVar in pView) { var lStr = pView[lVar]; lStr = Util.exec(lStr) || lStr; @@ -546,13 +546,13 @@ Util = exports || {}; * @param {function} pCallback * * Example: - * i >=0, pFuncs[i] = function(param, callback){} + * i >=0, pFuncs[i] = function(param, callback) {} */ - Util.paralelExec = function(pFuncs, pCallback){ + Util.paralelExec = function(pFuncs, pCallback) { var done = []; /* add items to array done*/ - function addFunc(pNum){ + function addFunc(pNum) { done.push(pNum); } @@ -561,16 +561,16 @@ Util = exports || {}; * we pop number of function and * if it's last we call pCallBack */ - function doneFunc(pParams){ + function doneFunc(pParams) { Util.exec(pParams.callback); var lNum = done.pop (pParams.number); - if (!lNum){ + if (!lNum) { Util.exec(pCallback); } } - for(var i = 0, n = pFuncs.length; i < n; i++){ + for(var i = 0, n = pFuncs.length; i < n; i++) { addFunc(i); var lFunc = pFuncs[i].callback; @@ -586,7 +586,7 @@ Util = exports || {}; * functions check is pVarible is array * @param pVarible */ - Util.isArray = function(pVarible){ + Util.isArray = function(pVarible) { return pVarible instanceof Array; }; @@ -594,7 +594,7 @@ Util = exports || {}; * functions check is pVarible is boolean * @param pVarible */ - Util.isBoolean = function(pVarible){ + Util.isBoolean = function(pVarible) { return Util.isType(pVarible, 'boolean'); }; @@ -602,7 +602,7 @@ Util = exports || {}; * functions check is pVarible is function * @param pVarible */ - Util.isFunction = function(pVarible){ + Util.isFunction = function(pVarible) { return Util.isType(pVarible, 'function'); }; @@ -610,7 +610,7 @@ Util = exports || {}; * functions check is pVarible is number * @param pVarible */ - Util.isNumber = function(pVarible){ + Util.isNumber = function(pVarible) { return Util.isType(pVarible, 'number'); }; @@ -618,7 +618,7 @@ Util = exports || {}; * functions check is pVarible is object * @param pVarible */ - Util.isObject = function(pVarible){ + Util.isObject = function(pVarible) { return Util.isType(pVarible, 'object'); }; @@ -626,7 +626,7 @@ Util = exports || {}; * functions check is pVarible is string * @param pVarible */ - Util.isString = function(pVarible){ + Util.isString = function(pVarible) { return Util.isType(pVarible, 'string'); }; @@ -634,7 +634,7 @@ Util = exports || {}; * functions check is pVarible is string * @param pVarible */ - Util.isUndefined = function(pVarible){ + Util.isUndefined = function(pVarible) { return Util.isType(pVarible, 'undefined'); }; @@ -643,7 +643,7 @@ Util = exports || {}; * @param pVarible * @param pType */ - Util.isType = function(pVarible, pType){ + Util.isType = function(pVarible, pType) { return typeof pVarible === pType; }; @@ -653,8 +653,8 @@ Util = exports || {}; * @param pCallBack * @param pArg */ - Util.retExec = function(pCallBack, pArg){ - return function(pArgument){ + Util.retExec = function(pCallBack, pArg) { + return function(pArgument) { if ( !Util.isUndefined(pArg) ) pArgument = pArg; Util.exec(pCallBack, pArgument); @@ -666,8 +666,8 @@ Util = exports || {}; * @param pCallBack * @param pArg */ - Util.retFunc = function(pCallBack, pArg){ - return function(){ + Util.retFunc = function(pCallBack, pArg) { + return function() { return Util.exec(pCallBack, pArg); }; }; @@ -675,7 +675,7 @@ Util = exports || {}; /** * function return false */ - Util.retFalse = function(){ + Util.retFalse = function() { var lRet = false; return lRet; @@ -684,7 +684,7 @@ Util = exports || {}; /** * function return param */ - Util.retParam = function(pParam){ + Util.retParam = function(pParam) { return pParam; }; @@ -693,8 +693,8 @@ Util = exports || {}; * @param pFunc_a {Array} - array of functions * @param pData - not necessarily */ - Util.retLoadOnLoad = function(pFunc_a, pData){ - return function(){ + Util.retLoadOnLoad = function(pFunc_a, pData) { + return function() { Util.loadOnLoad(pFunc_a, pData); }; }; @@ -703,15 +703,15 @@ Util = exports || {}; * set value to property of object, if object exist * @param pArgs {object, property, value} */ - Util.setValue = function(pArgs){ + Util.setValue = function(pArgs) { var lRet = false; - if ( Util.isObject(pArgs) ){ + if ( Util.isObject(pArgs) ) { var lObj = pArgs.object, lProp = pArgs.property, lVal = pArgs.lVal; - if (lObj){ + if (lObj) { lObj[lProp] = lVal; lRet = true; } @@ -724,18 +724,18 @@ Util = exports || {}; * set timout before callback would be called * @param pArgs {func, callback, time} */ - Util.setTimeout = function(pArgs){ + Util.setTimeout = function(pArgs) { var lDone, lFunc = pArgs.func, lTime = pArgs.time || 1000, - lCallBack = function(pArgument){ - if (!lDone){ + lCallBack = function(pArgument) { + if (!lDone) { lDone = Util.exec(pArgs.callback, pArgument); } }; - var lTimeoutFunc = function(){ - setTimeout(function(){ + var lTimeoutFunc = function() { + setTimeout(function() { Util.exec(lFunc, lCallBack); if (!lDone) lTimeoutFunc(); @@ -752,12 +752,12 @@ Util = exports || {}; * * @param pCallBack */ - Util.tryCatch = function(pCallBack){ + Util.tryCatch = function(pCallBack) { var lRet; try{ lRet = pCallBack(); } - catch(pError){ + catch(pError) { lRet = pError; } @@ -770,7 +770,7 @@ Util = exports || {}; * * @param pTryFunc */ - Util.tryCatchDebug = function(pTryFunc){ + Util.tryCatchDebug = function(pTryFunc) { var lRet = Util.tryCatch(pTryFunc); if (lRet) @@ -785,7 +785,7 @@ Util = exports || {}; * * @param pTryFunc */ - Util.tryCatchLog = function(pTryFunc){ + Util.tryCatchLog = function(pTryFunc) { var lRet; lRet = Util.tryCatch(pTryFunc); @@ -799,7 +799,7 @@ Util = exports || {}; * * @param pCallBack */ - Util.tryCatchCall = function(pTryFunc, pCallBack){ + Util.tryCatchCall = function(pTryFunc, pCallBack) { var lRet; lRet = Util.tryCatch(pTryFunc); @@ -815,10 +815,10 @@ Util = exports || {}; * @param pCallBack * @param pArg */ - Util.exec = function(pCallBack, pArg, pArg1){ + Util.exec = function(pCallBack, pArg, pArg1) { var lRet; - if (pCallBack){ + if (pCallBack) { if ( Util.isFunction(pCallBack) ) lRet = pCallBack(pArg, pArg1); else { @@ -834,10 +834,10 @@ Util = exports || {}; * exec function if it exist in object * @pArg */ - Util.execIfExist = function(pObj, pName, pArg){ + Util.execIfExist = function(pObj, pName, pArg) { var lRet; - if (pObj){ + if (pObj) { var lFunc = Util.bind(pObj[pName], pObj); lRet = Util.exec(lFunc, pArg); } @@ -851,7 +851,7 @@ Util = exports || {}; * @param pCallBack * @param pFunc */ - Util.ifExec = function(pCondition, pCallBack, pFunc){ + Util.ifExec = function(pCondition, pCallBack, pFunc) { var lRet; if (pCondition) @@ -867,10 +867,10 @@ Util = exports || {}; * @param pFileName * @return Ext */ - Util.getExtension = function(pFileName){ + Util.getExtension = function(pFileName) { var lRet, lDot; - if ( Util.isString(pFileName) ){ + if ( Util.isString(pFileName) ) { lDot = pFileName.lastIndexOf('.'); lRet = pFileName.substr(lDot); } @@ -883,14 +883,14 @@ Util = exports || {}; * or * @pObj */ - Util.getNamesFromObjArray = function(pArr){ + Util.getNamesFromObjArray = function(pArr) { var lRet = []; if (pArr && !Util.isArray(pArr)) pArr = pArr.data; if (pArr) - Util.fori(pArr.length, function(i){ + Util.fori(pArr.length, function(i) { lRet[i] = pArr[i].name || pArr[i]; }); @@ -902,10 +902,10 @@ Util = exports || {}; * or * @pObj */ - Util.findObjByNameInArr = function(pArr, pObjName){ + Util.findObjByNameInArr = function(pArr, pObjName) { var lRet; - if (pArr){ + if (pArr) { for(var i = 0, n = pArr.length; i < n; i++ ) if (pArr[i].name === pObjName) break; @@ -918,7 +918,7 @@ Util = exports || {}; /** * Gets current time in format hh:mm:ss */ - Util.getTime = function(){ + Util.getTime = function() { var lRet, date = new Date(), hours = date.getHours(), @@ -938,7 +938,7 @@ Util = exports || {}; * start timer * @pArg */ - Util.time = function(pArg){ + Util.time = function(pArg) { var lRet, lConsole = Scope.console; @@ -951,7 +951,7 @@ Util = exports || {}; * stop timer * @pArg */ - Util.timeEnd = function(pArg){ + Util.timeEnd = function(pArg) { var lRet, lConsole = Scope.console; @@ -963,7 +963,7 @@ Util = exports || {}; /** * Gets current date in format yy.mm.dd hh:mm:ss */ - Util.getDate = function(){ + Util.getDate = function() { var date = new Date(), day = date.getDate(), month = date.getMonth() + 1, From 5d42bf0e8c61317936e3981ee4297827f83aa4f0 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 9 Aug 2013 08:26:30 +0000 Subject: [PATCH 021/218] chore(key) "){" -> ") {" --- lib/client/key.js | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/client/key.js b/lib/client/key.js index e1bfdd75..aff95f32 100644 --- a/lib/client/key.js +++ b/lib/client/key.js @@ -1,5 +1,5 @@ var CloudCmd, Util, DOM; -(function(CloudCmd, Util, DOM){ +(function(CloudCmd, Util, DOM) { 'use strict'; var KEY = { @@ -46,7 +46,7 @@ var CloudCmd, Util, DOM; KeyProto.prototype = KEY; CloudCmd.Key = new KeyProto(CloudCmd, Util, DOM); - function KeyProto(CloudCmd, Util, DOM){ + function KeyProto(CloudCmd, Util, DOM) { var Key = this, Binded, lTabPanel = { @@ -55,20 +55,20 @@ var CloudCmd, Util, DOM; }; - this.isBind = function(){return Binded;}; + this.isBind = function() {return Binded;}; - this.setBind = function(){Binded = true;}; + this.setBind = function() {Binded = true;}; - this.unsetBind = function(){Binded = false;}; + this.unsetBind = function() {Binded = false;}; - this.bind = function(){ + this.bind = function() { DOM.Events.addKey(listener); /* клавиши назначены*/ Binded = true; }; - function listener(pEvent){ + function listener(pEvent) { /* получаем выдленный файл*/ var i, n, lCurrent = DOM.getCurrentFile(), lKeyCode = pEvent.keyCode, @@ -76,8 +76,8 @@ var CloudCmd, Util, DOM; lAlt = pEvent.altKey, lCtrl = pEvent.ctrlKey; /* если клавиши можно обрабатывать*/ - if(Binded){ - switch(lKeyCode){ + if (Binded) { + switch (lKeyCode) { case Key.TAB: /* changing parent panel of curent-file */ var lPanel = DOM.getPanel(), @@ -88,7 +88,7 @@ var CloudCmd, Util, DOM; lPanel = DOM.getPanel({active:false}); lId = lPanel.id; - if(lTabPanel[lId]) + if (lTabPanel[lId]) DOM.setCurrentFile(lTabPanel[lId]); else{ var lFirstFileOnList = DOM.getByTag('li', lPanel)[2]; @@ -105,13 +105,13 @@ var CloudCmd, Util, DOM; break; case Key.DELETE: - if(lShift){ + if (lShift) { var lUrl = DOM.getCurrentPath(lCurrent); - if( DOM.isCurrentIsDir(lCurrent) ) + if ( DOM.isCurrentIsDir(lCurrent) ) lUrl += '?dir'; - DOM.RESTfull.delete(lUrl, function(){ + DOM.RESTfull.delete(lUrl, function() { DOM.deleteCurrent(lCurrent); }); } @@ -244,8 +244,8 @@ var CloudCmd, Util, DOM; DOM.scrollByPages(DOM.getPanel(), -1); var lC = lCurrent, - tryCatch = function(pCurrentFile){ - Util.tryCatch(function(){ + tryCatch = function(pCurrentFile) { + Util.tryCatch(function() { return pCurrentFile .previousSibling .previousSibling @@ -254,7 +254,7 @@ var CloudCmd, Util, DOM; }); }; - for (i = 0; i < 30; i++){ + for (i = 0; i < 30; i++) { if (!lC.previousSibling || tryCatch(lC) ) break; lC = lC.previousSibling; @@ -331,7 +331,7 @@ var CloudCmd, Util, DOM; /* устанавливаем все обработчики * нажатий клавиш */ - else if(lKeyCode === Key.S && lAlt){ + else if (lKeyCode === Key.S && lAlt) { /* обрабатываем нажатия на клавиши*/ Binded = true; Util.log('+s pressed \n' + From 9e93692f1bc47ef287ac2f85e24d47420daf9274 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 9 Aug 2013 08:28:19 +0000 Subject: [PATCH 022/218] chore(key) rm promptDeleteCurrent --- lib/client/key.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/client/key.js b/lib/client/key.js index aff95f32..6b700ac1 100644 --- a/lib/client/key.js +++ b/lib/client/key.js @@ -156,10 +156,6 @@ var CloudCmd, Util, DOM; DOM.promptDeleteSelected(lCurrent); break; - case Key.F: - DOM.promptDeleteCurrent(lCurrent); - break; - case Key.F9: Util.exec(CloudCmd.Menu); DOM.preventDefault(pEvent); From d693b3838b1ea1960bdba1deaeff3ca844536605 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 9 Aug 2013 11:55:37 +0000 Subject: [PATCH 023/218] chore(dom) add "\n" --- lib/client/dom.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/client/dom.js b/lib/client/dom.js index a942e08a..07f8e3f3 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -105,6 +105,7 @@ var CloudCmd, Util, DOM, CloudFunc; setTimeout( Util.retExec(alert, lText), 100); }; }, + RESTfullProto = function(){ this.delete = function(pUrl, pData, pCallBack, pQuery){ sendRequest({ @@ -187,6 +188,7 @@ var CloudCmd, Util, DOM, CloudFunc; return lRet; } }, + DOMTreeProto = function(){ /** * add class to element @@ -264,6 +266,7 @@ var CloudCmd, Util, DOM, CloudFunc; this.removeClass(pElement, 'hidden'); }; }, + EventsProto = function(){ var Events = this, ADD = true, @@ -580,6 +583,7 @@ var CloudCmd, Util, DOM, CloudFunc; return lRet; }; }, + LoaderProto = function(){ var XMLHTTP; From b02e35ed977913144987200ae3d71ed229c5e6aa Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 9 Aug 2013 12:19:12 +0000 Subject: [PATCH 024/218] fix(rest) add lReadStream.on(error, lError) --- lib/server/rest.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/server/rest.js b/lib/server/rest.js index df19b415..b316176f 100644 --- a/lib/server/rest.js +++ b/lib/server/rest.js @@ -147,9 +147,16 @@ else { lName = p.name; + lError = function(pError) { + main.sendError(pParams, pError); + }; + if (lQuery === 'zip') { lZlib = zlib.createGzip(); lReadStream = fs.createReadStream(lName); + + lReadStream.on('error', lError); + lReadStream = lReadStream.pipe(lZlib); lName += '.' + lQuery; lMsg = lQuery; @@ -160,10 +167,6 @@ lWriteStream = fs.createWriteStream(lName); - lError = function(pError) { - main.sendError(pParams, pError); - }; - lWriteStream.on('error', lError); lReadStream.on('error', lError); From ea5d2a2b4dd06ea72794c7b8ffe1034e0bad14f8 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 9 Aug 2013 12:49:34 +0000 Subject: [PATCH 025/218] feature(menu, dom) add zipFile --- lib/client/dom.js | 13 +++++++++++++ lib/client/menu.js | 3 ++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/client/dom.js b/lib/client/dom.js index 07f8e3f3..f40e496a 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -1048,6 +1048,19 @@ var CloudCmd, Util, DOM, CloudFunc; RESTfull.save(lDir + lName + lType, null, CloudCmd.refresh); }; + /** + * zip file + * + */ + this.zipFile = function(){ + var lName = Cmd.getCurrentName(), + lDir = Cmd.getCurrentDirPath(), + lQuery = '?zip'; + + if (lName && lName !== '..') + RESTfull.save(lDir + lName, null, CloudCmd.refresh, lQuery); + }; + /** * delete currentfile, prompt before it diff --git a/lib/client/menu.js b/lib/client/menu.js index 945cc392..878b8746 100644 --- a/lib/client/menu.js +++ b/lib/client/menu.js @@ -173,7 +173,8 @@ var CloudCmd, Util, DOM, CloudFunc, $; 'Rename' : function(){ setTimeout( Util.retExec(DOM.renameCurrent), 100); }, - 'Delete' : Util.retExec(DOM.promptDeleteSelected) + 'Delete' : Util.retExec(DOM.promptDeleteSelected), + 'Zip file' : DOM.zipFile }; if (UploadToItemNames.length) From 24ea376ba147c112bf629bdd1a242d101229de3c Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 9 Aug 2013 12:51:13 +0000 Subject: [PATCH 026/218] chore(dom) change jsdoc params --- lib/client/dom.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/client/dom.js b/lib/client/dom.js index f40e496a..46705a32 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -1022,7 +1022,6 @@ var CloudCmd, Util, DOM, CloudFunc; /** * create new folder * - * @pCurrentFile */ this.promptNewDir = function(){ Cmd.promptNewFile('directory', '?dir'); @@ -1031,7 +1030,8 @@ var CloudCmd, Util, DOM, CloudFunc; /** * create new file * - * @pCurrentFile + * @pTypeName + * @pType */ this.promptNewFile = function(pTypeName, pType){ var lName = Cmd.getCurrentName(), From 4a484556699833f7724369f6abd72263b89dd8fb Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 9 Aug 2013 12:55:55 +0000 Subject: [PATCH 027/218] chore(server, minify, ischanged) add " " --- lib/server.js | 25 ++++++++++++------------- lib/server/ischanged.js | 2 +- lib/server/minify.js | 12 ++++++------ 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/lib/server.js b/lib/server.js index 84792a67..9bcf98e3 100644 --- a/lib/server.js +++ b/lib/server.js @@ -1,4 +1,4 @@ -(function(){ +(function() { 'use strict'; if(!global.cloudcmd) @@ -30,7 +30,7 @@ Server, Rest, Route, Minimize; /* базовая инициализация */ - function init(pAppCachProcessing){ + function init(pAppCachProcessing) { var lConfig = main.config, lMinifyAllowed = lConfig.minification; @@ -74,12 +74,12 @@ lConfig.ip || (main.WIN32 ? '127.0.0.1' : '0.0.0.0'), - lSSL = pProcessing.ssl, + lSSL = pProcessing.ssl, lSSLPort = lConfig.sslPort, lHTTP = 'http://', lHTTPS = 'https://', - lSockets = function(pServer){ + lSockets = function(pServer) { var lListen; if(lConfig.socket && Socket) lListen = Socket.listen(pServer); @@ -87,7 +87,7 @@ Util.log('* Sockets ' + (lListen ? 'running' : 'disabled')); }, - lHTTPServer = function(){ + lHTTPServer = function() { Server = http.createServer( controller ); Server.on('error', function (pError) { Util.log(pError); @@ -97,15 +97,15 @@ lSockets(Server); }, - lServerLog = function(pHTTP, pPort){ + lServerLog = function(pHTTP, pPort) { Util.log('* Server running at ' + pHTTP + lIP + ':' + pPort); }; /* server mode or testing mode */ if (lConfig.server) { - if(lSSL){ + if(lSSL) { Util.log('* Redirection http -> https is setted up'); lServerLog(lHTTP, lPort); - var lRedirectServer = http.createServer( function(pReq, pRes){ + var lRedirectServer = http.createServer( function(pReq, pRes) { var lHost = pReq.headers.host; main.redirect({ @@ -143,8 +143,7 @@ * @param req - запрос клиента (Request) * @param res - ответ сервера (Response) */ - function controller(pReq, pRes) - { + function controller(pReq, pRes) { /* Читаем содержимое папки, переданное в url */ var lRet, lName, lMin, lExt, lResult, lConfig = main.config, @@ -169,7 +168,7 @@ if( !lRet && Route) lRet = Util.exec(Route, lData); - if(!lRet){ + if(!lRet) { /* добавляем текующий каталог к пути */ lName = lData.name; Util.log('reading ' + lName); @@ -189,7 +188,7 @@ lExt === '.html' && lMin.html; Util.ifExec(!lResult, - function(pParams){ + function(pParams) { var lSendName = pParams && pParams.name || lName; main.sendFile({ @@ -199,7 +198,7 @@ request : pReq, response : pRes }); - }, function(pCallBack){ + }, function(pCallBack) { Minify.optimize(lName, { callback : pCallBack, returnName : true diff --git a/lib/server/ischanged.js b/lib/server/ischanged.js index 710ecfd9..2ed2392f 100644 --- a/lib/server/ischanged.js +++ b/lib/server/ischanged.js @@ -30,7 +30,7 @@ fs.stat(pFileName, function(pError, pStat){ var lTimeChanged, lFileTime; - if (!pError){ + if (!pError) { lFileTime = pStat.mtime.getTime(); if(lReadedTime !== lFileTime) diff --git a/lib/server/minify.js b/lib/server/minify.js index 4f8245d8..ff042240 100644 --- a/lib/server/minify.js +++ b/lib/server/minify.js @@ -1,6 +1,6 @@ /* Обьект для сжатия скриптов и стилей */ - (function(){ + (function() { 'use strict'; if(!global.cloudcmd) @@ -46,7 +46,7 @@ * img отвечает за перевод картинок в base64 * и сохранение их в css-файл */ - setAllowed :function(pAllowed){ + setAllowed :function(pAllowed) { this.allowed = pAllowed && Minify ? pAllowed : { js : false, css : false, @@ -54,9 +54,9 @@ }; }, - optimize: function(pName, pParams){ + optimize: function(pName, pParams) { var lRet; - if(Minify){ + if (Minify) { pParams.name = Minify.getName(pName); lRet = this.allowed.css || this.allowed.js || this.allowed.html; @@ -67,14 +67,14 @@ if(pParams && pParams.force) Minify.optimize(pName, pParams); else if(lRet) - IsChanged.isFileChanged(pName, function(pChanged){ + IsChanged.isFileChanged(pName, function(pChanged) { if(pChanged) Minify.optimize(pName, pParams); else Util.exec(pParams.callback, pParams); }); } - else{ + else { this.allowed = { js : false, css : false, From eac6aee3f360fb64d01734fc1f876936c7eab266 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 9 Aug 2013 13:13:19 +0000 Subject: [PATCH 028/218] chore(server) add " " --- lib/server.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/server.js b/lib/server.js index 9bcf98e3..837d5b99 100644 --- a/lib/server.js +++ b/lib/server.js @@ -102,7 +102,7 @@ }; /* server mode or testing mode */ if (lConfig.server) { - if(lSSL) { + if (lSSL) { Util.log('* Redirection http -> https is setted up'); lServerLog(lHTTP, lPort); var lRedirectServer = http.createServer( function(pReq, pRes) { @@ -169,7 +169,6 @@ lRet = Util.exec(Route, lData); if(!lRet) { - /* добавляем текующий каталог к пути */ lName = lData.name; Util.log('reading ' + lName); @@ -180,7 +179,6 @@ Util.log(Path.basename(lName)); lName = DIR + lName; - lMin = Minify.allowed, lExt = Util.getExtension(lName), lResult = lExt === '.js' && lMin.js || From bf33a6e15130d187b55d114c8056995bbf567854 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 9 Aug 2013 13:14:02 +0000 Subject: [PATCH 029/218] fix(server) Dir + Name -> path.join(Dir, Name) --- lib/server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/server.js b/lib/server.js index 837d5b99..8ef8cf54 100644 --- a/lib/server.js +++ b/lib/server.js @@ -178,7 +178,7 @@ Util.log(Path.basename(lName)); - lName = DIR + lName; + lName = Path.join(DIR, lName); lMin = Minify.allowed, lExt = Util.getExtension(lName), lResult = lExt === '.js' && lMin.js || From 49e0d4de6d612ff943cbc65e8430f92bd971b701 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 15 Aug 2013 12:15:17 +0300 Subject: [PATCH 030/218] doc(readme) node.js: // -> http:// --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 10acd342..179d825a 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ Install --------------- **Cloud Commander** install is very easy. All you need is -- install [node.js](//nodejs.org/ "node.js") +- install [node.js](http://nodejs.org/ "node.js") - [download](https://github.com/coderaiser/cloudcmd/archive/master.zip) and unpack or just clone repository from github: From b2fc62334e24a1c6ff58bf1464a20317ac0b18cb Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 15 Aug 2013 14:34:07 +0000 Subject: [PATCH 031/218] refactor(rest) add putFile --- lib/server/rest.js | 80 ++++++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 28 deletions(-) diff --git a/lib/server/rest.js b/lib/server/rest.js index b316176f..6211560f 100644 --- a/lib/server/rest.js +++ b/lib/server/rest.js @@ -94,7 +94,7 @@ } function onFS(pParams) { - var p, lError, lMsg, lName, lZlib, lZipStream, lReadStream, lWriteStream, lSize, lQuery, + var p, lError, lMsg, lName, lZip, lReadStream, lSize, lQuery, lRet = main.checkParams(pParams); if (lRet){ @@ -145,41 +145,32 @@ }); else { - lName = p.name; - - lError = function(pError) { - main.sendError(pParams, pError); - }; if (lQuery === 'zip') { - lZlib = zlib.createGzip(); - lReadStream = fs.createReadStream(lName); - - lReadStream.on('error', lError); - - lReadStream = lReadStream.pipe(lZlib); - lName += '.' + lQuery; - lMsg = lQuery; + lZip = true; + lName = p.name + '.zip'; + lReadStream = fs.createReadStream(p.name); } else { - lReadStream = p.request; - lMsg = 'save'; + lName = p.name; + lReadStream = p.request; } - lWriteStream = fs.createWriteStream(lName); - - lWriteStream.on('error', lError); - lReadStream.on('error', lError); - - lWriteStream.on('open', function() { - lReadStream.pipe(lWriteStream); - - lReadStream.on('end', function() { - lName = path.basename(lName); - main.sendResponse(pParams, lMsg + ': ok("' + lName +'")'); - }); + putFile({ + name : lName, + read : lReadStream, + zip : lZip, + callback : function(pError, pMsg) { + if (pError) + main.sendError(pParams, pError); + else { + lName = path.basename(lName); + main.sendResponse(pParams, pMsg + ': ok("' + p.name +'")'); + } + } }); } break; + case 'DELETE': if (lQuery === 'dir') fs.rmdir(p.name, function(pError){ @@ -385,4 +376,37 @@ }); } + function putFile(pParams) { + var p, lZlib, lError, lMsg, lWrite, + lRet = Util.checkObj(pParams, ['name', 'read']); + + if (lRet) { + p = pParams; + lError = function(pError) { + Util.exec(p.callback, pError); + }; + + if (!p.zip) { + lMsg = 'save'; + } else { + lZlib = zlib.createGzip(); + p.read.on('error', lError); + p.read = p.read.pipe(lZlib); + lMsg = 'zip'; + } + + lWrite = fs.createWriteStream(p.name); + lWrite.on('error', lError); + p.read.on('error', lError); + + lWrite.on('open', function() { + p.read.pipe(lWrite); + + p.read.on('end', function() { + Util.exec(p.callback, null, lMsg); + }); + }); + } + } + })(); From 53420f11541a3cf8ea1c18ae08375560f89c282a Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 15 Aug 2013 15:06:05 +0000 Subject: [PATCH 032/218] chore(rest) "){" -> ") {" --- lib/server/rest.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/server/rest.js b/lib/server/rest.js index 6211560f..d3bd34f4 100644 --- a/lib/server/rest.js +++ b/lib/server/rest.js @@ -179,7 +179,7 @@ else main.sendError(pParams, pError); }); - else if (lQuery === 'files'){ + else if (lQuery === 'files') { getBody(p.request, function(pBody) { var lFiles = Util.parseJSON(pBody), n = lFiles.length, @@ -187,7 +187,7 @@ log = Util.retExec(Util.log), lAssync = 0; - function stat(pStat){ + function stat(pStat) { var lRet = Util.checkObjTrue(pStat, 'params') && Util.checkObjTrue(pStat.params, 'name'); @@ -248,7 +248,7 @@ var p = pParams, lCmd = p.command; - switch(lCmd){ + switch(lCmd) { case '': p.data = { info: 'Cloud Commander API v1' @@ -317,7 +317,7 @@ case 'mv': if( Util.checkObjTrue(lFiles, ['from', 'to']) ) - fs.rename(lFiles.from, lFiles.to, function(pError){ + fs.rename(lFiles.from, lFiles.to, function(pError) { if(!pError) main.sendResponse(pParams); else From 9dfa40ac947bb43df22ced3f54db767eb78a7e3d Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 15 Aug 2013 15:18:49 +0000 Subject: [PATCH 033/218] chore(rest) "copied to" -> "copy: ok" --- lib/server/rest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/server/rest.js b/lib/server/rest.js index d3bd34f4..812de827 100644 --- a/lib/server/rest.js +++ b/lib/server/rest.js @@ -341,7 +341,7 @@ lReadStream.on('error', lError); lReadStream.on('end', function(){ - main.sendResponse(pParams, 'copied to: ' + l.to); + main.sendResponse(pParams, 'copy: ok("' + l.to + '")'); }); lReadStream.pipe(lWriteStream); From 81b397a339666620c38f311aeef71fd7518bbc00 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 15 Aug 2013 15:21:15 +0000 Subject: [PATCH 034/218] chore(rest) add " --- lib/server/rest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/server/rest.js b/lib/server/rest.js index 812de827..f1d3a485 100644 --- a/lib/server/rest.js +++ b/lib/server/rest.js @@ -225,7 +225,7 @@ }else fs.unlink(p.name, function(pError) { if (!pError) - main.sendResponse(pParams, 'delete: ok(' + p.name + '")'); + main.sendResponse(pParams, 'delete: ok("' + p.name + '")'); else main.sendError(pParams, pError); }); From 4bd98be8687539058828dc1d19f04ce79178dcda Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 16 Aug 2013 10:21:33 +0300 Subject: [PATCH 035/218] chore(rest) Folder created -> make dir: ok --- lib/server/rest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/server/rest.js b/lib/server/rest.js index f1d3a485..4dca3cc9 100644 --- a/lib/server/rest.js +++ b/lib/server/rest.js @@ -139,7 +139,7 @@ if (lQuery === 'dir') fs.mkdir(p.name, function(pError) { if (!pError) - main.sendResponse(pParams, 'Folder ' + p.name + ' created.'); + main.sendResponse(pParams, 'make dir: ok("' + p.name + '")'); else main.sendError(pParams, pError); }); From 7031a8478e0cee4e8c6210218eb8bfa508450767 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 16 Aug 2013 07:36:55 +0000 Subject: [PATCH 036/218] refactor(rest) main.sendResponse -> sendMsg --- lib/server/rest.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/server/rest.js b/lib/server/rest.js index 4dca3cc9..c964a7f4 100644 --- a/lib/server/rest.js +++ b/lib/server/rest.js @@ -139,7 +139,7 @@ if (lQuery === 'dir') fs.mkdir(p.name, function(pError) { if (!pError) - main.sendResponse(pParams, 'make dir: ok("' + p.name + '")'); + sendMsg(pParams, 'make dir', p.name); else main.sendError(pParams, pError); }); @@ -164,7 +164,7 @@ main.sendError(pParams, pError); else { lName = path.basename(lName); - main.sendResponse(pParams, pMsg + ': ok("' + p.name +'")'); + sendMsg(pParams, 'ok', p.name); } } }); @@ -175,7 +175,7 @@ if (lQuery === 'dir') fs.rmdir(p.name, function(pError){ if (!pError) - main.sendResponse(pParams, 'delete: ok("' + p.name + '")'); + sendMsg(pParams, 'delete', p.name); else main.sendError(pParams, pError); }); @@ -209,7 +209,7 @@ fs.unlink(d.name, log); if (lAssync === n && !p.error) - main.sendResponse(pParams, 'delete: ok("' + pBody + '")'); + sendMsg(pParams, 'delete', pBody); } } @@ -225,7 +225,7 @@ }else fs.unlink(p.name, function(pError) { if (!pError) - main.sendResponse(pParams, 'delete: ok("' + p.name + '")'); + sendMsg(pParams, 'delete', p.name); else main.sendError(pParams, pError); }); @@ -341,7 +341,7 @@ lReadStream.on('error', lError); lReadStream.on('end', function(){ - main.sendResponse(pParams, 'copy: ok("' + l.to + '")'); + sendMsg(pParams, 'copy', l.to); }); lReadStream.pipe(lWriteStream); @@ -409,4 +409,8 @@ } } + function sendMsg(pParams, pMsg, pName) { + main.sendResponse(pParams, pMsg + ': ok("' + pName + '")'); + } + })(); From eb30bd08537a8b5af6044d25ef423abbd317756a Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 16 Aug 2013 11:30:57 +0000 Subject: [PATCH 037/218] feature(edit) rm "nothing to save" --- lib/client/edit.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/client/edit.js b/lib/client/edit.js index 7fdef548..2780cd60 100644 --- a/lib/client/edit.js +++ b/lib/client/edit.js @@ -75,10 +75,7 @@ var CloudCmd, Util, DOM, JsDiff, ace; var lPath = DOM.getCurrentPath(), lValue = Ace.getValue(); - if ( Util.strCmp(Value, lValue) ) - Util.log('edit: nothing to save'); - else - DOM.RESTfull.save(lPath, lValue); + DOM.RESTfull.save(lPath, lValue); } }); } From 09919bad5c7bedf4505d5c07af87bd5a388ea826 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 16 Aug 2013 12:57:32 +0000 Subject: [PATCH 038/218] feature(console) rm jquery-migrate --- lib/client/console.js | 3 +- lib/client/console/jqconsole.js | 62 +++ lib/client/console/jquery-migrate-1.2.1.js | 521 --------------------- 3 files changed, 63 insertions(+), 523 deletions(-) delete mode 100644 lib/client/console/jquery-migrate-1.2.1.js diff --git a/lib/client/console.js b/lib/client/console.js index 32d6a744..11cb51d6 100644 --- a/lib/client/console.js +++ b/lib/client/console.js @@ -129,8 +129,7 @@ var CloudCmd, Util, DOM, $; lFiles = [ lDir + 'jqconsole.js', lDir + 'jqconsole.css', - lDir + 'ansi.css', - lDir + 'jquery-migrate-1.2.1.js' + lDir + 'ansi.css' ]; DOM.anyLoadInParallel(lFiles, function(){ diff --git a/lib/client/console/jqconsole.js b/lib/client/console/jqconsole.js index dc1c0bfb..0561b911 100644 --- a/lib/client/console/jqconsole.js +++ b/lib/client/console/jqconsole.js @@ -4,7 +4,69 @@ Copyrights 2011, the repl.it project. Licensed under the MIT license */ +// Limit scope pollution from any deprecated API +(function() { + var matched, browser; + +// Use of jQuery.browser is frowned upon. +// More details: http://api.jquery.com/jQuery.browser +// jQuery.uaMatch maintained for back-compat + jQuery.uaMatch = function( ua ) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || + /(webkit)[ \/]([\w.]+)/.exec( ua ) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || + /(msie) ([\w.]+)/.exec( ua ) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + + matched = jQuery.uaMatch( navigator.userAgent ); + browser = {}; + + if ( matched.browser ) { + browser[ matched.browser ] = true; + browser.version = matched.version; + } + +// Chrome is Webkit, but Webkit is also Safari. + if ( browser.chrome ) { + browser.webkit = true; + } else if ( browser.webkit ) { + browser.safari = true; + } + + jQuery.browser = browser; + + jQuery.sub = function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; + }; + +})(); (function() { var $, Ansi, CLASS_ANSI, CLASS_BLURRED, CLASS_CURSOR, CLASS_HEADER, CLASS_INPUT, CLASS_OLD_PROMPT, CLASS_PREFIX, CLASS_PROMPT, DEFAULT_INDENT_WIDTH, DEFAULT_PROMPT_CONINUE_LABEL, DEFAULT_PROMPT_LABEL, EMPTY_DIV, EMPTY_SELECTOR, EMPTY_SPAN, ESCAPE_CHAR, ESCAPE_SYNTAX, E_KEYPRESS, JQConsole, KEY_BACKSPACE, KEY_DELETE, KEY_DOWN, KEY_END, KEY_ENTER, KEY_HOME, KEY_LEFT, KEY_PAGE_DOWN, KEY_PAGE_UP, KEY_RIGHT, KEY_TAB, KEY_UP, NEWLINE, STATE_INPUT, STATE_OUTPUT, STATE_PROMPT, spanHtml, diff --git a/lib/client/console/jquery-migrate-1.2.1.js b/lib/client/console/jquery-migrate-1.2.1.js deleted file mode 100644 index cf3e74c2..00000000 --- a/lib/client/console/jquery-migrate-1.2.1.js +++ /dev/null @@ -1,521 +0,0 @@ -/*! - * jQuery Migrate - v1.2.1 - 2013-05-08 - * https://github.com/jquery/jquery-migrate - * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors; Licensed MIT - */ -(function( jQuery, window, undefined ) { -// See http://bugs.jquery.com/ticket/13335 -// "use strict"; - - -var warnedAbout = {}; - -// List of warnings already given; public read only -jQuery.migrateWarnings = []; - -// Set to true to prevent console output; migrateWarnings still maintained -// jQuery.migrateMute = false; - -// Show a message on the console so devs know we're active -if ( !jQuery.migrateMute && window.console && window.console.log ) { - window.console.log("JQMIGRATE: Logging is active"); -} - -// Set to false to disable traces that appear with warnings -if ( jQuery.migrateTrace === undefined ) { - jQuery.migrateTrace = true; -} - -// Forget any warnings we've already given; public -jQuery.migrateReset = function() { - warnedAbout = {}; - jQuery.migrateWarnings.length = 0; -}; - -function migrateWarn( msg) { - var console = window.console; - if ( !warnedAbout[ msg ] ) { - warnedAbout[ msg ] = true; - jQuery.migrateWarnings.push( msg ); - if ( console && console.warn && !jQuery.migrateMute ) { - console.warn( "JQMIGRATE: " + msg ); - if ( jQuery.migrateTrace && console.trace ) { - console.trace(); - } - } - } -} - -function migrateWarnProp( obj, prop, value, msg ) { - if ( Object.defineProperty ) { - // On ES5 browsers (non-oldIE), warn if the code tries to get prop; - // allow property to be overwritten in case some other plugin wants it - try { - Object.defineProperty( obj, prop, { - configurable: true, - enumerable: true, - get: function() { - migrateWarn( msg ); - return value; - }, - set: function( newValue ) { - migrateWarn( msg ); - value = newValue; - } - }); - return; - } catch( err ) { - // IE8 is a dope about Object.defineProperty, can't warn there - } - } - - // Non-ES5 (or broken) browser; just set the property - jQuery._definePropertyBroken = true; - obj[ prop ] = value; -} - -if ( document.compatMode === "BackCompat" ) { - // jQuery has never supported or tested Quirks Mode - migrateWarn( "jQuery is not compatible with Quirks Mode" ); -} - - -var attrFn = jQuery( "", { size: 1 } ).attr("size") && jQuery.attrFn, - oldAttr = jQuery.attr, - valueAttrGet = jQuery.attrHooks.value && jQuery.attrHooks.value.get || - function() { return null; }, - valueAttrSet = jQuery.attrHooks.value && jQuery.attrHooks.value.set || - function() { return undefined; }, - rnoType = /^(?:input|button)$/i, - rnoAttrNodeType = /^[238]$/, - rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, - ruseDefault = /^(?:checked|selected)$/i; - -// jQuery.attrFn -migrateWarnProp( jQuery, "attrFn", attrFn || {}, "jQuery.attrFn is deprecated" ); - -jQuery.attr = function( elem, name, value, pass ) { - var lowerName = name.toLowerCase(), - nType = elem && elem.nodeType; - - if ( pass ) { - // Since pass is used internally, we only warn for new jQuery - // versions where there isn't a pass arg in the formal params - if ( oldAttr.length < 4 ) { - migrateWarn("jQuery.fn.attr( props, pass ) is deprecated"); - } - if ( elem && !rnoAttrNodeType.test( nType ) && - (attrFn ? name in attrFn : jQuery.isFunction(jQuery.fn[name])) ) { - return jQuery( elem )[ name ]( value ); - } - } - - // Warn if user tries to set `type`, since it breaks on IE 6/7/8; by checking - // for disconnected elements we don't warn on $( "\ + \ \ \
\ @@ -244,7 +244,7 @@ var SearchBox = function(editor, range, showReplaceForm) { event.stopPropagation(e); }); event.addListener(sb, "click", function(e) { - var t = e.target; + var t = e.target || e.srcElement; var action = t.getAttribute("action"); if (action && _this[action]) _this[action](); @@ -369,10 +369,18 @@ var SearchBox = function(editor, range, showReplaceForm) { this.find(true, true); }; this.replace = function() { - this.editor.replace(this.replaceInput.value); + if (!this.editor.getReadOnly()) + this.editor.replace(this.replaceInput.value); + }; + this.replaceAndFindNext = function() { + if (!this.editor.getReadOnly()) { + this.editor.replace(this.replaceInput.value); + this.findNext() + } }; this.replaceAll = function() { - this.editor.replaceAll(this.replaceInput.value); + if (!this.editor.getReadOnly()) + this.editor.replaceAll(this.replaceInput.value); }; this.hide = function() { @@ -403,45 +411,4 @@ exports.Search = function(editor, isReplace) { sb.show(editor.session.getTextRange(), isReplace); }; - -exports.ISearch = function(session, options) { - this.$changeListener = this.$changeListener.bind(this); - this.startRange = session.selection.toOrientedRange(); - this.options = options || {}; -}; - -(function(){ - this.setSession = function(session) { - if (this.session) { - this.session.removeListener(this.$changeListener); - } - this.session = session; - this.session.addListener(this.$changeListener); - }; - this.setSearchString = function() { - - }; - this.getValue = function() { - if (this.value == null) - this.value = this.session.getValue(); - return this.value; - }; - this.$changeListener = function() { - this.value = null; - }; - this.find = function() { - - }; - this.$edgeBefore = function() { - this.cursor = this.startRange[this.options.backwards ? "start" : "end"]; - }; - this.$edgeAfter = function() { - - }; - this.next = function(dir) { - - }; -}).call(exports.ISearch.prototype); - - }); diff --git a/lib/client/edit/mode-javascript.js b/lib/client/edit/mode-javascript.js index 5bfc25dd..bf541754 100644 --- a/lib/client/edit/mode-javascript.js +++ b/lib/client/edit/mode-javascript.js @@ -28,7 +28,7 @@ * * ***** END LICENSE BLOCK ***** */ -define('ace/mode/javascript', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text', 'ace/tokenizer', 'ace/mode/javascript_highlight_rules', 'ace/mode/matching_brace_outdent', 'ace/range', 'ace/worker/worker_client', 'ace/mode/behaviour/cstyle', 'ace/mode/folding/cstyle'], function(require, exports, module) { +ace.define('ace/mode/javascript', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text', 'ace/tokenizer', 'ace/mode/javascript_highlight_rules', 'ace/mode/matching_brace_outdent', 'ace/range', 'ace/worker/worker_client', 'ace/mode/behaviour/cstyle', 'ace/mode/folding/cstyle'], function(require, exports, module) { var oop = require("../lib/oop"); @@ -42,9 +42,12 @@ var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; var CStyleFoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { - this.$tokenizer = new Tokenizer(new JavaScriptHighlightRules().getRules()); + var highlighter = new JavaScriptHighlightRules(); + + this.$tokenizer = new Tokenizer(highlighter.getRules()); this.$outdent = new MatchingBraceOutdent(); this.$behaviour = new CstyleBehaviour(); + this.$keywordList = highlighter.$keywordList; this.foldingRules = new CStyleFoldMode(); }; oop.inherits(Mode, TextMode); @@ -114,7 +117,7 @@ oop.inherits(Mode, TextMode); exports.Mode = Mode; }); -define('ace/mode/javascript_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/doc_comment_highlight_rules', 'ace/mode/text_highlight_rules'], function(require, exports, module) { +ace.define('ace/mode/javascript_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/doc_comment_highlight_rules', 'ace/mode/text_highlight_rules'], function(require, exports, module) { var oop = require("../lib/oop"); @@ -163,7 +166,8 @@ var JavaScriptHighlightRules = function() { "no_regex" : [ { token : "comment", - regex : /\/\/.*$/ + regex : "\\/\\/", + next : "line_comment" }, DocCommentHighlightRules.getStartRule("doc-start"), { @@ -238,7 +242,7 @@ var JavaScriptHighlightRules = function() { next : "start" }, { token : ["punctuation.operator", "support.function"], - regex : /(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:opzzzz|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/ + regex : /(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/ }, { token : ["punctuation.operator", "support.function.dom"], regex : /(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/ @@ -283,8 +287,8 @@ var JavaScriptHighlightRules = function() { next : "comment_regex_allowed" }, { token : "comment", - regex : "\\/\\/.*$", - next : "start" + regex : "\\/\\/", + next : "line_comment_regex_allowed" }, { token: "string.regexp", regex: "\\/", @@ -371,6 +375,14 @@ var JavaScriptHighlightRules = function() { {token : "comment", regex : "\\*\\/", next : "no_regex"}, {defaultToken : "comment"} ], + "line_comment_regex_allowed" : [ + {token : "comment", regex : "$|^", next : "start"}, + {defaultToken : "comment"} + ], + "line_comment" : [ + {token : "comment", regex : "$|^", next : "no_regex"}, + {defaultToken : "comment"} + ], "qqstring" : [ { token : "constant.language.escape", @@ -414,7 +426,7 @@ oop.inherits(JavaScriptHighlightRules, TextHighlightRules); exports.JavaScriptHighlightRules = JavaScriptHighlightRules; }); -define('ace/mode/doc_comment_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text_highlight_rules'], function(require, exports, module) { +ace.define('ace/mode/doc_comment_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text_highlight_rules'], function(require, exports, module) { var oop = require("../lib/oop"); @@ -458,7 +470,7 @@ exports.DocCommentHighlightRules = DocCommentHighlightRules; }); -define('ace/mode/matching_brace_outdent', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) { +ace.define('ace/mode/matching_brace_outdent', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) { var Range = require("../range").Range; @@ -498,7 +510,7 @@ var MatchingBraceOutdent = function() {}; exports.MatchingBraceOutdent = MatchingBraceOutdent; }); -define('ace/mode/behaviour/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/behaviour', 'ace/token_iterator', 'ace/lib/lang'], function(require, exports, module) { +ace.define('ace/mode/behaviour/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/behaviour', 'ace/token_iterator', 'ace/lib/lang'], function(require, exports, module) { var oop = require("../../lib/oop"); @@ -821,7 +833,7 @@ oop.inherits(CstyleBehaviour, Behaviour); exports.CstyleBehaviour = CstyleBehaviour; }); -define('ace/mode/folding/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/range', 'ace/mode/folding/fold_mode'], function(require, exports, module) { +ace.define('ace/mode/folding/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/range', 'ace/mode/folding/fold_mode'], function(require, exports, module) { var oop = require("../../lib/oop"); @@ -873,4 +885,4 @@ oop.inherits(FoldMode, BaseFoldMode); }).call(FoldMode.prototype); -}); \ No newline at end of file +}); diff --git a/lib/client/edit/theme-tomorrow_night_blue.js b/lib/client/edit/theme-tomorrow_night_blue.js index 86c6e45f..30e1146e 100644 --- a/lib/client/edit/theme-tomorrow_night_blue.js +++ b/lib/client/edit/theme-tomorrow_night_blue.js @@ -28,7 +28,7 @@ * * ***** END LICENSE BLOCK ***** */ -define('ace/theme/tomorrow_night_blue', ['require', 'exports', 'module' , 'ace/lib/dom'], function(require, exports, module) { +ace.define('ace/theme/tomorrow_night_blue', ['require', 'exports', 'module' , 'ace/lib/dom'], function(require, exports, module) { exports.isDark = true; exports.cssClass = "ace-tomorrow-night-blue"; @@ -119,7 +119,7 @@ color: #BBDAFF\ .ace-tomorrow-night-blue .ace_support.ace_type {\ color: #FFEEAD\ }\ -.ace-tomorrow-night-blue .ace_markup.ace_heading,\ +.ace-tomorrow-night-blue .ace_heading,\ .ace-tomorrow-night-blue .ace_string {\ color: #D1F1A9\ }\ @@ -133,13 +133,10 @@ color: #FF9DA4\ .ace-tomorrow-night-blue .ace_comment {\ color: #7285B7\ }\ -.ace-tomorrow-night-blue .ace_markup.ace_underline {\ -text-decoration: underline\ -}\ .ace-tomorrow-night-blue .ace_indent-guide {\ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYJDzqfwPAANXAeNsiA+ZAAAAAElFTkSuQmCC) right repeat-y;\ }"; var dom = require("../lib/dom"); dom.importCssString(exports.cssText, exports.cssClass); -}); \ No newline at end of file +}); diff --git a/lib/client/edit/worker-javascript.js b/lib/client/edit/worker-javascript.js index 95aee706..8beac737 100644 --- a/lib/client/edit/worker-javascript.js +++ b/lib/client/edit/worker-javascript.js @@ -4,16 +4,15 @@ if (typeof window.window != "undefined" && window.document) { return; } -window.console = { - log: function() { - var msgs = Array.prototype.slice.call(arguments, 0); - postMessage({type: "log", data: msgs}); - }, - error: function() { - var msgs = Array.prototype.slice.call(arguments, 0); - postMessage({type: "log", data: msgs}); - } +window.console = function() { + var msgs = Array.prototype.slice.call(arguments, 0); + postMessage({type: "log", data: msgs}); }; +window.console.error = +window.console.warn = +window.console.log = +window.console.trace = window.console; + window.window = window; window.ace = window; @@ -86,10 +85,9 @@ window.define = function(id, deps, factory) { }; require.modules[id] = { + exports: {}, factory: function() { - var module = { - exports: {} - }; + var module = this; var returnExports = factory(req, module.exports, module); if (returnExports) module.exports = returnExports; @@ -158,7 +156,7 @@ window.onmessage = function(e) { }; })(this); -define('ace/lib/event_emitter', ['require', 'exports', 'module' ], function(require, exports, module) { +ace.define('ace/lib/event_emitter', ['require', 'exports', 'module' ], function(require, exports, module) { var EventEmitter = {}; @@ -283,7 +281,7 @@ exports.EventEmitter = EventEmitter; }); -define('ace/lib/oop', ['require', 'exports', 'module' ], function(require, exports, module) { +ace.define('ace/lib/oop', ['require', 'exports', 'module' ], function(require, exports, module) { exports.inherits = (function() { @@ -309,7 +307,7 @@ exports.implement = function(proto, mixin) { }); -define('ace/lib/es5-shim', ['require', 'exports', 'module' ], function(require, exports, module) { +ace.define('ace/lib/es5-shim', ['require', 'exports', 'module' ], function(require, exports, module) { function Empty() {} @@ -1006,7 +1004,7 @@ var toObject = function (o) { }); -define('ace/mode/javascript_worker', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/worker/mirror', 'ace/mode/javascript/jshint'], function(require, exports, module) { +ace.define('ace/mode/javascript_worker', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/worker/mirror', 'ace/mode/javascript/jshint'], function(require, exports, module) { var oop = require("../lib/oop"); @@ -1055,8 +1053,8 @@ oop.inherits(JavaScriptWorker, Mirror); (function() { this.setOptions = function(options) { this.options = options || { - es5: true, esnext: true, + moz: true, devel: true, browser: true, node: true, @@ -1153,7 +1151,7 @@ oop.inherits(JavaScriptWorker, Mirror); }).call(JavaScriptWorker.prototype); }); -define('ace/worker/mirror', ['require', 'exports', 'module' , 'ace/document', 'ace/lib/lang'], function(require, exports, module) { +ace.define('ace/worker/mirror', ['require', 'exports', 'module' , 'ace/document', 'ace/lib/lang'], function(require, exports, module) { var Document = require("../document").Document; @@ -1196,7 +1194,7 @@ var Mirror = exports.Mirror = function(sender) { }); -define('ace/document', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter', 'ace/range', 'ace/anchor'], function(require, exports, module) { +ace.define('ace/document', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter', 'ace/range', 'ace/anchor'], function(require, exports, module) { var oop = require("./lib/oop"); @@ -1282,7 +1280,7 @@ var Document = function(text) { }; this.getTextRange = function(range) { if (range.start.row == range.end.row) { - return this.$lines[range.start.row] + return this.getLine(range.start.row) .substring(range.start.column, range.end.column); } var lines = this.getLines(range.start.row, range.end.row); @@ -1548,7 +1546,7 @@ var Document = function(text) { exports.Document = Document; }); -define('ace/range', ['require', 'exports', 'module' ], function(require, exports, module) { +ace.define('ace/range', ['require', 'exports', 'module' ], function(require, exports, module) { var comparePoints = function(p1, p2) { return p1.row - p2.row || p1.column - p2.column; @@ -1787,36 +1785,31 @@ Range.comparePoints = function(p1, p2) { exports.Range = Range; }); -define('ace/anchor', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter'], function(require, exports, module) { +ace.define('ace/anchor', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter'], function(require, exports, module) { var oop = require("./lib/oop"); var EventEmitter = require("./lib/event_emitter").EventEmitter; var Anchor = exports.Anchor = function(doc, row, column) { - this.document = doc; - + this.$onChange = this.onChange.bind(this); + this.attach(doc); + if (typeof column == "undefined") this.setPosition(row.row, row.column); else this.setPosition(row, column); - - this.$onChange = this.onChange.bind(this); - doc.on("change", this.$onChange); }; (function() { oop.implement(this, EventEmitter); - this.getPosition = function() { return this.$clipPositionToDocument(this.row, this.column); }; - this.getDocument = function() { return this.document; }; - this.onChange = function(e) { var delta = e.data; var range = delta.range; @@ -1878,7 +1871,6 @@ var Anchor = exports.Anchor = function(doc, row, column) { this.setPosition(row, column, true); }; - this.setPosition = function(row, column, noClip) { var pos; if (noClip) { @@ -1905,10 +1897,13 @@ var Anchor = exports.Anchor = function(doc, row, column) { value: pos }); }; - this.detach = function() { this.document.removeEventListener("change", this.$onChange); }; + this.attach = function(doc) { + this.document = doc || this.document; + this.document.on("change", this.$onChange); + }; this.$clipPositionToDocument = function(row, column) { var pos = {}; @@ -1935,7 +1930,7 @@ var Anchor = exports.Anchor = function(doc, row, column) { }); -define('ace/lib/lang', ['require', 'exports', 'module' ], function(require, exports, module) { +ace.define('ace/lib/lang', ['require', 'exports', 'module' ], function(require, exports, module) { exports.stringReverse = function(string) { @@ -2111,13 +2106,1089 @@ exports.delayedCall = function(fcn, defaultTimeout) { return _self; }; }); -define('ace/mode/javascript/jshint', ['require', 'exports', 'module' ], function(require, exports, module) { +ace.define('ace/mode/javascript/jshint', ['require', 'exports', 'module' ], function(require, exports, module) { +var require; +require=(function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s 0) { + var fn = queue.shift(); + fn(); + } + } + }, true); + + return function nextTick(fn) { + queue.push(fn); + window.postMessage('process-tick', '*'); + }; + } + + return function nextTick(fn) { + setTimeout(fn, 0); + }; +})(); + +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +} +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; + +}, +{}], +2:[function(req,module,exports){ +(function(process){if (!process.EventEmitter) process.EventEmitter = function () {}; + +var EventEmitter = exports.EventEmitter = process.EventEmitter; +var isArray = typeof Array.isArray === 'function' + ? Array.isArray + : function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]' + } +; +function indexOf (xs, x) { + if (xs.indexOf) return xs.indexOf(x); + for (var i = 0; i < xs.length; i++) { + if (x === xs[i]) return i; + } + return -1; +} +var defaultMaxListeners = 200; +EventEmitter.prototype.setMaxListeners = function(n) { + if (!this._events) this._events = {}; + this._events.maxListeners = n; +}; + + +EventEmitter.prototype.emit = function(type) { + if (type === 'error') { + if (!this._events || !this._events.error || + (isArray(this._events.error) && !this._events.error.length)) + { + if (arguments[1] instanceof Error) { + throw arguments[1]; // Unhandled 'error' event + } else { + throw new Error("Uncaught, unspecified 'error' event."); + } + return false; + } + } + + if (!this._events) return false; + var handler = this._events[type]; + if (!handler) return false; + + if (typeof handler == 'function') { + switch (arguments.length) { + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + default: + var args = Array.prototype.slice.call(arguments, 1); + handler.apply(this, args); + } + return true; + + } else if (isArray(handler)) { + var args = Array.prototype.slice.call(arguments, 1); + + var listeners = handler.slice(); + for (var i = 0, l = listeners.length; i < l; i++) { + listeners[i].apply(this, args); + } + return true; + + } else { + return false; + } +}; +EventEmitter.prototype.addListener = function(type, listener) { + if ('function' !== typeof listener) { + throw new Error('addListener only takes instances of Function'); + } + + if (!this._events) this._events = {}; + this.emit('newListener', type, listener); + + if (!this._events[type]) { + this._events[type] = listener; + } else if (isArray(this._events[type])) { + if (!this._events[type].warned) { + var m; + if (this._events.maxListeners !== undefined) { + m = this._events.maxListeners; + } else { + m = defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + console.trace(); + } + } + this._events[type].push(listener); + } else { + this._events[type] = [this._events[type], listener]; + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + var self = this; + self.on(type, function g() { + self.removeListener(type, g); + listener.apply(this, arguments); + }); + + return this; +}; + +EventEmitter.prototype.removeListener = function(type, listener) { + if ('function' !== typeof listener) { + throw new Error('removeListener only takes instances of Function'); + } + if (!this._events || !this._events[type]) return this; + + var list = this._events[type]; + + if (isArray(list)) { + var i = indexOf(list, listener); + if (i < 0) return this; + list.splice(i, 1); + if (list.length == 0) + delete this._events[type]; + } else if (this._events[type] === listener) { + delete this._events[type]; + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + if (arguments.length === 0) { + this._events = {}; + return this; + } + if (type && this._events && this._events[type]) this._events[type] = null; + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + if (!this._events) this._events = {}; + if (!this._events[type]) this._events[type] = []; + if (!isArray(this._events[type])) { + this._events[type] = [this._events[type]]; + } + return this._events[type]; +}; + +})(req("__browserify_process")) +}, +{"__browserify_process":1}], +3:[function(req,module,exports){ +(function(){// jshint -W001 + +exports.reservedVars = { + arguments : false, + NaN : false +}; + +exports.ecmaIdentifiers = { + Array : false, + Boolean : false, + Date : false, + decodeURI : false, + decodeURIComponent : false, + encodeURI : false, + encodeURIComponent : false, + Error : false, + "eval" : false, + EvalError : false, + Function : false, + hasOwnProperty : false, + isFinite : false, + isNaN : false, + JSON : false, + Math : false, + Map : false, + Number : false, + Object : false, + parseInt : false, + parseFloat : false, + RangeError : false, + ReferenceError : false, + RegExp : false, + Set : false, + String : false, + SyntaxError : false, + TypeError : false, + URIError : false, + WeakMap : false +}; + +exports.browser = { + ArrayBuffer : false, + ArrayBufferView : false, + Audio : false, + Blob : false, + addEventListener : false, + applicationCache : false, + atob : false, + blur : false, + btoa : false, + clearInterval : false, + clearTimeout : false, + close : false, + closed : false, + DataView : false, + DOMParser : false, + defaultStatus : false, + document : false, + Element : false, + ElementTimeControl : false, + event : false, + FileReader : false, + Float32Array : false, + Float64Array : false, + FormData : false, + focus : false, + frames : false, + getComputedStyle : false, + HTMLElement : false, + HTMLAnchorElement : false, + HTMLBaseElement : false, + HTMLBlockquoteElement: false, + HTMLBodyElement : false, + HTMLBRElement : false, + HTMLButtonElement : false, + HTMLCanvasElement : false, + HTMLDirectoryElement : false, + HTMLDivElement : false, + HTMLDListElement : false, + HTMLFieldSetElement : false, + HTMLFontElement : false, + HTMLFormElement : false, + HTMLFrameElement : false, + HTMLFrameSetElement : false, + HTMLHeadElement : false, + HTMLHeadingElement : false, + HTMLHRElement : false, + HTMLHtmlElement : false, + HTMLIFrameElement : false, + HTMLImageElement : false, + HTMLInputElement : false, + HTMLIsIndexElement : false, + HTMLLabelElement : false, + HTMLLayerElement : false, + HTMLLegendElement : false, + HTMLLIElement : false, + HTMLLinkElement : false, + HTMLMapElement : false, + HTMLMenuElement : false, + HTMLMetaElement : false, + HTMLModElement : false, + HTMLObjectElement : false, + HTMLOListElement : false, + HTMLOptGroupElement : false, + HTMLOptionElement : false, + HTMLParagraphElement : false, + HTMLParamElement : false, + HTMLPreElement : false, + HTMLQuoteElement : false, + HTMLScriptElement : false, + HTMLSelectElement : false, + HTMLStyleElement : false, + HTMLTableCaptionElement: false, + HTMLTableCellElement : false, + HTMLTableColElement : false, + HTMLTableElement : false, + HTMLTableRowElement : false, + HTMLTableSectionElement: false, + HTMLTextAreaElement : false, + HTMLTitleElement : false, + HTMLUListElement : false, + HTMLVideoElement : false, + history : false, + Int16Array : false, + Int32Array : false, + Int8Array : false, + Image : false, + length : false, + localStorage : false, + location : false, + MessageChannel : false, + MessageEvent : false, + MessagePort : false, + moveBy : false, + moveTo : false, + MutationObserver : false, + name : false, + Node : false, + NodeFilter : false, + navigator : false, + onbeforeunload : true, + onblur : true, + onerror : true, + onfocus : true, + onload : true, + onresize : true, + onunload : true, + open : false, + openDatabase : false, + opener : false, + Option : false, + parent : false, + print : false, + removeEventListener : false, + resizeBy : false, + resizeTo : false, + screen : false, + scroll : false, + scrollBy : false, + scrollTo : false, + sessionStorage : false, + setInterval : false, + setTimeout : false, + SharedWorker : false, + status : false, + SVGAElement : false, + SVGAltGlyphDefElement: false, + SVGAltGlyphElement : false, + SVGAltGlyphItemElement: false, + SVGAngle : false, + SVGAnimateColorElement: false, + SVGAnimateElement : false, + SVGAnimateMotionElement: false, + SVGAnimateTransformElement: false, + SVGAnimatedAngle : false, + SVGAnimatedBoolean : false, + SVGAnimatedEnumeration: false, + SVGAnimatedInteger : false, + SVGAnimatedLength : false, + SVGAnimatedLengthList: false, + SVGAnimatedNumber : false, + SVGAnimatedNumberList: false, + SVGAnimatedPathData : false, + SVGAnimatedPoints : false, + SVGAnimatedPreserveAspectRatio: false, + SVGAnimatedRect : false, + SVGAnimatedString : false, + SVGAnimatedTransformList: false, + SVGAnimationElement : false, + SVGCSSRule : false, + SVGCircleElement : false, + SVGClipPathElement : false, + SVGColor : false, + SVGColorProfileElement: false, + SVGColorProfileRule : false, + SVGComponentTransferFunctionElement: false, + SVGCursorElement : false, + SVGDefsElement : false, + SVGDescElement : false, + SVGDocument : false, + SVGElement : false, + SVGElementInstance : false, + SVGElementInstanceList: false, + SVGEllipseElement : false, + SVGExternalResourcesRequired: false, + SVGFEBlendElement : false, + SVGFEColorMatrixElement: false, + SVGFEComponentTransferElement: false, + SVGFECompositeElement: false, + SVGFEConvolveMatrixElement: false, + SVGFEDiffuseLightingElement: false, + SVGFEDisplacementMapElement: false, + SVGFEDistantLightElement: false, + SVGFEFloodElement : false, + SVGFEFuncAElement : false, + SVGFEFuncBElement : false, + SVGFEFuncGElement : false, + SVGFEFuncRElement : false, + SVGFEGaussianBlurElement: false, + SVGFEImageElement : false, + SVGFEMergeElement : false, + SVGFEMergeNodeElement: false, + SVGFEMorphologyElement: false, + SVGFEOffsetElement : false, + SVGFEPointLightElement: false, + SVGFESpecularLightingElement: false, + SVGFESpotLightElement: false, + SVGFETileElement : false, + SVGFETurbulenceElement: false, + SVGFilterElement : false, + SVGFilterPrimitiveStandardAttributes: false, + SVGFitToViewBox : false, + SVGFontElement : false, + SVGFontFaceElement : false, + SVGFontFaceFormatElement: false, + SVGFontFaceNameElement: false, + SVGFontFaceSrcElement: false, + SVGFontFaceUriElement: false, + SVGForeignObjectElement: false, + SVGGElement : false, + SVGGlyphElement : false, + SVGGlyphRefElement : false, + SVGGradientElement : false, + SVGHKernElement : false, + SVGICCColor : false, + SVGImageElement : false, + SVGLangSpace : false, + SVGLength : false, + SVGLengthList : false, + SVGLineElement : false, + SVGLinearGradientElement: false, + SVGLocatable : false, + SVGMPathElement : false, + SVGMarkerElement : false, + SVGMaskElement : false, + SVGMatrix : false, + SVGMetadataElement : false, + SVGMissingGlyphElement: false, + SVGNumber : false, + SVGNumberList : false, + SVGPaint : false, + SVGPathElement : false, + SVGPathSeg : false, + SVGPathSegArcAbs : false, + SVGPathSegArcRel : false, + SVGPathSegClosePath : false, + SVGPathSegCurvetoCubicAbs: false, + SVGPathSegCurvetoCubicRel: false, + SVGPathSegCurvetoCubicSmoothAbs: false, + SVGPathSegCurvetoCubicSmoothRel: false, + SVGPathSegCurvetoQuadraticAbs: false, + SVGPathSegCurvetoQuadraticRel: false, + SVGPathSegCurvetoQuadraticSmoothAbs: false, + SVGPathSegCurvetoQuadraticSmoothRel: false, + SVGPathSegLinetoAbs : false, + SVGPathSegLinetoHorizontalAbs: false, + SVGPathSegLinetoHorizontalRel: false, + SVGPathSegLinetoRel : false, + SVGPathSegLinetoVerticalAbs: false, + SVGPathSegLinetoVerticalRel: false, + SVGPathSegList : false, + SVGPathSegMovetoAbs : false, + SVGPathSegMovetoRel : false, + SVGPatternElement : false, + SVGPoint : false, + SVGPointList : false, + SVGPolygonElement : false, + SVGPolylineElement : false, + SVGPreserveAspectRatio: false, + SVGRadialGradientElement: false, + SVGRect : false, + SVGRectElement : false, + SVGRenderingIntent : false, + SVGSVGElement : false, + SVGScriptElement : false, + SVGSetElement : false, + SVGStopElement : false, + SVGStringList : false, + SVGStylable : false, + SVGStyleElement : false, + SVGSwitchElement : false, + SVGSymbolElement : false, + SVGTRefElement : false, + SVGTSpanElement : false, + SVGTests : false, + SVGTextContentElement: false, + SVGTextElement : false, + SVGTextPathElement : false, + SVGTextPositioningElement: false, + SVGTitleElement : false, + SVGTransform : false, + SVGTransformList : false, + SVGTransformable : false, + SVGURIReference : false, + SVGUnitTypes : false, + SVGUseElement : false, + SVGVKernElement : false, + SVGViewElement : false, + SVGViewSpec : false, + SVGZoomAndPan : false, + TimeEvent : false, + top : false, + Uint16Array : false, + Uint32Array : false, + Uint8Array : false, + Uint8ClampedArray : false, + WebSocket : false, + window : false, + Worker : false, + XMLHttpRequest : false, + XMLSerializer : false, + XPathEvaluator : false, + XPathException : false, + XPathExpression : false, + XPathNamespace : false, + XPathNSResolver : false, + XPathResult : false +}; + +exports.devel = { + alert : false, + confirm: false, + console: false, + Debug : false, + opera : false, + prompt : false +}; + +exports.worker = { + importScripts: true, + postMessage : true, + self : true +}; +exports.nonstandard = { + escape : false, + unescape: false +}; + +exports.couch = { + "require" : false, + respond : false, + getRow : false, + emit : false, + send : false, + start : false, + sum : false, + log : false, + exports : false, + module : false, + provides : false +}; + +exports.node = { + __filename : false, + __dirname : false, + Buffer : false, + DataView : false, + console : false, + exports : true, // In Node it is ok to exports = module.exports = foo(); + GLOBAL : false, + global : false, + module : false, + process : false, + require : false, + setTimeout : false, + clearTimeout : false, + setInterval : false, + clearInterval : false, + setImmediate : false, // v0.9.1+ + clearImmediate: false // v0.9.1+ +}; + +exports.phantom = { + phantom : true, + require : true, + WebPage : true +}; + +exports.rhino = { + defineClass : false, + deserialize : false, + gc : false, + help : false, + importPackage: false, + "java" : false, + load : false, + loadClass : false, + print : false, + quit : false, + readFile : false, + readUrl : false, + runCommand : false, + seal : false, + serialize : false, + spawn : false, + sync : false, + toint32 : false, + version : false +}; + +exports.shelljs = { + target : false, + echo : false, + exit : false, + cd : false, + pwd : false, + ls : false, + find : false, + cp : false, + rm : false, + mv : false, + mkdir : false, + test : false, + cat : false, + sed : false, + grep : false, + which : false, + dirs : false, + pushd : false, + popd : false, + env : false, + exec : false, + chmod : false, + config : false, + error : false, + tempdir : false +}; + +exports.wsh = { + ActiveXObject : true, + Enumerator : true, + GetObject : true, + ScriptEngine : true, + ScriptEngineBuildVersion : true, + ScriptEngineMajorVersion : true, + ScriptEngineMinorVersion : true, + VBArray : true, + WSH : true, + WScript : true, + XDomainRequest : true +}; + +exports.dojo = { + dojo : false, + dijit : false, + dojox : false, + define : false, + "require": false +}; + +exports.jquery = { + "$" : false, + jQuery : false +}; + +exports.mootools = { + "$" : false, + "$$" : false, + Asset : false, + Browser : false, + Chain : false, + Class : false, + Color : false, + Cookie : false, + Core : false, + Document : false, + DomReady : false, + DOMEvent : false, + DOMReady : false, + Drag : false, + Element : false, + Elements : false, + Event : false, + Events : false, + Fx : false, + Group : false, + Hash : false, + HtmlTable : false, + Iframe : false, + IframeShim : false, + InputValidator: false, + instanceOf : false, + Keyboard : false, + Locale : false, + Mask : false, + MooTools : false, + Native : false, + Options : false, + OverText : false, + Request : false, + Scroller : false, + Slick : false, + Slider : false, + Sortables : false, + Spinner : false, + Swiff : false, + Tips : false, + Type : false, + typeOf : false, + URI : false, + Window : false +}; + +exports.prototypejs = { + "$" : false, + "$$" : false, + "$A" : false, + "$F" : false, + "$H" : false, + "$R" : false, + "$break" : false, + "$continue" : false, + "$w" : false, + Abstract : false, + Ajax : false, + Class : false, + Enumerable : false, + Element : false, + Event : false, + Field : false, + Form : false, + Hash : false, + Insertion : false, + ObjectRange : false, + PeriodicalExecuter: false, + Position : false, + Prototype : false, + Selector : false, + Template : false, + Toggle : false, + Try : false, + Autocompleter : false, + Builder : false, + Control : false, + Draggable : false, + Draggables : false, + Droppables : false, + Effect : false, + Sortable : false, + SortableObserver : false, + Sound : false, + Scriptaculous : false +}; + +exports.yui = { + YUI : false, + Y : false, + YUI_config: false +}; + + +})() +}, +{}], +4:[function(req,module,exports){ + +"use string"; +exports.unsafeString = + /@cc|<\/?|script|\]\s*\]|<\s*!|</i; +exports.unsafeChars = + /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; +exports.needEsc = + /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; + +exports.needEscGlobal = + /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; +exports.starSlash = /\*\//; +exports.identifier = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/; +exports.javascriptURL = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i; +exports.fallsThrough = /^\s*\/\*\s*falls?\sthrough\s*\*\/\s*$/; + +}, +{}], +5:[function(req,module,exports){ + + +var state = { + syntax: {}, + + reset: function () { + this.tokens = { + prev: null, + next: null, + curr: null + }; + + this.option = {}; + this.ignored = {}; + this.directive = {}; + this.jsonMode = false; + this.jsonWarnings = []; + this.lines = []; + this.tab = ""; + this.cache = {}; // Node.JS doesn't have Map. Sniff. + } +}; + +exports.state = state; + +}, +{}], +6:[function(req,module,exports){ +(function(){ + +exports.register = function (linter) { + + linter.on("Identifier", function style_scanProto(data) { + if (linter.getOption("proto")) { + return; + } + + if (data.name === "__proto__") { + linter.warn("W103", { + line: data.line, + char: data.char, + data: [ data.name ] + }); + } + }); + + linter.on("Identifier", function style_scanIterator(data) { + if (linter.getOption("iterator")) { + return; + } + + if (data.name === "__iterator__") { + linter.warn("W104", { + line: data.line, + char: data.char, + data: [ data.name ] + }); + } + }); + + linter.on("Identifier", function style_scanDangling(data) { + if (!linter.getOption("nomen")) { + return; + } + if (data.name === "_") { + return; + } + if (linter.getOption("node")) { + if (/^(__dirname|__filename)$/.test(data.name) && !data.isProperty) { + return; + } + } + + if (/^(_+.*|.*_+)$/.test(data.name)) { + linter.warn("W105", { + line: data.line, + char: data.from, + data: [ "dangling '_'", data.name ] + }); + } + }); + + linter.on("Identifier", function style_scanCamelCase(data) { + if (!linter.getOption("camelcase")) { + return; + } + + if (data.name.replace(/^_+/, "").indexOf("_") > -1 && !data.name.match(/^[A-Z0-9_]*$/)) { + linter.warn("W106", { + line: data.line, + char: data.from, + data: [ data.name ] + }); + } + }); + + linter.on("String", function style_scanQuotes(data) { + var quotmark = linter.getOption("quotmark"); + var code; + + if (!quotmark) { + return; + } + + if (quotmark === "single" && data.quote !== "'") { + code = "W109"; + } + + if (quotmark === "double" && data.quote !== "\"") { + code = "W108"; + } + + if (quotmark === true) { + if (!linter.getCache("quotmark")) { + linter.setCache("quotmark", data.quote); + } + + if (linter.getCache("quotmark") !== data.quote) { + code = "W110"; + } + } + + if (code) { + linter.warn(code, { + line: data.line, + char: data.char, + }); + } + }); + + linter.on("Number", function style_scanNumbers(data) { + if (data.value.charAt(0) === ".") { + linter.warn("W008", { + line: data.line, + char: data.char, + data: [ data.value ] + }); + } + + if (data.value.substr(data.value.length - 1) === ".") { + linter.warn("W047", { + line: data.line, + char: data.char, + data: [ data.value ] + }); + } + + if (/^00+/.test(data.value)) { + linter.warn("W046", { + line: data.line, + char: data.char, + data: [ data.value ] + }); + } + }); + + linter.on("String", function style_scanJavaScriptURLs(data) { + var re = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i; + + if (linter.getOption("scripturl")) { + return; + } + + if (re.test(data.value)) { + linter.warn("W107", { + line: data.line, + char: data.char + }); + } + }); +}; +})() +}, +{}], +7:[function(req,module,exports){ +(function(global){/*global window, global*/ +var functions = [ + [log, "log"] + , [info, "info"] + , [warn, "warn"] + , [error, "error"] + , [time, "time"] + , [timeEnd, "timeEnd"] + , [trace, "trace"] + , [dir, "dir"] + , [assert, "assert"] +] + +for (var i = 0; i < functions.length; i++) { + var tuple = functions[i] + var f = tuple[0] + var name = tuple[1] + + if (!console[name]) { + console[name] = f + } +} + +module.exports = console + +function log() {} + +function info() {} + +function warn() {} + +function error() {} + +function time(label) {} + +function timeEnd(label) {} + +function trace() {} + +function dir(object) {} + +function assert(expression) {} + +})(window) +}, +{}], +"jshint":[function(req,module,exports){ +module.exports=req('E/GbHF'); +}, +{}],"E/GbHF":[function(req,module,exports){ +(function(){/*! + * JSHint, by JSHint Community. + * + * This file (and this file only) is licensed under the same slightly modified + * MIT license that JSLint is. It stops evil-doers everywhere: + * + * Copyright (c) 2002 Douglas Crockford (www.JSLint.com) + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * The Software shall be used for Good, not Evil. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +var _ = req("underscore"); +var events = req("events"); +var vars = req("../shared/vars.js"); +var messages = req("../shared/messages.js"); +var Lexer = req("./lex.js").Lexer; +var reg = req("./reg.js"); +var state = req("./state.js").state; +var style = req("./style.js"); +var console = req("console-browserify"); var JSHINT = (function () { - - - var anonname, // The guessed name for anonymous functions. + + var anonname, // The guessed name for anonymous functions. + api, // Extension API bang = { "<" : true, "<=" : true, @@ -2134,627 +3205,189 @@ var JSHINT = (function () { "%" : true }, boolOptions = { - asi : true, // if automatic semicolon insertion should be tolerated - bitwise : true, // if bitwise operators should not be allowed - boss : true, // if advanced usage of assignments should be allowed - browser : true, // if the standard browser globals should be predefined - camelcase : true, // if identifiers should be required in camel case - couch : true, // if CouchDB globals should be predefined - curly : true, // if curly braces around all blocks should be required - debug : true, // if debugger statements should be allowed - devel : true, // if logging globals should be predefined (console, - dojo : true, // if Dojo Toolkit globals should be predefined - eqeqeq : true, // if === should be required - eqnull : true, // if == null comparisons should be tolerated - es5 : true, // if ES5 syntax should be allowed - esnext : true, // if es.next specific syntax should be allowed - evil : true, // if eval should be allowed - expr : true, // if ExpressionStatement should be allowed as Programs - forin : true, // if for in statements must filter - funcscope : true, // if only function scope should be used for scope tests - globalstrict: true, // if global should be allowed (also - immed : true, // if immediate invocations must be wrapped in parens - iterator : true, // if the `__iterator__` property should be allowed - jquery : true, // if jQuery globals should be predefined - lastsemic : true, // if semicolons may be ommitted for the trailing - latedef : true, // if the use before definition should not be tolerated - laxbreak : true, // if line breaks should not be checked - laxcomma : true, // if line breaks should not be checked around commas - loopfunc : true, // if functions should be allowed to be defined within - mootools : true, // if MooTools globals should be predefined - multistr : true, // allow multiline strings - newcap : true, // if constructor names must be capitalized - noarg : true, // if arguments.caller and arguments.callee should be - node : true, // if the Node.js environment globals should be - noempty : true, // if empty blocks should be disallowed - nonew : true, // if using `new` for side-effects should be disallowed + asi : true, // if automatic semicolon insertion should be tolerated + bitwise : true, // if bitwise operators should not be allowed + boss : true, // if advanced usage of assignments should be allowed + browser : true, // if the standard browser globals should be predefined + camelcase : true, // if identifiers should be required in camel case + couch : true, // if CouchDB globals should be predefined + curly : true, // if curly braces around all blocks should be required + debug : true, // if debugger statements should be allowed + devel : true, // if logging globals should be predefined (console, alert, etc.) + dojo : true, // if Dojo Toolkit globals should be predefined + eqeqeq : true, // if === should be required + eqnull : true, // if == null comparisons should be tolerated + es3 : true, // if ES3 syntax should be allowed + es5 : true, // if ES5 syntax should be allowed (is now set per default) + esnext : true, // if es.next specific syntax should be allowed + moz : true, // if mozilla specific syntax should be allowed + evil : true, // if eval should be allowed + expr : true, // if ExpressionStatement should be allowed as Programs + forin : true, // if for in statements must filter + funcscope : true, // if only function scope should be used for scope tests + gcl : true, // if JSHint should be compatible with Google Closure Linter + globalstrict: true, // if global should be allowed (also enables 'strict') + immed : true, // if immediate invocations must be wrapped in parens + iterator : true, // if the `__iterator__` property should be allowed + jquery : true, // if jQuery globals should be predefined + lastsemic : true, // if semicolons may be ommitted for the trailing + laxbreak : true, // if line breaks should not be checked + laxcomma : true, // if line breaks should not be checked around commas + loopfunc : true, // if functions should be allowed to be defined within + mootools : true, // if MooTools globals should be predefined + multistr : true, // allow multiline strings + newcap : true, // if constructor names must be capitalized + noarg : true, // if arguments.caller and arguments.callee should be + node : true, // if the Node.js environment globals should be + noempty : true, // if empty blocks should be disallowed + nonew : true, // if using `new` for side-effects should be disallowed nonstandard : true, // if non-standard (but widely adopted) globals should - nomen : true, // if names should be checked - onevar : true, // if only one var statement per function should be - onecase : true, // if one case switch statements should be allowed - passfail : true, // if the scan should stop on first error - plusplus : true, // if increment/decrement should not be allowed - proto : true, // if the `__proto__` property should be allowed + nomen : true, // if names should be checked + onevar : true, // if only one var statement per function should be + passfail : true, // if the scan should stop on first error + phantom : true, // if PhantomJS symbols should be allowed + plusplus : true, // if increment/decrement should not be allowed + proto : true, // if the `__proto__` property should be allowed prototypejs : true, // if Prototype and Scriptaculous globals should be - regexdash : true, // if unescaped first/last dash (-) inside brackets - regexp : true, // if the . should not be allowed in regexp literals - rhino : true, // if the Rhino environment globals should be predefined - undef : true, // if variables should be declared before used - unused : true, // if variables should be always used - scripturl : true, // if script-targeted URLs should be tolerated - shadow : true, // if variable shadowing should be tolerated - smarttabs : true, // if smarttabs should be tolerated - strict : true, // require the pragma - sub : true, // if all forms of subscript notation are tolerated - supernew : true, // if `new function () { ... };` and `new Object;` - trailing : true, // if trailing whitespace rules apply - validthis : true, // if 'this' inside a non-constructor function is valid. - withstmt : true, // if with statements should be allowed - white : true, // if strict whitespace rules apply - worker : true, // if Web Worker script symbols should be allowed - wsh : true, // if the Windows Scripting Host environment globals - yui : true // YUI variables should be predefined + rhino : true, // if the Rhino environment globals should be predefined + shelljs : true, // if ShellJS globals should be predefined + undef : true, // if variables should be declared before used + scripturl : true, // if script-targeted URLs should be tolerated + shadow : true, // if variable shadowing should be tolerated + smarttabs : true, // if smarttabs should be tolerated + strict : true, // require the pragma + sub : true, // if all forms of subscript notation are tolerated + supernew : true, // if `new function () { ... };` and `new Object;` + trailing : true, // if trailing whitespace rules apply + validthis : true, // if 'this' inside a non-constructor function is valid. + withstmt : true, // if with statements should be allowed + white : true, // if strict whitespace rules apply + worker : true, // if Web Worker script symbols should be allowed + wsh : true, // if the Windows Scripting Host environment globals + yui : true, // YUI variables should be predefined + onecase : true, // if one case switch statements should be allowed + regexp : true, // if the . should not be allowed in regexp literals + regexdash : true // if unescaped first/last dash (-) inside brackets }, valOptions = { - maxlen : false, - indent : false, - maxerr : false, - predef : false, - quotmark : false, //'single'|'double'|true - scope : false, + maxlen : false, + indent : false, + maxerr : false, + predef : false, + quotmark : false, //'single'|'double'|true + scope : false, maxstatements: false, // {int} max statements per function - maxdepth : false, // {int} max nested block depth per function - maxparams : false, // {int} max params per function - maxcomplexity: false // {int} max cyclomatic complexity per function + maxdepth : false, // {int} max nested block depth per function + maxparams : false, // {int} max params per function + maxcomplexity: false, // {int} max cyclomatic complexity per function + unused : true, // warn if variables are unused. Available options: + latedef : false // warn if the variable is used before its definition }, invertedOptions = { - bitwise : true, - forin : true, - newcap : true, - nomen : true, - plusplus : true, - regexp : true, - undef : true, - white : true, - eqeqeq : true, - onevar : true + bitwise : true, + forin : true, + newcap : true, + nomen : true, + plusplus: true, + regexp : true, + undef : true, + white : true, + eqeqeq : true, + onevar : true, + strict : true }, renamedOptions = { - eqeq : "eqeqeq", - vars : "onevar", - windows : "wsh" - }, - browser = { - ArrayBuffer : false, - ArrayBufferView : false, - Audio : false, - Blob : false, - addEventListener : false, - applicationCache : false, - atob : false, - blur : false, - btoa : false, - clearInterval : false, - clearTimeout : false, - close : false, - closed : false, - DataView : false, - DOMParser : false, - defaultStatus : false, - document : false, - event : false, - FileReader : false, - Float32Array : false, - Float64Array : false, - FormData : false, - focus : false, - frames : false, - getComputedStyle : false, - HTMLElement : false, - HTMLAnchorElement : false, - HTMLBaseElement : false, - HTMLBlockquoteElement : false, - HTMLBodyElement : false, - HTMLBRElement : false, - HTMLButtonElement : false, - HTMLCanvasElement : false, - HTMLDirectoryElement : false, - HTMLDivElement : false, - HTMLDListElement : false, - HTMLFieldSetElement : false, - HTMLFontElement : false, - HTMLFormElement : false, - HTMLFrameElement : false, - HTMLFrameSetElement : false, - HTMLHeadElement : false, - HTMLHeadingElement : false, - HTMLHRElement : false, - HTMLHtmlElement : false, - HTMLIFrameElement : false, - HTMLImageElement : false, - HTMLInputElement : false, - HTMLIsIndexElement : false, - HTMLLabelElement : false, - HTMLLayerElement : false, - HTMLLegendElement : false, - HTMLLIElement : false, - HTMLLinkElement : false, - HTMLMapElement : false, - HTMLMenuElement : false, - HTMLMetaElement : false, - HTMLModElement : false, - HTMLObjectElement : false, - HTMLOListElement : false, - HTMLOptGroupElement : false, - HTMLOptionElement : false, - HTMLParagraphElement : false, - HTMLParamElement : false, - HTMLPreElement : false, - HTMLQuoteElement : false, - HTMLScriptElement : false, - HTMLSelectElement : false, - HTMLStyleElement : false, - HTMLTableCaptionElement : false, - HTMLTableCellElement : false, - HTMLTableColElement : false, - HTMLTableElement : false, - HTMLTableRowElement : false, - HTMLTableSectionElement : false, - HTMLTextAreaElement : false, - HTMLTitleElement : false, - HTMLUListElement : false, - HTMLVideoElement : false, - history : false, - Int16Array : false, - Int32Array : false, - Int8Array : false, - Image : false, - length : false, - localStorage : false, - location : false, - MessageChannel : false, - MessageEvent : false, - MessagePort : false, - moveBy : false, - moveTo : false, - MutationObserver : false, - name : false, - Node : false, - NodeFilter : false, - navigator : false, - onbeforeunload : true, - onblur : true, - onerror : true, - onfocus : true, - onload : true, - onresize : true, - onunload : true, - open : false, - openDatabase : false, - opener : false, - Option : false, - parent : false, - print : false, - removeEventListener : false, - resizeBy : false, - resizeTo : false, - screen : false, - scroll : false, - scrollBy : false, - scrollTo : false, - sessionStorage : false, - setInterval : false, - setTimeout : false, - SharedWorker : false, - status : false, - top : false, - Uint16Array : false, - Uint32Array : false, - Uint8Array : false, - WebSocket : false, - window : false, - Worker : false, - XMLHttpRequest : false, - XMLSerializer : false, - XPathEvaluator : false, - XPathException : false, - XPathExpression : false, - XPathNamespace : false, - XPathNSResolver : false, - XPathResult : false - }, - - couch = { - "require" : false, - respond : false, - getRow : false, - emit : false, - send : false, - start : false, - sum : false, - log : false, - exports : false, - module : false, - provides : false + eqeq : "eqeqeq", + vars : "onevar", + windows: "wsh", + sloppy : "strict" }, declared, // Globals that were declared using /*global ... */ syntax. - - devel = { - alert : false, - confirm : false, - console : false, - Debug : false, - opera : false, - prompt : false - }, - - dojo = { - dojo : false, - dijit : false, - dojox : false, - define : false, - "require" : false - }, - - funct, // The current function + exported, // Variables that are used outside of the current file. functionicity = [ "closure", "exception", "global", "label", "outer", "unused", "var" ], - functions, // All of the functions + funct, // The current function + functions, // All of the functions - global, // The global scope - implied, // Implied globals + global, // The global scope + implied, // Implied globals inblock, indent, - jsonmode, - - jquery = { - "$" : false, - jQuery : false - }, - - lines, lookahead, + lex, member, membersOnly, - - mootools = { - "$" : false, - "$$" : false, - Asset : false, - Browser : false, - Chain : false, - Class : false, - Color : false, - Cookie : false, - Core : false, - Document : false, - DomReady : false, - DOMEvent : false, - DOMReady : false, - Drag : false, - Element : false, - Elements : false, - Event : false, - Events : false, - Fx : false, - Group : false, - Hash : false, - HtmlTable : false, - Iframe : false, - IframeShim : false, - InputValidator : false, - instanceOf : false, - Keyboard : false, - Locale : false, - Mask : false, - MooTools : false, - Native : false, - Options : false, - OverText : false, - Request : false, - Scroller : false, - Slick : false, - Slider : false, - Sortables : false, - Spinner : false, - Swiff : false, - Tips : false, - Type : false, - typeOf : false, - URI : false, - Window : false - }, - - nexttoken, - - node = { - __filename : false, - __dirname : false, - Buffer : false, - console : false, - exports : true, // In Node it is ok to exports = module.exports = foo(); - GLOBAL : false, - global : false, - module : false, - process : false, - require : false, - setTimeout : false, - clearTimeout : false, - setInterval : false, - clearInterval : false - }, - noreach, - option, predefined, // Global variables defined by option - prereg, - prevtoken, - prototypejs = { - "$" : false, - "$$" : false, - "$A" : false, - "$F" : false, - "$H" : false, - "$R" : false, - "$break" : false, - "$continue" : false, - "$w" : false, - Abstract : false, - Ajax : false, - Class : false, - Enumerable : false, - Element : false, - Event : false, - Field : false, - Form : false, - Hash : false, - Insertion : false, - ObjectRange : false, - PeriodicalExecuter: false, - Position : false, - Prototype : false, - Selector : false, - Template : false, - Toggle : false, - Try : false, - Autocompleter : false, - Builder : false, - Control : false, - Draggable : false, - Draggables : false, - Droppables : false, - Effect : false, - Sortable : false, - SortableObserver : false, - Sound : false, - Scriptaculous : false - }, - - quotmark, - - rhino = { - defineClass : false, - deserialize : false, - gc : false, - help : false, - importPackage: false, - "java" : false, - load : false, - loadClass : false, - print : false, - quit : false, - readFile : false, - readUrl : false, - runCommand : false, - seal : false, - serialize : false, - spawn : false, - sync : false, - toint32 : false, - version : false - }, - - scope, // The current scope + scope, // The current scope stack, - standard = { - Array : false, - Boolean : false, - Date : false, - decodeURI : false, - decodeURIComponent : false, - encodeURI : false, - encodeURIComponent : false, - Error : false, - "eval" : false, - EvalError : false, - Function : false, - hasOwnProperty : false, - isFinite : false, - isNaN : false, - JSON : false, - Map : false, - Math : false, - NaN : false, - Number : false, - Object : false, - parseInt : false, - parseFloat : false, - RangeError : false, - ReferenceError : false, - RegExp : false, - Set : false, - String : false, - SyntaxError : false, - TypeError : false, - URIError : false, - WeakMap : false - }, - nonstandard = { - escape : false, - unescape : false - }, - - directive, - syntax = {}, - tab, - token, unuseds, urls, - useESNextSyntax, warnings, - worker = { - importScripts : true, - postMessage : true, - self : true - }, - - wsh = { - ActiveXObject : true, - Enumerator : true, - GetObject : true, - ScriptEngine : true, - ScriptEngineBuildVersion : true, - ScriptEngineMajorVersion : true, - ScriptEngineMinorVersion : true, - VBArray : true, - WSH : true, - WScript : true, - XDomainRequest : true - }, - - yui = { - YUI : false, - Y : false, - YUI_config : false - }; - var ax, cx, tx, nx, nxg, lx, ix, jx, ft; - (function () { - ax = /@cc|<\/?|script|\]\s*\]|<\s*!|</i; - cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; - tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/=(?!(\S*\/[gim]?))|\/(\*(jshint|jslint|members?|global)?|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/; - nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; - nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; - lx = /\*\//; - ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/; - jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i; - ft = /^\s*\/\*\s*falls\sthrough\s*\*\/\s*$/; - }()); - - function F() {} // Used by Object.create - - function is_own(object, name) { - return Object.prototype.hasOwnProperty.call(object, name); - } + extraModules = [], + emitter = new events.EventEmitter(); function checkOption(name, t) { - if (valOptions[name] === undefined && boolOptions[name] === undefined) { - warning("Bad option: '" + name + "'.", t); + name = name.trim(); + + if (/^[+-]W\d{3}$/g.test(name)) { + return true; } + + if (valOptions[name] === undefined && boolOptions[name] === undefined) { + if (t.type !== "jslint") { + error("E001", t, name); + return false; + } + } + + return true; } function isString(obj) { return Object.prototype.toString.call(obj) === "[object String]"; } - if (typeof Array.isArray !== "function") { - Array.isArray = function (o) { - return Object.prototype.toString.apply(o) === "[object Array]"; - }; - } - - if (!Array.prototype.forEach) { - Array.prototype.forEach = function (fn, scope) { - var len = this.length; - - for (var i = 0; i < len; i++) { - fn.call(scope || this, this[i], i, this); - } - }; - } - - if (!Array.prototype.indexOf) { - Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) { - if (this === null || this === undefined) { - throw new TypeError(); - } - - var t = new Object(this); - var len = t.length >>> 0; - - if (len === 0) { - return -1; - } - - var n = 0; - if (arguments.length > 0) { - n = Number(arguments[1]); - if (n != n) { // shortcut for verifying if it's NaN - n = 0; - } else if (n !== 0 && n != Infinity && n != -Infinity) { - n = (n > 0 || -1) * Math.floor(Math.abs(n)); - } - } - - if (n >= len) { - return -1; - } - - var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); - for (; k < len; k++) { - if (k in t && t[k] === searchElement) { - return k; - } - } - - return -1; - }; - } - - if (typeof Object.create !== "function") { - Object.create = function (o) { - F.prototype = o; - return new F(); - }; - } - - if (typeof Object.keys !== "function") { - Object.keys = function (o) { - var a = [], k; - for (k in o) { - if (is_own(o, k)) { - a.push(k); - } - } - return a; - }; - } - - function isAlpha(str) { - return (str >= "a" && str <= "z\uffff") || - (str >= "A" && str <= "Z\uffff"); - } - - function isDigit(str) { - return (str >= "0" && str <= "9"); - } - - function isIdentifier(token, value) { - if (!token) + function isIdentifier(tkn, value) { + if (!tkn) return false; - if (!token.identifier || token.value !== value) + if (!tkn.identifier || tkn.value !== value) return false; return true; } + function isReserved(token) { + if (!token.reserved) { + return false; + } + + if (token.meta && token.meta.isFutureReservedWord) { + if (state.option.inES5(true) && !token.meta.es5) { + return false; + } + if (token.meta.strictOnly) { + if (!state.option.strict && !state.directive["use strict"]) { + return false; + } + } + + if (token.isProperty) { + return false; + } + } + + return true; + } + function supplant(str, data) { return str.replace(/\{([^{}]*)\}/g, function (a, b) { var r = data[b]; @@ -2765,7 +3398,7 @@ var JSHINT = (function () { function combine(t, o) { var n; for (n in o) { - if (is_own(o, n) && !is_own(JSHINT.blacklist, n)) { + if (_.has(o, n) && !_.has(JSHINT.blacklist, n)) { t[n] = o[n]; } } @@ -2778,69 +3411,92 @@ var JSHINT = (function () { } function assume() { - if (option.couch) { - combine(predefined, couch); + if (state.option.couch) { + combine(predefined, vars.couch); } - if (option.rhino) { - combine(predefined, rhino); + if (state.option.rhino) { + combine(predefined, vars.rhino); } - if (option.prototypejs) { - combine(predefined, prototypejs); + if (state.option.shelljs) { + combine(predefined, vars.shelljs); } - if (option.node) { - combine(predefined, node); - option.globalstrict = true; + if (state.option.phantom) { + combine(predefined, vars.phantom); } - if (option.devel) { - combine(predefined, devel); + if (state.option.prototypejs) { + combine(predefined, vars.prototypejs); } - if (option.dojo) { - combine(predefined, dojo); + if (state.option.node) { + combine(predefined, vars.node); } - if (option.browser) { - combine(predefined, browser); + if (state.option.devel) { + combine(predefined, vars.devel); } - if (option.nonstandard) { - combine(predefined, nonstandard); + if (state.option.dojo) { + combine(predefined, vars.dojo); } - if (option.jquery) { - combine(predefined, jquery); + if (state.option.browser) { + combine(predefined, vars.browser); } - if (option.mootools) { - combine(predefined, mootools); + if (state.option.nonstandard) { + combine(predefined, vars.nonstandard); } - if (option.worker) { - combine(predefined, worker); + if (state.option.jquery) { + combine(predefined, vars.jquery); } - if (option.wsh) { - combine(predefined, wsh); + if (state.option.mootools) { + combine(predefined, vars.mootools); } - if (option.esnext) { - useESNextSyntax(); + if (state.option.worker) { + combine(predefined, vars.worker); } - if (option.globalstrict && option.strict !== false) { - option.strict = true; + if (state.option.wsh) { + combine(predefined, vars.wsh); } - if (option.yui) { - combine(predefined, yui); + if (state.option.globalstrict && state.option.strict !== false) { + state.option.strict = true; } + + if (state.option.yui) { + combine(predefined, vars.yui); + } + + state.option.inMoz = function (strict) { + return state.option.moz; + }; + + state.option.inESNext = function (strict) { + return state.option.moz || state.option.esnext; + }; + + state.option.inES5 = function (/* strict */) { + return !state.option.es3; + }; + + state.option.inES3 = function (strict) { + if (strict) { + return !state.option.moz && !state.option.esnext && state.option.es3; + } + return state.option.es3; + }; } - function quit(message, line, chr) { - var percentage = Math.floor((line / lines.length) * 100); + function quit(code, line, chr) { + var percentage = Math.floor((line / state.lines.length) * 100); + var message = messages.errors[code].desc; throw { name: "JSHintError", @@ -2851,22 +3507,37 @@ var JSHINT = (function () { }; } - function isundef(scope, m, t, a) { - return JSHINT.undefs.push([scope, m, t, a]); + function isundef(scope, code, token, a) { + return JSHINT.undefs.push([scope, code, token, a]); } - function warning(m, t, a, b, c, d) { - var ch, l, w; - t = t || nexttoken; - if (t.id === "(end)") { // `~ - t = token; + function warning(code, t, a, b, c, d) { + var ch, l, w, msg; + + if (/^W\d{3}$/.test(code)) { + if (state.ignored[code]) + return; + + msg = messages.warnings[code]; + } else if (/E\d{3}/.test(code)) { + msg = messages.errors[code]; + } else if (/I\d{3}/.test(code)) { + msg = messages.info[code]; } + + t = t || state.tokens.next; + if (t.id === "(end)") { // `~ + t = state.tokens.curr; + } + l = t.line || 0; ch = t.from || 0; + w = { id: "(error)", - raw: m, - evidence: lines[l - 1] || "", + raw: msg.desc, + code: msg.code, + evidence: state.lines[l - 1] || "", line: l, character: ch, scope: JSHINT.scope, @@ -2875,15 +3546,19 @@ var JSHINT = (function () { c: c, d: d }; - w.reason = supplant(m, w); + + w.reason = supplant(msg.desc, w); JSHINT.errors.push(w); - if (option.passfail) { - quit("Stopping. ", l, ch); + + if (state.option.passfail) { + quit("E042", l, ch); } + warnings += 1; - if (warnings >= option.maxerr) { - quit("Too many errors.", l, ch); + if (warnings >= state.option.maxerr) { + quit("E043", l, ch); } + return w; } @@ -2915,905 +3590,258 @@ var JSHINT = (function () { return i; } - var lex = (function lex() { - var character, from, line, s; - - function nextLine() { - var at, - match, - tw; // trailing whitespace check - - if (line >= lines.length) - return false; - - character = 1; - s = lines[line]; - line += 1; - if (option.smarttabs) { - match = s.match(/(\/\/)? \t/); - at = match && !match[1] ? 0 : -1; - } else { - at = s.search(/ \t|\t [^\*]/); - } - - if (at >= 0) - warningAt("Mixed spaces and tabs.", line, at + 1); - - s = s.replace(/\t/g, tab); - at = s.search(cx); - - if (at >= 0) - warningAt("Unsafe character.", line, at); - - if (option.maxlen && option.maxlen < s.length) - warningAt("Line too long.", line, s.length); - tw = option.trailing && s.match(/^(.*?)\s+$/); - if (tw && !/^\s+$/.test(s)) { - warningAt("Trailing whitespace.", line, tw[1].length + 1); - } - return true; - } - - function it(type, value) { - var i, t; - - function checkName(name) { - if (!option.proto && name === "__proto__") { - warningAt("The '{a}' property is deprecated.", line, from, name); - return; - } - - if (!option.iterator && name === "__iterator__") { - warningAt("'{a}' is only available in JavaScript 1.7.", line, from, name); - return; - } - - var hasDangling = /^(_+.*|.*_+)$/.test(name); - - if (option.nomen && hasDangling && name !== "_") { - if (option.node && token.id !== "." && /^(__dirname|__filename)$/.test(name)) - return; - - warningAt("Unexpected {a} in '{b}'.", line, from, "dangling '_'", name); - return; - } - - if (option.camelcase) { - if (name.replace(/^_+/, "").indexOf("_") > -1 && !name.match(/^[A-Z0-9_]*$/)) { - warningAt("Identifier '{a}' is not in camel case.", line, from, value); - } - } - } - - if (type === "(color)" || type === "(range)") { - t = {type: type}; - } else if (type === "(punctuator)" || - (type === "(identifier)" && is_own(syntax, value))) { - t = syntax[value] || syntax["(error)"]; - } else { - t = syntax[type]; - } - - t = Object.create(t); - - if (type === "(string)" || type === "(range)") { - if (!option.scripturl && jx.test(value)) { - warningAt("Script URL.", line, from); - } - } - - if (type === "(identifier)") { - t.identifier = true; - checkName(value); - } - - t.value = value; - t.line = line; - t.character = character; - t.from = from; - i = t.id; - if (i !== "(endline)") { - prereg = i && - (("(,=:[!&|?{};".indexOf(i.charAt(i.length - 1)) >= 0) || - i === "return" || - i === "case"); - } - return t; - } - return { - init: function (source) { - if (typeof source === "string") { - lines = source - .replace(/\r\n/g, "\n") - .replace(/\r/g, "\n") - .split("\n"); - } else { - lines = source; - } - if (lines[0] && lines[0].substr(0, 2) === "#!") - lines[0] = ""; - - line = 0; - nextLine(); - from = 1; - }, - - range: function (begin, end) { - var c, value = ""; - from = character; - if (s.charAt(0) !== begin) { - errorAt("Expected '{a}' and instead saw '{b}'.", - line, character, begin, s.charAt(0)); - } - for (;;) { - s = s.slice(1); - character += 1; - c = s.charAt(0); - switch (c) { - case "": - errorAt("Missing '{a}'.", line, character, c); - break; - case end: - s = s.slice(1); - character += 1; - return it("(range)", value); - case "\\": - warningAt("Unexpected '{a}'.", line, character, c); - } - value += c; - } - - }, - token: function () { - var b, c, captures, d, depth, high, i, l, low, q, t, isLiteral, isInRange, n; - - function match(x) { - var r = x.exec(s), r1; - - if (r) { - l = r[0].length; - r1 = r[1]; - c = r1.charAt(0); - s = s.substr(l); - from = character + l - r1.length; - character += l; - return r1; - } - } - - function string(x) { - var c, j, r = "", allowNewLine = false; - - if (jsonmode && x !== "\"") { - warningAt("Strings must use doublequote.", - line, character); - } - - if (option.quotmark) { - if (option.quotmark === "single" && x !== "'") { - warningAt("Strings must use singlequote.", - line, character); - } else if (option.quotmark === "double" && x !== "\"") { - warningAt("Strings must use doublequote.", - line, character); - } else if (option.quotmark === true) { - quotmark = quotmark || x; - if (quotmark !== x) { - warningAt("Mixed double and single quotes.", - line, character); - } - } - } - - function esc(n) { - var i = parseInt(s.substr(j + 1, n), 16); - j += n; - if (i >= 32 && i <= 126 && - i !== 34 && i !== 92 && i !== 39) { - warningAt("Unnecessary escapement.", line, character); - } - character += n; - c = String.fromCharCode(i); - } - - j = 0; - -unclosedString: - for (;;) { - while (j >= s.length) { - j = 0; - - var cl = line, cf = from; - if (!nextLine()) { - errorAt("Unclosed string.", cl, cf); - break unclosedString; - } - - if (allowNewLine) { - allowNewLine = false; - } else { - warningAt("Unclosed string.", cl, cf); - } - } - - c = s.charAt(j); - if (c === x) { - character += 1; - s = s.substr(j + 1); - return it("(string)", r, x); - } - - if (c < " ") { - if (c === "\n" || c === "\r") { - break; - } - warningAt("Control character in string: {a}.", - line, character + j, s.slice(0, j)); - } else if (c === "\\") { - j += 1; - character += 1; - c = s.charAt(j); - n = s.charAt(j + 1); - switch (c) { - case "\\": - case "\"": - case "/": - break; - case "\'": - if (jsonmode) { - warningAt("Avoid \\'.", line, character); - } - break; - case "b": - c = "\b"; - break; - case "f": - c = "\f"; - break; - case "n": - c = "\n"; - break; - case "r": - c = "\r"; - break; - case "t": - c = "\t"; - break; - case "0": - c = "\0"; - if (n >= 0 && n <= 7 && directive["use strict"]) { - warningAt( - "Octal literals are not allowed in strict mode.", - line, character); - } - break; - case "u": - esc(4); - break; - case "v": - if (jsonmode) { - warningAt("Avoid \\v.", line, character); - } - c = "\v"; - break; - case "x": - if (jsonmode) { - warningAt("Avoid \\x-.", line, character); - } - esc(2); - break; - case "": - allowNewLine = true; - if (option.multistr) { - if (jsonmode) { - warningAt("Avoid EOL escapement.", line, character); - } - c = ""; - character -= 1; - break; - } - warningAt("Bad escapement of EOL. Use option multistr if needed.", - line, character); - break; - case "!": - if (s.charAt(j - 2) === "<") - break; - default: - warningAt("Bad escapement.", line, character); - } - } - r += c; - character += 1; - j += 1; - } - } - - for (;;) { - if (!s) { - return it(nextLine() ? "(endline)" : "(end)", ""); - } - - t = match(tx); - - if (!t) { - t = ""; - c = ""; - while (s && s < "!") { - s = s.substr(1); - } - if (s) { - errorAt("Unexpected '{a}'.", line, character, s.substr(0, 1)); - s = ""; - } - } else { - - if (isAlpha(c) || c === "_" || c === "$") { - return it("(identifier)", t); - } - - if (isDigit(c)) { - if (!isFinite(Number(t))) { - warningAt("Bad number '{a}'.", - line, character, t); - } - if (isAlpha(s.substr(0, 1))) { - warningAt("Missing space after '{a}'.", - line, character, t); - } - if (c === "0") { - d = t.substr(1, 1); - if (isDigit(d)) { - if (token.id !== ".") { - warningAt("Don't use extra leading zeros '{a}'.", - line, character, t); - } - } else if (jsonmode && (d === "x" || d === "X")) { - warningAt("Avoid 0x-. '{a}'.", - line, character, t); - } - } - if (t.substr(t.length - 1) === ".") { - warningAt( -"A trailing decimal point can be confused with a dot '{a}'.", line, character, t); - } - return it("(number)", t); - } - switch (t) { - - case "\"": - case "'": - return string(t); - - case "//": - s = ""; - token.comment = true; - break; - - case "/*": - for (;;) { - i = s.search(lx); - if (i >= 0) { - break; - } - if (!nextLine()) { - errorAt("Unclosed comment.", line, character); - } - } - s = s.substr(i + 2); - token.comment = true; - break; - - case "/*members": - case "/*member": - case "/*jshint": - case "/*jslint": - case "/*global": - case "*/": - return { - value: t, - type: "special", - line: line, - character: character, - from: from - }; - - case "": - break; - case "/": - if (s.charAt(0) === "=") { - errorAt("A regular expression literal can be confused with '/='.", - line, from); - } - - if (prereg) { - depth = 0; - captures = 0; - l = 0; - for (;;) { - b = true; - c = s.charAt(l); - l += 1; - switch (c) { - case "": - errorAt("Unclosed regular expression.", line, from); - return quit("Stopping.", line, from); - case "/": - if (depth > 0) { - warningAt("{a} unterminated regular expression " + - "group(s).", line, from + l, depth); - } - c = s.substr(0, l - 1); - q = { - g: true, - i: true, - m: true - }; - while (q[s.charAt(l)] === true) { - q[s.charAt(l)] = false; - l += 1; - } - character += l; - s = s.substr(l); - q = s.charAt(0); - if (q === "/" || q === "*") { - errorAt("Confusing regular expression.", - line, from); - } - return it("(regexp)", c); - case "\\": - c = s.charAt(l); - if (c < " ") { - warningAt( -"Unexpected control character in regular expression.", line, from + l); - } else if (c === "<") { - warningAt( -"Unexpected escaped character '{a}' in regular expression.", line, from + l, c); - } - l += 1; - break; - case "(": - depth += 1; - b = false; - if (s.charAt(l) === "?") { - l += 1; - switch (s.charAt(l)) { - case ":": - case "=": - case "!": - l += 1; - break; - default: - warningAt( -"Expected '{a}' and instead saw '{b}'.", line, from + l, ":", s.charAt(l)); - } - } else { - captures += 1; - } - break; - case "|": - b = false; - break; - case ")": - if (depth === 0) { - warningAt("Unescaped '{a}'.", - line, from + l, ")"); - } else { - depth -= 1; - } - break; - case " ": - q = 1; - while (s.charAt(l) === " ") { - l += 1; - q += 1; - } - if (q > 1) { - warningAt( -"Spaces are hard to count. Use {{a}}.", line, from + l, q); - } - break; - case "[": - c = s.charAt(l); - if (c === "^") { - l += 1; - if (s.charAt(l) === "]") { - errorAt("Unescaped '{a}'.", - line, from + l, "^"); - } - } - if (c === "]") { - warningAt("Empty class.", line, - from + l - 1); - } - isLiteral = false; - isInRange = false; -klass: - do { - c = s.charAt(l); - l += 1; - switch (c) { - case "[": - case "^": - warningAt("Unescaped '{a}'.", - line, from + l, c); - if (isInRange) { - isInRange = false; - } else { - isLiteral = true; - } - break; - case "-": - if (isLiteral && !isInRange) { - isLiteral = false; - isInRange = true; - } else if (isInRange) { - isInRange = false; - } else if (s.charAt(l) === "]") { - isInRange = true; - } else { - if (option.regexdash !== (l === 2 || (l === 3 && - s.charAt(1) === "^"))) { - warningAt("Unescaped '{a}'.", - line, from + l - 1, "-"); - } - isLiteral = true; - } - break; - case "]": - if (isInRange && !option.regexdash) { - warningAt("Unescaped '{a}'.", - line, from + l - 1, "-"); - } - break klass; - case "\\": - c = s.charAt(l); - if (c < " ") { - warningAt( -"Unexpected control character in regular expression.", line, from + l); - } else if (c === "<") { - warningAt( -"Unexpected escaped character '{a}' in regular expression.", line, from + l, c); - } - l += 1; - if (/[wsd]/i.test(c)) { - if (isInRange) { - warningAt("Unescaped '{a}'.", - line, from + l, "-"); - isInRange = false; - } - isLiteral = false; - } else if (isInRange) { - isInRange = false; - } else { - isLiteral = true; - } - break; - case "/": - warningAt("Unescaped '{a}'.", - line, from + l - 1, "/"); - - if (isInRange) { - isInRange = false; - } else { - isLiteral = true; - } - break; - case "<": - if (isInRange) { - isInRange = false; - } else { - isLiteral = true; - } - break; - default: - if (isInRange) { - isInRange = false; - } else { - isLiteral = true; - } - } - } while (c); - break; - case ".": - if (option.regexp) { - warningAt("Insecure '{a}'.", line, - from + l, c); - } - break; - case "]": - case "?": - case "{": - case "}": - case "+": - case "*": - warningAt("Unescaped '{a}'.", line, - from + l, c); - } - if (b) { - switch (s.charAt(l)) { - case "?": - case "+": - case "*": - l += 1; - if (s.charAt(l) === "?") { - l += 1; - } - break; - case "{": - l += 1; - c = s.charAt(l); - if (c < "0" || c > "9") { - warningAt( -"Expected a number and instead saw '{a}'.", line, from + l, c); - break; // No reason to continue checking numbers. - } - l += 1; - low = +c; - for (;;) { - c = s.charAt(l); - if (c < "0" || c > "9") { - break; - } - l += 1; - low = +c + (low * 10); - } - high = low; - if (c === ",") { - l += 1; - high = Infinity; - c = s.charAt(l); - if (c >= "0" && c <= "9") { - l += 1; - high = +c; - for (;;) { - c = s.charAt(l); - if (c < "0" || c > "9") { - break; - } - l += 1; - high = +c + (high * 10); - } - } - } - if (s.charAt(l) !== "}") { - warningAt( -"Expected '{a}' and instead saw '{b}'.", line, from + l, "}", c); - } else { - l += 1; - } - if (s.charAt(l) === "?") { - l += 1; - } - if (low > high) { - warningAt( -"'{a}' should not be greater than '{b}'.", line, from + l, low, high); - } - } - } - } - c = s.substr(0, l - 1); - character += l; - s = s.substr(l); - return it("(regexp)", c); - } - return it("(punctuator)", t); - - case "#": - return it("(punctuator)", t); - default: - return it("(punctuator)", t); - } - } - } - } - }; - }()); - - - function addlabel(t, type, token) { - if (t === "hasOwnProperty") { - warning("'hasOwnProperty' is a really bad name."); - } + function addlabel(t, type, tkn, islet) { if (type === "exception") { - if (is_own(funct["(context)"], t)) { - if (funct[t] !== true && !option.node) { - warning("Value of '{a}' may be overwritten in IE.", nexttoken, t); + if (_.has(funct["(context)"], t)) { + if (funct[t] !== true && !state.option.node) { + warning("W002", state.tokens.next, t); } } } - if (is_own(funct, t) && !funct["(global)"]) { + if (_.has(funct, t) && !funct["(global)"]) { if (funct[t] === true) { - if (option.latedef) - warning("'{a}' was used before it was defined.", nexttoken, t); + if (state.option.latedef) { + if ((state.option.latedef === true && _.contains([funct[t], type], "unction")) || + !_.contains([funct[t], type], "unction")) { + warning("W003", state.tokens.next, t); + } + } } else { - if (!option.shadow && type !== "exception") { - warning("'{a}' is already defined.", nexttoken, t); + if (!state.option.shadow && type !== "exception" || + (funct["(blockscope)"].getlabel(t))) { + warning("W004", state.tokens.next, t); } } } - - funct[t] = type; - - if (token) { - funct["(tokens)"][t] = token; + if (funct["(blockscope)"] && funct["(blockscope)"].current.has(t)) { + error("E044", state.tokens.next, t); } - - if (funct["(global)"]) { - global[t] = funct; - if (is_own(implied, t)) { - if (option.latedef) - warning("'{a}' was used before it was defined.", nexttoken, t); - delete implied[t]; - } + if (islet) { + funct["(blockscope)"].current.add(t, type, state.tokens.curr); } else { - scope[t] = funct; + + funct[t] = type; + + if (tkn) { + funct["(tokens)"][t] = tkn; + } + + if (funct["(global)"]) { + global[t] = funct; + if (_.has(implied, t)) { + if (state.option.latedef) { + if ((state.option.latedef === true && _.contains([funct[t], type], "unction")) || + !_.contains([funct[t], type], "unction")) { + warning("W003", state.tokens.next, t); + } + } + + delete implied[t]; + } + } else { + scope[t] = funct; + } } } - function doOption() { - var nt = nexttoken; - var o = nt.value; - var quotmarkValue = option.quotmark; + var nt = state.tokens.next; + var body = nt.body.split(",").map(function (s) { return s.trim(); }); var predef = {}; - var b, obj, filter, t, tn, v, minus; - switch (o) { - case "*/": - error("Unbegun comment."); - break; - case "/*members": - case "/*member": - o = "/*members"; - if (!membersOnly) { - membersOnly = {}; + if (nt.type === "globals") { + body.forEach(function (g) { + g = g.split(":"); + var key = g[0]; + var val = g[1]; + + if (key.charAt(0) === "-") { + key = key.slice(1); + val = false; + + JSHINT.blacklist[key] = key; + updatePredefined(); + } else { + predef[key] = (val === "true"); + } + }); + + combine(predefined, predef); + + for (var key in predef) { + if (_.has(predef, key)) { + declared[key] = nt; + } } - obj = membersOnly; - option.quotmark = false; - break; - case "/*jshint": - case "/*jslint": - obj = option; - filter = boolOptions; - break; - case "/*global": - obj = predef; - break; - default: - error("What?"); } - t = lex.token(); + if (nt.type === "exported") { + body.forEach(function (e) { + exported[e] = true; + }); + } - for (;;) { - minus = false; - var breakOuterLoop; - for (;;) { - if (t.type === "special" && t.value === "*/") { - breakOuterLoop = true; - break; - } - if (t.id !== "(endline)" && t.id !== ",") { - break; - } - t = lex.token(); - } - if (breakOuterLoop) - break; + if (nt.type === "members") { + membersOnly = membersOnly || {}; - if (o === "/*global" && t.value === "-") { - minus = true; - t = lex.token(); - } + body.forEach(function (m) { + var ch1 = m.charAt(0); + var ch2 = m.charAt(m.length - 1); - if (t.type !== "(string)" && t.type !== "(identifier)" && o !== "/*members") { - error("Bad option.", t); - } - - v = lex.token(); - if (v.id === ":") { - v = lex.token(); - - if (obj === membersOnly) { - error("Expected '{a}' and instead saw '{b}'.", t, "*/", ":"); + if (ch1 === ch2 && (ch1 === "\"" || ch1 === "'")) { + m = m + .substr(1, m.length - 2) + .replace("\\b", "\b") + .replace("\\t", "\t") + .replace("\\n", "\n") + .replace("\\v", "\v") + .replace("\\f", "\f") + .replace("\\r", "\r") + .replace("\\\\", "\\") + .replace("\\\"", "\""); } - if (o === "/*jshint") { - checkOption(t.value, t); + membersOnly[m] = false; + }); + } + + var numvals = [ + "maxstatements", + "maxparams", + "maxdepth", + "maxcomplexity", + "maxerr", + "maxlen", + "indent" + ]; + + if (nt.type === "jshint" || nt.type === "jslint") { + body.forEach(function (g) { + g = g.split(":"); + var key = (g[0] || "").trim(); + var val = (g[1] || "").trim(); + + if (!checkOption(key, nt)) { + return; } - var numericVals = [ - "maxstatements", - "maxparams", - "maxdepth", - "maxcomplexity", - "maxerr", - "maxlen", - "indent" - ]; + if (numvals.indexOf(key) >= 0) { + if (val !== "false") { + val = +val; - if (numericVals.indexOf(t.value) > -1 && (o === "/*jshint" || o === "/*jslint")) { - b = +v.value; + if (typeof val !== "number" || !isFinite(val) || val <= 0 || Math.floor(val) !== val) { + error("E032", nt, g[1].trim()); + return; + } - if (typeof b !== "number" || !isFinite(b) || b <= 0 || Math.floor(b) !== b) { - error("Expected a small integer and instead saw '{a}'.", v, v.value); - } - - if (t.value === "indent") - obj.white = true; - - obj[t.value] = b; - } else if (t.value === "validthis") { - if (funct["(global)"]) { - error("Option 'validthis' can't be used in a global scope."); + if (key === "indent") { + state.option["(explicitIndent)"] = true; + } + state.option[key] = val; } else { - if (v.value === "true" || v.value === "false") - obj[t.value] = v.value === "true"; - else - error("Bad option value.", v); + if (key === "indent") { + state.option["(explicitIndent)"] = false; + } else { + state.option[key] = false; + } } - } else if (t.value === "quotmark" && (o === "/*jshint")) { - switch (v.value) { + + return; + } + + if (key === "validthis") { + if (funct["(global)"]) { + error("E009"); + } else { + if (val === "true" || val === "false") { + state.option.validthis = (val === "true"); + } else { + error("E002", nt); + } + } + return; + } + + if (key === "quotmark") { + switch (val) { case "true": - obj.quotmark = true; - break; case "false": - obj.quotmark = false; + state.option.quotmark = (val === "true"); break; case "double": case "single": - obj.quotmark = v.value; + state.option.quotmark = val; break; default: - error("Bad option value.", v); + error("E002", nt); } - } else if (v.value === "true" || v.value === "false") { - if (o === "/*jslint") { - tn = renamedOptions[t.value] || t.value; - obj[tn] = v.value === "true"; + return; + } + + if (key === "unused") { + switch (val) { + case "true": + state.option.unused = true; + break; + case "false": + state.option.unused = false; + break; + case "vars": + case "strict": + state.option.unused = val; + break; + default: + error("E002", nt); + } + return; + } + + if (key === "latedef") { + switch (val) { + case "true": + state.option.latedef = true; + break; + case "false": + state.option.latedef = false; + break; + case "nofunc": + state.option.latedef = "nofunc"; + break; + default: + error("E002", nt); + } + return; + } + + var match = /^([+-])(W\d{3})$/g.exec(key); + if (match) { + state.ignored[match[2]] = (match[1] === "-"); + return; + } + + var tn; + if (val === "true" || val === "false") { + if (nt.type === "jslint") { + tn = renamedOptions[key] || key; + state.option[tn] = (val === "true"); + if (invertedOptions[tn] !== undefined) { - obj[tn] = !obj[tn]; + state.option[tn] = !state.option[tn]; } } else { - obj[t.value] = v.value === "true"; + state.option[key] = (val === "true"); } - if (t.value === "newcap") - obj["(explicitNewcap)"] = true; - } else { - error("Bad option value.", v); - } - t = lex.token(); - } else { - if (o === "/*jshint" || o === "/*jslint") { - error("Missing option value.", t); + if (key === "newcap") { + state.option["(explicitNewcap)"] = true; + } + return; } - obj[t.value] = false; + error("E002", nt); + }); - if (o === "/*global" && minus === true) { - JSHINT.blacklist[t.value] = t.value; - updatePredefined(); - } - - t = v; - } - } - - if (o === "/*members") { - option.quotmark = quotmarkValue; - } - - combine(predefined, predef); - - for (var key in predef) { - if (is_own(predef, key)) { - declared[key] = nt; - } - } - - if (filter) { assume(); } } @@ -3832,54 +3860,61 @@ klass: } function advance(id, t) { - switch (token.id) { + switch (state.tokens.curr.id) { case "(number)": - if (nexttoken.id === ".") { - warning("A dot following a number can be confused with a decimal point.", token); + if (state.tokens.next.id === ".") { + warning("W005", state.tokens.curr); } break; case "-": - if (nexttoken.id === "-" || nexttoken.id === "--") { - warning("Confusing minusses."); + if (state.tokens.next.id === "-" || state.tokens.next.id === "--") { + warning("W006"); } break; case "+": - if (nexttoken.id === "+" || nexttoken.id === "++") { - warning("Confusing plusses."); + if (state.tokens.next.id === "+" || state.tokens.next.id === "++") { + warning("W007"); } break; } - if (token.type === "(string)" || token.identifier) { - anonname = token.value; + if (state.tokens.curr.type === "(string)" || state.tokens.curr.identifier) { + anonname = state.tokens.curr.value; } - if (id && nexttoken.id !== id) { + if (id && state.tokens.next.id !== id) { if (t) { - if (nexttoken.id === "(end)") { - warning("Unmatched '{a}'.", t, t.id); + if (state.tokens.next.id === "(end)") { + error("E019", t, t.id); } else { - warning("Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.", - nexttoken, id, t.id, t.line, nexttoken.value); + error("E020", state.tokens.next, id, t.id, t.line, state.tokens.next.value); } - } else if (nexttoken.type !== "(identifier)" || - nexttoken.value !== id) { - warning("Expected '{a}' and instead saw '{b}'.", - nexttoken, id, nexttoken.value); + } else if (state.tokens.next.type !== "(identifier)" || state.tokens.next.value !== id) { + warning("W116", state.tokens.next, id, state.tokens.next.value); } } - prevtoken = token; - token = nexttoken; + state.tokens.prev = state.tokens.curr; + state.tokens.curr = state.tokens.next; for (;;) { - nexttoken = lookahead.shift() || lex.token(); - if (nexttoken.id === "(end)" || nexttoken.id === "(error)") { + state.tokens.next = lookahead.shift() || lex.token(); + + if (!state.tokens.next) { // No more tokens left, give up + quit("E041", state.tokens.curr.line); + } + + if (state.tokens.next.id === "(end)" || state.tokens.next.id === "(error)") { return; } - if (nexttoken.type === "special") { + + if (state.tokens.next.check) { + state.tokens.next.check(); + } + + if (state.tokens.next.isSpecial) { doOption(); } else { - if (nexttoken.id !== "(endline)") { + if (state.tokens.next.id !== "(endline)") { break; } } @@ -3887,84 +3922,100 @@ klass: } function expression(rbp, initial) { - var left, isArray = false, isObject = false; + var left, isArray = false, isObject = false, isLetExpr = false; + if (!initial && state.tokens.next.value === "let" && peek(0).value === "(") { + if (!state.option.inMoz(true)) { + warning("W118", state.tokens.next, "let expressions"); + } + isLetExpr = true; + funct["(blockscope)"].stack(); + advance("let"); + advance("("); + state.syntax["let"].fud.call(state.syntax["let"].fud, false); + advance(")"); + } - if (nexttoken.id === "(end)") - error("Unexpected early end of program.", token); + if (state.tokens.next.id === "(end)") + error("E006", state.tokens.curr); advance(); + if (initial) { anonname = "anonymous"; - funct["(verb)"] = token.value; + funct["(verb)"] = state.tokens.curr.value; } - if (initial === true && token.fud) { - left = token.fud(); + + if (initial === true && state.tokens.curr.fud) { + left = state.tokens.curr.fud(); } else { - if (token.nud) { - left = token.nud(); + if (state.tokens.curr.nud) { + left = state.tokens.curr.nud(); } else { - if (nexttoken.type === "(number)" && token.id === ".") { - warning("A leading decimal point can be confused with a dot: '.{a}'.", - token, nexttoken.value); - advance(); - return token; - } else { - error("Expected an identifier and instead saw '{a}'.", - token, token.id); - } + error("E030", state.tokens.curr, state.tokens.curr.id); } - while (rbp < nexttoken.lbp) { - isArray = token.value === "Array"; - isObject = token.value === "Object"; + + var end_of_expr = state.tokens.next.identifier && + !state.tokens.curr.led && + state.tokens.curr.line !== state.tokens.next.line; + while (rbp < state.tokens.next.lbp && !end_of_expr) { + isArray = state.tokens.curr.value === "Array"; + isObject = state.tokens.curr.value === "Object"; if (left && (left.value || (left.first && left.first.value))) { if (left.value !== "new" || (left.first && left.first.value && left.first.value === ".")) { isArray = false; - if (left.value !== token.value) { + if (left.value !== state.tokens.curr.value) { isObject = false; } } } advance(); - if (isArray && token.id === "(" && nexttoken.id === ")") - warning("Use the array literal notation [].", token); - if (isObject && token.id === "(" && nexttoken.id === ")") - warning("Use the object literal notation {}.", token); - if (token.led) { - left = token.led(left); + + if (isArray && state.tokens.curr.id === "(" && state.tokens.next.id === ")") { + warning("W009", state.tokens.curr); + } + + if (isObject && state.tokens.curr.id === "(" && state.tokens.next.id === ")") { + warning("W010", state.tokens.curr); + } + + if (left && state.tokens.curr.led) { + left = state.tokens.curr.led(left); } else { - error("Expected an operator and instead saw '{a}'.", - token, token.id); + error("E033", state.tokens.curr, state.tokens.curr.id); } } } + if (isLetExpr) { + funct["(blockscope)"].unstack(); + } return left; } function adjacent(left, right) { - left = left || token; - right = right || nexttoken; - if (option.white) { + left = left || state.tokens.curr; + right = right || state.tokens.next; + if (state.option.white) { if (left.character !== right.from && left.line === right.line) { left.from += (left.character - left.from); - warning("Unexpected space after '{a}'.", left, left.value); + warning("W011", left, left.value); } } } function nobreak(left, right) { - left = left || token; - right = right || nexttoken; - if (option.white && (left.character !== right.from || left.line !== right.line)) { - warning("Unexpected space before '{a}'.", right, right.value); + left = left || state.tokens.curr; + right = right || state.tokens.next; + if (state.option.white && (left.character !== right.from || left.line !== right.line)) { + warning("W012", right, right.value); } } function nospace(left, right) { - left = left || token; - right = right || nexttoken; - if (option.white && !left.comment) { + left = left || state.tokens.curr; + right = right || state.tokens.next; + if (state.option.white && !left.comment) { if (left.line === right.line) { adjacent(left, right); } @@ -3972,77 +4023,132 @@ klass: } function nonadjacent(left, right) { - if (option.white) { - left = left || token; - right = right || nexttoken; + if (state.option.white) { + left = left || state.tokens.curr; + right = right || state.tokens.next; + if (left.value === ";" && right.value === ";") { return; } + if (left.line === right.line && left.character === right.from) { left.from += (left.character - left.from); - warning("Missing space after '{a}'.", - left, left.value); + warning("W013", left, left.value); } } } function nobreaknonadjacent(left, right) { - left = left || token; - right = right || nexttoken; - if (!option.laxbreak && left.line !== right.line) { - warning("Bad line breaking before '{a}'.", right, right.id); - } else if (option.white) { - left = left || token; - right = right || nexttoken; + left = left || state.tokens.curr; + right = right || state.tokens.next; + if (!state.option.laxbreak && left.line !== right.line) { + warning("W014", right, right.id); + } else if (state.option.white) { + left = left || state.tokens.curr; + right = right || state.tokens.next; if (left.character === right.from) { left.from += (left.character - left.from); - warning("Missing space after '{a}'.", - left, left.value); + warning("W013", left, left.value); } } } function indentation(bias) { - var i; - if (option.white && nexttoken.id !== "(end)") { - i = indent + (bias || 0); - if (nexttoken.from !== i) { - warning( -"Expected '{a}' to have an indentation at {b} instead at {c}.", - nexttoken, nexttoken.value, i, nexttoken.from); - } + if (!state.option.white && !state.option["(explicitIndent)"]) { + return; + } + + if (state.tokens.next.id === "(end)") { + return; + } + + var i = indent + (bias || 0); + if (state.tokens.next.from !== i) { + warning("W015", state.tokens.next, state.tokens.next.value, i, state.tokens.next.from); } } function nolinebreak(t) { - t = t || token; - if (t.line !== nexttoken.line) { - warning("Line breaking error '{a}'.", t, t.value); + t = t || state.tokens.curr; + if (t.line !== state.tokens.next.line) { + warning("E022", t, t.value); } } - function comma() { - if (token.line !== nexttoken.line) { - if (!option.laxcomma) { - if (comma.first) { - warning("Comma warnings can be turned off with 'laxcomma'"); - comma.first = false; + function comma(opts) { + opts = opts || {}; + + if (!opts.peek) { + if (state.tokens.curr.line !== state.tokens.next.line) { + if (!state.option.laxcomma) { + if (comma.first) { + warning("I001"); + comma.first = false; + } + warning("W014", state.tokens.curr, state.tokens.next.value); } - warning("Bad line breaking before '{a}'.", token, nexttoken.id); + } else if (!state.tokens.curr.comment && + state.tokens.curr.character !== state.tokens.next.from && state.option.white) { + state.tokens.curr.from += (state.tokens.curr.character - state.tokens.curr.from); + warning("W011", state.tokens.curr, state.tokens.curr.value); } - } else if (!token.comment && token.character !== nexttoken.from && option.white) { - token.from += (token.character - token.from); - warning("Unexpected space after '{a}'.", token, token.value); + + advance(","); } - advance(","); - nonadjacent(token, nexttoken); + + if (state.tokens.next.value !== "]" && state.tokens.next.value !== "}") { + nonadjacent(state.tokens.curr, state.tokens.next); + } + + if (state.tokens.next.identifier && !(opts.property && state.option.inES5())) { + switch (state.tokens.next.value) { + case "break": + case "case": + case "catch": + case "continue": + case "default": + case "do": + case "else": + case "finally": + case "for": + case "if": + case "in": + case "instanceof": + case "return": + case "yield": + case "switch": + case "throw": + case "try": + case "var": + case "let": + case "while": + case "with": + error("E024", state.tokens.next, state.tokens.next.value); + return false; + } + } + + if (state.tokens.next.type === "(punctuator)") { + switch (state.tokens.next.value) { + case "}": + case "]": + case ",": + if (opts.allowTrailing) { + return true; + } + case ")": + error("E024", state.tokens.next, state.tokens.next.value); + return false; + } + } + return true; } function symbol(s, p) { - var x = syntax[s]; + var x = state.syntax[s]; if (!x || typeof x !== "object") { - syntax[s] = x = { + state.syntax[s] = x = { id: s, lbp: p, value: s @@ -4051,12 +4157,10 @@ klass: return x; } - function delim(s) { return symbol(s, 0); } - function stmt(s, f) { var x = delim(s); x.identifier = x.reserved = true; @@ -4064,14 +4168,12 @@ klass: return x; } - function blockstmt(s, f) { var x = stmt(s, f); x.block = true; return x; } - function reserveName(x) { var c = x.id.charAt(0); if ((c >= "a" && c <= "z") || (c >= "A" && c <= "Z")) { @@ -4080,7 +4182,6 @@ klass: return x; } - function prefix(s, f) { var x = symbol(s, 150); reserveName(x); @@ -4088,11 +4189,11 @@ klass: this.right = expression(150); this.arity = "unary"; if (this.id === "++" || this.id === "--") { - if (option.plusplus) { - warning("Unexpected use of '{a}'.", this, this.id); - } else if ((!this.right.identifier || this.right.reserved) && + if (state.option.plusplus) { + warning("W016", this, this.id); + } else if ((!this.right.identifier || isReserved(this.right)) && this.right.id !== "." && this.right.id !== "[") { - warning("Bad operand.", this); + warning("W017", this); } } return this; @@ -4100,7 +4201,6 @@ klass: return x; } - function type(s, f) { var x = delim(s); x.type = s; @@ -4108,13 +4208,28 @@ klass: return x; } - - function reserve(s, f) { - var x = type(s, f); - x.identifier = x.reserved = true; + function reserve(name, func) { + var x = type(name, func); + x.identifier = true; + x.reserved = true; return x; } + function FutureReservedWord(name, meta) { + var x = type(name, (meta && meta.nud) || function () { + return this; + }); + + meta = meta || {}; + meta.isFutureReservedWord = true; + + x.value = name; + x.identifier = true; + x.reserved = true; + x.meta = meta; + + return x; + } function reservevar(s, v) { return reserve(s, function () { @@ -4125,17 +4240,16 @@ klass: }); } - function infix(s, f, p, w) { var x = symbol(s, p); reserveName(x); x.led = function (left) { if (!w) { - nobreaknonadjacent(prevtoken, token); - nonadjacent(token, nexttoken); + nobreaknonadjacent(state.tokens.prev, state.tokens.curr); + nonadjacent(state.tokens.curr, state.tokens.next); } if (s === "in" && left.id === "!") { - warning("Confusing use of '{a}'.", left, "!"); + warning("W018", left, "!"); } if (typeof f === "function") { return f(left, this); @@ -4149,24 +4263,50 @@ klass: } + function application(s) { + var x = symbol(s, 42); + + x.led = function (left) { + if (!state.option.inESNext()) { + warning("W104", state.tokens.curr, "arrow function syntax (=>)"); + } + + nobreaknonadjacent(state.tokens.prev, state.tokens.curr); + nonadjacent(state.tokens.curr, state.tokens.next); + + this.left = left; + this.right = doFunction(undefined, undefined, false, left); + return this; + }; + return x; + } + function relation(s, f) { var x = symbol(s, 100); + x.led = function (left) { - nobreaknonadjacent(prevtoken, token); - nonadjacent(token, nexttoken); + nobreaknonadjacent(state.tokens.prev, state.tokens.curr); + nonadjacent(state.tokens.curr, state.tokens.next); var right = expression(100); if (isIdentifier(left, "NaN") || isIdentifier(right, "NaN")) { - warning("Use the isNaN function to compare with NaN.", this); + warning("W019", this); } else if (f) { f.apply(this, [left, right]); } + + if (!left || !right) { + quit("E041", state.tokens.curr.line); + } + if (left.id === "!") { - warning("Confusing use of '{a}'.", left, "!"); + warning("W018", left, "!"); } + if (right.id === "!") { - warning("Confusing use of '{a}'.", right, "!"); + warning("W018", right, "!"); } + this.left = left; this.right = right; return this; @@ -4174,58 +4314,71 @@ klass: return x; } - function isPoorRelation(node) { return node && ((node.type === "(number)" && +node.value === 0) || (node.type === "(string)" && node.value === "") || - (node.type === "null" && !option.eqnull) || + (node.type === "null" && !state.option.eqnull) || node.type === "true" || node.type === "false" || node.type === "undefined"); } - function assignop(s) { symbol(s, 20).exps = true; return infix(s, function (left, that) { that.left = left; - if (predefined[left.value] === false && - scope[left.value]["(global)"] === true) { - warning("Read only.", left); - } else if (left["function"]) { - warning("'{a}' is a function.", left, left.value); - } - if (left) { - if (option.esnext && funct[left.value] === "const") { - warning("Attempting to override '{a}' which is a constant", left, left.value); + if (predefined[left.value] === false && + scope[left.value]["(global)"] === true) { + warning("W020", left); + } else if (left["function"]) { + warning("W021", left, left.value); } - if (left.id === "." || left.id === "[") { - if (!left.left || left.left.value === "arguments") { - warning("Bad assignment.", that); + if (funct[left.value] === "const") { + error("E013", left, left.value); + } + + if (left.id === ".") { + if (!left.left) { + warning("E031", that); + } else if (left.left.value === "arguments" && !state.directive["use strict"]) { + warning("E031", that); + } + + that.right = expression(19); + return that; + } else if (left.id === "[") { + if (state.tokens.curr.left.first) { + state.tokens.curr.left.first.forEach(function (t) { + if (funct[t.value] === "const") { + error("E013", t, t.value); + } + }); + } else if (!left.left) { + warning("E031", that); + } else if (left.left.value === "arguments" && !state.directive["use strict"]) { + warning("E031", that); } that.right = expression(19); return that; - } else if (left.identifier && !left.reserved) { + } else if (left.identifier && !isReserved(left)) { if (funct[left.value] === "exception") { - warning("Do not assign to the exception parameter.", left); + warning("W022", left); } that.right = expression(19); return that; } - if (left === syntax["function"]) { - warning( -"Expected an identifier in an assignment and instead saw a function invocation.", - token); + if (left === state.syntax["function"]) { + warning("W023", state.tokens.curr); } } - error("Bad assignment.", that); + error("E031", that); }, 20); } @@ -4234,8 +4387,8 @@ klass: var x = symbol(s, p); reserveName(x); x.led = (typeof f === "function") ? f : function (left) { - if (option.bitwise) { - warning("Unexpected use of '{a}'.", this, this.id); + if (state.option.bitwise) { + warning("W016", this, this.id); } this.left = left; this.right = expression(p); @@ -4248,72 +4401,91 @@ klass: function bitwiseassignop(s) { symbol(s, 20).exps = true; return infix(s, function (left, that) { - if (option.bitwise) { - warning("Unexpected use of '{a}'.", that, that.id); + if (state.option.bitwise) { + warning("W016", that, that.id); } - nonadjacent(prevtoken, token); - nonadjacent(token, nexttoken); + nonadjacent(state.tokens.prev, state.tokens.curr); + nonadjacent(state.tokens.curr, state.tokens.next); if (left) { if (left.id === "." || left.id === "[" || - (left.identifier && !left.reserved)) { + (left.identifier && !isReserved(left))) { expression(19); return that; } - if (left === syntax["function"]) { - warning( -"Expected an identifier in an assignment, and instead saw a function invocation.", - token); + if (left === state.syntax["function"]) { + warning("W023", state.tokens.curr); } return that; } - error("Bad assignment.", that); + error("E031", that); }, 20); } function suffix(s) { var x = symbol(s, 150); + x.led = function (left) { - if (option.plusplus) { - warning("Unexpected use of '{a}'.", this, this.id); - } else if ((!left.identifier || left.reserved) && - left.id !== "." && left.id !== "[") { - warning("Bad operand.", this); + if (state.option.plusplus) { + warning("W016", this, this.id); + } else if ((!left.identifier || isReserved(left)) && left.id !== "." && left.id !== "[") { + warning("W017", this); } + this.left = left; return this; }; return x; } - function optionalidentifier(fnparam) { - if (nexttoken.identifier) { - advance(); - if (token.reserved && !option.es5) { - if (!fnparam || token.value !== "undefined") { - warning("Expected an identifier and instead saw '{a}' (a reserved word).", - token, token.id); - } - } - return token.value; + + function optionalidentifier(fnparam, prop) { + if (!state.tokens.next.identifier) { + return; } + + advance(); + + var curr = state.tokens.curr; + var meta = curr.meta || {}; + var val = state.tokens.curr.value; + + if (!isReserved(curr)) { + return val; + } + + if (prop) { + if (state.option.inES5() || meta.isFutureReservedWord) { + return val; + } + } + + if (fnparam && val === "undefined") { + return val; + } + if (prop && !api.getCache("displayed:I002")) { + api.setCache("displayed:I002", true); + warning("I002"); + } + + warning("W024", state.tokens.curr, state.tokens.curr.id); + return val; } - function identifier(fnparam) { - var i = optionalidentifier(fnparam); + function identifier(fnparam, prop) { + var i = optionalidentifier(fnparam, prop); if (i) { return i; } - if (token.id === "function" && nexttoken.id === "(") { - warning("Missing name in function declaration."); + if (state.tokens.curr.id === "function" && state.tokens.next.id === "(") { + warning("W025"); } else { - error("Expected an identifier and instead saw '{a}'.", - nexttoken, nexttoken.value); + error("E030", state.tokens.next, state.tokens.next.value); } } function reachable(s) { var i = 0, t; - if (nexttoken.id !== ";" || noreach) { + if (state.tokens.next.id !== ";" || noreach) { return; } for (;;) { @@ -4323,14 +4495,15 @@ klass: } if (t.id !== "(endline)") { if (t.id === "function") { - if (!option.latedef) { + if (!state.option.latedef) { break; } - warning( -"Inner functions should be listed at the top of the outer function.", t); + + warning("W026", t); break; } - warning("Unreachable '{a}' after '{b}'.", t, t.value, s); + + warning("W027", t, t.value, s); break; } i += 1; @@ -4339,29 +4512,46 @@ klass: function statement(noindent) { - var i = indent, r, s = scope, t = nexttoken; + var values; + var i = indent, r, s = scope, t = state.tokens.next; if (t.id === ";") { advance(";"); return; } + var res = isReserved(t); - if (t.identifier && !t.reserved && peek().id === ":") { + if (res && t.meta && t.meta.isFutureReservedWord && peek().id === ":") { + warning("W024", t, t.id); + res = false; + } + if (_.has(["[", "{"], t.value)) { + if (lookupBlockType().isDestAssign) { + if (!state.option.inESNext()) { + warning("W104", state.tokens.curr, "destructuring expression"); + } + values = destructuringExpression(); + values.forEach(function (tok) { + isundef(funct, "W117", tok.token, tok.id); + }); + advance("="); + destructuringExpressionMatch(values, expression(5, true)); + advance(";"); + return; + } + } + if (t.identifier && !res && peek().id === ":") { advance(); advance(":"); scope = Object.create(s); addlabel(t.value, "label"); - if (!nexttoken.labelled && nexttoken.value !== "{") { - warning("Label '{a}' on {b} statement.", nexttoken, t.value, nexttoken.value); + if (!state.tokens.next.labelled && state.tokens.next.value !== "{") { + warning("W028", state.tokens.next, t.value, state.tokens.next.value); } - if (jx.test(t.value + ":")) { - warning("Label '{a}' looks like a javascript url.", t, t.value); - } - - nexttoken.label = t.value; - t = nexttoken; + state.tokens.next.label = t.value; + t = state.tokens.next; } if (t.id === "{") { @@ -4375,28 +4565,23 @@ klass: r = expression(0, true); if (!t.block) { - if (!option.expr && (!r || !r.exps)) { - warning("Expected an assignment or function call and instead saw an expression.", - token); - } else if (option.nonew && r.id === "(" && r.left.id === "new") { - warning("Do not use 'new' for side effects.", t); + if (!state.option.expr && (!r || !r.exps)) { + warning("W030", state.tokens.curr); + } else if (state.option.nonew && r && r.left && r.id === "(" && r.left.id === "new") { + warning("W031", t); } - if (nexttoken.id === ",") { - return comma(); - } - - if (nexttoken.id !== ";") { - if (!option.asi) { - if (!option.lastsemic || nexttoken.id !== "}" || - nexttoken.line !== token.line) { - warningAt("Missing semicolon.", token.line, token.character); + if (state.tokens.next.id !== ";") { + if (!state.option.asi) { + if (!state.option.lastsemic || state.tokens.next.id !== "}" || + state.tokens.next.line !== state.tokens.curr.line) { + warningAt("W033", state.tokens.curr.line, state.tokens.curr.character); } } } else { - adjacent(token, nexttoken); + adjacent(state.tokens.curr, state.tokens.next); advance(";"); - nonadjacent(token, nexttoken); + nonadjacent(state.tokens.curr, state.tokens.next); } } @@ -4409,15 +4594,17 @@ klass: function statements(startLine) { var a = [], p; - while (!nexttoken.reach && nexttoken.id !== "(end)") { - if (nexttoken.id === ";") { + while (!state.tokens.next.reach && state.tokens.next.id !== "(end)") { + if (state.tokens.next.id === ";") { p = peek(); - if (!p || p.id !== "(") { - warning("Unnecessary semicolon."); + + if (!p || (p.id !== "(" && p.id !== "[")) { + warning("W032"); } + advance(";"); } else { - a.push(statement(startLine === nexttoken.line)); + a.push(statement(startLine === state.tokens.next.line)); } } return a; @@ -4426,7 +4613,7 @@ klass: var i, p, pn; for (;;) { - if (nexttoken.id === "(string)") { + if (state.tokens.next.id === "(string)") { p = peek(0); if (p.id === "(endline)") { i = 1; @@ -4441,28 +4628,28 @@ klass: pn.id !== "}") { break; } - warning("Missing semicolon.", nexttoken); + warning("W033", state.tokens.next); } else { p = pn; } } else if (p.id === "}") { - warning("Missing semicolon.", p); + warning("W033", p); } else if (p.id !== ";") { break; } indentation(); advance(); - if (directive[token.value]) { - warning("Unnecessary directive \"{a}\".", token, token.value); + if (state.directive[state.tokens.curr.value]) { + warning("W034", state.tokens.curr, state.tokens.curr.value); } - if (token.value === "use strict") { - if (!option["(explicitNewcap)"]) - option.newcap = true; - option.undef = true; + if (state.tokens.curr.value === "use strict") { + if (!state.option["(explicitNewcap)"]) + state.option.newcap = true; + state.option.undef = true; } - directive[token.value] = true; + state.directive[state.tokens.curr.value] = true; if (p.id === ";") { advance(";"); @@ -4472,7 +4659,7 @@ klass: break; } } - function block(ordinary, stmt, isfunc) { + function block(ordinary, stmt, isfunc, isfatarrow) { var a, b = inblock, old_indent = indent, @@ -4484,37 +4671,39 @@ klass: inblock = ordinary; - if (!ordinary || !option.funcscope) + if (!ordinary || !state.option.funcscope) scope = Object.create(scope); - nonadjacent(token, nexttoken); - t = nexttoken; + nonadjacent(state.tokens.curr, state.tokens.next); + t = state.tokens.next; var metrics = funct["(metrics)"]; metrics.nestedBlockDepth += 1; metrics.verifyMaxNestedBlockDepthPerFunction(); - if (nexttoken.id === "{") { + if (state.tokens.next.id === "{") { advance("{"); - line = token.line; - if (nexttoken.id !== "}") { - indent += option.indent; - while (!ordinary && nexttoken.from > indent) { - indent += option.indent; + funct["(blockscope)"].stack(); + + line = state.tokens.curr.line; + if (state.tokens.next.id !== "}") { + indent += state.option.indent; + while (!ordinary && state.tokens.next.from > indent) { + indent += state.option.indent; } if (isfunc) { m = {}; - for (d in directive) { - if (is_own(directive, d)) { - m[d] = directive[d]; + for (d in state.directive) { + if (_.has(state.directive, d)) { + m[d] = state.directive[d]; } } directives(); - if (option.strict && funct["(context)"]["(global)"]) { - if (!m["use strict"] && !directive["use strict"]) { - warning("Missing \"use strict\" statement."); + if (state.option.strict && funct["(context)"]["(global)"]) { + if (!m["use strict"] && !state.directive["use strict"]) { + warning("E007"); } } } @@ -4524,37 +4713,65 @@ klass: metrics.statementCount += a.length; if (isfunc) { - directive = m; + state.directive = m; } - indent -= option.indent; - if (line !== nexttoken.line) { + indent -= state.option.indent; + if (line !== state.tokens.next.line) { indentation(); } - } else if (line !== nexttoken.line) { + } else if (line !== state.tokens.next.line) { indentation(); } advance("}", t); + + funct["(blockscope)"].unstack(); + indent = old_indent; } else if (!ordinary) { - error("Expected '{a}' and instead saw '{b}'.", - nexttoken, "{", nexttoken.value); + if (isfunc) { + m = {}; + if (stmt && !isfatarrow && !state.option.inMoz(true)) { + error("W118", state.tokens.curr, "function closure expressions"); + } + + if (!stmt) { + for (d in state.directive) { + if (_.has(state.directive, d)) { + m[d] = state.directive[d]; + } + } + } + expression(5); + + if (state.option.strict && funct["(context)"]["(global)"]) { + if (!m["use strict"] && !state.directive["use strict"]) { + warning("E007"); + } + } + } else { + error("E021", state.tokens.next, "{", state.tokens.next.value); + } } else { - if (!stmt || option.curly) - warning("Expected '{a}' and instead saw '{b}'.", - nexttoken, "{", nexttoken.value); + funct["(nolet)"] = true; + + if (!stmt || state.option.curly) { + warning("W116", state.tokens.next, "{", state.tokens.next.value); + } noreach = true; - indent += option.indent; - a = [statement(nexttoken.line === token.line)]; - indent -= option.indent; + indent += state.option.indent; + a = [statement(state.tokens.next.line === state.tokens.curr.line)]; + indent -= state.option.indent; noreach = false; + + delete funct["(nolet)"]; } funct["(verb)"] = null; - if (!ordinary || !option.funcscope) scope = s; + if (!ordinary || !state.option.funcscope) scope = s; inblock = b; - if (ordinary && option.noempty && (!a || a.length === 0)) { - warning("Empty block."); + if (ordinary && state.option.noempty && (!a || a.length === 0)) { + warning("W035"); } metrics.nestedBlockDepth -= 1; return a; @@ -4563,7 +4780,7 @@ klass: function countMember(m) { if (membersOnly && typeof membersOnly[m] !== "boolean") { - warning("Unexpected /*member '{a}'.", token, m); + warning("W036", state.tokens.curr, m); } if (typeof member[m] === "number") { member[m] += 1; @@ -4573,8 +4790,8 @@ klass: } - function note_implied(token) { - var name = token.value, line = token.line, a = implied[name]; + function note_implied(tkn) { + var name = tkn.value, line = tkn.line, a = implied[name]; if (typeof a === "function") { a = false; } @@ -4595,7 +4812,7 @@ klass: return this; }); - syntax["(identifier)"] = { + state.syntax["(identifier)"] = { type: "(identifier)", lbp: 0, identifier: true, @@ -4613,33 +4830,42 @@ klass: s = funct; funct = f; } - if (funct === s) { - switch (funct[v]) { + var block; + if (_.has(funct, "(blockscope)")) { + block = funct["(blockscope)"].getlabel(v); + } + if (funct === s || block) { + switch (block ? block[v]["(type)"] : funct[v]) { case "unused": - funct[v] = "var"; + if (block) block[v]["(type)"] = "var"; + else funct[v] = "var"; break; case "unction": - funct[v] = "function"; + if (block) block[v]["(type)"] = "function"; + else funct[v] = "function"; this["function"] = true; break; case "function": this["function"] = true; break; case "label": - warning("'{a}' is a statement label.", token, v); + warning("W037", state.tokens.curr, v); break; } } else if (funct["(global)"]) { - if (option.undef && typeof predefined[v] !== "boolean") { + if (typeof predefined[v] !== "boolean") { if (!(anonname === "typeof" || anonname === "delete") || - (nexttoken && (nexttoken.value === "." || nexttoken.value === "["))) { + (state.tokens.next && (state.tokens.next.value === "." || + state.tokens.next.value === "["))) { - isundef(funct, "'{a}' is not defined.", token, v); + if (!funct["(comparray)"].check(v)) { + isundef(funct, "W117", state.tokens.curr, v); + } } } - note_implied(token); + note_implied(state.tokens.curr); } else { switch (funct[v]) { @@ -4647,10 +4873,10 @@ klass: case "function": case "var": case "unused": - warning("'{a}' used out of scope.", token, v); + warning("W038", state.tokens.curr, v); break; case "label": - warning("'{a}' is a statement label.", token, v); + warning("W037", state.tokens.curr, v); break; case "outer": case "global": @@ -4659,19 +4885,17 @@ klass: if (s === true) { funct[v] = true; } else if (s === null) { - warning("'{a}' is not allowed.", token, v); - note_implied(token); + warning("W039", state.tokens.curr, v); + note_implied(state.tokens.curr); } else if (typeof s !== "object") { - if (option.undef) { - if (!(anonname === "typeof" || anonname === "delete") || - (nexttoken && - (nexttoken.value === "." || nexttoken.value === "["))) { + if (!(anonname === "typeof" || anonname === "delete") || + (state.tokens.next && + (state.tokens.next.value === "." || state.tokens.next.value === "["))) { - isundef(funct, "'{a}' is not defined.", token, v); - } + isundef(funct, "W117", state.tokens.curr, v); } funct[v] = true; - note_implied(token); + note_implied(state.tokens.curr); } else { switch (s[v]) { case "function": @@ -4689,7 +4913,7 @@ klass: funct[v] = s["(global)"] ? "global" : "outer"; break; case "label": - warning("'{a}' is a statement label.", token, v); + warning("W037", state.tokens.curr, v); } } } @@ -4697,8 +4921,7 @@ klass: return this; }, led: function () { - error("Expected an operator and instead saw '{a}'.", - nexttoken, nexttoken.value); + error("E033", state.tokens.next, state.tokens.next.value); } }; @@ -4709,10 +4932,6 @@ klass: delim("(endline)"); delim("(begin)"); delim("(end)").reach = true; - delim(""); delim("(error)").reach = true; delim("}").reach = true; delim(")"); @@ -4721,17 +4940,16 @@ klass: delim("'").reach = true; delim(";"); delim(":").reach = true; - delim(","); delim("#"); - delim("@"); + reserve("else"); reserve("case").reach = true; reserve("catch"); reserve("default").reach = true; reserve("finally"); reservevar("arguments", function (x) { - if (directive["use strict"] && funct["(global)"]) { - warning("Strict violation.", x); + if (state.directive["use strict"] && funct["(global)"]) { + warning("E008", x); } }); reservevar("eval"); @@ -4739,27 +4957,46 @@ klass: reservevar("Infinity"); reservevar("null"); reservevar("this", function (x) { - if (directive["use strict"] && !option.validthis && ((funct["(statement)"] && + if (state.directive["use strict"] && !state.option.validthis && ((funct["(statement)"] && funct["(name)"].charAt(0) > "Z") || funct["(global)"])) { - warning("Possible strict violation.", x); + warning("W040", x); } }); reservevar("true"); reservevar("undefined"); + assignop("=", "assign", 20); assignop("+=", "assignadd", 20); assignop("-=", "assignsub", 20); assignop("*=", "assignmult", 20); assignop("/=", "assigndiv", 20).nud = function () { - error("A regular expression literal can be confused with '/='."); + error("E014"); }; assignop("%=", "assignmod", 20); + bitwiseassignop("&=", "assignbitand", 20); bitwiseassignop("|=", "assignbitor", 20); bitwiseassignop("^=", "assignbitxor", 20); bitwiseassignop("<<=", "assignshiftleft", 20); bitwiseassignop(">>=", "assignshiftright", 20); bitwiseassignop(">>>=", "assignshiftrightunsigned", 20); + infix(",", function (left, that) { + var expr; + that.exprs = [left]; + if (!comma({peek: true})) { + return that; + } + while (true) { + if (!(expr = expression(5))) { + break; + } + that.exprs.push(expr); + if (state.tokens.next.value !== "," || !comma()) { + break; + } + } + return that; + }, 5, true); infix("?", function (left, that) { that.left = left; that.right = expression(10); @@ -4774,31 +5011,28 @@ klass: bitwise("^", "bitxor", 80); bitwise("&", "bitand", 90); relation("==", function (left, right) { - var eqnull = option.eqnull && (left.value === "null" || right.value === "null"); + var eqnull = state.option.eqnull && (left.value === "null" || right.value === "null"); - if (!eqnull && option.eqeqeq) - warning("Expected '{a}' and instead saw '{b}'.", this, "===", "=="); + if (!eqnull && state.option.eqeqeq) + warning("W116", this, "===", "=="); else if (isPoorRelation(left)) - warning("Use '{a}' to compare with '{b}'.", this, "===", left.value); + warning("W041", this, "===", left.value); else if (isPoorRelation(right)) - warning("Use '{a}' to compare with '{b}'.", this, "===", right.value); + warning("W041", this, "===", right.value); return this; }); relation("==="); relation("!=", function (left, right) { - var eqnull = option.eqnull && + var eqnull = state.option.eqnull && (left.value === "null" || right.value === "null"); - if (!eqnull && option.eqeqeq) { - warning("Expected '{a}' and instead saw '{b}'.", - this, "!==", "!="); + if (!eqnull && state.option.eqeqeq) { + warning("W116", this, "!==", "!="); } else if (isPoorRelation(left)) { - warning("Use '{a}' to compare with '{b}'.", - this, "!==", left.value); + warning("W041", this, "!==", left.value); } else if (isPoorRelation(right)) { - warning("Use '{a}' to compare with '{b}'.", - this, "!==", right.value); + warning("W041", this, "!==", right.value); } return this; }); @@ -4817,8 +5051,8 @@ klass: if (left && right && left.id === "(string)" && right.id === "(string)") { left.value += right.value; left.character = right.character; - if (!option.scripturl && jx.test(left.value)) { - warning("JavaScript URL.", left); + if (!state.option.scripturl && reg.javascriptURL.test(left.value)) { + warning("W050", left); } return left; } @@ -4828,13 +5062,13 @@ klass: }, 130); prefix("+", "num"); prefix("+++", function () { - warning("Confusing pluses."); + warning("W007"); this.right = expression(150); this.arity = "unary"; return this; }); infix("+++", function (left) { - warning("Confusing pluses."); + warning("W007"); this.left = left; this.right = expression(130); return this; @@ -4842,13 +5076,13 @@ klass: infix("-", "sub", 130); prefix("-", "neg"); prefix("---", function () { - warning("Confusing minuses."); + warning("W006"); this.right = expression(150); this.arity = "unary"; return this; }); infix("---", function (left) { - warning("Confusing minuses."); + warning("W006"); this.left = left; this.right = expression(130); return this; @@ -4859,23 +5093,34 @@ klass: suffix("++", "postinc"); prefix("++", "preinc"); - syntax["++"].exps = true; + state.syntax["++"].exps = true; suffix("--", "postdec"); prefix("--", "predec"); - syntax["--"].exps = true; + state.syntax["--"].exps = true; prefix("delete", function () { - var p = expression(0); + var p = expression(5); if (!p || (p.id !== "." && p.id !== "[")) { - warning("Variables should not be deleted."); + warning("W051"); } this.first = p; return this; }).exps = true; prefix("~", function () { - if (option.bitwise) { - warning("Unexpected '{a}'.", this, "~"); + if (state.option.bitwise) { + warning("W052", this, "~"); + } + expression(150); + return this; + }); + + prefix("...", function () { + if (!state.option.inESNext()) { + warning("W104", this, "spread/rest operator"); + } + if (!state.tokens.next.identifier) { + error("E030", state.tokens.next, state.tokens.next.value); } expression(150); return this; @@ -4884,11 +5129,17 @@ klass: prefix("!", function () { this.right = expression(150); this.arity = "unary"; + + if (!this.right) { // '!' followed by nothing? Give up. + quit("E041", this.line || 0); + } + if (bang[this.right.id] === true) { - warning("Confusing use of '{a}'.", this, "!"); + warning("W018", this, "!"); } return this; }); + prefix("typeof", "typeof"); prefix("new", function () { var c = expression(155), i; @@ -4901,11 +5152,11 @@ klass: case "Boolean": case "Math": case "JSON": - warning("Do not use {a} as a constructor.", prevtoken, c.value); + warning("W053", state.tokens.prev, c.value); break; case "Function": - if (!option.evil) { - warning("The Function constructor is eval."); + if (!state.option.evil) { + warning("W054"); } break; case "Date": @@ -4914,102 +5165,113 @@ klass: default: if (c.id !== "function") { i = c.value.substr(0, 1); - if (option.newcap && (i < "A" || i > "Z") && !is_own(global, c.value)) { - warning("A constructor name should start with an uppercase letter.", - token); + if (state.option.newcap && (i < "A" || i > "Z") && !_.has(global, c.value)) { + warning("W055", state.tokens.curr); } } } } else { if (c.id !== "." && c.id !== "[" && c.id !== "(") { - warning("Bad constructor.", token); + warning("W056", state.tokens.curr); } } } else { - if (!option.supernew) - warning("Weird construction. Delete 'new'.", this); + if (!state.option.supernew) + warning("W057", this); } - adjacent(token, nexttoken); - if (nexttoken.id !== "(" && !option.supernew) { - warning("Missing '()' invoking a constructor.", - token, token.value); + adjacent(state.tokens.curr, state.tokens.next); + if (state.tokens.next.id !== "(" && !state.option.supernew) { + warning("W058", state.tokens.curr, state.tokens.curr.value); } this.first = c; return this; }); - syntax["new"].exps = true; + state.syntax["new"].exps = true; prefix("void").exps = true; infix(".", function (left, that) { - adjacent(prevtoken, token); + adjacent(state.tokens.prev, state.tokens.curr); nobreak(); - var m = identifier(); + var m = identifier(false, true); + if (typeof m === "string") { countMember(m); } + that.left = left; that.right = m; + + if (m && m === "hasOwnProperty" && state.tokens.next.value === "=") { + warning("W001"); + } + if (left && left.value === "arguments" && (m === "callee" || m === "caller")) { - if (option.noarg) - warning("Avoid arguments.{a}.", left, m); - else if (directive["use strict"]) - error("Strict violation."); - } else if (!option.evil && left && left.value === "document" && + if (state.option.noarg) + warning("W059", left, m); + else if (state.directive["use strict"]) + error("E008"); + } else if (!state.option.evil && left && left.value === "document" && (m === "write" || m === "writeln")) { - warning("document.write can be a form of eval.", left); + warning("W060", left); } - if (!option.evil && (m === "eval" || m === "execScript")) { - warning("eval is evil."); + + if (!state.option.evil && (m === "eval" || m === "execScript")) { + warning("W061"); } + return that; }, 160, true); infix("(", function (left, that) { - if (prevtoken.id !== "}" && prevtoken.id !== ")") { - nobreak(prevtoken, token); + if (state.tokens.prev.id !== "}" && state.tokens.prev.id !== ")") { + nobreak(state.tokens.prev, state.tokens.curr); } + nospace(); - if (option.immed && !left.immed && left.id === "function") { - warning("Wrap an immediate function invocation in parentheses " + - "to assist the reader in understanding that the expression " + - "is the result of a function, and not the function itself."); + if (state.option.immed && left && !left.immed && left.id === "function") { + warning("W062"); } - var n = 0, - p = []; + + var n = 0; + var p = []; + if (left) { if (left.type === "(identifier)") { if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) { if ("Number String Boolean Date Object".indexOf(left.value) === -1) { if (left.value === "Math") { - warning("Math is not a function.", left); - } else if (option.newcap) { - warning("Missing 'new' prefix when invoking a constructor.", left); + warning("W063", left); + } else if (state.option.newcap) { + warning("W064", left); } } } } } - if (nexttoken.id !== ")") { + + if (state.tokens.next.id !== ")") { for (;;) { p[p.length] = expression(10); n += 1; - if (nexttoken.id !== ",") { + if (state.tokens.next.id !== ",") { break; } comma(); } } + advance(")"); - nospace(prevtoken, token); + nospace(state.tokens.prev, state.tokens.curr); + if (typeof left === "object") { if (left.value === "parseInt" && n === 1) { - warning("Missing radix parameter.", token); + warning("W065", state.tokens.curr); } - if (!option.evil) { + if (!state.option.evil) { if (left.value === "eval" || left.value === "Function" || left.value === "execScript") { - warning("eval is evil.", left); + warning("W061", left); if (p[0] && [0].id === "(string)") { addInternalSrc(left, p[0].value); @@ -5017,99 +5279,188 @@ klass: } else if (p[0] && p[0].id === "(string)" && (left.value === "setTimeout" || left.value === "setInterval")) { - warning( - "Implied eval is evil. Pass a function instead of a string.", left); + warning("W066", left); addInternalSrc(left, p[0].value); } else if (p[0] && p[0].id === "(string)" && left.value === "." && left.left.value === "window" && (left.right === "setTimeout" || left.right === "setInterval")) { - warning( - "Implied eval is evil. Pass a function instead of a string.", left); + warning("W066", left); addInternalSrc(left, p[0].value); } } if (!left.identifier && left.id !== "." && left.id !== "[" && left.id !== "(" && left.id !== "&&" && left.id !== "||" && left.id !== "?") { - warning("Bad invocation.", left); + warning("W067", left); } } + that.left = left; return that; }, 155, true).exps = true; prefix("(", function () { nospace(); - if (nexttoken.id === "function") { - nexttoken.immed = true; + var bracket, brackets = []; + var pn, pn1, i = 0; + var ret; + + do { + pn = peek(i); + i += 1; + pn1 = peek(i); + i += 1; + } while (pn.value !== ")" && pn1.value !== "=>" && pn1.value !== ";" && pn1.type !== "(end)"); + + if (state.tokens.next.id === "function") { + state.tokens.next.immed = true; } - var v = expression(0); - advance(")", this); - nospace(prevtoken, token); - if (option.immed && v.id === "function") { - if (nexttoken.id !== "(" && - (nexttoken.id !== "." || (peek().value !== "call" && peek().value !== "apply"))) { - warning( -"Do not wrap function literals in parens unless they are to be immediately invoked.", - this); + + var exprs = []; + + if (state.tokens.next.id !== ")") { + for (;;) { + if (pn1.value === "=>" && state.tokens.next.value === "{") { + bracket = state.tokens.next; + bracket.left = destructuringExpression(); + brackets.push(bracket); + for (var t in bracket.left) { + exprs.push(bracket.left[t].token); + } + } else { + exprs.push(expression(5)); + } + if (state.tokens.next.id !== ",") { + break; + } + comma(); } } - return v; + advance(")", this); + nospace(state.tokens.prev, state.tokens.curr); + if (state.option.immed && exprs[0] && exprs[0].id === "function") { + if (state.tokens.next.id !== "(" && + (state.tokens.next.id !== "." || (peek().value !== "call" && peek().value !== "apply"))) { + warning("W068", this); + } + } + + if (state.tokens.next.value === "=>") { + return exprs; + } + if (!exprs.length) { + return; + } + if (exprs.length > 1) { + ret = Object.create(state.syntax[","]); + ret.exprs = exprs; + } else { + ret = exprs[0]; + } + if (ret) { + ret.paren = true; + } + return ret; }); + application("=>"); + infix("[", function (left, that) { - nobreak(prevtoken, token); + nobreak(state.tokens.prev, state.tokens.curr); nospace(); - var e = expression(0), s; + var e = expression(5), s; if (e && e.type === "(string)") { - if (!option.evil && (e.value === "eval" || e.value === "execScript")) { - warning("eval is evil.", that); + if (!state.option.evil && (e.value === "eval" || e.value === "execScript")) { + warning("W061", that); } + countMember(e.value); - if (!option.sub && ix.test(e.value)) { - s = syntax[e.value]; - if (!s || !s.reserved) { - warning("['{a}'] is better written in dot notation.", - prevtoken, e.value); + if (!state.option.sub && reg.identifier.test(e.value)) { + s = state.syntax[e.value]; + if (!s || !isReserved(s)) { + warning("W069", state.tokens.prev, e.value); } } } advance("]", that); - nospace(prevtoken, token); + + if (e && e.value === "hasOwnProperty" && state.tokens.next.value === "=") { + warning("W001"); + } + + nospace(state.tokens.prev, state.tokens.curr); that.left = left; that.right = e; return that; }, 160, true); - prefix("[", function () { - var b = token.line !== nexttoken.line; - this.first = []; - if (b) { - indent += option.indent; - if (nexttoken.from === indent + option.indent) { - indent += option.indent; + function comprehensiveArrayExpression() { + var res = {}; + res.exps = true; + funct["(comparray)"].stack(); + + res.right = expression(5); + advance("for"); + if (state.tokens.next.value === "each") { + advance("each"); + if (!state.option.inMoz(true)) { + warning("W118", state.tokens.curr, "for each"); } } - while (nexttoken.id !== "(end)") { - while (nexttoken.id === ",") { - if (!option.es5) - warning("Extra comma."); + advance("("); + funct["(comparray)"].setState("define"); + res.left = expression(5); + advance(")"); + if (state.tokens.next.value === "if") { + advance("if"); + advance("("); + funct["(comparray)"].setState("filter"); + res.filter = expression(5); + advance(")"); + } + advance("]"); + funct["(comparray)"].unstack(); + return res; + } + + prefix("[", function () { + var blocktype = lookupBlockType(true); + if (blocktype.isCompArray) { + if (!state.option.inMoz(true)) { + warning("W118", state.tokens.curr, "array comprehension"); + } + return comprehensiveArrayExpression(); + } else if (blocktype.isDestAssign && !state.option.inESNext()) { + warning("W104", state.tokens.curr, "destructuring assignment"); + } + var b = state.tokens.curr.line !== state.tokens.next.line; + this.first = []; + if (b) { + indent += state.option.indent; + if (state.tokens.next.from === indent + state.option.indent) { + indent += state.option.indent; + } + } + while (state.tokens.next.id !== "(end)") { + while (state.tokens.next.id === ",") { + if (!state.option.inES5()) + warning("W070"); advance(","); } - if (nexttoken.id === "]") { + if (state.tokens.next.id === "]") { break; } - if (b && token.line !== nexttoken.line) { + if (b && state.tokens.curr.line !== state.tokens.next.line) { indentation(); } this.first.push(expression(10)); - if (nexttoken.id === ",") { - comma(); - if (nexttoken.id === "]" && !option.es5) { - warning("Extra comma.", token); + if (state.tokens.next.id === ",") { + comma({ allowTrailing: true }); + if (state.tokens.next.id === "]" && !state.option.inES5(true)) { + warning("W070", state.tokens.curr); break; } } else { @@ -5117,7 +5468,7 @@ klass: } } if (b) { - indent -= option.indent; + indent -= state.option.indent; indentation(); } advance("]", this); @@ -5126,71 +5477,139 @@ klass: function property_name() { - var id = optionalidentifier(true); + var id = optionalidentifier(false, true); + if (!id) { - if (nexttoken.id === "(string)") { - id = nexttoken.value; + if (state.tokens.next.id === "(string)") { + id = state.tokens.next.value; advance(); - } else if (nexttoken.id === "(number)") { - id = nexttoken.value.toString(); + } else if (state.tokens.next.id === "(number)") { + id = state.tokens.next.value.toString(); advance(); } } + + if (id === "hasOwnProperty") { + warning("W001"); + } + return id; } - function functionparams() { - var next = nexttoken; + function functionparams(parsed) { + var curr, next; var params = []; var ident; + var tokens = []; + var t; + + if (parsed) { + if (parsed instanceof Array) { + for (var i in parsed) { + curr = parsed[i]; + if (_.contains(["{", "["], curr.id)) { + for (t in curr.left) { + t = tokens[t]; + if (t.id) { + params.push(t.id); + addlabel(t.id, "unused", t.token); + } + } + } else if (curr.value === "...") { + if (!state.option.inESNext()) { + warning("W104", curr, "spread/rest operator"); + } + continue; + } else { + addlabel(curr.value, "unused", curr); + } + } + return params; + } else { + if (parsed.identifier === true) { + addlabel(parsed.value, "unused", parsed); + return [parsed]; + } + } + } + + next = state.tokens.next; advance("("); nospace(); - if (nexttoken.id === ")") { + if (state.tokens.next.id === ")") { advance(")"); return; } for (;;) { - ident = identifier(true); - params.push(ident); - addlabel(ident, "unused", token); - if (nexttoken.id === ",") { + if (_.contains(["{", "["], state.tokens.next.id)) { + tokens = destructuringExpression(); + for (t in tokens) { + t = tokens[t]; + if (t.id) { + params.push(t.id); + addlabel(t.id, "unused", t.token); + } + } + } else if (state.tokens.next.value === "...") { + if (!state.option.inESNext()) { + warning("W104", state.tokens.next, "spread/rest operator"); + } + advance("..."); + nospace(); + ident = identifier(true); + params.push(ident); + addlabel(ident, "unused", state.tokens.curr); + } else { + ident = identifier(true); + params.push(ident); + addlabel(ident, "unused", state.tokens.curr); + } + if (state.tokens.next.id === ",") { comma(); } else { advance(")", next); - nospace(prevtoken, token); + nospace(state.tokens.prev, state.tokens.curr); return params; } } } - function doFunction(name, statement) { + function doFunction(name, statement, generator, fatarrowparams) { var f; - var oldOption = option; + var oldOption = state.option; + var oldIgnored = state.ignored; var oldScope = scope; - option = Object.create(option); + state.option = Object.create(state.option); + state.ignored = Object.create(state.ignored); scope = Object.create(scope); funct = { - "(name)" : name || "\"" + anonname + "\"", - "(line)" : nexttoken.line, - "(character)": nexttoken.character, - "(context)" : funct, - "(breakage)" : 0, - "(loopage)" : 0, - "(metrics)" : createMetrics(nexttoken), - "(scope)" : scope, - "(statement)": statement, - "(tokens)" : {} + "(name)" : name || "\"" + anonname + "\"", + "(line)" : state.tokens.next.line, + "(character)" : state.tokens.next.character, + "(context)" : funct, + "(breakage)" : 0, + "(loopage)" : 0, + "(metrics)" : createMetrics(state.tokens.next), + "(scope)" : scope, + "(statement)" : statement, + "(tokens)" : {}, + "(blockscope)": funct["(blockscope)"], + "(comparray)" : funct["(comparray)"] }; + if (generator) { + funct["(generator)"] = true; + } + f = funct; - token.funct = funct; + state.tokens.curr.funct = funct; functions.push(funct); @@ -5198,18 +5617,25 @@ klass: addlabel(name, "function"); } - funct["(params)"] = functionparams(); + funct["(params)"] = functionparams(fatarrowparams); + funct["(metrics)"].verifyMaxParametersPerFunction(funct["(params)"]); - block(false, false, true); + block(false, true, true, fatarrowparams ? true:false); + + if (generator && funct["(generator)"] !== "yielded") { + error("E047", state.tokens.curr); + } funct["(metrics)"].verifyMaxStatementsPerFunction(); funct["(metrics)"].verifyMaxComplexityPerFunction(); + funct["(unusedOption)"] = state.option.unused; scope = oldScope; - option = oldOption; - funct["(last)"] = token.line; - funct["(lastcharacter)"] = token.character; + state.option = oldOption; + state.ignored = oldIgnored; + funct["(last)"] = state.tokens.curr.line; + funct["(lastcharacter)"] = state.tokens.curr.character; funct = funct["(context)"]; return f; @@ -5221,37 +5647,33 @@ klass: nestedBlockDepth: -1, ComplexityCount: 1, verifyMaxStatementsPerFunction: function () { - if (option.maxstatements && - this.statementCount > option.maxstatements) { - var message = "Too many statements per function (" + this.statementCount + ")."; - warning(message, functionStartToken); + if (state.option.maxstatements && + this.statementCount > state.option.maxstatements) { + warning("W071", functionStartToken, this.statementCount); } }, verifyMaxParametersPerFunction: function (params) { params = params || []; - if (option.maxparams && params.length > option.maxparams) { - var message = "Too many parameters per function (" + params.length + ")."; - warning(message, functionStartToken); + if (state.option.maxparams && params.length > state.option.maxparams) { + warning("W072", functionStartToken, params.length); } }, verifyMaxNestedBlockDepthPerFunction: function () { - if (option.maxdepth && + if (state.option.maxdepth && this.nestedBlockDepth > 0 && - this.nestedBlockDepth === option.maxdepth + 1) { - var message = "Blocks are nested too deeply (" + this.nestedBlockDepth + ")."; - warning(message); + this.nestedBlockDepth === state.option.maxdepth + 1) { + warning("W073", null, this.nestedBlockDepth); } }, verifyMaxComplexityPerFunction: function () { - var max = option.maxcomplexity; + var max = state.option.maxcomplexity; var cc = this.ComplexityCount; if (max && cc > max) { - var message = "Cyclomatic complexity is too high per function (" + cc + ")."; - warning(message, functionStartToken); + warning("W074", functionStartToken, cc); } } }; @@ -5261,236 +5683,406 @@ klass: funct["(metrics)"].ComplexityCount += 1; } + function checkCondAssignment(expr) { + var id, paren; + if (expr) { + id = expr.id; + paren = expr.paren; + if (id === "," && (expr = expr.exprs[expr.exprs.length - 1])) { + id = expr.id; + paren = paren || expr.paren; + } + } + switch (id) { + case "=": + case "+=": + case "-=": + case "*=": + case "%=": + case "&=": + case "|=": + case "^=": + case "/=": + if (!paren && !state.option.boss) { + warning("W084"); + } + } + } + (function (x) { - x.nud = function () { - var b, f, i, p, t; + x.nud = function (isclassdef) { + var b, f, i, p, t, g; var props = {}; // All properties, including accessors + var tag = ""; - function saveProperty(name, token) { - if (props[name] && is_own(props, name)) - warning("Duplicate member '{a}'.", nexttoken, i); + function saveProperty(name, tkn) { + if (props[name] && _.has(props, name)) + warning("W075", state.tokens.next, i); else props[name] = {}; props[name].basic = true; - props[name].basicToken = token; + props[name].basictkn = tkn; } - function saveSetter(name, token) { - if (props[name] && is_own(props, name)) { + function saveSetter(name, tkn) { + if (props[name] && _.has(props, name)) { if (props[name].basic || props[name].setter) - warning("Duplicate member '{a}'.", nexttoken, i); + warning("W075", state.tokens.next, i); } else { props[name] = {}; } props[name].setter = true; - props[name].setterToken = token; + props[name].setterToken = tkn; } function saveGetter(name) { - if (props[name] && is_own(props, name)) { + if (props[name] && _.has(props, name)) { if (props[name].basic || props[name].getter) - warning("Duplicate member '{a}'.", nexttoken, i); + warning("W075", state.tokens.next, i); } else { props[name] = {}; } props[name].getter = true; - props[name].getterToken = token; + props[name].getterToken = state.tokens.curr; } - b = token.line !== nexttoken.line; + b = state.tokens.curr.line !== state.tokens.next.line; if (b) { - indent += option.indent; - if (nexttoken.from === indent + option.indent) { - indent += option.indent; + indent += state.option.indent; + if (state.tokens.next.from === indent + state.option.indent) { + indent += state.option.indent; } } + for (;;) { - if (nexttoken.id === "}") { + if (state.tokens.next.id === "}") { break; } + if (b) { indentation(); } - if (nexttoken.value === "get" && peek().id !== ":") { + + if (isclassdef && state.tokens.next.value === "static") { + advance("static"); + tag = "static "; + } + + if (state.tokens.next.value === "get" && peek().id !== ":") { advance("get"); - if (!option.es5) { - error("get/set are ES5 features."); + + if (!state.option.inES5(!isclassdef)) { + error("E034"); } + i = property_name(); if (!i) { - error("Missing property name."); + error("E035"); } - saveGetter(i); - t = nexttoken; - adjacent(token, nexttoken); + if (isclassdef && i === "constructor") { + error("E049", state.tokens.next, "class getter method", i); + } + + saveGetter(tag + i); + t = state.tokens.next; + adjacent(state.tokens.curr, state.tokens.next); f = doFunction(); p = f["(params)"]; + if (p) { - warning("Unexpected parameter '{a}' in get {b} function.", t, p[0], i); + warning("W076", t, p[0], i); } - adjacent(token, nexttoken); - } else if (nexttoken.value === "set" && peek().id !== ":") { + + adjacent(state.tokens.curr, state.tokens.next); + } else if (state.tokens.next.value === "set" && peek().id !== ":") { advance("set"); - if (!option.es5) { - error("get/set are ES5 features."); + + if (!state.option.inES5(!isclassdef)) { + error("E034"); } + i = property_name(); if (!i) { - error("Missing property name."); + error("E035"); } - saveSetter(i, nexttoken); - t = nexttoken; - adjacent(token, nexttoken); + if (isclassdef && i === "constructor") { + error("E049", state.tokens.next, "class setter method", i); + } + + saveSetter(tag + i, state.tokens.next); + t = state.tokens.next; + adjacent(state.tokens.curr, state.tokens.next); f = doFunction(); p = f["(params)"]; + if (!p || p.length !== 1) { - warning("Expected a single parameter in set {a} function.", t, i); + warning("W077", t, i); } } else { + g = false; + if (state.tokens.next.value === "*" && state.tokens.next.type === "(punctuator)") { + if (!state.option.inESNext()) { + warning("W104", state.tokens.next, "generator functions"); + } + advance("*"); + g = true; + } i = property_name(); - saveProperty(i, nexttoken); + saveProperty(tag + i, state.tokens.next); + if (typeof i !== "string") { break; } - advance(":"); - nonadjacent(token, nexttoken); - expression(10); + + if (state.tokens.next.value === "(") { + if (!state.option.inESNext()) { + warning("W104", state.tokens.curr, "concise methods"); + } + doFunction(i, undefined, g); + } else if (!isclassdef) { + advance(":"); + nonadjacent(state.tokens.curr, state.tokens.next); + expression(10); + } + } + if (isclassdef && i === "prototype") { + error("E049", state.tokens.next, "class method", i); } countMember(i); - if (nexttoken.id === ",") { - comma(); - if (nexttoken.id === ",") { - warning("Extra comma.", token); - } else if (nexttoken.id === "}" && !option.es5) { - warning("Extra comma.", token); + if (isclassdef) { + tag = ""; + continue; + } + if (state.tokens.next.id === ",") { + comma({ allowTrailing: true, property: true }); + if (state.tokens.next.id === ",") { + warning("W070", state.tokens.curr); + } else if (state.tokens.next.id === "}" && !state.option.inES5(true)) { + warning("W070", state.tokens.curr); } } else { break; } } if (b) { - indent -= option.indent; + indent -= state.option.indent; indentation(); } advance("}", this); - if (option.es5) { + if (state.option.inES5()) { for (var name in props) { - if (is_own(props, name) && props[name].setter && !props[name].getter) { - warning("Setter is defined without getter.", props[name].setterToken); + if (_.has(props, name) && props[name].setter && !props[name].getter) { + warning("W078", props[name].setterToken); } } } return this; }; x.fud = function () { - error("Expected to see a statement and instead saw a block.", token); + error("E036", state.tokens.curr); }; }(delim("{"))); - useESNextSyntax = function () { - var conststatement = stmt("const", function (prefix) { - var id, name, value; - - this.first = []; - for (;;) { - nonadjacent(token, nexttoken); - id = identifier(); - if (funct[id] === "const") { - warning("const '" + id + "' has already been declared"); + function destructuringExpression() { + var id, ids; + var identifiers = []; + if (!state.option.inESNext()) { + warning("W104", state.tokens.curr, "destructuring expression"); + } + var nextInnerDE = function () { + var ident; + if (_.contains(["[", "{"], state.tokens.next.value)) { + ids = destructuringExpression(); + for (var id in ids) { + id = ids[id]; + identifiers.push({ id: id.id, token: id.token }); } - if (funct["(global)"] && predefined[id] === false) { - warning("Redefinition of '{a}'.", token, id); - } - addlabel(id, "const"); - if (prefix) { - break; - } - name = token; - this.first.push(token); - - if (nexttoken.id !== "=") { - warning("const " + - "'{a}' is initialized to 'undefined'.", token, id); - } - - if (nexttoken.id === "=") { - nonadjacent(token, nexttoken); - advance("="); - nonadjacent(token, nexttoken); - if (nexttoken.id === "undefined") { - warning("It is not necessary to initialize " + - "'{a}' to 'undefined'.", token, id); - } - if (peek(0).id === "=" && nexttoken.identifier) { - error("Constant {a} was not declared correctly.", - nexttoken, nexttoken.value); - } - value = expression(0); - name.first = value; - } - - if (nexttoken.id !== ",") { - break; - } - comma(); + } else if (state.tokens.next.value === ",") { + identifiers.push({ id: null, token: state.tokens.curr }); + } else { + ident = identifier(); + if (ident) + identifiers.push({ id: ident, token: state.tokens.curr }); } - return this; - }); - conststatement.exps = true; - }; + }; + if (state.tokens.next.value === "[") { + advance("["); + nextInnerDE(); + while (state.tokens.next.value !== "]") { + advance(","); + nextInnerDE(); + } + advance("]"); + } else if (state.tokens.next.value === "{") { + advance("{"); + id = identifier(); + if (state.tokens.next.value === ":") { + advance(":"); + nextInnerDE(); + } else { + identifiers.push({ id: id, token: state.tokens.curr }); + } + while (state.tokens.next.value !== "}") { + advance(","); + id = identifier(); + if (state.tokens.next.value === ":") { + advance(":"); + nextInnerDE(); + } else { + identifiers.push({ id: id, token: state.tokens.curr }); + } + } + advance("}"); + } + return identifiers; + } + function destructuringExpressionMatch(tokens, value) { + if (value.first) { + _.zip(tokens, value.first).forEach(function (val) { + var token = val[0]; + var value = val[1]; + if (token && value) { + token.first = value; + } else if (token && token.first && !value) { + warning("W080", token.first, token.first.value); + } /* else { + XXX value is discarded: wouldn't it need a warning ? + } */ + }); + } + } + var conststatement = stmt("const", function (prefix) { + var tokens, value; + var lone; + + if (!state.option.inESNext()) { + warning("W104", state.tokens.curr, "const"); + } + + this.first = []; + for (;;) { + var names = []; + nonadjacent(state.tokens.curr, state.tokens.next); + if (_.contains(["{", "["], state.tokens.next.value)) { + tokens = destructuringExpression(); + lone = false; + } else { + tokens = [ { id: identifier(), token: state.tokens.curr } ]; + lone = true; + } + for (var t in tokens) { + t = tokens[t]; + if (funct[t.id] === "const") { + warning("E011", null, t.id); + } + if (funct["(global)"] && predefined[t.id] === false) { + warning("W079", t.token, t.id); + } + if (t.id) { + addlabel(t.id, "const"); + names.push(t.token); + } + } + if (prefix) { + break; + } + + this.first = this.first.concat(names); + + if (state.tokens.next.id !== "=") { + warning("E012", state.tokens.curr, state.tokens.curr.value); + } + + if (state.tokens.next.id === "=") { + nonadjacent(state.tokens.curr, state.tokens.next); + advance("="); + nonadjacent(state.tokens.curr, state.tokens.next); + if (state.tokens.next.id === "undefined") { + warning("W080", state.tokens.prev, state.tokens.prev.value); + } + if (peek(0).id === "=" && state.tokens.next.identifier) { + error("E037", state.tokens.next, state.tokens.next.value); + } + value = expression(5); + if (lone) { + tokens[0].first = value; + } else { + destructuringExpressionMatch(names, value); + } + } + + if (state.tokens.next.id !== ",") { + break; + } + comma(); + } + return this; + }); + conststatement.exps = true; var varstatement = stmt("var", function (prefix) { - var id, name, value; + var tokens, lone, value; - if (funct["(onevar)"] && option.onevar) { - warning("Too many var statements."); + if (funct["(onevar)"] && state.option.onevar) { + warning("W081"); } else if (!funct["(global)"]) { funct["(onevar)"] = true; } this.first = []; - for (;;) { - nonadjacent(token, nexttoken); - id = identifier(); - - if (option.esnext && funct[id] === "const") { - warning("const '" + id + "' has already been declared"); + var names = []; + nonadjacent(state.tokens.curr, state.tokens.next); + if (_.contains(["{", "["], state.tokens.next.value)) { + tokens = destructuringExpression(); + lone = false; + } else { + tokens = [ { id: identifier(), token: state.tokens.curr } ]; + lone = true; } - - if (funct["(global)"] && predefined[id] === false) { - warning("Redefinition of '{a}'.", token, id); + for (var t in tokens) { + t = tokens[t]; + if (state.option.inESNext() && funct[t.id] === "const") { + warning("E011", null, t.id); + } + if (funct["(global)"] && predefined[t.id] === false) { + warning("W079", t.token, t.id); + } + if (t.id) { + addlabel(t.id, "unused", t.token); + names.push(t.token); + } } - - addlabel(id, "unused", token); - if (prefix) { break; } - name = token; - this.first.push(token); + this.first = this.first.concat(names); - if (nexttoken.id === "=") { - nonadjacent(token, nexttoken); + if (state.tokens.next.id === "=") { + nonadjacent(state.tokens.curr, state.tokens.next); advance("="); - nonadjacent(token, nexttoken); - if (nexttoken.id === "undefined") { - warning("It is not necessary to initialize '{a}' to 'undefined'.", token, id); + nonadjacent(state.tokens.curr, state.tokens.next); + if (state.tokens.next.id === "undefined") { + warning("W080", state.tokens.prev, state.tokens.prev.value); } - if (peek(0).id === "=" && nexttoken.identifier) { - error("Variable {a} was not declared correctly.", - nexttoken, nexttoken.value); + if (peek(0).id === "=" && state.tokens.next.identifier) { + error("E038", state.tokens.next, state.tokens.next.value); + } + value = expression(5); + if (lone) { + tokens[0].first = value; + } else { + destructuringExpressionMatch(names, value); } - value = expression(0); - name.first = value; } - if (nexttoken.id !== ",") { + + if (state.tokens.next.id !== ",") { break; } comma(); @@ -5498,63 +6090,190 @@ klass: return this; }); varstatement.exps = true; + var letstatement = stmt("let", function (prefix) { + var tokens, lone, value, letblock; + + if (!state.option.inESNext()) { + warning("W104", state.tokens.curr, "let"); + } + + if (state.tokens.next.value === "(") { + if (!state.option.inMoz(true)) { + warning("W118", state.tokens.next, "let block"); + } + advance("("); + funct["(blockscope)"].stack(); + letblock = true; + } else if (funct["(nolet)"]) { + error("E048", state.tokens.curr); + } + + if (funct["(onevar)"] && state.option.onevar) { + warning("W081"); + } else if (!funct["(global)"]) { + funct["(onevar)"] = true; + } + + this.first = []; + for (;;) { + var names = []; + nonadjacent(state.tokens.curr, state.tokens.next); + if (_.contains(["{", "["], state.tokens.next.value)) { + tokens = destructuringExpression(); + lone = false; + } else { + tokens = [ { id: identifier(), token: state.tokens.curr.value } ]; + lone = true; + } + for (var t in tokens) { + t = tokens[t]; + if (state.option.inESNext() && funct[t.id] === "const") { + warning("E011", null, t.id); + } + if (funct["(global)"] && predefined[t.id] === false) { + warning("W079", t.token, t.id); + } + if (t.id && !funct["(nolet)"]) { + addlabel(t.id, "unused", t.token, true); + names.push(t.token); + } + } + if (prefix) { + break; + } + + this.first = this.first.concat(names); + + if (state.tokens.next.id === "=") { + nonadjacent(state.tokens.curr, state.tokens.next); + advance("="); + nonadjacent(state.tokens.curr, state.tokens.next); + if (state.tokens.next.id === "undefined") { + warning("W080", state.tokens.prev, state.tokens.prev.value); + } + if (peek(0).id === "=" && state.tokens.next.identifier) { + error("E037", state.tokens.next, state.tokens.next.value); + } + value = expression(5); + if (lone) { + tokens[0].first = value; + } else { + destructuringExpressionMatch(names, value); + } + } + + if (state.tokens.next.id !== ",") { + break; + } + comma(); + } + if (letblock) { + advance(")"); + block(true, true); + this.block = true; + funct["(blockscope)"].unstack(); + } + + return this; + }); + letstatement.exps = true; + + blockstmt("class", function () { + return classdef.call(this, true); + }); + + function classdef(stmt) { + if (!state.option.inESNext()) { + warning("W104", state.tokens.curr, "class"); + } + if (stmt) { + this.name = identifier(); + addlabel(this.name, "unused", state.tokens.curr); + } else if (state.tokens.next.identifier && state.tokens.next.value !== "extends") { + this.name = identifier(); + } + classtail(this); + return this; + } + + function classtail(c) { + var strictness = state.directive["use strict"]; + if (state.tokens.next.value === "extends") { + advance("extends"); + c.heritage = expression(10); + } + state.directive["use strict"] = true; + advance("{"); + c.body = state.syntax["{"].nud(true); + state.directive["use strict"] = strictness; + } blockstmt("function", function () { + var generator = false; + if (state.tokens.next.value === "*") { + advance("*"); + if (state.option.inESNext(true)) { + generator = true; + } else { + warning("W119", state.tokens.curr, "function*"); + } + } if (inblock) { - warning("Function declarations should not be placed in blocks. " + - "Use a function expression or move the statement to the top of " + - "the outer function.", token); + warning("W082", state.tokens.curr); } var i = identifier(); - if (option.esnext && funct[i] === "const") { - warning("const '" + i + "' has already been declared"); + if (funct[i] === "const") { + warning("E011", null, i); } - adjacent(token, nexttoken); - addlabel(i, "unction", token); + adjacent(state.tokens.curr, state.tokens.next); + addlabel(i, "unction", state.tokens.curr); - doFunction(i, { statement: true }); - if (nexttoken.id === "(" && nexttoken.line === token.line) { - error( -"Function declarations are not invocable. Wrap the whole function invocation in parens."); + doFunction(i, { statement: true }, generator); + if (state.tokens.next.id === "(" && state.tokens.next.line === state.tokens.curr.line) { + error("E039"); } return this; }); prefix("function", function () { - var i = optionalidentifier(); - if (i) { - adjacent(token, nexttoken); - } else { - nonadjacent(token, nexttoken); + var generator = false; + if (state.tokens.next.value === "*") { + if (!state.option.inESNext()) { + warning("W119", state.tokens.curr, "function*"); + } + advance("*"); + generator = true; } - doFunction(i); - if (!option.loopfunc && funct["(loopage)"]) { - warning("Don't make functions within a loop."); + var i = optionalidentifier(); + if (i || state.option.gcl) { + adjacent(state.tokens.curr, state.tokens.next); + } else { + nonadjacent(state.tokens.curr, state.tokens.next); + } + doFunction(i, undefined, generator); + if (!state.option.loopfunc && funct["(loopage)"]) { + warning("W083"); } return this; }); blockstmt("if", function () { - var t = nexttoken; + var t = state.tokens.next; increaseComplexityCount(); + state.condition = true; advance("("); nonadjacent(this, t); nospace(); - expression(20); - if (nexttoken.id === "=") { - if (!option.boss) - warning("Assignment in conditional expression"); - advance("="); - expression(20); - } + checkCondAssignment(expression(0)); advance(")", t); - nospace(prevtoken, token); + state.condition = false; + nospace(state.tokens.prev, state.tokens.curr); block(true, true); - if (nexttoken.id === "else") { - nonadjacent(token, nexttoken); + if (state.tokens.next.id === "else") { + nonadjacent(state.tokens.curr, state.tokens.next); advance("else"); - if (nexttoken.id === "if" || nexttoken.id === "switch") { + if (state.tokens.next.id === "if" || state.tokens.next.id === "switch") { statement(true); } else { block(true, true); @@ -5571,87 +6290,96 @@ klass: var e; advance("catch"); - nonadjacent(token, nexttoken); + nonadjacent(state.tokens.curr, state.tokens.next); advance("("); scope = Object.create(oldScope); - e = nexttoken.value; - if (nexttoken.type !== "(identifier)") { + e = state.tokens.next.value; + if (state.tokens.next.type !== "(identifier)") { e = null; - warning("Expected an identifier and instead saw '{a}'.", nexttoken, e); + warning("E030", state.tokens.next, e); } advance(); - advance(")"); funct = { - "(name)" : "(catch)", - "(line)" : nexttoken.line, - "(character)": nexttoken.character, + "(name)" : "(catch)", + "(line)" : state.tokens.next.line, + "(character)": state.tokens.next.character, "(context)" : funct, "(breakage)" : funct["(breakage)"], "(loopage)" : funct["(loopage)"], - "(scope)" : scope, + "(scope)" : scope, "(statement)": false, - "(metrics)" : createMetrics(nexttoken), - "(catch)" : true, - "(tokens)" : {} + "(metrics)" : createMetrics(state.tokens.next), + "(catch)" : true, + "(tokens)" : {}, + "(blockscope)": funct["(blockscope)"], + "(comparray)": funct["(comparray)"] }; if (e) { addlabel(e, "exception"); } - token.funct = funct; + if (state.tokens.next.value === "if") { + if (!state.option.inMoz(true)) { + warning("W118", state.tokens.curr, "catch filter"); + } + advance("if"); + expression(0); + } + + advance(")"); + + state.tokens.curr.funct = funct; functions.push(funct); block(false); scope = oldScope; - funct["(last)"] = token.line; - funct["(lastcharacter)"] = token.character; + funct["(last)"] = state.tokens.curr.line; + funct["(lastcharacter)"] = state.tokens.curr.character; funct = funct["(context)"]; } block(false); - if (nexttoken.id === "catch") { + while (state.tokens.next.id === "catch") { increaseComplexityCount(); + if (b && (!state.option.inMoz(true))) { + warning("W118", state.tokens.next, "multiple catch blocks"); + } doCatch(); b = true; } - if (nexttoken.id === "finally") { + if (state.tokens.next.id === "finally") { advance("finally"); block(false); return; - } else if (!b) { - error("Expected '{a}' and instead saw '{b}'.", - nexttoken, "catch", nexttoken.value); + } + + if (!b) { + error("E021", state.tokens.next, "catch", state.tokens.next.value); } return this; }); blockstmt("while", function () { - var t = nexttoken; + var t = state.tokens.next; funct["(breakage)"] += 1; funct["(loopage)"] += 1; increaseComplexityCount(); advance("("); nonadjacent(this, t); nospace(); - expression(20); - if (nexttoken.id === "=") { - if (!option.boss) - warning("Assignment in conditional expression"); - advance("="); - expression(20); - } + checkCondAssignment(expression(0)); advance(")", t); - nospace(prevtoken, token); + nospace(state.tokens.prev, state.tokens.curr); block(true, true); funct["(breakage)"] -= 1; funct["(loopage)"] -= 1; @@ -5659,11 +6387,11 @@ klass: }).labelled = true; blockstmt("with", function () { - var t = nexttoken; - if (directive["use strict"]) { - error("'with' is not allowed in strict mode.", token); - } else if (!option.withstmt) { - warning("Don't use 'with'.", token); + var t = state.tokens.next; + if (state.directive["use strict"]) { + error("E010", state.tokens.curr); + } else if (!state.option.withstmt) { + warning("W085", state.tokens.curr); } advance("("); @@ -5671,32 +6399,34 @@ klass: nospace(); expression(0); advance(")", t); - nospace(prevtoken, token); + nospace(state.tokens.prev, state.tokens.curr); block(true, true); return this; }); blockstmt("switch", function () { - var t = nexttoken, + var t = state.tokens.next, g = false; funct["(breakage)"] += 1; advance("("); nonadjacent(this, t); nospace(); - this.condition = expression(20); + checkCondAssignment(expression(0)); advance(")", t); - nospace(prevtoken, token); - nonadjacent(token, nexttoken); - t = nexttoken; + nospace(state.tokens.prev, state.tokens.curr); + nonadjacent(state.tokens.curr, state.tokens.next); + t = state.tokens.next; advance("{"); - nonadjacent(token, nexttoken); - indent += option.indent; + nonadjacent(state.tokens.curr, state.tokens.next); + indent += state.option.indent; this.cases = []; + for (;;) { - switch (nexttoken.id) { + switch (state.tokens.next.id) { case "case": switch (funct["(verb)"]) { + case "yield": case "break": case "case": case "continue": @@ -5705,13 +6435,11 @@ klass: case "throw": break; default: - if (!ft.test(lines[nexttoken.line - 2])) { - warning( - "Expected a 'break' statement before 'case'.", - token); + if (!reg.fallsThrough.test(state.lines[state.tokens.next.line - 2])) { + warning("W086", state.tokens.curr, "case"); } } - indentation(-option.indent); + indentation(-state.option.indent); advance("case"); this.cases.push(expression(20)); increaseComplexityCount(); @@ -5721,60 +6449,55 @@ klass: break; case "default": switch (funct["(verb)"]) { + case "yield": case "break": case "continue": case "return": case "throw": break; default: - if (!ft.test(lines[nexttoken.line - 2])) { - warning( - "Expected a 'break' statement before 'default'.", - token); + if (this.cases.length) { + if (!reg.fallsThrough.test(state.lines[state.tokens.next.line - 2])) { + warning("W086", state.tokens.curr, "default"); + } } } - indentation(-option.indent); + indentation(-state.option.indent); advance("default"); g = true; advance(":"); break; case "}": - indent -= option.indent; + indent -= state.option.indent; indentation(); advance("}", t); - if (this.cases.length === 1 || this.condition.id === "true" || - this.condition.id === "false") { - if (!option.onecase) - warning("This 'switch' should be an 'if'.", this); - } funct["(breakage)"] -= 1; funct["(verb)"] = undefined; return; case "(end)": - error("Missing '{a}'.", nexttoken, "}"); + error("E023", state.tokens.next, "}"); return; default: if (g) { - switch (token.id) { + switch (state.tokens.curr.id) { case ",": - error("Each value should have its own case label."); + error("E040"); return; case ":": g = false; statements(); break; default: - error("Missing ':' on a case clause.", token); + error("E025", state.tokens.curr); return; } } else { - if (token.id === ":") { + if (state.tokens.curr.id === ":") { advance(":"); - error("Unexpected '{a}'.", token, ":"); + error("E024", state.tokens.curr, ":"); statements(); } else { - error("Expected '{a}' and instead saw '{b}'.", - nexttoken, "case", nexttoken.value); + error("E021", state.tokens.next, "case", state.tokens.next.value); return; } } @@ -5783,8 +6506,8 @@ klass: }).labelled = true; stmt("debugger", function () { - if (!option.debug) { - warning("All 'debugger' statements should be removed."); + if (!state.option.debug) { + warning("W087"); } return this; }).exps = true; @@ -5795,21 +6518,15 @@ klass: funct["(loopage)"] += 1; increaseComplexityCount(); - this.first = block(true); + this.first = block(true, true); advance("while"); - var t = nexttoken; - nonadjacent(token, t); + var t = state.tokens.next; + nonadjacent(state.tokens.curr, t); advance("("); nospace(); - expression(20); - if (nexttoken.id === "=") { - if (!option.boss) - warning("Assignment in conditional expression"); - advance("="); - expression(20); - } + checkCondAssignment(expression(0)); advance(")", t); - nospace(prevtoken, token); + nospace(state.tokens.prev, state.tokens.curr); funct["(breakage)"] -= 1; funct["(loopage)"] -= 1; return this; @@ -5819,110 +6536,140 @@ klass: }()); blockstmt("for", function () { - var s, t = nexttoken; + var s, t = state.tokens.next; + var letscope = false; + var foreachtok = null; + + if (t.value === "each") { + foreachtok = t; + advance("each"); + if (!state.option.inMoz(true)) { + warning("W118", state.tokens.curr, "for each"); + } + } + funct["(breakage)"] += 1; funct["(loopage)"] += 1; increaseComplexityCount(); advance("("); nonadjacent(this, t); nospace(); - if (peek(nexttoken.id === "var" ? 1 : 0).id === "in") { - if (nexttoken.id === "var") { + var nextop; // contains the token of the "in" or "of" operator + var i = 0; + var inof = ["in", "of"]; + do { + nextop = peek(i); + ++i; + } while (!_.contains(inof, nextop.value) && nextop.value !== ";" && + nextop.type !== "(end)"); + if (_.contains(inof, nextop.value)) { + if (!state.option.inESNext() && nextop.value === "of") { + error("W104", nextop, "for of"); + } + if (state.tokens.next.id === "var") { advance("var"); - varstatement.fud.call(varstatement, true); + state.syntax["var"].fud.call(state.syntax["var"].fud, true); + } else if (state.tokens.next.id === "let") { + advance("let"); + letscope = true; + funct["(blockscope)"].stack(); + state.syntax["let"].fud.call(state.syntax["let"].fud, true); } else { - switch (funct[nexttoken.value]) { + switch (funct[state.tokens.next.value]) { case "unused": - funct[nexttoken.value] = "var"; + funct[state.tokens.next.value] = "var"; break; case "var": break; default: - warning("Bad for in variable '{a}'.", - nexttoken, nexttoken.value); + if (!funct["(blockscope)"].getlabel(state.tokens.next.value)) + warning("W088", state.tokens.next, state.tokens.next.value); } advance(); } - advance("in"); + advance(nextop.value); expression(20); advance(")", t); s = block(true, true); - if (option.forin && s && (s.length > 1 || typeof s[0] !== "object" || + if (state.option.forin && s && (s.length > 1 || typeof s[0] !== "object" || s[0].value !== "if")) { - warning("The body of a for in should be wrapped in an if statement to filter " + - "unwanted properties from the prototype.", this); + warning("W089", this); } funct["(breakage)"] -= 1; funct["(loopage)"] -= 1; - return this; } else { - if (nexttoken.id !== ";") { - if (nexttoken.id === "var") { + if (foreachtok) { + error("E045", foreachtok); + } + if (state.tokens.next.id !== ";") { + if (state.tokens.next.id === "var") { advance("var"); - varstatement.fud.call(varstatement); + state.syntax["var"].fud.call(state.syntax["var"].fud); + } else if (state.tokens.next.id === "let") { + advance("let"); + letscope = true; + funct["(blockscope)"].stack(); + state.syntax["let"].fud.call(state.syntax["let"].fud); } else { for (;;) { expression(0, "for"); - if (nexttoken.id !== ",") { + if (state.tokens.next.id !== ",") { break; } comma(); } } } - nolinebreak(token); + nolinebreak(state.tokens.curr); advance(";"); - if (nexttoken.id !== ";") { - expression(20); - if (nexttoken.id === "=") { - if (!option.boss) - warning("Assignment in conditional expression"); - advance("="); - expression(20); - } + if (state.tokens.next.id !== ";") { + checkCondAssignment(expression(0)); } - nolinebreak(token); + nolinebreak(state.tokens.curr); advance(";"); - if (nexttoken.id === ";") { - error("Expected '{a}' and instead saw '{b}'.", - nexttoken, ")", ";"); + if (state.tokens.next.id === ";") { + error("E021", state.tokens.next, ")", ";"); } - if (nexttoken.id !== ")") { + if (state.tokens.next.id !== ")") { for (;;) { expression(0, "for"); - if (nexttoken.id !== ",") { + if (state.tokens.next.id !== ",") { break; } comma(); } } advance(")", t); - nospace(prevtoken, token); + nospace(state.tokens.prev, state.tokens.curr); block(true, true); funct["(breakage)"] -= 1; funct["(loopage)"] -= 1; - return this; + } + if (letscope) { + funct["(blockscope)"].unstack(); + } + return this; }).labelled = true; stmt("break", function () { - var v = nexttoken.value; + var v = state.tokens.next.value; if (funct["(breakage)"] === 0) - warning("Unexpected '{a}'.", nexttoken, this.value); + warning("W052", state.tokens.next, this.value); - if (!option.asi) + if (!state.option.asi) nolinebreak(this); - if (nexttoken.id !== ";") { - if (token.line === nexttoken.line) { + if (state.tokens.next.id !== ";" && !state.tokens.next.reach) { + if (state.tokens.curr.line === state.tokens.next.line) { if (funct[v] !== "label") { - warning("'{a}' is not a statement label.", nexttoken, v); + warning("W090", state.tokens.next, v); } else if (scope[v] !== funct) { - warning("'{a}' is out of scope.", nexttoken, v); + warning("W091", state.tokens.next, v); } - this.first = nexttoken; + this.first = state.tokens.next; advance(); } } @@ -5932,26 +6679,26 @@ klass: stmt("continue", function () { - var v = nexttoken.value; + var v = state.tokens.next.value; if (funct["(breakage)"] === 0) - warning("Unexpected '{a}'.", nexttoken, this.value); + warning("W052", state.tokens.next, this.value); - if (!option.asi) + if (!state.option.asi) nolinebreak(this); - if (nexttoken.id !== ";") { - if (token.line === nexttoken.line) { + if (state.tokens.next.id !== ";" && !state.tokens.next.reach) { + if (state.tokens.curr.line === state.tokens.next.line) { if (funct[v] !== "label") { - warning("'{a}' is not a statement label.", nexttoken, v); + warning("W090", state.tokens.next, v); } else if (scope[v] !== funct) { - warning("'{a}' is out of scope.", nexttoken, v); + warning("W091", state.tokens.next, v); } - this.first = nexttoken; + this.first = state.tokens.next; advance(); } } else if (!funct["(loopage)"]) { - warning("Unexpected '{a}'.", nexttoken, this.value); + warning("W052", state.tokens.next, this.value); } reachable("continue"); return this; @@ -5959,86 +6706,248 @@ klass: stmt("return", function () { - if (this.line === nexttoken.line) { - if (nexttoken.id === "(regexp)") - warning("Wrap the /regexp/ literal in parens to disambiguate the slash operator."); + if (this.line === state.tokens.next.line) { + if (state.tokens.next.id === "(regexp)") + warning("W092"); - if (nexttoken.id !== ";" && !nexttoken.reach) { - nonadjacent(token, nexttoken); - if (peek().value === "=" && !option.boss) { - warningAt("Did you mean to return a conditional instead of an assignment?", - token.line, token.character + 1); - } + if (state.tokens.next.id !== ";" && !state.tokens.next.reach) { + nonadjacent(state.tokens.curr, state.tokens.next); this.first = expression(0); + + if (this.first && + this.first.type === "(punctuator)" && this.first.value === "=" && !state.option.boss) { + warningAt("W093", this.first.line, this.first.character); + } + } + } else { + if (state.tokens.next.type === "(punctuator)" && + ["[", "{", "+", "-"].indexOf(state.tokens.next.value) > -1) { + nolinebreak(this); // always warn (Line breaking error) } - } else if (!option.asi) { - nolinebreak(this); // always warn (Line breaking error) } reachable("return"); return this; }).exps = true; + stmt("yield", function () { + if (state.option.inESNext(true) && funct["(generator)"] !== true) { + error("E046", state.tokens.curr, "yield"); + } else if (!state.option.inESNext()) { + warning("W104", state.tokens.curr, "yield"); + } + funct["(generator)"] = "yielded"; + if (this.line === state.tokens.next.line) { + if (state.tokens.next.id === "(regexp)") + warning("W092"); + + if (state.tokens.next.id !== ";" && !state.tokens.next.reach) { + nonadjacent(state.tokens.curr, state.tokens.next); + this.first = expression(0); + + if (this.first.type === "(punctuator)" && this.first.value === "=" && !state.option.boss) { + warningAt("W093", this.first.line, this.first.character); + } + } + } else if (!state.option.asi) { + nolinebreak(this); // always warn (Line breaking error) + } + return this; + }).exps = true; + stmt("throw", function () { nolinebreak(this); - nonadjacent(token, nexttoken); + nonadjacent(state.tokens.curr, state.tokens.next); this.first = expression(20); reachable("throw"); return this; }).exps = true; - reserve("class"); - reserve("const"); - reserve("enum"); - reserve("export"); - reserve("extends"); - reserve("import"); - reserve("super"); + FutureReservedWord("abstract"); + FutureReservedWord("boolean"); + FutureReservedWord("byte"); + FutureReservedWord("char"); + FutureReservedWord("class", { es5: true, nud: classdef }); + FutureReservedWord("double"); + FutureReservedWord("enum", { es5: true }); + FutureReservedWord("export", { es5: true }); + FutureReservedWord("extends", { es5: true }); + FutureReservedWord("final"); + FutureReservedWord("float"); + FutureReservedWord("goto"); + FutureReservedWord("implements", { es5: true, strictOnly: true }); + FutureReservedWord("import", { es5: true }); + FutureReservedWord("int"); + FutureReservedWord("interface", { es5: true, strictOnly: true }); + FutureReservedWord("long"); + FutureReservedWord("native"); + FutureReservedWord("package", { es5: true, strictOnly: true }); + FutureReservedWord("private", { es5: true, strictOnly: true }); + FutureReservedWord("protected", { es5: true, strictOnly: true }); + FutureReservedWord("public", { es5: true, strictOnly: true }); + FutureReservedWord("short"); + FutureReservedWord("static", { es5: true, strictOnly: true }); + FutureReservedWord("super", { es5: true }); + FutureReservedWord("synchronized"); + FutureReservedWord("throws"); + FutureReservedWord("transient"); + FutureReservedWord("volatile"); - reserve("let"); - reserve("yield"); - reserve("implements"); - reserve("interface"); - reserve("package"); - reserve("private"); - reserve("protected"); - reserve("public"); - reserve("static"); + var lookupBlockType = function () { + var pn, pn1; + var i = 0; + var bracketStack = 0; + var ret = {}; + if (_.contains(["[", "{"], state.tokens.curr.value)) + bracketStack += 1; + if (_.contains(["[", "{"], state.tokens.next.value)) + bracketStack += 1; + if (_.contains(["]", "}"], state.tokens.next.value)) + bracketStack -= 1; + do { + pn = peek(i); + pn1 = peek(i + 1); + i = i + 1; + if (_.contains(["[", "{"], pn.value)) { + bracketStack += 1; + } else if (_.contains(["]", "}"], pn.value)) { + bracketStack -= 1; + } + if (pn.identifier && pn.value === "for" && bracketStack === 1) { + ret.isCompArray = true; + ret.notJson = true; + break; + } + if (_.contains(["}", "]"], pn.value) && pn1.value === "=") { + ret.isDestAssign = true; + ret.notJson = true; + break; + } + if (pn.value === ";") { + ret.isBlock = true; + ret.notJson = true; + } + } while (bracketStack > 0 && pn.id !== "(end)" && i < 15); + return ret; + }; + function destructuringAssignOrJsonValue() { + + var block = lookupBlockType(); + if (block.notJson) { + if (!state.option.inESNext() && block.isDestAssign) { + warning("W104", state.tokens.curr, "destructuring assignment"); + } + statements(); + } else { + state.option.laxbreak = true; + state.jsonMode = true; + jsonValue(); + } + } + + var arrayComprehension = function () { + var CompArray = function () { + this.mode = "use"; + this.variables = []; + }; + var _carrays = []; + var _current; + function declare(v) { + var l = _current.variables.filter(function (elt) { + if (elt.value === v) { + elt.undef = false; + return v; + } + }).length; + return l !== 0; + } + function use(v) { + var l = _current.variables.filter(function (elt) { + if (elt.value === v && !elt.undef) { + if (elt.unused === true) { + elt.unused = false; + } + return v; + } + }).length; + return (l === 0); + } + return {stack: function () { + _current = new CompArray(); + _carrays.push(_current); + }, + unstack: function () { + _current.variables.filter(function (v) { + if (v.unused) + warning("W098", v.token, v.value); + if (v.undef) + isundef(v.funct, "W117", v.token, v.value); + }); + _carrays.splice(_carrays[_carrays.length - 1], 1); + _current = _carrays[_carrays.length - 1]; + }, + setState: function (s) { + if (_.contains(["use", "define", "filter"], s)) + _current.mode = s; + }, + check: function (v) { + if (_current && _current.mode === "use") { + _current.variables.push({funct: funct, + token: state.tokens.curr, + value: v, + undef: true, + unused: false}); + return true; + } else if (_current && _current.mode === "define") { + if (!declare(v)) { + _current.variables.push({funct: funct, + token: state.tokens.curr, + value: v, + undef: false, + unused: true}); + } + return true; + } else if (_current && _current.mode === "filter") { + if (use(v)) { + isundef(funct, "W117", state.tokens.curr, v); + } + return true; + } + return false; + } + }; + }; function jsonValue() { function jsonObject() { - var o = {}, t = nexttoken; + var o = {}, t = state.tokens.next; advance("{"); - if (nexttoken.id !== "}") { + if (state.tokens.next.id !== "}") { for (;;) { - if (nexttoken.id === "(end)") { - error("Missing '}' to match '{' from line {a}.", - nexttoken, t.line); - } else if (nexttoken.id === "}") { - warning("Unexpected comma.", token); + if (state.tokens.next.id === "(end)") { + error("E026", state.tokens.next, t.line); + } else if (state.tokens.next.id === "}") { + warning("W094", state.tokens.curr); break; - } else if (nexttoken.id === ",") { - error("Unexpected comma.", nexttoken); - } else if (nexttoken.id !== "(string)") { - warning("Expected a string and instead saw {a}.", - nexttoken, nexttoken.value); + } else if (state.tokens.next.id === ",") { + error("E028", state.tokens.next); + } else if (state.tokens.next.id !== "(string)") { + warning("W095", state.tokens.next, state.tokens.next.value); } - if (o[nexttoken.value] === true) { - warning("Duplicate key '{a}'.", - nexttoken, nexttoken.value); - } else if ((nexttoken.value === "__proto__" && - !option.proto) || (nexttoken.value === "__iterator__" && - !option.iterator)) { - warning("The '{a}' key may produce unexpected results.", - nexttoken, nexttoken.value); + if (o[state.tokens.next.value] === true) { + warning("W075", state.tokens.next, state.tokens.next.value); + } else if ((state.tokens.next.value === "__proto__" && + !state.option.proto) || (state.tokens.next.value === "__iterator__" && + !state.option.iterator)) { + warning("W096", state.tokens.next, state.tokens.next.value); } else { - o[nexttoken.value] = true; + o[state.tokens.next.value] = true; } advance(); advance(":"); jsonValue(); - if (nexttoken.id !== ",") { + if (state.tokens.next.id !== ",") { break; } advance(","); @@ -6048,21 +6957,20 @@ klass: } function jsonArray() { - var t = nexttoken; + var t = state.tokens.next; advance("["); - if (nexttoken.id !== "]") { + if (state.tokens.next.id !== "]") { for (;;) { - if (nexttoken.id === "(end)") { - error("Missing ']' to match '[' from line {a}.", - nexttoken, t.line); - } else if (nexttoken.id === "]") { - warning("Unexpected comma.", token); + if (state.tokens.next.id === "(end)") { + error("E027", state.tokens.next, t.line); + } else if (state.tokens.next.id === "]") { + warning("W094", state.tokens.curr); break; - } else if (nexttoken.id === ",") { - error("Unexpected comma.", nexttoken); + } else if (state.tokens.next.id === ",") { + error("E028", state.tokens.next); } jsonValue(); - if (nexttoken.id !== ",") { + if (state.tokens.next.id !== ",") { break; } advance(","); @@ -6071,7 +6979,7 @@ klass: advance("]"); } - switch (nexttoken.id) { + switch (state.tokens.next.id) { case "{": jsonObject(); break; @@ -6087,20 +6995,72 @@ klass: break; case "-": advance("-"); - if (token.character !== nexttoken.from) { - warning("Unexpected space after '-'.", token); + if (state.tokens.curr.character !== state.tokens.next.from) { + warning("W011", state.tokens.curr); } - adjacent(token, nexttoken); + adjacent(state.tokens.curr, state.tokens.next); advance("(number)"); break; default: - error("Expected a JSON value.", nexttoken); + error("E003", state.tokens.next); } } + + var blockScope = function () { + var _current = {}; + var _variables = [_current]; + + function _checkBlockLabels() { + for (var t in _current) { + if (_current[t]["(type)"] === "unused") { + if (state.option.unused) { + var tkn = _current[t]["(token)"]; + var line = tkn.line; + var chr = tkn.character; + warningAt("W098", line, chr, t); + } + } + } + } + + return { + stack: function () { + _current = {}; + _variables.push(_current); + }, + + unstack: function () { + _checkBlockLabels(); + _variables.splice(_variables.length - 1, 1); + _current = _.last(_variables); + }, + + getlabel: function (l) { + for (var i = _variables.length - 1 ; i >= 0; --i) { + if (_.has(_variables[i], l)) { + return _variables[i]; + } + } + }, + + current: { + has: function (t) { + return _.has(_current, t); + }, + add: function (t, type, tok) { + _current[t] = { "(type)" : type, + "(token)": tok }; + } + } + }; + }; var itself = function (s, o, g) { - var a, i, k, x; + var i, k, x; var optionKeys; var newOptionObj = {}; + var newIgnoredObj = {}; + + state.reset(); if (o && o.scope) { JSHINT.scope = o.scope; @@ -6112,48 +7072,67 @@ klass: JSHINT.scope = "(main)"; } - predefined = Object.create(standard); - declared = Object.create(null); + predefined = Object.create(null); + combine(predefined, vars.ecmaIdentifiers); + combine(predefined, vars.reservedVars); + combine(predefined, g || {}); + declared = Object.create(null); + exported = Object.create(null); + + function each(obj, cb) { + if (!obj) + return; + + if (!Array.isArray(obj) && typeof obj === "object") + obj = Object.keys(obj); + + obj.forEach(cb); + } + if (o) { - a = o.predef; - if (a) { - if (!Array.isArray(a) && typeof a === "object") { - a = Object.keys(a); + each(o.predef || null, function (item) { + var slice, prop; + + if (item[0] === "-") { + slice = item.slice(1); + JSHINT.blacklist[slice] = slice; + } else { + prop = Object.getOwnPropertyDescriptor(o.predef, item); + predefined[item] = prop ? prop.value : false; } - a.forEach(function (item) { - var slice; - if (item[0] === "-") { - slice = item.slice(1); - JSHINT.blacklist[slice] = slice; - } else { - predefined[item] = true; - } - }); - } + }); + + each(o.exported || null, function (item) { + exported[item] = true; + }); + + delete o.predef; + delete o.exported; optionKeys = Object.keys(o); for (x = 0; x < optionKeys.length; x++) { - newOptionObj[optionKeys[x]] = o[optionKeys[x]]; + if (/^-W\d{3}$/g.test(optionKeys[x])) { + newIgnoredObj[optionKeys[x].slice(1)] = true; + } else { + newOptionObj[optionKeys[x]] = o[optionKeys[x]]; - if (optionKeys[x] === "newcap" && o[optionKeys[x]] === false) - newOptionObj["(explicitNewcap)"] = true; + if (optionKeys[x] === "newcap" && o[optionKeys[x]] === false) + newOptionObj["(explicitNewcap)"] = true; - if (optionKeys[x] === "indent") - newOptionObj.white = true; + if (optionKeys[x] === "indent") + newOptionObj["(explicitIndent)"] = o[optionKeys[x]] === false ? false : true; + } } } - option = newOptionObj; + state.option = newOptionObj; + state.ignored = newIgnoredObj; - option.indent = option.indent || 4; - option.maxerr = option.maxerr || 50; + state.option.indent = state.option.indent || 4; + state.option.maxerr = state.option.maxerr || 50; - tab = ""; - for (i = 0; i < option.indent; i += 1) { - tab += " "; - } indent = 1; global = Object.create(predefined); scope = global; @@ -6164,7 +7143,9 @@ klass: "(breakage)": 0, "(loopage)": 0, "(tokens)": {}, - "(metrics)": createMetrics(nexttoken) + "(metrics)": createMetrics(state.tokens.next), + "(blockscope)": blockScope(), + "(comparray)": arrayComprehension() }; functions = [funct]; urls = []; @@ -6174,61 +7155,106 @@ klass: implied = {}; inblock = false; lookahead = []; - jsonmode = false; warnings = 0; - lines = []; unuseds = []; if (!isString(s) && !Array.isArray(s)) { - errorAt("Input is neither a string nor an array of strings.", 0); + errorAt("E004", 0); return false; } - if (isString(s) && /^\s*$/g.test(s)) { - errorAt("Input is an empty string.", 0); - return false; - } + api = { + get isJSON() { + return state.jsonMode; + }, - if (s.length === 0) { - errorAt("Input is an empty array.", 0); - return false; - } + getOption: function (name) { + return state.option[name] || null; + }, - lex.init(s); + getCache: function (name) { + return state.cache[name]; + }, - prereg = true; - directive = {}; + setCache: function (name, value) { + state.cache[name] = value; + }, - prevtoken = token = nexttoken = syntax["(begin)"]; + warn: function (code, data) { + warningAt.apply(null, [ code, data.line, data.char ].concat(data.data)); + }, + + on: function (names, listener) { + names.split(" ").forEach(function (name) { + emitter.on(name, listener); + }.bind(this)); + } + }; + + emitter.removeAllListeners(); + (extraModules || []).forEach(function (func) { + func(api); + }); + + state.tokens.prev = state.tokens.curr = state.tokens.next = state.syntax["(begin)"]; + + lex = new Lexer(s); + + lex.on("warning", function (ev) { + warningAt.apply(null, [ ev.code, ev.line, ev.character].concat(ev.data)); + }); + + lex.on("error", function (ev) { + errorAt.apply(null, [ ev.code, ev.line, ev.character ].concat(ev.data)); + }); + + lex.on("fatal", function (ev) { + quit("E041", ev.line, ev.from); + }); + + lex.on("Identifier", function (ev) { + emitter.emit("Identifier", ev); + }); + + lex.on("String", function (ev) { + emitter.emit("String", ev); + }); + + lex.on("Number", function (ev) { + emitter.emit("Number", ev); + }); + + lex.start(); for (var name in o) { - if (is_own(o, name)) { - checkOption(name, token); + if (_.has(o, name)) { + checkOption(name, state.tokens.curr); } } assume(); combine(predefined, g || {}); comma.first = true; - quotmark = undefined; try { advance(); - switch (nexttoken.id) { + switch (state.tokens.next.id) { case "{": case "[": - option.laxbreak = true; - jsonmode = true; - jsonValue(); + destructuringAssignOrJsonValue(); break; default: directives(); - if (directive["use strict"] && !option.globalstrict) { - warning("Use the function form of \"use strict\".", prevtoken); + + if (state.directive["use strict"]) { + if (!state.option.globalstrict && !state.option.node) { + warning("W097", state.tokens.prev); + } } statements(); } - advance((nexttoken && nexttoken.value !== ".") ? "(end)" : undefined); + advance((state.tokens.next && state.tokens.next.value !== ".") ? "(end)" : undefined); + funct["(blockscope)"].unstack(); var markDefined = function (name, context) { do { @@ -6264,12 +7290,29 @@ klass: implied[name] = newImplied; }; - var warnUnused = function (name, token) { - var line = token.line; - var chr = token.character; + var warnUnused = function (name, tkn, type, unused_opt) { + var line = tkn.line; + var chr = tkn.character; - if (option.unused) - warningAt("'{a}' is defined but never used.", line, chr, name); + if (unused_opt === undefined) { + unused_opt = state.option.unused; + } + + if (unused_opt === true) { + unused_opt = "last-param"; + } + + var warnable_types = { + "vars": ["var"], + "last-param": ["var", "param"], + "strict": ["var", "param", "last-param"] + }; + + if (unused_opt) { + if (warnable_types[unused_opt] && warnable_types[unused_opt].indexOf(type) !== -1) { + warningAt("W098", line, chr, name); + } + } unuseds.push({ name: name, @@ -6280,7 +7323,7 @@ klass: var checkUnused = function (func, key) { var type = func[key]; - var token = func["(tokens)"][key]; + var tkn = func["(tokens)"][key]; if (key.charAt(0) === "(") return; @@ -6289,22 +7332,29 @@ klass: return; if (func["(params)"] && func["(params)"].indexOf(key) !== -1) return; + if (func["(global)"] && _.has(exported, key)) { + return; + } - warnUnused(key, token); + warnUnused(key, tkn, "var"); }; for (i = 0; i < JSHINT.undefs.length; i += 1) { k = JSHINT.undefs[i].slice(0); if (markDefined(k[2].value, k[0])) { clearImplied(k[2].value, k[2].line); - } else { + } else if (state.option.undef) { warning.apply(warning, k.slice(1)); } } functions.forEach(function (func) { + if (func["(unusedOption)"] === false) { + return; + } + for (var key in func) { - if (is_own(func, key)) { + if (_.has(func, key)) { checkUnused(func, key); } } @@ -6314,36 +7364,44 @@ klass: var params = func["(params)"].slice(); var param = params.pop(); - var type; + var type, unused_opt; while (param) { type = func[param]; + unused_opt = func["(unusedOption)"] || state.option.unused; + unused_opt = unused_opt === true ? "last-param" : unused_opt; if (param === "undefined") return; - if (type !== "unused" && type !== "unction") + if (type === "unused" || type === "unction") { + warnUnused(param, func["(tokens)"][param], "param", func["(unusedOption)"]); + } else if (unused_opt === "last-param") { return; + } - warnUnused(param, func["(tokens)"][param]); param = params.pop(); } }); for (var key in declared) { - if (is_own(declared, key) && !is_own(global, key)) { - warnUnused(key, declared[key]); + if (_.has(declared, key) && !_.has(global, key)) { + warnUnused(key, declared[key], "var"); } } - } catch (e) { - if (e) { - var nt = nexttoken || {}; + + } catch (err) { + if (err && err.name === "JSHintError") { + var nt = state.tokens.next || {}; JSHINT.errors.push({ - raw : e.raw, - reason : e.message, - line : e.line || nt.line, - character : e.character || nt.from + scope : "(main)", + raw : err.raw, + reason : err.message, + line : err.line || nt.line, + character : err.character || nt.from }, null); + } else { + throw err; } } @@ -6359,10 +7417,15 @@ klass: return JSHINT.errors.length === 0; }; + itself.addModule = function (func) { + extraModules.push(func); + }; + + itself.addModule(style.register); itself.data = function () { var data = { functions: [], - options: option + options: state.option }; var implieds = []; var members = []; @@ -6372,12 +7435,12 @@ klass: data.errors = itself.errors; } - if (jsonmode) { + if (state.jsonMode) { data.json = true; } for (n in implied) { - if (is_own(implied, n)) { + if (_.has(implied, n)) { implieds.push({ name: n, line: implied[n] @@ -6444,4 +7507,2474 @@ if (typeof exports === "object" && exports) { exports.JSHINT = JSHINT; } +})() +}, +{"events":2,"../shared/vars.js":3,"../shared/messages.js":10,"./lex.js":11,"./reg.js":4,"./state.js":5,"./style.js":6,"console-browserify":7,"underscore":12}], +10:[function(req,module,exports){ +(function(){ + +var _ = req("underscore"); + +var errors = { + E001: "Bad option: '{a}'.", + E002: "Bad option value.", + E003: "Expected a JSON value.", + E004: "Input is neither a string nor an array of strings.", + E005: "Input is empty.", + E006: "Unexpected early end of program.", + E007: "Missing \"use strict\" statement.", + E008: "Strict violation.", + E009: "Option 'validthis' can't be used in a global scope.", + E010: "'with' is not allowed in strict mode.", + E011: "const '{a}' has already been declared.", + E012: "const '{a}' is initialized to 'undefined'.", + E013: "Attempting to override '{a}' which is a constant.", + E014: "A regular expression literal can be confused with '/='.", + E015: "Unclosed regular expression.", + E016: "Invalid regular expression.", + E017: "Unclosed comment.", + E018: "Unbegun comment.", + E019: "Unmatched '{a}'.", + E020: "Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.", + E021: "Expected '{a}' and instead saw '{b}'.", + E022: "Line breaking error '{a}'.", + E023: "Missing '{a}'.", + E024: "Unexpected '{a}'.", + E025: "Missing ':' on a case clause.", + E026: "Missing '}' to match '{' from line {a}.", + E027: "Missing ']' to match '[' form line {a}.", + E028: "Illegal comma.", + E029: "Unclosed string.", + E030: "Expected an identifier and instead saw '{a}'.", + E031: "Bad assignment.", // FIXME: Rephrase + E032: "Expected a small integer or 'false' and instead saw '{a}'.", + E033: "Expected an operator and instead saw '{a}'.", + E034: "get/set are ES5 features.", + E035: "Missing property name.", + E036: "Expected to see a statement and instead saw a block.", + E037: "Constant {a} was not declared correctly.", + E038: "Variable {a} was not declared correctly.", + E039: "Function declarations are not invocable. Wrap the whole function invocation in parens.", + E040: "Each value should have its own case label.", + E041: "Unrecoverable syntax error.", + E042: "Stopping.", + E043: "Too many errors.", + E044: "'{a}' is already defined and can't be redefined.", + E045: "Invalid for each loop.", + E046: "A yield statement shall be within a generator function (with syntax: `function*`)", + E047: "A generator function shall contain a yield statement.", + E048: "Let declaration not directly within block.", + E049: "A {a} cannot be named '{b}'." +}; + +var warnings = { + W001: "'hasOwnProperty' is a really bad name.", + W002: "Value of '{a}' may be overwritten in IE 8 and earlier.", + W003: "'{a}' was used before it was defined.", + W004: "'{a}' is already defined.", + W005: "A dot following a number can be confused with a decimal point.", + W006: "Confusing minuses.", + W007: "Confusing pluses.", + W008: "A leading decimal point can be confused with a dot: '{a}'.", + W009: "The array literal notation [] is preferrable.", + W010: "The object literal notation {} is preferrable.", + W011: "Unexpected space after '{a}'.", + W012: "Unexpected space before '{a}'.", + W013: "Missing space after '{a}'.", + W014: "Bad line breaking before '{a}'.", + W015: "Expected '{a}' to have an indentation at {b} instead at {c}.", + W016: "Unexpected use of '{a}'.", + W017: "Bad operand.", + W018: "Confusing use of '{a}'.", + W019: "Use the isNaN function to compare with NaN.", + W020: "Read only.", + W021: "'{a}' is a function.", + W022: "Do not assign to the exception parameter.", + W023: "Expected an identifier in an assignment and instead saw a function invocation.", + W024: "Expected an identifier and instead saw '{a}' (a reserved word).", + W025: "Missing name in function declaration.", + W026: "Inner functions should be listed at the top of the outer function.", + W027: "Unreachable '{a}' after '{b}'.", + W028: "Label '{a}' on {b} statement.", + W030: "Expected an assignment or function call and instead saw an expression.", + W031: "Do not use 'new' for side effects.", + W032: "Unnecessary semicolon.", + W033: "Missing semicolon.", + W034: "Unnecessary directive \"{a}\".", + W035: "Empty block.", + W036: "Unexpected /*member '{a}'.", + W037: "'{a}' is a statement label.", + W038: "'{a}' used out of scope.", + W039: "'{a}' is not allowed.", + W040: "Possible strict violation.", + W041: "Use '{a}' to compare with '{b}'.", + W042: "Avoid EOL escaping.", + W043: "Bad escaping of EOL. Use option multistr if needed.", + W044: "Bad or unnecessary escaping.", + W045: "Bad number '{a}'.", + W046: "Don't use extra leading zeros '{a}'.", + W047: "A trailing decimal point can be confused with a dot: '{a}'.", + W048: "Unexpected control character in regular expression.", + W049: "Unexpected escaped character '{a}' in regular expression.", + W050: "JavaScript URL.", + W051: "Variables should not be deleted.", + W052: "Unexpected '{a}'.", + W053: "Do not use {a} as a constructor.", + W054: "The Function constructor is a form of eval.", + W055: "A constructor name should start with an uppercase letter.", + W056: "Bad constructor.", + W057: "Weird construction. Is 'new' unnecessary?", + W058: "Missing '()' invoking a constructor.", + W059: "Avoid arguments.{a}.", + W060: "document.write can be a form of eval.", + W061: "eval can be harmful.", + W062: "Wrap an immediate function invocation in parens " + + "to assist the reader in understanding that the expression " + + "is the result of a function, and not the function itself.", + W063: "Math is not a function.", + W064: "Missing 'new' prefix when invoking a constructor.", + W065: "Missing radix parameter.", + W066: "Implied eval. Consider passing a function instead of a string.", + W067: "Bad invocation.", + W068: "Wrapping non-IIFE function literals in parens is unnecessary.", + W069: "['{a}'] is better written in dot notation.", + W070: "Extra comma. (it breaks older versions of IE)", + W071: "This function has too many statements. ({a})", + W072: "This function has too many parameters. ({a})", + W073: "Blocks are nested too deeply. ({a})", + W074: "This function's cyclomatic complexity is too high. ({a})", + W075: "Duplicate key '{a}'.", + W076: "Unexpected parameter '{a}' in get {b} function.", + W077: "Expected a single parameter in set {a} function.", + W078: "Setter is defined without getter.", + W079: "Redefinition of '{a}'.", + W080: "It's not necessary to initialize '{a}' to 'undefined'.", + W081: "Too many var statements.", + W082: "Function declarations should not be placed in blocks. " + + "Use a function expression or move the statement to the top of " + + "the outer function.", + W083: "Don't make functions within a loop.", + W084: "Assignment in conditional expression", + W085: "Don't use 'with'.", + W086: "Expected a 'break' statement before '{a}'.", + W087: "Forgotten 'debugger' statement?", + W088: "Creating global 'for' variable. Should be 'for (var {a} ...'.", + W089: "The body of a for in should be wrapped in an if statement to filter " + + "unwanted properties from the prototype.", + W090: "'{a}' is not a statement label.", + W091: "'{a}' is out of scope.", + W092: "Wrap the /regexp/ literal in parens to disambiguate the slash operator.", + W093: "Did you mean to return a conditional instead of an assignment?", + W094: "Unexpected comma.", + W095: "Expected a string and instead saw {a}.", + W096: "The '{a}' key may produce unexpected results.", + W097: "Use the function form of \"use strict\".", + W098: "'{a}' is defined but never used.", + W099: "Mixed spaces and tabs.", + W100: "This character may get silently deleted by one or more browsers.", + W101: "Line is too long.", + W102: "Trailing whitespace.", + W103: "The '{a}' property is deprecated.", + W104: "'{a}' is only available in JavaScript 1.7.", + W105: "Unexpected {a} in '{b}'.", + W106: "Identifier '{a}' is not in camel case.", + W107: "Script URL.", + W108: "Strings must use doublequote.", + W109: "Strings must use singlequote.", + W110: "Mixed double and single quotes.", + W112: "Unclosed string.", + W113: "Control character in string: {a}.", + W114: "Avoid {a}.", + W115: "Octal literals are not allowed in strict mode.", + W116: "Expected '{a}' and instead saw '{b}'.", + W117: "'{a}' is not defined.", + W118: "'{a}' is only available in Mozilla JavaScript extensions (use moz option).", + W119: "'{a}' is only available in ES6 (use esnext option)." +}; + +var info = { + I001: "Comma warnings can be turned off with 'laxcomma'.", + I002: "Reserved words as properties can be used under the 'es5' option.", + I003: "ES5 option is now set per default" +}; + +exports.errors = {}; +exports.warnings = {}; +exports.info = {}; + +_.each(errors, function (desc, code) { + exports.errors[code] = { code: code, desc: desc }; +}); + +_.each(warnings, function (desc, code) { + exports.warnings[code] = { code: code, desc: desc }; +}); + +_.each(info, function (desc, code) { + exports.info[code] = { code: code, desc: desc }; +}); + +})() +}, +{"underscore":12}], +11:[function(req,module,exports){ +(function(){/* + * Lexical analysis and token construction. + */ + + + +var _ = req("underscore"); +var events = req("events"); +var reg = req("./reg.js"); +var state = req("./state.js").state; + +var Token = { + Identifier: 1, + Punctuator: 2, + NumericLiteral: 3, + StringLiteral: 4, + Comment: 5, + Keyword: 6, + NullLiteral: 7, + BooleanLiteral: 8, + RegExp: 9 +}; + +var unicodeLetterTable = [ + 170, 170, 181, 181, 186, 186, 192, 214, + 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, + 880, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, + 910, 929, 931, 1013, 1015, 1153, 1162, 1319, 1329, 1366, + 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1568, 1610, + 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, + 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, + 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069, + 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2308, 2361, + 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2423, 2425, 2431, + 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, + 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, + 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, + 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, + 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, + 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785, + 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, + 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, + 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, + 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, + 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, + 3125, 3129, 3133, 3133, 3160, 3161, 3168, 3169, 3205, 3212, + 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261, + 3294, 3294, 3296, 3297, 3313, 3314, 3333, 3340, 3342, 3344, + 3346, 3386, 3389, 3389, 3406, 3406, 3424, 3425, 3450, 3455, + 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, + 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, + 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, + 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, + 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3805, + 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138, + 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198, + 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4304, 4346, + 4348, 4348, 4352, 4680, 4682, 4685, 4688, 4694, 4696, 4696, + 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, + 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, + 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5108, 5121, 5740, + 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, + 5902, 5905, 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000, + 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6263, 6272, 6312, + 6314, 6314, 6320, 6389, 6400, 6428, 6480, 6509, 6512, 6516, + 6528, 6571, 6593, 6599, 6656, 6678, 6688, 6740, 6823, 6823, + 6917, 6963, 6981, 6987, 7043, 7072, 7086, 7087, 7104, 7141, + 7168, 7203, 7245, 7247, 7258, 7293, 7401, 7404, 7406, 7409, + 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, + 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, + 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, + 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, + 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455, + 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, + 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, + 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, + 11360, 11492, 11499, 11502, 11520, 11557, 11568, 11621, + 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, + 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, + 11728, 11734, 11736, 11742, 11823, 11823, 12293, 12295, + 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, + 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, + 12593, 12686, 12704, 12730, 12784, 12799, 13312, 13312, + 19893, 19893, 19968, 19968, 40907, 40907, 40960, 42124, + 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539, + 42560, 42606, 42623, 42647, 42656, 42735, 42775, 42783, + 42786, 42888, 42891, 42894, 42896, 42897, 42912, 42921, + 43002, 43009, 43011, 43013, 43015, 43018, 43020, 43042, + 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259, + 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442, + 43471, 43471, 43520, 43560, 43584, 43586, 43588, 43595, + 43616, 43638, 43642, 43642, 43648, 43695, 43697, 43697, + 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714, + 43739, 43741, 43777, 43782, 43785, 43790, 43793, 43798, + 43808, 43814, 43816, 43822, 43968, 44002, 44032, 44032, + 55203, 55203, 55216, 55238, 55243, 55291, 63744, 64045, + 64048, 64109, 64112, 64217, 64256, 64262, 64275, 64279, + 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, + 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, + 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, + 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370, + 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, + 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594, + 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786, + 65856, 65908, 66176, 66204, 66208, 66256, 66304, 66334, + 66352, 66378, 66432, 66461, 66464, 66499, 66504, 66511, + 66513, 66517, 66560, 66717, 67584, 67589, 67592, 67592, + 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669, + 67840, 67861, 67872, 67897, 68096, 68096, 68112, 68115, + 68117, 68119, 68121, 68147, 68192, 68220, 68352, 68405, + 68416, 68437, 68448, 68466, 68608, 68680, 69635, 69687, + 69763, 69807, 73728, 74606, 74752, 74850, 77824, 78894, + 92160, 92728, 110592, 110593, 119808, 119892, 119894, 119964, + 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980, + 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069, + 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121, + 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144, + 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570, + 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686, + 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779, + 131072, 131072, 173782, 173782, 173824, 173824, 177972, 177972, + 177984, 177984, 178205, 178205, 194560, 195101 +]; + +var identifierStartTable = []; + +for (var i = 0; i < 128; i++) { + identifierStartTable[i] = + i === 36 || // $ + i >= 65 && i <= 90 || // A-Z + i === 95 || // _ + i >= 97 && i <= 122; // a-z +} + +var identifierPartTable = []; + +for (var i = 0; i < 128; i++) { + identifierPartTable[i] = + identifierStartTable[i] || // $, _, A-Z, a-z + i >= 48 && i <= 57; // 0-9 +} + +function asyncTrigger() { + var _checks = []; + + return { + push: function (fn) { + _checks.push(fn); + }, + + check: function () { + for (var check = 0; check < _checks.length; ++check) { + _checks[check](); + } + + _checks.splice(0, _checks.length); + } + }; +} +function Lexer(source) { + var lines = source; + + if (typeof lines === "string") { + lines = lines + .replace(/\r\n/g, "\n") + .replace(/\r/g, "\n") + .split("\n"); + } + + if (lines[0] && lines[0].substr(0, 2) === "#!") { + lines[0] = ""; + } + + this.emitter = new events.EventEmitter(); + this.source = source; + this.setLines(lines); + this.prereg = true; + + this.line = 0; + this.char = 1; + this.from = 1; + this.input = ""; + + for (var i = 0; i < state.option.indent; i += 1) { + state.tab += " "; + } +} + +Lexer.prototype = { + _lines: [], + + getLines: function () { + this._lines = state.lines; + return this._lines; + }, + + setLines: function (val) { + this._lines = val; + state.lines = this._lines; + }, + peek: function (i) { + return this.input.charAt(i || 0); + }, + skip: function (i) { + i = i || 1; + this.char += i; + this.input = this.input.slice(i); + }, + on: function (names, listener) { + names.split(" ").forEach(function (name) { + this.emitter.on(name, listener); + }.bind(this)); + }, + trigger: function () { + this.emitter.emit.apply(this.emitter, Array.prototype.slice.call(arguments)); + }, + triggerAsync: function (type, args, checks, fn) { + checks.push(function () { + if (fn()) { + this.trigger(type, args); + } + }.bind(this)); + }, + scanPunctuator: function () { + var ch1 = this.peek(); + var ch2, ch3, ch4; + + switch (ch1) { + case ".": + if ((/^[0-9]$/).test(this.peek(1))) { + return null; + } + if (this.peek(1) === "." && this.peek(2) === ".") { + return { + type: Token.Punctuator, + value: "..." + }; + } + case "(": + case ")": + case ";": + case ",": + case "{": + case "}": + case "[": + case "]": + case ":": + case "~": + case "?": + return { + type: Token.Punctuator, + value: ch1 + }; + case "#": + return { + type: Token.Punctuator, + value: ch1 + }; + case "": + return null; + } + + ch2 = this.peek(1); + ch3 = this.peek(2); + ch4 = this.peek(3); + + if (ch1 === ">" && ch2 === ">" && ch3 === ">" && ch4 === "=") { + return { + type: Token.Punctuator, + value: ">>>=" + }; + } + + if (ch1 === "=" && ch2 === "=" && ch3 === "=") { + return { + type: Token.Punctuator, + value: "===" + }; + } + + if (ch1 === "!" && ch2 === "=" && ch3 === "=") { + return { + type: Token.Punctuator, + value: "!==" + }; + } + + if (ch1 === ">" && ch2 === ">" && ch3 === ">") { + return { + type: Token.Punctuator, + value: ">>>" + }; + } + + if (ch1 === "<" && ch2 === "<" && ch3 === "=") { + return { + type: Token.Punctuator, + value: "<<=" + }; + } + + if (ch1 === ">" && ch2 === ">" && ch3 === "=") { + return { + type: Token.Punctuator, + value: ">>=" + }; + } + if (ch1 === "=" && ch2 === ">") { + return { + type: Token.Punctuator, + value: ch1 + ch2 + }; + } + if (ch1 === ch2 && ("+-<>&|".indexOf(ch1) >= 0)) { + return { + type: Token.Punctuator, + value: ch1 + ch2 + }; + } + + if ("<>=!+-*%&|^".indexOf(ch1) >= 0) { + if (ch2 === "=") { + return { + type: Token.Punctuator, + value: ch1 + ch2 + }; + } + + return { + type: Token.Punctuator, + value: ch1 + }; + } + + if (ch1 === "/") { + if (ch2 === "=" && /\/=(?!(\S*\/[gim]?))/.test(this.input)) { + return { + type: Token.Punctuator, + value: "/=" + }; + } + + return { + type: Token.Punctuator, + value: "/" + }; + } + + return null; + }, + scanComments: function () { + var ch1 = this.peek(); + var ch2 = this.peek(1); + var rest = this.input.substr(2); + var startLine = this.line; + var startChar = this.char; + + function commentToken(label, body, opt) { + var special = ["jshint", "jslint", "members", "member", "globals", "global", "exported"]; + var isSpecial = false; + var value = label + body; + var commentType = "plain"; + opt = opt || {}; + + if (opt.isMultiline) { + value += "*/"; + } + + special.forEach(function (str) { + if (isSpecial) { + return; + } + if (label === "//" && str !== "jshint") { + return; + } + + if (body.substr(0, str.length) === str) { + isSpecial = true; + label = label + str; + body = body.substr(str.length); + } + + if (!isSpecial && body.charAt(0) === " " && body.substr(1, str.length) === str) { + isSpecial = true; + label = label + " " + str; + body = body.substr(str.length + 1); + } + + if (!isSpecial) { + return; + } + + switch (str) { + case "member": + commentType = "members"; + break; + case "global": + commentType = "globals"; + break; + default: + commentType = str; + } + }); + + return { + type: Token.Comment, + commentType: commentType, + value: value, + body: body, + isSpecial: isSpecial, + isMultiline: opt.isMultiline || false, + isMalformed: opt.isMalformed || false + }; + } + if (ch1 === "*" && ch2 === "/") { + this.trigger("error", { + code: "E018", + line: startLine, + character: startChar + }); + + this.skip(2); + return null; + } + if (ch1 !== "/" || (ch2 !== "*" && ch2 !== "/")) { + return null; + } + if (ch2 === "/") { + this.skip(this.input.length); // Skip to the EOL. + return commentToken("//", rest); + } + + var body = ""; + if (ch2 === "*") { + this.skip(2); + + while (this.peek() !== "*" || this.peek(1) !== "/") { + if (this.peek() === "") { // End of Line + body += "\n"; + if (!this.nextLine()) { + this.trigger("error", { + code: "E017", + line: startLine, + character: startChar + }); + + return commentToken("/*", body, { + isMultiline: true, + isMalformed: true + }); + } + } else { + body += this.peek(); + this.skip(); + } + } + + this.skip(2); + return commentToken("/*", body, { isMultiline: true }); + } + }, + scanKeyword: function () { + var result = /^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(this.input); + var keywords = [ + "if", "in", "do", "var", "for", "new", + "try", "let", "this", "else", "case", + "void", "with", "enum", "while", "break", + "catch", "throw", "const", "yield", "class", + "super", "return", "typeof", "delete", + "switch", "export", "import", "default", + "finally", "extends", "function", "continue", + "debugger", "instanceof" + ]; + + if (result && keywords.indexOf(result[0]) >= 0) { + return { + type: Token.Keyword, + value: result[0] + }; + } + + return null; + }, + scanIdentifier: function () { + var id = ""; + var index = 0; + var type, char; + + function isUnicodeLetter(code) { + for (var i = 0; i < unicodeLetterTable.length;) { + if (code < unicodeLetterTable[i++]) { + return false; + } + + if (code <= unicodeLetterTable[i++]) { + return true; + } + } + + return false; + } + + function isHexDigit(str) { + return (/^[0-9a-fA-F]$/).test(str); + } + + var readUnicodeEscapeSequence = function () { + index += 1; + + if (this.peek(index) !== "u") { + return null; + } + + var ch1 = this.peek(index + 1); + var ch2 = this.peek(index + 2); + var ch3 = this.peek(index + 3); + var ch4 = this.peek(index + 4); + var code; + + if (isHexDigit(ch1) && isHexDigit(ch2) && isHexDigit(ch3) && isHexDigit(ch4)) { + code = parseInt(ch1 + ch2 + ch3 + ch4, 16); + + if (isUnicodeLetter(code)) { + index += 5; + return "\\u" + ch1 + ch2 + ch3 + ch4; + } + + return null; + } + + return null; + }.bind(this); + + var getIdentifierStart = function () { + var chr = this.peek(index); + var code = chr.charCodeAt(0); + + if (code === 92) { + return readUnicodeEscapeSequence(); + } + + if (code < 128) { + if (identifierStartTable[code]) { + index += 1; + return chr; + } + + return null; + } + + if (isUnicodeLetter(code)) { + index += 1; + return chr; + } + + return null; + }.bind(this); + + var getIdentifierPart = function () { + var chr = this.peek(index); + var code = chr.charCodeAt(0); + + if (code === 92) { + return readUnicodeEscapeSequence(); + } + + if (code < 128) { + if (identifierPartTable[code]) { + index += 1; + return chr; + } + + return null; + } + + if (isUnicodeLetter(code)) { + index += 1; + return chr; + } + + return null; + }.bind(this); + + char = getIdentifierStart(); + if (char === null) { + return null; + } + + id = char; + for (;;) { + char = getIdentifierPart(); + + if (char === null) { + break; + } + + id += char; + } + + switch (id) { + case "true": + case "false": + type = Token.BooleanLiteral; + break; + case "null": + type = Token.NullLiteral; + break; + default: + type = Token.Identifier; + } + + return { + type: type, + value: id + }; + }, + scanNumericLiteral: function () { + var index = 0; + var value = ""; + var length = this.input.length; + var char = this.peek(index); + var bad; + + function isDecimalDigit(str) { + return (/^[0-9]$/).test(str); + } + + function isOctalDigit(str) { + return (/^[0-7]$/).test(str); + } + + function isHexDigit(str) { + return (/^[0-9a-fA-F]$/).test(str); + } + + function isIdentifierStart(ch) { + return (ch === "$") || (ch === "_") || (ch === "\\") || + (ch >= "a" && ch <= "z") || (ch >= "A" && ch <= "Z"); + } + + if (char !== "." && !isDecimalDigit(char)) { + return null; + } + + if (char !== ".") { + value = this.peek(index); + index += 1; + char = this.peek(index); + + if (value === "0") { + if (char === "x" || char === "X") { + index += 1; + value += char; + + while (index < length) { + char = this.peek(index); + if (!isHexDigit(char)) { + break; + } + value += char; + index += 1; + } + + if (value.length <= 2) { // 0x + return { + type: Token.NumericLiteral, + value: value, + isMalformed: true + }; + } + + if (index < length) { + char = this.peek(index); + if (isIdentifierStart(char)) { + return null; + } + } + + return { + type: Token.NumericLiteral, + value: value, + base: 16, + isMalformed: false + }; + } + if (isOctalDigit(char)) { + index += 1; + value += char; + bad = false; + + while (index < length) { + char = this.peek(index); + + if (isDecimalDigit(char)) { + bad = true; + } else if (!isOctalDigit(char)) { + break; + } + value += char; + index += 1; + } + + if (index < length) { + char = this.peek(index); + if (isIdentifierStart(char)) { + return null; + } + } + + return { + type: Token.NumericLiteral, + value: value, + base: 8, + isMalformed: false + }; + } + + if (isDecimalDigit(char)) { + index += 1; + value += char; + } + } + + while (index < length) { + char = this.peek(index); + if (!isDecimalDigit(char)) { + break; + } + value += char; + index += 1; + } + } + + if (char === ".") { + value += char; + index += 1; + + while (index < length) { + char = this.peek(index); + if (!isDecimalDigit(char)) { + break; + } + value += char; + index += 1; + } + } + + if (char === "e" || char === "E") { + value += char; + index += 1; + char = this.peek(index); + + if (char === "+" || char === "-") { + value += this.peek(index); + index += 1; + } + + char = this.peek(index); + if (isDecimalDigit(char)) { + value += char; + index += 1; + + while (index < length) { + char = this.peek(index); + if (!isDecimalDigit(char)) { + break; + } + value += char; + index += 1; + } + } else { + return null; + } + } + + if (index < length) { + char = this.peek(index); + if (isIdentifierStart(char)) { + return null; + } + } + + return { + type: Token.NumericLiteral, + value: value, + base: 10, + isMalformed: !isFinite(value) + }; + }, + scanStringLiteral: function (checks) { + var quote = this.peek(); + if (quote !== "\"" && quote !== "'") { + return null; + } + this.triggerAsync("warning", { + code: "W108", + line: this.line, + character: this.char // +1? + }, checks, function () { return state.jsonMode && quote !== "\""; }); + + var value = ""; + var startLine = this.line; + var startChar = this.char; + var allowNewLine = false; + + this.skip(); + + while (this.peek() !== quote) { + while (this.peek() === "") { // End Of Line + + if (!allowNewLine) { + this.trigger("warning", { + code: "W112", + line: this.line, + character: this.char + }); + } else { + allowNewLine = false; + + this.triggerAsync("warning", { + code: "W043", + line: this.line, + character: this.char + }, checks, function () { return !state.option.multistr; }); + + this.triggerAsync("warning", { + code: "W042", + line: this.line, + character: this.char + }, checks, function () { return state.jsonMode && state.option.multistr; }); + } + + if (!this.nextLine()) { + this.trigger("error", { + code: "E029", + line: startLine, + character: startChar + }); + + return { + type: Token.StringLiteral, + value: value, + isUnclosed: true, + quote: quote + }; + } + } + + allowNewLine = false; + var char = this.peek(); + var jump = 1; // A length of a jump, after we're done + + if (char < " ") { + this.trigger("warning", { + code: "W113", + line: this.line, + character: this.char, + data: [ "" ] + }); + } + + if (char === "\\") { + this.skip(); + char = this.peek(); + + switch (char) { + case "'": + this.triggerAsync("warning", { + code: "W114", + line: this.line, + character: this.char, + data: [ "\\'" ] + }, checks, function () {return state.jsonMode; }); + break; + case "b": + char = "\b"; + break; + case "f": + char = "\f"; + break; + case "n": + char = "\n"; + break; + case "r": + char = "\r"; + break; + case "t": + char = "\t"; + break; + case "0": + char = "\0"; + var n = parseInt(this.peek(1), 10); + this.triggerAsync("warning", { + code: "W115", + line: this.line, + character: this.char + }, checks, + function () { return n >= 0 && n <= 7 && state.directive["use strict"]; }); + break; + case "u": + char = String.fromCharCode(parseInt(this.input.substr(1, 4), 16)); + jump = 5; + break; + case "v": + this.triggerAsync("warning", { + code: "W114", + line: this.line, + character: this.char, + data: [ "\\v" ] + }, checks, function () { return state.jsonMode; }); + + char = "\v"; + break; + case "x": + var x = parseInt(this.input.substr(1, 2), 16); + + this.triggerAsync("warning", { + code: "W114", + line: this.line, + character: this.char, + data: [ "\\x-" ] + }, checks, function () { return state.jsonMode; }); + + char = String.fromCharCode(x); + jump = 3; + break; + case "\\": + case "\"": + case "/": + break; + case "": + allowNewLine = true; + char = ""; + break; + case "!": + if (value.slice(value.length - 2) === "<") { + break; + } + default: + this.trigger("warning", { + code: "W044", + line: this.line, + character: this.char + }); + } + } + + value += char; + this.skip(jump); + } + + this.skip(); + return { + type: Token.StringLiteral, + value: value, + isUnclosed: false, + quote: quote + }; + }, + scanRegExp: function () { + var index = 0; + var length = this.input.length; + var char = this.peek(); + var value = char; + var body = ""; + var flags = []; + var malformed = false; + var isCharSet = false; + var terminated; + + var scanUnexpectedChars = function () { + if (char < " ") { + malformed = true; + this.trigger("warning", { + code: "W048", + line: this.line, + character: this.char + }); + } + if (char === "<") { + malformed = true; + this.trigger("warning", { + code: "W049", + line: this.line, + character: this.char, + data: [ char ] + }); + } + }.bind(this); + if (!this.prereg || char !== "/") { + return null; + } + + index += 1; + terminated = false; + + while (index < length) { + char = this.peek(index); + value += char; + body += char; + + if (isCharSet) { + if (char === "]") { + if (this.peek(index - 1) !== "\\" || this.peek(index - 2) === "\\") { + isCharSet = false; + } + } + + if (char === "\\") { + index += 1; + char = this.peek(index); + body += char; + value += char; + + scanUnexpectedChars(); + } + + index += 1; + continue; + } + + if (char === "\\") { + index += 1; + char = this.peek(index); + body += char; + value += char; + + scanUnexpectedChars(); + + if (char === "/") { + index += 1; + continue; + } + + if (char === "[") { + index += 1; + continue; + } + } + + if (char === "[") { + isCharSet = true; + index += 1; + continue; + } + + if (char === "/") { + body = body.substr(0, body.length - 1); + terminated = true; + index += 1; + break; + } + + index += 1; + } + + if (!terminated) { + this.trigger("error", { + code: "E015", + line: this.line, + character: this.from + }); + + return void this.trigger("fatal", { + line: this.line, + from: this.from + }); + } + + while (index < length) { + char = this.peek(index); + if (!/[gim]/.test(char)) { + break; + } + flags.push(char); + value += char; + index += 1; + } + + try { + new RegExp(body, flags.join("")); + } catch (err) { + malformed = true; + this.trigger("error", { + code: "E016", + line: this.line, + character: this.char, + data: [ err.message ] // Platform dependent! + }); + } + + return { + type: Token.RegExp, + value: value, + flags: flags, + isMalformed: malformed + }; + }, + scanMixedSpacesAndTabs: function () { + var at, match; + + if (state.option.smarttabs) { + match = this.input.match(/(\/\/|^\s?\*)? \t/); + at = match && !match[1] ? 0 : -1; + } else { + at = this.input.search(/ \t|\t [^\*]/); + } + + return at; + }, + scanUnsafeChars: function () { + return this.input.search(reg.unsafeChars); + }, + next: function (checks) { + this.from = this.char; + var start; + if (/\s/.test(this.peek())) { + start = this.char; + + while (/\s/.test(this.peek())) { + this.from += 1; + this.skip(); + } + + if (this.peek() === "") { // EOL + if (!/^\s*$/.test(this.getLines()[this.line - 1]) && state.option.trailing) { + this.trigger("warning", { code: "W102", line: this.line, character: start }); + } + } + } + + var match = this.scanComments() || + this.scanStringLiteral(checks); + + if (match) { + return match; + } + + match = + this.scanRegExp() || + this.scanPunctuator() || + this.scanKeyword() || + this.scanIdentifier() || + this.scanNumericLiteral(); + + if (match) { + this.skip(match.value.length); + return match; + } + + return null; + }, + nextLine: function () { + var char; + + if (this.line >= this.getLines().length) { + return false; + } + + this.input = this.getLines()[this.line]; + this.line += 1; + this.char = 1; + this.from = 1; + + char = this.scanMixedSpacesAndTabs(); + if (char >= 0) { + this.trigger("warning", { code: "W099", line: this.line, character: char + 1 }); + } + + this.input = this.input.replace(/\t/g, state.tab); + char = this.scanUnsafeChars(); + + if (char >= 0) { + this.trigger("warning", { code: "W100", line: this.line, character: char }); + } + + if (state.option.maxlen && state.option.maxlen < this.input.length) { + this.trigger("warning", { code: "W101", line: this.line, character: this.input.length }); + } + + return true; + }, + start: function () { + this.nextLine(); + }, + token: function () { + var checks = asyncTrigger(); + var token; + + + function isReserved(token, isProperty) { + if (!token.reserved) { + return false; + } + + if (token.meta && token.meta.isFutureReservedWord) { + if (state.option.inES5(true) && !token.meta.es5) { + return false; + } + if (token.meta.strictOnly) { + if (!state.option.strict && !state.directive["use strict"]) { + return false; + } + } + + if (isProperty) { + return false; + } + } + + return true; + } + var create = function (type, value, isProperty) { + var obj; + + if (type !== "(endline)" && type !== "(end)") { + this.prereg = false; + } + + if (type === "(punctuator)") { + switch (value) { + case ".": + case ")": + case "~": + case "#": + case "]": + this.prereg = false; + break; + default: + this.prereg = true; + } + + obj = Object.create(state.syntax[value] || state.syntax["(error)"]); + } + + if (type === "(identifier)") { + if (value === "return" || value === "case" || value === "typeof") { + this.prereg = true; + } + + if (_.has(state.syntax, value)) { + obj = Object.create(state.syntax[value] || state.syntax["(error)"]); + if (!isReserved(obj, isProperty && type === "(identifier)")) { + obj = null; + } + } + } + + if (!obj) { + obj = Object.create(state.syntax[type]); + } + + obj.identifier = (type === "(identifier)"); + obj.type = obj.type || type; + obj.value = value; + obj.line = this.line; + obj.character = this.char; + obj.from = this.from; + + if (isProperty && obj.identifier) { + obj.isProperty = isProperty; + } + + obj.check = checks.check; + + return obj; + }.bind(this); + + for (;;) { + if (!this.input.length) { + return create(this.nextLine() ? "(endline)" : "(end)", ""); + } + + token = this.next(checks); + + if (!token) { + if (this.input.length) { + this.trigger("error", { + code: "E024", + line: this.line, + character: this.char, + data: [ this.peek() ] + }); + + this.input = ""; + } + + continue; + } + + switch (token.type) { + case Token.StringLiteral: + this.triggerAsync("String", { + line: this.line, + char: this.char, + from: this.from, + value: token.value, + quote: token.quote + }, checks, function () { return true; }); + + return create("(string)", token.value); + case Token.Identifier: + this.trigger("Identifier", { + line: this.line, + char: this.char, + from: this.form, + name: token.value, + isProperty: state.tokens.curr.id === "." + }); + case Token.Keyword: + case Token.NullLiteral: + case Token.BooleanLiteral: + return create("(identifier)", token.value, state.tokens.curr.id === "."); + + case Token.NumericLiteral: + if (token.isMalformed) { + this.trigger("warning", { + code: "W045", + line: this.line, + character: this.char, + data: [ token.value ] + }); + } + + this.triggerAsync("warning", { + code: "W114", + line: this.line, + character: this.char, + data: [ "0x-" ] + }, checks, function () { return token.base === 16 && state.jsonMode; }); + + this.triggerAsync("warning", { + code: "W115", + line: this.line, + character: this.char + }, checks, function () { + return state.directive["use strict"] && token.base === 8; + }); + + this.trigger("Number", { + line: this.line, + char: this.char, + from: this.from, + value: token.value, + base: token.base, + isMalformed: token.malformed + }); + + return create("(number)", token.value); + + case Token.RegExp: + return create("(regexp)", token.value); + + case Token.Comment: + state.tokens.curr.comment = true; + + if (token.isSpecial) { + return { + value: token.value, + body: token.body, + type: token.commentType, + isSpecial: token.isSpecial, + line: this.line, + character: this.char, + from: this.from + }; + } + + break; + + case "": + break; + + default: + return create("(punctuator)", token.value); + } + } + } +}; + +exports.Lexer = Lexer; + +})() +}, +{"events":2,"./reg.js":4,"./state.js":5,"underscore":12}], +12:[function(req,module,exports){ +(function(){// Underscore.js 1.4.4 + +(function() { + var root = this; + var previousUnderscore = root._; + var breaker = {}; + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + var push = ArrayProto.push, + slice = ArrayProto.slice, + concat = ArrayProto.concat, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + var + nativeForEach = ArrayProto.forEach, + nativeMap = ArrayProto.map, + nativeReduce = ArrayProto.reduce, + nativeReduceRight = ArrayProto.reduceRight, + nativeFilter = ArrayProto.filter, + nativeEvery = ArrayProto.every, + nativeSome = ArrayProto.some, + nativeIndexOf = ArrayProto.indexOf, + nativeLastIndexOf = ArrayProto.lastIndexOf, + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind; + var _ = function(obj) { + if (obj instanceof _) return obj; + if (!(this instanceof _)) return new _(obj); + this._wrapped = obj; + }; + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = _; + } + exports._ = _; + } else { + root._ = _; + } + _.VERSION = '1.4.4'; + var each = _.each = _.forEach = function(obj, iterator, context) { + if (obj == null) return; + if (nativeForEach && obj.forEach === nativeForEach) { + obj.forEach(iterator, context); + } else if (obj.length === +obj.length) { + for (var i = 0, l = obj.length; i < l; i++) { + if (iterator.call(context, obj[i], i, obj) === breaker) return; + } + } else { + for (var key in obj) { + if (_.has(obj, key)) { + if (iterator.call(context, obj[key], key, obj) === breaker) return; + } + } + } + }; + _.map = _.collect = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); + each(obj, function(value, index, list) { + results[results.length] = iterator.call(context, value, index, list); + }); + return results; + }; + + var reduceError = 'Reduce of empty array with no initial value'; + _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { + var initial = arguments.length > 2; + if (obj == null) obj = []; + if (nativeReduce && obj.reduce === nativeReduce) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); + } + each(obj, function(value, index, list) { + if (!initial) { + memo = value; + initial = true; + } else { + memo = iterator.call(context, memo, value, index, list); + } + }); + if (!initial) throw new TypeError(reduceError); + return memo; + }; + _.reduceRight = _.foldr = function(obj, iterator, memo, context) { + var initial = arguments.length > 2; + if (obj == null) obj = []; + if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); + } + var length = obj.length; + if (length !== +length) { + var keys = _.keys(obj); + length = keys.length; + } + each(obj, function(value, index, list) { + index = keys ? keys[--length] : --length; + if (!initial) { + memo = obj[index]; + initial = true; + } else { + memo = iterator.call(context, memo, obj[index], index, list); + } + }); + if (!initial) throw new TypeError(reduceError); + return memo; + }; + _.find = _.detect = function(obj, iterator, context) { + var result; + any(obj, function(value, index, list) { + if (iterator.call(context, value, index, list)) { + result = value; + return true; + } + }); + return result; + }; + _.filter = _.select = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); + each(obj, function(value, index, list) { + if (iterator.call(context, value, index, list)) results[results.length] = value; + }); + return results; + }; + _.reject = function(obj, iterator, context) { + return _.filter(obj, function(value, index, list) { + return !iterator.call(context, value, index, list); + }, context); + }; + _.every = _.all = function(obj, iterator, context) { + iterator || (iterator = _.identity); + var result = true; + if (obj == null) return result; + if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); + each(obj, function(value, index, list) { + if (!(result = result && iterator.call(context, value, index, list))) return breaker; + }); + return !!result; + }; + var any = _.some = _.any = function(obj, iterator, context) { + iterator || (iterator = _.identity); + var result = false; + if (obj == null) return result; + if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); + each(obj, function(value, index, list) { + if (result || (result = iterator.call(context, value, index, list))) return breaker; + }); + return !!result; + }; + _.contains = _.include = function(obj, target) { + if (obj == null) return false; + if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; + return any(obj, function(value) { + return value === target; + }); + }; + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + var isFunc = _.isFunction(method); + return _.map(obj, function(value) { + return (isFunc ? method : value[method]).apply(value, args); + }); + }; + _.pluck = function(obj, key) { + return _.map(obj, function(value){ return value[key]; }); + }; + _.where = function(obj, attrs, first) { + if (_.isEmpty(attrs)) return first ? null : []; + return _[first ? 'find' : 'filter'](obj, function(value) { + for (var key in attrs) { + if (attrs[key] !== value[key]) return false; + } + return true; + }); + }; + _.findWhere = function(obj, attrs) { + return _.where(obj, attrs, true); + }; + _.max = function(obj, iterator, context) { + if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { + return Math.max.apply(Math, obj); + } + if (!iterator && _.isEmpty(obj)) return -Infinity; + var result = {computed : -Infinity, value: -Infinity}; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + computed >= result.computed && (result = {value : value, computed : computed}); + }); + return result.value; + }; + _.min = function(obj, iterator, context) { + if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { + return Math.min.apply(Math, obj); + } + if (!iterator && _.isEmpty(obj)) return Infinity; + var result = {computed : Infinity, value: Infinity}; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + computed < result.computed && (result = {value : value, computed : computed}); + }); + return result.value; + }; + _.shuffle = function(obj) { + var rand; + var index = 0; + var shuffled = []; + each(obj, function(value) { + rand = _.random(index++); + shuffled[index - 1] = shuffled[rand]; + shuffled[rand] = value; + }); + return shuffled; + }; + var lookupIterator = function(value) { + return _.isFunction(value) ? value : function(obj){ return obj[value]; }; + }; + _.sortBy = function(obj, value, context) { + var iterator = lookupIterator(value); + return _.pluck(_.map(obj, function(value, index, list) { + return { + value : value, + index : index, + criteria : iterator.call(context, value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria; + var b = right.criteria; + if (a !== b) { + if (a > b || a === void 0) return 1; + if (a < b || b === void 0) return -1; + } + return left.index < right.index ? -1 : 1; + }), 'value'); + }; + var group = function(obj, value, context, behavior) { + var result = {}; + var iterator = lookupIterator(value || _.identity); + each(obj, function(value, index) { + var key = iterator.call(context, value, index, obj); + behavior(result, key, value); + }); + return result; + }; + _.groupBy = function(obj, value, context) { + return group(obj, value, context, function(result, key, value) { + (_.has(result, key) ? result[key] : (result[key] = [])).push(value); + }); + }; + _.countBy = function(obj, value, context) { + return group(obj, value, context, function(result, key) { + if (!_.has(result, key)) result[key] = 0; + result[key]++; + }); + }; + _.sortedIndex = function(array, obj, iterator, context) { + iterator = iterator == null ? _.identity : lookupIterator(iterator); + var value = iterator.call(context, obj); + var low = 0, high = array.length; + while (low < high) { + var mid = (low + high) >>> 1; + iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid; + } + return low; + }; + _.toArray = function(obj) { + if (!obj) return []; + if (_.isArray(obj)) return slice.call(obj); + if (obj.length === +obj.length) return _.map(obj, _.identity); + return _.values(obj); + }; + _.size = function(obj) { + if (obj == null) return 0; + return (obj.length === +obj.length) ? obj.length : _.keys(obj).length; + }; + _.first = _.head = _.take = function(array, n, guard) { + if (array == null) return void 0; + return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; + }; + _.initial = function(array, n, guard) { + return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n)); + }; + _.last = function(array, n, guard) { + if (array == null) return void 0; + if ((n != null) && !guard) { + return slice.call(array, Math.max(array.length - n, 0)); + } else { + return array[array.length - 1]; + } + }; + _.rest = _.tail = _.drop = function(array, n, guard) { + return slice.call(array, (n == null) || guard ? 1 : n); + }; + _.compact = function(array) { + return _.filter(array, _.identity); + }; + var flatten = function(input, shallow, output) { + each(input, function(value) { + if (_.isArray(value)) { + shallow ? push.apply(output, value) : flatten(value, shallow, output); + } else { + output.push(value); + } + }); + return output; + }; + _.flatten = function(array, shallow) { + return flatten(array, shallow, []); + }; + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; + _.uniq = _.unique = function(array, isSorted, iterator, context) { + if (_.isFunction(isSorted)) { + context = iterator; + iterator = isSorted; + isSorted = false; + } + var initial = iterator ? _.map(array, iterator, context) : array; + var results = []; + var seen = []; + each(initial, function(value, index) { + if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) { + seen.push(value); + results.push(array[index]); + } + }); + return results; + }; + _.union = function() { + return _.uniq(concat.apply(ArrayProto, arguments)); + }; + _.intersection = function(array) { + var rest = slice.call(arguments, 1); + return _.filter(_.uniq(array), function(item) { + return _.every(rest, function(other) { + return _.indexOf(other, item) >= 0; + }); + }); + }; + _.difference = function(array) { + var rest = concat.apply(ArrayProto, slice.call(arguments, 1)); + return _.filter(array, function(value){ return !_.contains(rest, value); }); + }; + _.zip = function() { + var args = slice.call(arguments); + var length = _.max(_.pluck(args, 'length')); + var results = new Array(length); + for (var i = 0; i < length; i++) { + results[i] = _.pluck(args, "" + i); + } + return results; + }; + _.object = function(list, values) { + if (list == null) return {}; + var result = {}; + for (var i = 0, l = list.length; i < l; i++) { + if (values) { + result[list[i]] = values[i]; + } else { + result[list[i][0]] = list[i][1]; + } + } + return result; + }; + _.indexOf = function(array, item, isSorted) { + if (array == null) return -1; + var i = 0, l = array.length; + if (isSorted) { + if (typeof isSorted == 'number') { + i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted); + } else { + i = _.sortedIndex(array, item); + return array[i] === item ? i : -1; + } + } + if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted); + for (; i < l; i++) if (array[i] === item) return i; + return -1; + }; + _.lastIndexOf = function(array, item, from) { + if (array == null) return -1; + var hasIndex = from != null; + if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) { + return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item); + } + var i = (hasIndex ? from : array.length); + while (i--) if (array[i] === item) return i; + return -1; + }; + _.range = function(start, stop, step) { + if (arguments.length <= 1) { + stop = start || 0; + start = 0; + } + step = arguments[2] || 1; + + var len = Math.max(Math.ceil((stop - start) / step), 0); + var idx = 0; + var range = new Array(len); + + while(idx < len) { + range[idx++] = start; + start += step; + } + + return range; + }; + _.bind = function(func, context) { + if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + var args = slice.call(arguments, 2); + return function() { + return func.apply(context, args.concat(slice.call(arguments))); + }; + }; + _.partial = function(func) { + var args = slice.call(arguments, 1); + return function() { + return func.apply(this, args.concat(slice.call(arguments))); + }; + }; + _.bindAll = function(obj) { + var funcs = slice.call(arguments, 1); + if (funcs.length === 0) funcs = _.functions(obj); + each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); + return obj; + }; + _.memoize = function(func, hasher) { + var memo = {}; + hasher || (hasher = _.identity); + return function() { + var key = hasher.apply(this, arguments); + return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); + }; + }; + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ return func.apply(null, args); }, wait); + }; + _.defer = function(func) { + return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); + }; + _.throttle = function(func, wait) { + var context, args, timeout, result; + var previous = 0; + var later = function() { + previous = new Date; + timeout = null; + result = func.apply(context, args); + }; + return function() { + var now = new Date; + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0) { + clearTimeout(timeout); + timeout = null; + previous = now; + result = func.apply(context, args); + } else if (!timeout) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }; + _.debounce = function(func, wait, immediate) { + var timeout, result; + return function() { + var context = this, args = arguments; + var later = function() { + timeout = null; + if (!immediate) result = func.apply(context, args); + }; + var callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if (callNow) result = func.apply(context, args); + return result; + }; + }; + _.once = function(func) { + var ran = false, memo; + return function() { + if (ran) return memo; + ran = true; + memo = func.apply(this, arguments); + func = null; + return memo; + }; + }; + _.wrap = function(func, wrapper) { + return function() { + var args = [func]; + push.apply(args, arguments); + return wrapper.apply(this, args); + }; + }; + _.compose = function() { + var funcs = arguments; + return function() { + var args = arguments; + for (var i = funcs.length - 1; i >= 0; i--) { + args = [funcs[i].apply(this, args)]; + } + return args[0]; + }; + }; + _.after = function(times, func) { + if (times <= 0) return func(); + return function() { + if (--times < 1) { + return func.apply(this, arguments); + } + }; + }; + _.keys = nativeKeys || function(obj) { + if (obj !== Object(obj)) throw new TypeError('Invalid object'); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key; + return keys; + }; + _.values = function(obj) { + var values = []; + for (var key in obj) if (_.has(obj, key)) values.push(obj[key]); + return values; + }; + _.pairs = function(obj) { + var pairs = []; + for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]); + return pairs; + }; + _.invert = function(obj) { + var result = {}; + for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key; + return result; + }; + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; + _.extend = function(obj) { + each(slice.call(arguments, 1), function(source) { + if (source) { + for (var prop in source) { + obj[prop] = source[prop]; + } + } + }); + return obj; + }; + _.pick = function(obj) { + var copy = {}; + var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); + each(keys, function(key) { + if (key in obj) copy[key] = obj[key]; + }); + return copy; + }; + _.omit = function(obj) { + var copy = {}; + var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); + for (var key in obj) { + if (!_.contains(keys, key)) copy[key] = obj[key]; + } + return copy; + }; + _.defaults = function(obj) { + each(slice.call(arguments, 1), function(source) { + if (source) { + for (var prop in source) { + if (obj[prop] == null) obj[prop] = source[prop]; + } + } + }); + return obj; + }; + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + var eq = function(a, b, aStack, bStack) { + if (a === b) return a !== 0 || 1 / a == 1 / b; + if (a == null || b == null) return a === b; + if (a instanceof _) a = a._wrapped; + if (b instanceof _) b = b._wrapped; + var className = toString.call(a); + if (className != toString.call(b)) return false; + switch (className) { + case '[object String]': + return a == String(b); + case '[object Number]': + return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); + case '[object Date]': + case '[object Boolean]': + return +a == +b; + case '[object RegExp]': + return a.source == b.source && + a.global == b.global && + a.multiline == b.multiline && + a.ignoreCase == b.ignoreCase; + } + if (typeof a != 'object' || typeof b != 'object') return false; + var length = aStack.length; + while (length--) { + if (aStack[length] == a) return bStack[length] == b; + } + aStack.push(a); + bStack.push(b); + var size = 0, result = true; + if (className == '[object Array]') { + size = a.length; + result = size == b.length; + if (result) { + while (size--) { + if (!(result = eq(a[size], b[size], aStack, bStack))) break; + } + } + } else { + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) && + _.isFunction(bCtor) && (bCtor instanceof bCtor))) { + return false; + } + for (var key in a) { + if (_.has(a, key)) { + size++; + if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break; + } + } + if (result) { + for (key in b) { + if (_.has(b, key) && !(size--)) break; + } + result = !size; + } + } + aStack.pop(); + bStack.pop(); + return result; + }; + _.isEqual = function(a, b) { + return eq(a, b, [], []); + }; + _.isEmpty = function(obj) { + if (obj == null) return true; + if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; + for (var key in obj) if (_.has(obj, key)) return false; + return true; + }; + _.isElement = function(obj) { + return !!(obj && obj.nodeType === 1); + }; + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) == '[object Array]'; + }; + _.isObject = function(obj) { + return obj === Object(obj); + }; + each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) { + _['is' + name] = function(obj) { + return toString.call(obj) == '[object ' + name + ']'; + }; + }); + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return !!(obj && _.has(obj, 'callee')); + }; + } + if (typeof (/./) !== 'function') { + _.isFunction = function(obj) { + return typeof obj === 'function'; + }; + } + _.isFinite = function(obj) { + return isFinite(obj) && !isNaN(parseFloat(obj)); + }; + _.isNaN = function(obj) { + return _.isNumber(obj) && obj != +obj; + }; + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) == '[object Boolean]'; + }; + _.isNull = function(obj) { + return obj === null; + }; + _.isUndefined = function(obj) { + return obj === void 0; + }; + _.has = function(obj, key) { + return hasOwnProperty.call(obj, key); + }; + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + _.identity = function(value) { + return value; + }; + _.times = function(n, iterator, context) { + var accum = Array(n); + for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i); + return accum; + }; + _.random = function(min, max) { + if (max == null) { + max = min; + min = 0; + } + return min + Math.floor(Math.random() * (max - min + 1)); + }; + var entityMap = { + escape: { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '/': '/' + } + }; + entityMap.unescape = _.invert(entityMap.escape); + var entityRegexes = { + escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'), + unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g') + }; + _.each(['escape', 'unescape'], function(method) { + _[method] = function(string) { + if (string == null) return ''; + return ('' + string).replace(entityRegexes[method], function(match) { + return entityMap[method][match]; + }); + }; + }); + _.result = function(object, property) { + if (object == null) return null; + var value = object[property]; + return _.isFunction(value) ? value.call(object) : value; + }; + _.mixin = function(obj) { + each(_.functions(obj), function(name){ + var func = _[name] = obj[name]; + _.prototype[name] = function() { + var args = [this._wrapped]; + push.apply(args, arguments); + return result.call(this, func.apply(_, args)); + }; + }); + }; + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; + }; + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; + var noMatch = /(.)^/; + var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\t': 't', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; + _.template = function(text, data, settings) { + var render; + settings = _.defaults({}, settings, _.templateSettings); + var matcher = new RegExp([ + (settings.escape || noMatch).source, + (settings.interpolate || noMatch).source, + (settings.evaluate || noMatch).source + ].join('|') + '|$', 'g'); + var index = 0; + var source = "__p+='"; + text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { + source += text.slice(index, offset) + .replace(escaper, function(match) { return '\\' + escapes[match]; }); + + if (escape) { + source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; + } + if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } + if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + index = offset + match.length; + return match; + }); + source += "';\n"; + if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; + + source = "var __t,__p='',__j=Array.prototype.join," + + "print=function(){__p+=__j.call(arguments,'');};\n" + + source + "return __p;\n"; + + try { + render = new Function(settings.variable || 'obj', '_', source); + } catch (e) { + e.source = source; + throw e; + } + + if (data) return render(data, _); + var template = function(data) { + return render.call(this, data, _); + }; + template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}'; + + return template; + }; + _.chain = function(obj) { + return _(obj).chain(); + }; + var result = function(obj) { + return this._chain ? _(obj).chain() : obj; + }; + _.mixin(_); + each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + var obj = this._wrapped; + method.apply(obj, arguments); + if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0]; + return result.call(this, obj); + }; + }); + each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + return result.call(this, method.apply(this._wrapped, arguments)); + }; + }); + + _.extend(_.prototype, { + chain: function() { + this._chain = true; + return this; + }, + value: function() { + return this._wrapped; + } + + }); + +}).call(this); + +})() +}, +{}] +},{},["E/GbHF"]) +; + +function req() {return require.apply(this, arguments)} +module.exports = req("jshint"); + }); \ No newline at end of file From 723b848dd319ebcc4b8660777e81093f608d2443 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 28 Aug 2013 11:22:48 +0000 Subject: [PATCH 066/218] chore(cloudcmd) coderaiser.github.com -> coderaiser.github.io --- lib/cloudfunc.js | 2 +- lib/server.js | 2 +- lib/server/appcache.js | 2 +- lib/server/auth.js | 2 +- lib/server/commander.js | 2 +- lib/server/dir.js | 2 +- lib/server/minify.js | 2 +- lib/server/rest.js | 2 +- lib/server/stream.js | 2 +- lib/server/update.js | 2 +- lib/server/win.js | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/cloudfunc.js b/lib/cloudfunc.js index 52d5bda5..e9abed7b 100644 --- a/lib/cloudfunc.js +++ b/lib/cloudfunc.js @@ -16,7 +16,7 @@ var Util, exports, CloudFunc = {}; '# Module is part of Cloud Commander,' + '\n' + '# used for generate html from json.' + '\n' + '# ' + '\n' + - '# http://coderaiser.github.com/cloudcmd' + '\n'); + '# http://coderaiser.github.io/cloudcmd' + '\n'); Util = global.cloudcmd.main.util; CloudFunc = exports; diff --git a/lib/server.js b/lib/server.js index 8ef8cf54..e29ce69d 100644 --- a/lib/server.js +++ b/lib/server.js @@ -7,7 +7,7 @@ '# -----------' + '\n' + '# Module is part of Cloud Commander,' + '\n' + '# easy to use web server.' + '\n' + - '# http://coderaiser.github.com/cloudcmd' + '\n'); + '# http://coderaiser.github.io/cloudcmd' + '\n'); var main = global.cloudcmd.main, diff --git a/lib/server/appcache.js b/lib/server/appcache.js index 0a7c7e72..2c5745eb 100644 --- a/lib/server/appcache.js +++ b/lib/server/appcache.js @@ -10,7 +10,7 @@ '# used for work with Aplication Cache.' + '\n' + '# If you wont to see at work set appcache: true' + '\n' + '# in config.json and start cloudcmd.js' + '\n' + - '# http://coderaiser.github.com/cloudcmd' + '\n'); + '# http://coderaiser.github.io/cloudcmd' + '\n'); var main = global.cloudcmd.main, fs = main.fs, diff --git a/lib/server/auth.js b/lib/server/auth.js index efaa622f..c5df78ee 100644 --- a/lib/server/auth.js +++ b/lib/server/auth.js @@ -12,7 +12,7 @@ '# parameters in config.json or environment' + '\n' + '# and start cloudcmd.js or just do' + '\n' + '# require(\'auth.js\').auth(pCode, pCallBack)' + '\n' + - '# http://coderaiser.github.com/cloudcmd' + '\n'); + '# http://coderaiser.github.io/cloudcmd' + '\n'); var main = global.cloudcmd.main, diff --git a/lib/server/commander.js b/lib/server/commander.js index ab88d557..f88cf2b4 100644 --- a/lib/server/commander.js +++ b/lib/server/commander.js @@ -8,7 +8,7 @@ '# Module is part of Cloud Commander,' + '\n' + '# used for getting dir content.' + '\n' + '# and forming html content' + '\n' + - '# http://coderaiser.github.com/cloudcmd' + '\n'); + '# http://coderaiser.github.io/cloudcmd' + '\n'); var main = global.cloudcmd.main, fs = main.fs, diff --git a/lib/server/dir.js b/lib/server/dir.js index 761aee67..06566078 100644 --- a/lib/server/dir.js +++ b/lib/server/dir.js @@ -12,7 +12,7 @@ '# try GET /api/v1/fs/etc?size or' + '\n' + '# dir.getSize(\'/etc, function(err, size){' + '\n' + '# });' + '\n' + - '# http://coderaiser.github.com/cloudcmd' + '\n'); + '# http://coderaiser.github.io/cloudcmd' + '\n'); var main = global.cloudcmd.main, fs = main.fs, diff --git a/lib/server/minify.js b/lib/server/minify.js index ff042240..7f7bf32a 100644 --- a/lib/server/minify.js +++ b/lib/server/minify.js @@ -12,7 +12,7 @@ '# If you wont to see at work set minify' + '\n' + '# parameters in config.json or environment' + '\n' + '# and start cloudcmd.js' + '\n' + - '# http://coderaiser.github.com/cloudcmd' + '\n'); + '# http://coderaiser.github.io/cloudcmd' + '\n'); var main = global.cloudcmd.main, DIR = main.DIR, diff --git a/lib/server/rest.js b/lib/server/rest.js index 3a50eef7..16883236 100644 --- a/lib/server/rest.js +++ b/lib/server/rest.js @@ -11,7 +11,7 @@ '# used for work with REST API.' + '\n' + '# If you wont to see at work set rest: true' + '\n' + '# and api_url in config.json' + '\n' + - '# http://coderaiser.github.com/cloudcmd' + '\n'); + '# http://coderaiser.github.io/cloudcmd' + '\n'); var main = global.cloudcmd.main, fs = main.fs, diff --git a/lib/server/stream.js b/lib/server/stream.js index 3fa9596e..2bfda8d1 100644 --- a/lib/server/stream.js +++ b/lib/server/stream.js @@ -9,7 +9,7 @@ '# used for work with stream.' + '\n' + '# If you wont to see at work call' + '\n' + '# stream.createPipe' + '\n' + - '# http://coderaiser.github.com/cloudcmd' + '\n'); + '# http://coderaiser.github.io/cloudcmd' + '\n'); var main = global.cloudcmd.main, fs = main.fs, diff --git a/lib/server/update.js b/lib/server/update.js index fbef3db8..81902a04 100644 --- a/lib/server/update.js +++ b/lib/server/update.js @@ -10,7 +10,7 @@ '# Module is part of Cloud Commander,' + '\n' + '# used for work update thru git.' + '\n' + '# If you wont to see at work install git' + '\n' + - '# http://coderaiser.github.com/cloudcmd' + '\n'); + '# http://coderaiser.github.io/cloudcmd' + '\n'); var main = global.cloudcmd.main, mainpackage = main.mainpackage || {}, diff --git a/lib/server/win.js b/lib/server/win.js index b98368dc..2d0e0c69 100644 --- a/lib/server/win.js +++ b/lib/server/win.js @@ -13,7 +13,7 @@ '# Module is part of Cloud Commander,' + '\n' + '# used for work with windows specific' + '\n' + '# functions like work with drives(etc c).' + '\n' + - '# http://coderaiser.github.com/cloudcmd' + '\n'); + '# http://coderaiser.github.io/cloudcmd' + '\n'); var main = global.cloudcmd.main, Charset ={ From e602a0ada1c72cb14881395e2881740af9003d10 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 29 Aug 2013 13:34:24 +0000 Subject: [PATCH 067/218] chore(dom) "){" -> ") {" --- lib/client/dom.js | 330 +++++++++++++++++++++++----------------------- 1 file changed, 165 insertions(+), 165 deletions(-) diff --git a/lib/client/dom.js b/lib/client/dom.js index 450353cc..fe9a5f96 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -1,14 +1,14 @@ var CloudCmd, Util, DOM, CloudFunc; -(function(Util){ +(function(Util) { 'use strict'; - var DOMFunc = function(){}, + var DOMFunc = function() {}, DOMProto, - ImagesProto = function(){ - var LImagesProto = function (){ - function getImage(pName){ + ImagesProto = function() { + var LImagesProto = function() { + function getImage(pName) { var lId = pName + '-image', lE = DOM.getById(lId); @@ -24,12 +24,12 @@ var CloudCmd, Util, DOM, CloudFunc; } /* Функция создаёт картинку загрузки */ - this.loading = function(){ + this.loading = function() { return getImage('loading'); }; /* Функция создаёт картинку ошибки загрузки */ - this.error = function(){ + this.error = function() { return getImage('error'); }; }, @@ -38,7 +38,7 @@ var CloudCmd, Util, DOM, CloudFunc; * Function shows loading spinner * pPosition = {top: true}; */ - this.showLoad = function(pPosition){ + this.showLoad = function(pPosition) { var lRet_b, lLoadingImage = lImages.loading(), lErrorImage = lImages.error(); @@ -67,14 +67,14 @@ var CloudCmd, Util, DOM, CloudFunc; /** * hide load image */ - this.hideLoad = function(){ + this.hideLoad = function() { DOM.hide( lImages.loading() ); }; /** * show error image (usualy after error on ajax request) */ - this.showError = function(jqXHR, textStatus, errorThrown){ + this.showError = function(jqXHR, textStatus, errorThrown) { var lLoadingImage = lImages.loading(), lErrorImage = lImages.error(), lResponse = jqXHR.responseText, @@ -106,8 +106,8 @@ var CloudCmd, Util, DOM, CloudFunc; }; }, - RESTfullProto = function(){ - this.delete = function(pUrl, pData, pCallBack, pQuery){ + RESTfullProto = function() { + this.delete = function(pUrl, pData, pCallBack, pQuery) { sendRequest({ method : 'DELETE', url : CloudFunc.FS + pUrl + (pQuery || ''), @@ -117,7 +117,7 @@ var CloudCmd, Util, DOM, CloudFunc; }); }; - this.save = function(pUrl, pData, pCallBack, pQuery){ + this.save = function(pUrl, pData, pCallBack, pQuery) { sendRequest({ method : 'PUT', url : CloudFunc.FS + pUrl + (pQuery || ''), @@ -127,7 +127,7 @@ var CloudCmd, Util, DOM, CloudFunc; }); }; - this.read = function(pUrl, pCallBack, pQuery){ + this.read = function(pUrl, pCallBack, pQuery) { sendRequest({ method : 'GET', url : CloudFunc.FS + pUrl + (pQuery || ''), @@ -135,7 +135,7 @@ var CloudCmd, Util, DOM, CloudFunc; }); }; - this.cp = function(pData, pCallBack){ + this.cp = function(pData, pCallBack) { sendRequest({ method : 'PUT', url : '/cp', @@ -144,7 +144,7 @@ var CloudCmd, Util, DOM, CloudFunc; }); }; - this.zip = function(pData, pCallBack){ + this.zip = function(pData, pCallBack) { sendRequest({ method : 'PUT', url : '/zip', @@ -153,7 +153,7 @@ var CloudCmd, Util, DOM, CloudFunc; }); }; - this.mv = function(pData, pCallBack){ + this.mv = function(pData, pCallBack) { sendRequest({ method : 'PUT', url : '/mv', @@ -162,13 +162,13 @@ var CloudCmd, Util, DOM, CloudFunc; }); }; - function sendRequest(pParams){ + function sendRequest(pParams) { var lRet = Util.checkObjTrue(pParams, ['method']); - if (lRet){ + if (lRet) { var p = pParams; Images.showLoad( p.imgPosition ); - CloudCmd.getConfig(function(pConfig){ + CloudCmd.getConfig(function(pConfig) { var lData; if ( Util.isString(p.url) ) @@ -198,17 +198,17 @@ var CloudCmd, Util, DOM, CloudFunc; } }, - DOMTreeProto = function(){ + DOMTreeProto = function() { /** * add class to element * * @param pElement * @param pClass */ - this.addClass = function(pElement, pClass){ + this.addClass = function(pElement, pClass) { var lRet; - if (pElement){ + if (pElement) { var lClassList = pElement.classList; lRet = !this.isContainClass(pElement, pClass); @@ -225,7 +225,7 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pElement * @param pClass */ - this.isContainClass = function(pElement, pClass){ + this.isContainClass = function(pElement, pClass) { var lRet, lClassList = pElement && pElement.classList; @@ -240,7 +240,7 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pTag - className * @param pElement - element */ - this.getByTag = function(pTag, pElement){ + this.getByTag = function(pTag, pElement) { return (pElement || document).getElementsByTagName(pTag); }; @@ -249,7 +249,7 @@ var CloudCmd, Util, DOM, CloudFunc; * @param Id - className * @param pElement - element */ - this.getById = function(pId, pElement){ + this.getById = function(pId, pElement) { return (pElement || document).getElementById(pId); }; @@ -258,7 +258,7 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pClass - className * @param pElement - element */ - this.getByClass = function(pClass, pElement){ + this.getByClass = function(pClass, pElement) { return (pElement || document).getElementsByClassName(pClass); }; @@ -267,16 +267,16 @@ var CloudCmd, Util, DOM, CloudFunc; * * @param pElement */ - this.hide = function(pElement){ + this.hide = function(pElement) { return this.addClass(pElement, 'hidden'); }; - this.show = function(pElement){ + this.show = function(pElement) { this.removeClass(pElement, 'hidden'); }; }, - EventsProto = function(){ + EventsProto = function() { var Events = this, ADD = true, REMOVE = false; @@ -289,7 +289,7 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pUseCapture * @param pElement {document by default} */ - this.add = function(pType, pListener, pElement, pUseCapture){ + this.add = function(pType, pListener, pElement, pUseCapture) { return process( ADD, pType, @@ -307,9 +307,9 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pUseCapture * @param pElement {document by default} */ - this.addOneTime = function(pType, pListener, pElement, pUseCapture){ + this.addOneTime = function(pType, pListener, pElement, pUseCapture) { var lRet = this, - lOneTime = function (pEvent){ + lOneTime = function (pEvent) { lRet.remove(pType, lOneTime, pElement, pUseCapture); pListener(pEvent); }; @@ -327,7 +327,7 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pUseCapture * @param pElement {document by default} */ - this.remove = function(pType, pListener, pElement, pUseCapture){ + this.remove = function(pType, pListener, pElement, pUseCapture) { return process( REMOVE, pType, @@ -344,7 +344,7 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pListener * @param pUseCapture */ - this.addKey = function(pListener, pElement, pUseCapture){ + this.addKey = function(pListener, pElement, pUseCapture) { return this.add('keydown', pListener, pElement, pUseCapture); }; @@ -354,11 +354,11 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pListener * @param pUseCapture */ - this.addClick = function(pListener, pElement, pUseCapture){ + this.addClick = function(pListener, pElement, pUseCapture) { return this.add('click', pListener, pElement, pUseCapture); }; - this.addContextMenu = function(pListener, pElement, pUseCapture){ + this.addContextMenu = function(pListener, pElement, pUseCapture) { return this.add('contextmenu', pListener, pElement, pUseCapture); }; @@ -368,7 +368,7 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pListener * @param pUseCapture */ - this.addError = function(pListener, pElement, pUseCapture){ + this.addError = function(pListener, pElement, pUseCapture) { return this.add('error', pListener, pElement, pUseCapture); }; @@ -378,7 +378,7 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pEventName * @param pKeyCode - not necessarily */ - this.create = function(pEventName, pKeyCode){ + this.create = function(pEventName, pKeyCode) { var lEvent = document.createEvent('Event'); lEvent.initEvent(pEventName, true, true); @@ -386,7 +386,7 @@ var CloudCmd, Util, DOM, CloudFunc; if (pKeyCode) lEvent.keyCode = pKeyCode; - lEvent.isDefaultPrevented = function(){ + lEvent.isDefaultPrevented = function() { return this.defaultPrevented; }; @@ -399,7 +399,7 @@ var CloudCmd, Util, DOM, CloudFunc; * * @param pKeyCode */ - this.createKey = function(pKeyCode){ + this.createKey = function(pKeyCode) { return this.create('keydown', pKeyCode); }; @@ -408,7 +408,7 @@ var CloudCmd, Util, DOM, CloudFunc; * * @param pKeyCode */ - this.createClick = function(){ + this.createClick = function() { return this.create('click'); }; @@ -417,7 +417,7 @@ var CloudCmd, Util, DOM, CloudFunc; * * @param pKeyCode */ - this.createDblClick = function(){ + this.createDblClick = function() { return this.create('dblclick'); }; @@ -426,7 +426,7 @@ var CloudCmd, Util, DOM, CloudFunc; * * @param pEvent */ - this.dispatch = function(pEvent, pElement){ + this.dispatch = function(pEvent, pElement) { var lRet, lEvent; if (Util.isString(pEvent)) @@ -443,7 +443,7 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pKeyCode * @param pElement */ - this.dispatchKey = function(pKeyCode, pElement){ + this.dispatchKey = function(pKeyCode, pElement) { var lEvent = this.createKey(pKeyCode), lRet = this.dispatch(lEvent, pElement); @@ -455,7 +455,7 @@ var CloudCmd, Util, DOM, CloudFunc; * * @param pElement */ - this.dispatchClick = function(pElement){ + this.dispatchClick = function(pElement) { var lEvent = this.createClick(), lRet = this.dispatch(lEvent, pElement); @@ -467,14 +467,14 @@ var CloudCmd, Util, DOM, CloudFunc; * * @param pElement */ - this.dispatchDblClick = function(pElement){ + this.dispatchDblClick = function(pElement) { var lEvent = this.createDblClick(), lRet = this.dispatch(lEvent, pElement); return lRet; }; - function process(pAdd, pType, pListener, pElement, pUseCapture){ + function process(pAdd, pType, pListener, pElement, pUseCapture) { var i, n, lElement = (pElement || window), @@ -490,14 +490,14 @@ var CloudCmd, Util, DOM, CloudFunc; lEventProcess = lEventProcess.bind(lElement); - if (lRet){ + if (lRet) { if (Util.isString(pType) ) lEventProcess( pType, pListener, pUseCapture ); - else if (Util.isArray(pType)) + else if (Util.isArray(pType)) for (i = 0, n = pType.length; i < n; i++) lProcess( pType[i], @@ -505,7 +505,7 @@ var CloudCmd, Util, DOM, CloudFunc; pElement, pUseCapture ); - else if (Util.isObject(pType)){ + else if (Util.isObject(pType)) { if (pListener) pElement = pListener; @@ -520,12 +520,12 @@ var CloudCmd, Util, DOM, CloudFunc; } } }, - CacheProto = function(){ + CacheProto = function() { /* приватный переключатель возможности работы с кэшем */ var CacheAllowed; /* функция проверяет возможно ли работать с кэшем каким-либо образом */ - this.isAllowed = function(){ + this.isAllowed = function() { var lRet = CacheAllowed && window.localStorage; return lRet; }; @@ -533,14 +533,14 @@ var CloudCmd, Util, DOM, CloudFunc; /** * allow cache usage */ - this.setAllowed = function(pAllowd){ + this.setAllowed = function(pAllowd) { CacheAllowed = pAllowd; return pAllowd; }; /** remove element */ - this.remove = function(pItem){ + this.remove = function(pItem) { var lRet = this; if (CacheAllowed) @@ -553,7 +553,7 @@ var CloudCmd, Util, DOM, CloudFunc; * в нём есть нужная нам директория - * записываем данные в него */ - this.set = function(pName, pData){ + this.set = function(pName, pData) { var lRet = this; if (CacheAllowed && pName && pData) @@ -563,7 +563,7 @@ var CloudCmd, Util, DOM, CloudFunc; }, /** Если доступен Cache принимаем из него данные*/ - this.get = function(pName){ + this.get = function(pName) { var lRet; if (CacheAllowed) @@ -573,7 +573,7 @@ var CloudCmd, Util, DOM, CloudFunc; }, /* get all cache from local storage */ - this.getAll = function(){ + this.getAll = function() { var lRet = null; if (CacheAllowed) @@ -583,7 +583,7 @@ var CloudCmd, Util, DOM, CloudFunc; }; /** функция чистит весь кэш для всех каталогов*/ - this.clear = function(){ + this.clear = function() { var lRet = this; if (CacheAllowed) @@ -593,7 +593,7 @@ var CloudCmd, Util, DOM, CloudFunc; }; }, - LoaderProto = function(){ + LoaderProto = function() { var XMLHTTP; /** @@ -602,10 +602,10 @@ var CloudCmd, Util, DOM, CloudFunc; * * Example: http://domain.com/1.js -> 1_js */ - this.getIdBySrc = function(pSrc){ + this.getIdBySrc = function(pSrc) { var lRet = Util.isString(pSrc); - if (lRet){ + if (lRet) { var lNum = pSrc.lastIndexOf('/') + 1, lSub = pSrc.substr(pSrc, lNum), lID = Util.removeStrOneTime(pSrc, lSub ); @@ -625,9 +625,9 @@ var CloudCmd, Util, DOM, CloudFunc; * * @param pParams */ - this.ajax = function(pParams){ + this.ajax = function(pParams) { var lRet = Util.checkObjTrue(pParams, ['url', 'success']); - if (lRet){ + if (lRet) { var p = pParams, lType = p.type || p.method || 'GET'; @@ -637,12 +637,12 @@ var CloudCmd, Util, DOM, CloudFunc; XMLHTTP.open(lType, pParams.url, true); XMLHTTP.send(p.data); - XMLHTTP.onreadystatechange = function(pEvent){ - if (XMLHTTP.readyState === 4 /* Complete */){ + XMLHTTP.onreadystatechange = function(pEvent) { + if (XMLHTTP.readyState === 4 /* Complete */) { var lJqXHR = pEvent.target, lType = XMLHTTP.getResponseHeader('content-type'); - if (XMLHTTP.status === 200 /* OK */){ + if (XMLHTTP.status === 200 /* OK */) { var lData = lJqXHR.response; /* If it's json - parse it as json */ @@ -675,23 +675,23 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pParams_a * @param pFunc - onload function */ - this.anyLoadOnLoad = function(pParams_a, pFunc){ + this.anyLoadOnLoad = function(pParams_a, pFunc) { var lRet = this; if ( Util.isArray(pParams_a) ) { var lParam = pParams_a.pop(), - lFunc = function(){ + lFunc = function() { Loader.anyLoadOnLoad(pParams_a, pFunc); }; if ( Util.isString(lParam) ) lParam = { src : lParam }; - else if ( Util.isArray(lParam) ){ + else if ( Util.isArray(lParam) ) { this.anyLoadInParallel(lParam, lFunc); } - if (lParam && !lParam.func){ + if (lParam && !lParam.func) { lParam.func = lFunc; this.anyload(lParam); @@ -711,25 +711,25 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pParams_a * @param pFunc - onload function */ - this.anyLoadInParallel = function(pParams_a, pFunc){ + this.anyLoadInParallel = function(pParams_a, pFunc) { var lRet = this, lDone = [], - lDoneFunc = function (pCallBack){ + lDoneFunc = function (pCallBack) { Util.exec(pCallBack); if ( !lDone.pop() ) Util.exec(pFunc); }; - if ( !Util.isArray(pParams_a) ){ + if ( !Util.isArray(pParams_a) ) { pParams_a = [pParams_a]; } - for(var i = 0, n = pParams_a.length; i < n; i++){ + for(var i = 0, n = pParams_a.length; i < n; i++) { var lParam = pParams_a.pop(); - if (lParam){ + if (lParam) { lDone.push(i); if (Util.isString(lParam) ) @@ -753,7 +753,7 @@ var CloudCmd, Util, DOM, CloudFunc; * src', - путь к файлу * func, - обьект, содержаий одну из функций * или сразу две onload и onerror - * {onload: function(){}, onerror: function();} + * {onload: function() {}, onerror: function();} * style, * id, * element, @@ -763,7 +763,7 @@ var CloudCmd, Util, DOM, CloudFunc; * not_append - false by default * } */ - this.anyload = function(pParams_o){ + this.anyload = function(pParams_o) { var i, n, lElements_a; if ( !pParams_o ) return; @@ -772,7 +772,7 @@ var CloudCmd, Util, DOM, CloudFunc; * processing every of params * and quit */ - if ( Util.isArray(pParams_o) ){ + if ( Util.isArray(pParams_o) ) { lElements_a = []; for(i = 0, n = pParams_o.length; i < n ; i++) lElements_a[i] = this.anyload(pParams_o[i]); @@ -793,7 +793,7 @@ var CloudCmd, Util, DOM, CloudFunc; lStyle = pParams_o.style, lNotAppend = pParams_o.not_append; - if ( Util.isObject(lFunc) ){ + if ( Util.isObject(lFunc) ) { lOnError = lFunc.onerror; lFunc = lFunc.onload; } @@ -804,12 +804,12 @@ var CloudCmd, Util, DOM, CloudFunc; var lElement = DOMTree.getById(lID); /* если скрипт еще не загружен */ - if (!lElement){ - if (!lName && lSrc){ + if (!lElement) { + if (!lName && lSrc) { var lDot = lSrc.lastIndexOf('.'), lExt = lSrc.substr(lDot); - switch(lExt){ + switch(lExt) { case '.js': lName = 'script'; break; @@ -831,7 +831,7 @@ var CloudCmd, Util, DOM, CloudFunc; if(lSrc) { /* if work with css use href */ - if (lName === 'link'){ + if (lName === 'link') { lElement.href = lSrc; lElement.rel = 'stylesheet'; }else @@ -843,14 +843,14 @@ var CloudCmd, Util, DOM, CloudFunc; * * if object - then onload and onerror */ - var lLoad = function(pEvent){ + var lLoad = function(pEvent) { Events.remove('load', lLoad, lElement); Events.remove('error', lError, lElement); Util.exec(lFunc, pEvent); }, - lError = function(){ + lError = function() { lParent.removeChild(lElement); Images.showError({ @@ -898,7 +898,7 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pSrc * @param pFunc */ - this.jsload = function(pSrc, pFunc){ + this.jsload = function(pSrc, pFunc) { var lRet = this.anyload({ name : 'script', src : pSrc, @@ -911,8 +911,8 @@ var CloudCmd, Util, DOM, CloudFunc; /** * returns jsload functions */ - this.retJSLoad = function(pSrc, pFunc){ - var lRet = function(){ + this.retJSLoad = function(pSrc, pFunc) { + var lRet = function() { return this.jsload(pSrc, pFunc); }; @@ -926,7 +926,7 @@ var CloudCmd, Util, DOM, CloudFunc; * образом: {src: ' ',func: '', id: '', element: '', inner: ''} * все параметры опциональны */ - this.cssSet = function(pParams_o){ + this.cssSet = function(pParams_o) { pParams_o.name = 'style'; pParams_o.parent = pParams_o.parent || document.head; @@ -939,9 +939,9 @@ var CloudCmd, Util, DOM, CloudFunc; * образом: {src: ' ',func: '', id: '', element: '', inner: ''} * все параметры опциональны */ - this.cssLoad = function(pParams_o){ - if ( Util.isArray(pParams_o) ){ - for(var i = 0, n = pParams_o.length; i < n; i++){ + this.cssLoad = function(pParams_o) { + if ( Util.isArray(pParams_o) ) { + for(var i = 0, n = pParams_o.length; i < n; i++) { pParams_o[i].name = 'link'; pParams_o[i].parent = pParams_o.parent || document.head; } @@ -962,7 +962,7 @@ var CloudCmd, Util, DOM, CloudFunc; * load jquery from google cdn or local copy * @param pParams */ - this.jquery = function(pParams){ + this.jquery = function(pParams) { if (!pParams) pParams = {}; /* загружаем jquery: */ @@ -973,7 +973,7 @@ var CloudCmd, Util, DOM, CloudFunc; }; }, - CmdProto = function(){ + CmdProto = function() { var Cmd = this, CURRENT_FILE = 'current-file', SELECTED_FILE = 'selected-file', @@ -984,7 +984,7 @@ var CloudCmd, Util, DOM, CloudFunc; * * @pCurrentFile */ - function unsetCurrentFile(pCurrentFile){ + function unsetCurrentFile(pCurrentFile) { var lRet = DOM.isCurrentFile(pCurrentFile); if (lRet) @@ -998,11 +998,11 @@ var CloudCmd, Util, DOM, CloudFunc; * load jquery from google cdn or local copy * @param pCallBack */ - this.jqueryLoad = function(pCallBack){ + this.jqueryLoad = function(pCallBack) { Loader.jquery({ onload: pCallBack, - onerror: function(){ + onerror: function() { Loader.jsload('/lib/client/jquery.js'); /* if could not load jquery from google server @@ -1024,7 +1024,7 @@ var CloudCmd, Util, DOM, CloudFunc; * load socket.io * @param pCallBack */ - this.socketLoad = function(pCallBack){ + this.socketLoad = function(pCallBack) { Loader.jsload('/lib/client/socket.js', pCallBack); }; @@ -1032,7 +1032,7 @@ var CloudCmd, Util, DOM, CloudFunc; * create new folder * */ - this.promptNewDir = function(){ + this.promptNewDir = function() { Cmd.promptNewFile('directory', '?dir'); }; @@ -1042,7 +1042,7 @@ var CloudCmd, Util, DOM, CloudFunc; * @pTypeName * @pType */ - this.promptNewFile = function(pTypeName, pType){ + this.promptNewFile = function(pTypeName, pType) { var lName = Cmd.getCurrentName(), lDir = Cmd.getCurrentDirPath(), lMsg = 'New ' + pTypeName || 'File', @@ -1061,7 +1061,7 @@ var CloudCmd, Util, DOM, CloudFunc; * zip file * */ - this.zipFile = function(){ + this.zipFile = function() { var lName = Cmd.getCurrentName(), lDir = Cmd.getCurrentDirPath(), lPath = lDir + lName, @@ -1079,7 +1079,7 @@ var CloudCmd, Util, DOM, CloudFunc; * * @pCurrentFile */ - this.promptDeleteSelected = function(pCurrentFile){ + this.promptDeleteSelected = function(pCurrentFile) { var lRet, lCurrent, lQuery, lMsg, lName = '', @@ -1092,7 +1092,7 @@ var CloudCmd, Util, DOM, CloudFunc; if ( !Cmd.isCurrentFile(pCurrentFile) ) pCurrentFile = null; - if (n > 1){ + if (n > 1) { for (i = 0; i < 5 && i < n; i++) lName += '\n' + lSelected[i]; @@ -1112,7 +1112,7 @@ var CloudCmd, Util, DOM, CloudFunc; lIsDir = Cmd.isCurrentIsDir(lCurrent); - if (lIsDir){ + if (lIsDir) { lQuery = '?dir'; lType ='directory'; } @@ -1141,7 +1141,7 @@ var CloudCmd, Util, DOM, CloudFunc; } if (lCurrent || lSelected) - RESTfull.delete(lUrl, lSelected, function(){ + RESTfull.delete(lUrl, lSelected, function() { if (n > 1) DOM.deleteSelected(lFiles); else @@ -1164,7 +1164,7 @@ var CloudCmd, Util, DOM, CloudFunc; /** * get current direcotory name */ - this.getCurrentDirName = function(){ + this.getCurrentDirName = function() { var lRet, lSubstr, lPanel = this.getPanel(), @@ -1183,7 +1183,7 @@ var CloudCmd, Util, DOM, CloudFunc; /** * get current direcotory path */ - this.getCurrentDirPath = function(pPanel){ + this.getCurrentDirPath = function(pPanel) { var lPanel = pPanel || this.getPanel(), lPath = this.getByClass('path', lPanel)[0], lRet; @@ -1197,7 +1197,7 @@ var CloudCmd, Util, DOM, CloudFunc; /** * get current direcotory path */ - this.getNotCurrentDirPath = function(){ + this.getNotCurrentDirPath = function() { var lPanel = this.getPanel(true), lPath = this.getByClass('path', lPanel)[0], lRet; @@ -1213,7 +1213,7 @@ var CloudCmd, Util, DOM, CloudFunc; * * @pCurrentFile */ - this.getCurrentFile = function(){ + this.getCurrentFile = function() { var lRet = this.getByClass( CURRENT_FILE )[0]; return lRet; @@ -1222,7 +1222,7 @@ var CloudCmd, Util, DOM, CloudFunc; /** * get current file by name */ - this.getCurrentFileByName = function(pName){ + this.getCurrentFileByName = function(pName) { var lRet, lPanel, lName; lPanel = DOM.getPanel(); @@ -1237,7 +1237,7 @@ var CloudCmd, Util, DOM, CloudFunc; * * @pCurrentFile */ - this.getSelectedFiles = function(){ + this.getSelectedFiles = function() { var lRet = this.getByClass(SELECTED_FILE); return lRet.length ? lRet : null; @@ -1247,7 +1247,7 @@ var CloudCmd, Util, DOM, CloudFunc; * get size * @pCurrentFile */ - this.getCurrentSize = function(pCurrentFile){ + this.getCurrentSize = function(pCurrentFile) { var lRet, lCurrent = pCurrentFile || this.getCurrentFile(), lSize = this.getByClass('size', lCurrent); @@ -1262,7 +1262,7 @@ var CloudCmd, Util, DOM, CloudFunc; * get size * @pCurrentFile */ - this.loadCurrentSize = function(pCallBack, pCurrent){ + this.loadCurrentSize = function(pCallBack, pCurrent) { var lRet, lCurrent = pCurrent || this.getCurrentFile(), lLink = this.getCurrentPath(lCurrent), @@ -1270,7 +1270,7 @@ var CloudCmd, Util, DOM, CloudFunc; /* если это папка - возвращаем слово dir вместо размера*/ if (lName !== '..') - RESTfull.read(lLink, function(pSize){ + RESTfull.read(lLink, function(pSize) { DOM.setCurrentSize(pSize, lCurrent); Util.exec(pCallBack, lCurrent); }, '?size'); @@ -1282,7 +1282,7 @@ var CloudCmd, Util, DOM, CloudFunc; * set size * @pCurrentFile */ - this.setCurrentSize = function(pSize, pCurrentFile){ + this.setCurrentSize = function(pSize, pCurrentFile) { var lCurrent = pCurrentFile || this.getCurrentFile(), lSizeElement = this.getByClass('size', lCurrent), lSize = CloudFunc.getShortSize(pSize); @@ -1294,7 +1294,7 @@ var CloudCmd, Util, DOM, CloudFunc; /** * @pCurrentFile */ - this.getCurrentMode = function(pCurrentFile){ + this.getCurrentMode = function(pCurrentFile) { var lRet, lCurrent = pCurrentFile || this.getCurrentFile(), lMode = this.getByClass('mode', lCurrent); @@ -1309,13 +1309,13 @@ var CloudCmd, Util, DOM, CloudFunc; * @pCallBack - callback function or data struct {sucess, error} * @pCurrentFile */ - this.getCurrentFileContent = function(pParams, pCurrentFile){ + this.getCurrentFileContent = function(pParams, pCurrentFile) { var lRet, lCurrentFile = pCurrentFile ? pCurrentFile : this.getCurrentFile(), lParams = pParams ? pParams : {}, lPath = this.getCurrentPath(lCurrentFile), lErrorWas = pParams.error, - lError = function(jqXHR){ + lError = function(jqXHR) { Util.exec(lErrorWas); Images.showError(jqXHR); }; @@ -1340,15 +1340,15 @@ var CloudCmd, Util, DOM, CloudFunc; /** * unified way to get current file content * - * @pCallBack - function({data, name}){} + * @pCallBack - function({data, name}) {} * @pCurrentFile */ - this.getCurrentData = function(pCallBack, pCurrentFile){ + this.getCurrentData = function(pCallBack, pCurrentFile) { var lParams, lCurrentFile = pCurrentFile ? pCurrentFile : this.getCurrentFile(), - lFunc = function(pData){ + lFunc = function(pData) { var lName = DOM.getCurrentName(lCurrentFile); - if ( Util.isObject(pData) ){ + if ( Util.isObject(pData) ) { pData = Util.stringifyJSON(pData); var lExt = '.json'; @@ -1377,7 +1377,7 @@ var CloudCmd, Util, DOM, CloudFunc; /** * unified way to get RefreshButton */ - this.getRefreshButton = function(){ + this.getRefreshButton = function() { if (!CloudFunc) console.trace(); @@ -1392,11 +1392,11 @@ var CloudCmd, Util, DOM, CloudFunc; /** * unified way to set current file */ - this.setCurrentFile = function(pCurrentFile){ + this.setCurrentFile = function(pCurrentFile) { var lRet, lCurrentFileWas = this.getCurrentFile(); - if (pCurrentFile){ + if (pCurrentFile) { if (pCurrentFile.className === 'path') pCurrentFile = pCurrentFile.nextSibling; @@ -1421,7 +1421,7 @@ var CloudCmd, Util, DOM, CloudFunc; * select current file * @param pCurrent */ - this.setSelectedFile = function(pCurrent){ + this.setSelectedFile = function(pCurrent) { var lCurrent = pCurrent || this.getCurrentFile(), lRet = this.addClass(pCurrent, SELECTED_FILE); @@ -1435,7 +1435,7 @@ var CloudCmd, Util, DOM, CloudFunc; * unselect current file * @param pCurrent */ - this.unsetSelectedFile = function(pCurrent){ + this.unsetSelectedFile = function(pCurrent) { var lCurrent = pCurrent || this.getCurrentFile(), lRet = this.removeClass(lCurrent, SELECTED_FILE); @@ -1445,7 +1445,7 @@ var CloudCmd, Util, DOM, CloudFunc; /** * setting history wrapper */ - this.setHistory = function(pData, pTitle, pUrl){ + this.setHistory = function(pData, pTitle, pUrl) { var lRet = window.history; if (lRet) @@ -1458,7 +1458,7 @@ var CloudCmd, Util, DOM, CloudFunc; * set onclick handler on buttons f1-f10 * @param pKey - 'f1'-'f10' */ - this.setButtonKey = function(pKey, pFunc){ + this.setButtonKey = function(pKey, pFunc) { Events.addClick(pFunc, CloudCmd.KeysPanel[pKey]); }; @@ -1469,7 +1469,7 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pName */ - this.setTitle = function(pName){ + this.setTitle = function(pName) { if (!Title) Title = DOMTree.getByTag('title')[0] || Loader.anyload({ @@ -1488,7 +1488,7 @@ var CloudCmd, Util, DOM, CloudFunc; * * @param pCurrentFile */ - this.isCurrentFile = function(pCurrent){ + this.isCurrentFile = function(pCurrent) { var lRet; if ( pCurrent ) @@ -1502,7 +1502,7 @@ var CloudCmd, Util, DOM, CloudFunc; * * @param pCurrentFile */ - this.isSelected = function(pSelected){ + this.isSelected = function(pSelected) { var lRet; if ( pSelected ) @@ -1516,7 +1516,7 @@ var CloudCmd, Util, DOM, CloudFunc; * * @param pCurrentFile */ - this.isCurrentIsDir = function(pCurrent){ + this.isCurrentIsDir = function(pCurrent) { var lCurrent = pCurrent || this.getCurrentFile(), lFileType = this.getByClass('mini-icon', lCurrent)[0], lRet = this.isContainClass(lFileType, 'directory'); @@ -1530,7 +1530,7 @@ var CloudCmd, Util, DOM, CloudFunc; * * @param pCurrentFile - current file by default */ - this.getCurrentLink = function(pCurrentFile){ + this.getCurrentLink = function(pCurrentFile) { var lLink = this.getByTag( 'a', pCurrentFile || this.getCurrentFile() ), lRet = lLink.length > 0 ? lLink[0] : -1; @@ -1543,7 +1543,7 @@ var CloudCmd, Util, DOM, CloudFunc; * * @param pCurrentFile - current file by default */ - this.getCurrentPath = function(pCurrentFile){ + this.getCurrentPath = function(pCurrentFile) { var lCurrent = pCurrentFile || this.getCurrentFile(), lPath = this.getCurrentLink( lCurrent ).href; @@ -1559,7 +1559,7 @@ var CloudCmd, Util, DOM, CloudFunc; * * @param pCurrentFile */ - this.getCurrentName = function(pCurrentFile){ + this.getCurrentName = function(pCurrentFile) { var lCurrent = pCurrentFile || this.getCurrentFile(), lLink = this.getCurrentLink( lCurrent ); @@ -1569,11 +1569,11 @@ var CloudCmd, Util, DOM, CloudFunc; return lLink; }; - this.getSelectedNames = function(pSelected){ + this.getSelectedNames = function(pSelected) { var lSelected = pSelected || this.getSelectedFiles(), lRet = lSelected ? [] : null; - if (lRet){ + if (lRet) { var lFirst = lSelected[0], lName = this.getCurrentName( lFirst ); @@ -1591,7 +1591,7 @@ var CloudCmd, Util, DOM, CloudFunc; * * @param pCurrentFile */ - this.setCurrentName = function(pName, pCurrentFile){ + this.setCurrentName = function(pName, pCurrentFile) { var lLink = this.getCurrentLink( pCurrentFile ), lDir = this.getCurrentDirName() + '/'; @@ -1604,18 +1604,18 @@ var CloudCmd, Util, DOM, CloudFunc; /** function getting FM * @param pPanel_o = {active: true} */ - this.getFM = function(){ + this.getFM = function() { return this.getPanel().parentElement; }; /** function getting panel active, or passive * @param pPanel_o = {active: true} */ - this.getPanel = function(pActive){ + this.getPanel = function(pActive) { var lPanel = this.getCurrentFile().parentElement; /* if {active : false} getting passive panel */ - if (pActive && !pActive.active){ + if (pActive && !pActive.active) { var lId = lPanel.id === 'left' ? 'right' : 'left'; lPanel = this.getById(lId); } @@ -1635,7 +1635,7 @@ var CloudCmd, Util, DOM, CloudFunc; }; /** prevent default event */ - this.preventDefault = function(pEvent){ + this.preventDefault = function(pEvent) { var lRet, lPreventDefault = pEvent && pEvent.preventDefault, lFunc = Util.bind(lPreventDefault, pEvent); @@ -1648,7 +1648,7 @@ var CloudCmd, Util, DOM, CloudFunc; /** * shows panel right or left (or active) */ - this.showPanel = function(pActive){ + this.showPanel = function(pActive) { var lRet = true, lPanel = this.getPanel(pActive); @@ -1663,7 +1663,7 @@ var CloudCmd, Util, DOM, CloudFunc; /** * hides panel right or left (or active) */ - this.hidePanel = function(pActive){ + this.hidePanel = function(pActive) { var lRet = false, lPanel = this.getPanel(pActive); @@ -1677,7 +1677,7 @@ var CloudCmd, Util, DOM, CloudFunc; * open window with URL * @param pUrl */ - this.openWindow = function(pUrl){ + this.openWindow = function(pUrl) { var left = 140, top = 187, width = 1000, @@ -1700,7 +1700,7 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pChild * @param pElement */ - this.remove = function(pChild, pElement){ + this.remove = function(pChild, pElement) { return (pElement || document.body).removeChild(pChild); }; @@ -1709,7 +1709,7 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pElement * @param pClass */ - this.removeClass = function(pElement, pClass){ + this.removeClass = function(pElement, pClass) { var lRet_b = true, lClassList = pElement.classList; @@ -1726,12 +1726,12 @@ var CloudCmd, Util, DOM, CloudFunc; * remove current file from file table * @pCurrent */ - this.deleteCurrent = function(pCurrent, pNextFile, pPreviousFile, pNotSet){ + this.deleteCurrent = function(pCurrent, pNextFile, pPreviousFile, pNotSet) { var lCurrent = pCurrent || Cmd.getCurrentFile(), lParent = lCurrent && lCurrent.parentElement, lName = Cmd.getCurrentName(lCurrent); - if (lCurrent && lParent && lName !== '..'){ + if (lCurrent && lParent && lName !== '..') { var lNext = pNextFile || lCurrent.nextSibling, lPrevious = pPreviousFile || lCurrent.previousSibling; @@ -1751,10 +1751,10 @@ var CloudCmd, Util, DOM, CloudFunc; * remove selected files from file table * @Selected */ - this.deleteSelected = function(pSelected){ + this.deleteSelected = function(pSelected) { var lSelected = pSelected || this.getSelectedFiles(); - if (lSelected){ + if (lSelected) { var n = lSelected.length, lLast = n-1, lNext = lSelected[lLast].nextSibling, @@ -1775,7 +1775,7 @@ var CloudCmd, Util, DOM, CloudFunc; * * @pCurrent */ - this.renameCurrent = function(pCurrentFile){ + this.renameCurrent = function(pCurrentFile) { if ( !Cmd.isCurrentFile(pCurrentFile) ) pCurrentFile = null; @@ -1784,13 +1784,13 @@ var CloudCmd, Util, DOM, CloudFunc; lTo = prompt('Rename', lFrom) || lFrom, lDirPath = Cmd.getCurrentDirPath(); - if ( !Util.strCmp(lFrom, lTo) ){ + if ( !Util.strCmp(lFrom, lTo) ) { var lFiles = { from : lDirPath + lFrom, to : lDirPath + lTo }; - RESTfull.mv(lFiles, function(){ + RESTfull.mv(lFiles, function() { DOM.setCurrentName(lTo, lCurrent); }); } @@ -1801,7 +1801,7 @@ var CloudCmd, Util, DOM, CloudFunc; * * @pCurrent */ - this.moveCurrent = function(pCurrentFile){ + this.moveCurrent = function(pCurrentFile) { if ( !Cmd.isCurrentFile(pCurrentFile) ) pCurrentFile = null; @@ -1812,13 +1812,13 @@ var CloudCmd, Util, DOM, CloudFunc; lToPath = prompt( 'Rename/Move file "' + lName + '"', lToPath ); - if ( lToPath && !Util.strCmp(lFromPath, lToPath) ){ + if ( lToPath && !Util.strCmp(lFromPath, lToPath) ) { var lFiles = { from : lFromPath, to : lToPath }; - RESTfull.mv(lFiles, function(){ + RESTfull.mv(lFiles, function() { DOM.deleteCurrent(lCurrent); var lPanel = DOM.getPanel(true), @@ -1835,7 +1835,7 @@ var CloudCmd, Util, DOM, CloudFunc; * * @pCurrent */ - this.copyCurrent = function(pCurrentFile){ + this.copyCurrent = function(pCurrentFile) { if ( !Cmd.isCurrentFile(pCurrentFile) ) pCurrentFile = null; @@ -1845,13 +1845,13 @@ var CloudCmd, Util, DOM, CloudFunc; lToPath = Cmd.getNotCurrentDirPath() + lName; lToPath = prompt( 'Copy file "' + lName + '" to', lToPath ); - if ( lToPath && !Util.strCmp(lFromPath, lToPath) ){ + if ( lToPath && !Util.strCmp(lFromPath, lToPath) ) { var lFiles = { from : lFromPath, to : lToPath }; - RESTfull.cp(lFiles, function(){ + RESTfull.cp(lFiles, function() { var lPanel = DOM.getPanel(true), lDotDot = DOM.getById( '..(' + lPanel.id + ')'); @@ -1866,7 +1866,7 @@ var CloudCmd, Util, DOM, CloudFunc; * (native suporte by webkit only) * @param pElement */ - this.scrollIntoViewIfNeeded = function(pElement){ + this.scrollIntoViewIfNeeded = function(pElement) { var lRet = pElement && pElement.scrollIntoViewIfNeeded; if (lRet) @@ -1876,7 +1876,7 @@ var CloudCmd, Util, DOM, CloudFunc; }; /* scroll on one page*/ - this.scrollByPages = function(pElement, pPages){ + this.scrollByPages = function(pElement, pPages) { var lRet = pElement && pElement.scrollByPages && pPages; if (lRet) @@ -1888,7 +1888,7 @@ var CloudCmd, Util, DOM, CloudFunc; /** * function gets time */ - this.getTime = function(){ + this.getTime = function() { var lRet, lDate = new Date(), lHours = lDate.getHours(), From 9265297fc581b0d3616bfbd7c9fb27e00ca1509f Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 30 Aug 2013 10:59:21 +0300 Subject: [PATCH 068/218] chore(travis) add node.js v0.11 --- .travis.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 954609f8..7396b16b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,9 +3,15 @@ node_js: - 0.6 - 0.8 - 0.10 + - 0.11 + +matrix: + allow_failures: + - node_js: '0.11' + notifications: #webhooks: #http://requestb.in/12h5bl71 email: on_success: never - on_failure: change \ No newline at end of file + on_failure: change From 25389c0648b933a434da9d64bfb46d6bf373e1b4 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 30 Aug 2013 11:21:28 +0300 Subject: [PATCH 069/218] fix(test) keyBinding -> key, ie -> polyfill, viewer -> view, editor/_codemirror -> edit, terminal -> console --- test/test.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test.sh b/test/test.sh index e9c2fd3e..76170e7b 100755 --- a/test/test.sh +++ b/test/test.sh @@ -3,13 +3,13 @@ npm i recess jshint echo "jshint server.js client.js cloudcmd.js" node_modules/jshint/bin/jshint --config test/.jshintrc lib/server.js lib/client.js cloudcmd.js echo "jshint lib/cloudfunc.js lib/client/keyBinding.js" -node_modules/jshint/bin/jshint --config test/.jshintrc lib/util.js lib/cloudfunc.js lib/client/keyBinding.js +node_modules/jshint/bin/jshint --config test/.jshintrc lib/util.js lib/cloudfunc.js lib/client/key.js echo "lib/client/dom.js lib/client/ie.js lib/client/menu.js lib/client/socket.js ./lib/client/terminal.js lib/client/viewer.js lib/client/storage/_github.js lib/client/menu.js lib/client/editor/_codemirror.js" -node_modules/jshint/bin/jshint --config test/.jshintrc lib/client/dom.js lib/client/ie.js lib/client/menu.js lib/client/socket.js ./lib/client/terminal.js lib/client/viewer.js lib/client/storage/_github.js lib/client/menu.js lib/client/editor/_codemirror.js +node_modules/jshint/bin/jshint --config test/.jshintrc lib/client/dom.js lib/client/polyfill.js lib/client/menu.js lib/client/socket.js ./lib/client/console.js lib/client/view.js lib/client/storage/_github.js lib/client/menu.js lib/client/edit.js echo "jshint ./package.json ./json/config.json" node_modules/jshint/bin/jshint --config test/.jshintrc ./package.json ./json/config.json #linting css files echo "recess css/*.css" ./node_modules/recess/bin/recess css/*.css node test/test.js -node cloudcmd.js test \ No newline at end of file +node cloudcmd.js test From 4fb52556061bc6aa33857fdfa84af4585cb2bb6b Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 30 Aug 2013 12:29:39 +0300 Subject: [PATCH 070/218] chore(readme) add npm info --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 179d825a..54c6b41c 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,14 @@ Cloud Commander v0.3.0 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status] [BuildStatusIMGURL]: https://secure.travis-ci.org/coderaiser/cloudcmd.png?branch=master [DependencyStatusIMGURL]: https://gemnasium.com/coderaiser/cloudcmd.png [FlattrIMGURL]: http://api.flattr.com/button/flattr-badge-large.png +[NPM_INFO_IMG]: https://nodei.co/npm/cloudcmd.png [NPMURL]: http://badge.fury.io/js/cloudcmd [BuildStatusURL]: http://travis-ci.org/coderaiser/cloudcmd "Build Status" [DependencyStatusURL]: https://gemnasium.com/coderaiser/cloudcmd "Dependency Status" -[FlattrURL]: https://flattr.com/submit/auto?user_id=coderaiser&url=github.com/coderaiser/cloudcmd&title=cloudcmd&language=&tags=github&category=software +[FlattrURL]: https://flattr.com/submit/auto?user_id=coderaiser&url=github.com/coderaiser/cloudcmd&title=cloudcmd&language=&tags=github&category=software "flattr" +[NPM_INFO_URL]: https://npmjs.org/package/cloudcmd "npm" + +[![NPM_INFO][NPM_INFO_IMG]][NPM_INFO_URL] **Cloud Commander** - user friendly cloud file manager. DEMO: From f88fa22aecd5b1e8860b6282c25865ae9cbbb0a3 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 30 Aug 2013 13:53:42 +0300 Subject: [PATCH 071/218] chore(readme) mv npm info to Install; add stars, downloads --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 54c6b41c..2124e36a 100644 --- a/README.md +++ b/README.md @@ -5,15 +5,13 @@ Cloud Commander v0.3.0 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status] [BuildStatusIMGURL]: https://secure.travis-ci.org/coderaiser/cloudcmd.png?branch=master [DependencyStatusIMGURL]: https://gemnasium.com/coderaiser/cloudcmd.png [FlattrIMGURL]: http://api.flattr.com/button/flattr-badge-large.png -[NPM_INFO_IMG]: https://nodei.co/npm/cloudcmd.png +[NPM_INFO_IMG]: https://nodei.co/npm/cloudcmd.png?downloads=true&&stars [NPMURL]: http://badge.fury.io/js/cloudcmd [BuildStatusURL]: http://travis-ci.org/coderaiser/cloudcmd "Build Status" [DependencyStatusURL]: https://gemnasium.com/coderaiser/cloudcmd "Dependency Status" [FlattrURL]: https://flattr.com/submit/auto?user_id=coderaiser&url=github.com/coderaiser/cloudcmd&title=cloudcmd&language=&tags=github&category=software "flattr" [NPM_INFO_URL]: https://npmjs.org/package/cloudcmd "npm" -[![NPM_INFO][NPM_INFO_IMG]][NPM_INFO_URL] - **Cloud Commander** - user friendly cloud file manager. DEMO: [cloudfoundry] (https://cloudcmd.cloudfoundry.com "cloudfoundry"), @@ -100,6 +98,8 @@ Right mouse click button show context menu with items: Install --------------- +[![NPM_INFO][NPM_INFO_IMG]][NPM_INFO_URL] + **Cloud Commander** install is very easy. All you need is - install [node.js](http://nodejs.org/ "node.js") From 73dfaef19f406df935fb38b0254a5e6b25b91a15 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 2 Sep 2013 08:03:23 +0000 Subject: [PATCH 072/218] refactor(dom) Events: process --- lib/client/dom.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/client/dom.js b/lib/client/dom.js index fe9a5f96..9183d014 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -482,9 +482,6 @@ var CloudCmd, Util, DOM, CloudFunc; lElement.addEventListener : lElement.removeEventListener, - lProcessName = pAdd ? 'add' : 'remove', - lProcess = Events[lProcessName], - lRet = pType && lEventProcess, lEvent = ''; @@ -499,7 +496,8 @@ var CloudCmd, Util, DOM, CloudFunc; ); else if (Util.isArray(pType)) for (i = 0, n = pType.length; i < n; i++) - lProcess( + process( + pAdd, pType[i], pListener, pElement, @@ -510,7 +508,8 @@ var CloudCmd, Util, DOM, CloudFunc; pElement = pListener; for(lEvent in pType) - lProcess( + process( + pAdd, lEvent, pType[lEvent], pElement, From 9c8ee6fc52bfbf7588579b4ffb9b44cc4ad2993a Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 2 Sep 2013 11:31:40 +0000 Subject: [PATCH 073/218] refactor(edit) add initAce, worker condition --- lib/client/edit.js | 78 +++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/lib/client/edit.js b/lib/client/edit.js index 2780cd60..5438078f 100644 --- a/lib/client/edit.js +++ b/lib/client/edit.js @@ -6,6 +6,7 @@ var CloudCmd, Util, DOM, JsDiff, ace; function EditProto(CloudCmd, Util, DOM){ var Name = 'Edit', + DIR = CloudCmd.LIBDIRCLIENT + 'edit/', Value, Edit = this, Ace, @@ -35,7 +36,9 @@ var CloudCmd, Util, DOM, JsDiff, ace; }; this.show = function(pValue) { - var lMode, lSession; + var lName = DOM.getCurrentName(), + lExt = Util.getExtension(lName), + lUseWorker = Util.strCmp(lExt, ['.js', '.json']); Images.showLoad(); @@ -50,36 +53,12 @@ var CloudCmd, Util, DOM, JsDiff, ace; 'position: absolute;', not_append : true }); - - Ace = ace.edit(Element); - lSession = Ace.getSession(); - - Ace.setTheme('ace/theme/tomorrow_night_blue'); - lSession.setMode('ace/mode/javascript'); - Ace.setShowPrintMargin(false); - Ace.setShowInvisibles(true); - lSession.setUseSoftTabs(true); - - Ace.commands.addCommand({ - name : 'hide', - bindKey : { win: 'Esc', mac: 'Esc' }, - exec : function () { - Edit.hide(); - } - }); - - Ace.commands.addCommand({ - name : 'save', - bindKey : { win: 'Ctrl-S', mac: 'Command-S' }, - exec : function (pEditor) { - var lPath = DOM.getCurrentPath(), - lValue = Ace.getValue(); - - DOM.RESTfull.save(lPath, lValue); - } - }); + + initAce(); } + Ace.session.setOption('useWorker', lUseWorker); + if ( Util.isString(pValue) ) { Ace.setValue(pValue); CloudCmd.View.show(Element, focus); @@ -111,15 +90,44 @@ var CloudCmd, Util, DOM, JsDiff, ace; Ace.moveCursorTo(0, 0); } + function initAce() { + var lSession; + + Ace = ace.edit(Element); + lSession = Ace.getSession(); + + Ace.setTheme('ace/theme/tomorrow_night_blue'); + lSession.setMode('ace/mode/javascript'); + Ace.setShowPrintMargin(false); + Ace.setShowInvisibles(true); + lSession.setUseSoftTabs(true); + + Ace.commands.addCommand({ + name : 'hide', + bindKey : { win: 'Esc', mac: 'Esc' }, + exec : function () { + Edit.hide(); + } + }); + + Ace.commands.addCommand({ + name : 'save', + bindKey : { win: 'Ctrl-S', mac: 'Command-S' }, + exec : function (pEditor) { + var lPath = DOM.getCurrentPath(), + lValue = Ace.getValue(); + + DOM.RESTfull.save(lPath, lValue); + } + }); + } + function load(pCallBack){ Util.time(Name + ' load'); - var lDir = CloudCmd.LIBDIRCLIENT + 'edit/', - - lFiles = [ - lDir + 'mode-javascript.js', - lDir + 'worker-javascript.js', - lDir + 'ace.js', + var lFiles = [ + DIR + 'theme-tomorrow_night_blue.js', + DIR + 'ace.js', ]; DOM.anyLoadOnLoad(lFiles, function(){ From 94407a192a23ba1c8e694e028b684650498e41ac Mon Sep 17 00:00:00 2001 From: coderaiser Date: Tue, 3 Sep 2013 09:46:30 +0000 Subject: [PATCH 074/218] refactor(dom) removeClass: Events -> DOMTree --- lib/client/dom.js | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/lib/client/dom.js b/lib/client/dom.js index 9183d014..341edc98 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -219,6 +219,24 @@ var CloudCmd, Util, DOM, CloudFunc; return lRet; }; + /** + * remove class pClass from element pElement + * @param pElement + * @param pClass + */ + this.removeClass = function(pElement, pClass) { + var lRet_b = true, + lClassList = pElement.classList; + + if (pElement && lClassList) + lClassList.remove(pClass); + + else + lRet_b = false; + + return lRet_b; + }; + /** * check class of element * @@ -1703,24 +1721,6 @@ var CloudCmd, Util, DOM, CloudFunc; return (pElement || document.body).removeChild(pChild); }; - /** - * remove class pClass from element pElement - * @param pElement - * @param pClass - */ - this.removeClass = function(pElement, pClass) { - var lRet_b = true, - lClassList = pElement.classList; - - if (pElement && lClassList) - lClassList.remove(pClass); - - else - lRet_b = false; - - return lRet_b; - }; - /** * remove current file from file table * @pCurrent From 2b83f213f20e451261ad99fe20f4b9de94e649b8 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Tue, 3 Sep 2013 09:51:15 +0000 Subject: [PATCH 075/218] feature(dom) add toggleClass --- lib/client/dom.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/client/dom.js b/lib/client/dom.js index 341edc98..49bb9531 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -237,6 +237,19 @@ var CloudCmd, Util, DOM, CloudFunc; return lRet_b; }; + this.toggleClass = function(pElement, pClass) { + var lRet_b = true, + lClassList = pElement.classList; + + if (pElement && lClassList) + lClassList.toggle(pClass); + + else + lRet_b = false; + + return lRet_b; + }; + /** * check class of element * From ece10e59423dd06fe97df442c43f70e2563b6f8a Mon Sep 17 00:00:00 2001 From: coderaiser Date: Tue, 3 Sep 2013 10:02:35 +0000 Subject: [PATCH 076/218] refactor(dom) addClass, removeClass, toggleClass --- lib/client/dom.js | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/lib/client/dom.js b/lib/client/dom.js index 49bb9531..024af43a 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -206,17 +206,12 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pClass */ this.addClass = function(pElement, pClass) { - var lRet; + var lRet = pElement && pClass; - if (pElement) { - var lClassList = pElement.classList; - lRet = !this.isContainClass(pElement, pClass); - - if ( lRet ) - lClassList.add(pClass); - } + if (lRet) + pElement.classList.add(pClass); - return lRet; + return this; }; /** @@ -225,29 +220,21 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pClass */ this.removeClass = function(pElement, pClass) { - var lRet_b = true, - lClassList = pElement.classList; + var lRet = pElement && pClass; - if (pElement && lClassList) - lClassList.remove(pClass); + if (lRet) + pElement.classList.remove(pClass); - else - lRet_b = false; - - return lRet_b; + return this; }; this.toggleClass = function(pElement, pClass) { - var lRet_b = true, - lClassList = pElement.classList; + var lRet = pElement && pClass; - if (pElement && lClassList) - lClassList.toggle(pClass); + if (lRet) + pElement.classList.toggle(pClass); - else - lRet_b = false; - - return lRet_b; + return this; }; /** From f67af2471101b0127b036e893f8bb494bfe8ba85 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Tue, 3 Sep 2013 12:10:27 +0000 Subject: [PATCH 077/218] style(css) "{" -> " {" --- css/style.css | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/css/style.css b/css/style.css index d71b8634..c6faf440 100644 --- a/css/style.css +++ b/css/style.css @@ -180,7 +180,7 @@ body { #path{ margin-left:1.5%; } -.left, #left{ +.left, #left { float:left; } @@ -189,14 +189,14 @@ body { transition: ease 0.05s; } -.selected-file, .selected-file .name > a{ +.selected-file, .selected-file .name > a { color: rgb(254,159,224); } -.right, #right{ +.right, #right { float:right; } -.panel{ +.panel { width: 46%; overflow-y: auto; border: 1.5px solid rgba(49, 123, 249, .40); @@ -204,7 +204,7 @@ body { padding: 20px; } -#keyspanel{ +#keyspanel { text-align: center; } From be4ac392c2e469e5b75ac3b763fc58130e066885 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Tue, 3 Sep 2013 12:38:24 +0000 Subject: [PATCH 078/218] feature(client) add panel backlight on drag --- css/style.css | 4 ++++ lib/client.js | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/css/style.css b/css/style.css index c6faf440..acb149d6 100644 --- a/css/style.css +++ b/css/style.css @@ -204,6 +204,10 @@ body { padding: 20px; } +.selected-panel { + border-color: rgba(254, 159, 224, .40); +} + #keyspanel { text-align: center; } diff --git a/lib/client.js b/lib/client.js index 92ffa10a..a5c31c16 100644 --- a/lib/client.js +++ b/lib/client.js @@ -260,6 +260,15 @@ var Util, DOM, CloudFunc, CloudCmd; Util.log('app cacheed'); location.reload(); }, applicationCache); + + Events.add(['dragstart', 'dragend'], function () { + var panels = DOM.getByClass('panel'), + i = 0, + n = panels.length; + + for (i = 0; i < n; i++) + DOM.toggleClass(panels[i], 'selected-panel'); + }); /* загружаем общие функции для клиента и сервера */ DOM.jsload(CloudCmd.LIBDIR + 'cloudfunc.js', function() { From a81b853ad37c99a6cc127bf09dbb17fb23946973 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Tue, 3 Sep 2013 17:23:42 +0300 Subject: [PATCH 079/218] docs(CodingStyle) rm --- CodingStyle | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 CodingStyle diff --git a/CodingStyle b/CodingStyle deleted file mode 100644 index cc8e4a75..00000000 --- a/CodingStyle +++ /dev/null @@ -1,15 +0,0 @@ -Правила названий: - varName - имя функции - lVarName - имя локальной переменной - pVarName - имя параметра - VarName_f - имя функции созданной внутри функции - VARNAME - имя константы - -Varible types: - varName_s - string - varName_n - number - varName_o - object - varName_a - array - -SS - Server Side; -CS - Client Side; \ No newline at end of file From f6459ace02072cb27b407a265e85bf262258ee9b Mon Sep 17 00:00:00 2001 From: coderaiser Date: Tue, 3 Sep 2013 17:39:44 +0300 Subject: [PATCH 080/218] docs(readme) rm big change --- CONTRIBUTING.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 83671978..823924c1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -45,5 +45,3 @@ For example util, console, view, edit, style etc... **Examples**: - [fix(style) .name{width}: 37% -> 35%](https://github.com/coderaiser/cloudcmd/commit/94b0642e3990c17b3a0ee3efeb75f343e1e7c050) - [fix(console) dispatch: focus -> mouseup](https://github.com/coderaiser/cloudcmd/commit/f41ec5058d1411e86a881f8e8077e0572e0409ec) - -**Big change should be writed in ChangeLog like [this](https://github.com/coderaiser/cloudcmd/commit/e1893f77be09585decf8a260d45a42efc11c98e5).** \ No newline at end of file From 3530f0872f91620dc844359a557dd85e0cd0852e Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 4 Sep 2013 07:05:24 +0000 Subject: [PATCH 081/218] chore(dom) tab -> " " --- lib/client/dom.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/client/dom.js b/lib/client/dom.js index 024af43a..a5c35aab 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -921,8 +921,8 @@ var CloudCmd, Util, DOM, CloudFunc; src : pSrc, func : pFunc }); - - return lRet; + + return lRet; }, /** From 94d11aeddd59577cdbab0f37e79a08391904ddea Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 4 Sep 2013 07:30:15 +0000 Subject: [PATCH 082/218] fix(dom) retJSLoad: this -> Loader --- lib/client/dom.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/client/dom.js b/lib/client/dom.js index a5c35aab..dc9c83f7 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -611,7 +611,8 @@ var CloudCmd, Util, DOM, CloudFunc; }, LoaderProto = function() { - var XMLHTTP; + var XMLHTTP, + Loader = this; /** * Function gets id by src @@ -930,7 +931,7 @@ var CloudCmd, Util, DOM, CloudFunc; */ this.retJSLoad = function(pSrc, pFunc) { var lRet = function() { - return this.jsload(pSrc, pFunc); + return Loader.jsload(pSrc, pFunc); }; return lRet; From 250f4898700c8d46a87dc8ed3e1caac95965c030 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 4 Sep 2013 08:01:14 +0000 Subject: [PATCH 083/218] feature(dom) {setSelected,unsetSelected}File -> toggleSelectedFile --- lib/client/dom.js | 21 ++++----------------- lib/client/key.js | 12 ++++++------ 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/lib/client/dom.js b/lib/client/dom.js index dc9c83f7..8b2fdfab 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -1439,26 +1439,13 @@ var CloudCmd, Util, DOM, CloudFunc; * select current file * @param pCurrent */ - this.setSelectedFile = function(pCurrent) { + this.toggleSelectedFile = function(pCurrent) { var lCurrent = pCurrent || this.getCurrentFile(), - lRet = this.addClass(pCurrent, SELECTED_FILE); + lRet = this.toggleClass(pCurrent, SELECTED_FILE); - if (!lRet) - this.unsetSelectedFile(lCurrent); - - return lRet; + return this; }; - /** - * unselect current file - * @param pCurrent - */ - this.unsetSelectedFile = function(pCurrent) { - var lCurrent = pCurrent || this.getCurrentFile(), - lRet = this.removeClass(lCurrent, SELECTED_FILE); - - return lRet; - }; /** * setting history wrapper @@ -1596,7 +1583,7 @@ var CloudCmd, Util, DOM, CloudFunc; lName = this.getCurrentName( lFirst ); if (lName === '..') - this.unsetSelectedFile( lFirst ); + this.toggleSelectedFile( lFirst ); for(var i = 0, n = lSelected.length; i < n;i++) lRet[i] = this.getCurrentName( lSelected[i] ); diff --git a/lib/client/key.js b/lib/client/key.js index 6b700ac1..85ac4ff7 100644 --- a/lib/client/key.js +++ b/lib/client/key.js @@ -100,8 +100,8 @@ var CloudCmd, Util, DOM; break; case Key.INSERT: - DOM.setSelectedFile( lCurrent ); - DOM.setCurrentFile( lCurrent.nextSibling ); + DOM .toggleSelectedFile(lCurrent) + .setCurrentFile(lCurrent.nextSibling); break; case Key.DELETE: @@ -177,7 +177,7 @@ var CloudCmd, Util, DOM; lSelected = true; Util.ifExec(lSelected, function() { - DOM.setSelectedFile(lCurrent); + DOM.toggleSelectedFile(lCurrent); }, function(pCallBack) { DOM.loadCurrentSize(pCallBack, lCurrent); }); @@ -191,7 +191,7 @@ var CloudCmd, Util, DOM; * выделяем предыдущую строку */ case Key.UP: if (lShift) - DOM.setSelectedFile(lCurrent); + DOM.toggleSelectedFile(lCurrent); DOM.setCurrentFile( lCurrent.previousSibling ); DOM.preventDefault( pEvent ); @@ -200,7 +200,7 @@ var CloudCmd, Util, DOM; /* если нажали клавишу в низ - выделяем следующую строку */ case Key.DOWN: if (lShift) - DOM.setSelectedFile(lCurrent); + DOM.toggleSelectedFile(lCurrent); DOM.setCurrentFile( lCurrent.nextSibling ); DOM.preventDefault( pEvent ); @@ -273,7 +273,7 @@ var CloudCmd, Util, DOM; /* not path and fm_header */ for (i = 2, n = lNodes.length; i < n; i++) - DOM.setSelectedFile( lNodes[i] ); + DOM.toggleSelectedFile( lNodes[i] ); DOM.preventDefault(pEvent); } From 435029fcac598e1e55c945caed9516affcf8652c Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 4 Sep 2013 08:46:38 +0000 Subject: [PATCH 084/218] feature(view) add minWidth, minHeight --- lib/client/view.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/client/view.js b/lib/client/view.js index 86554f16..05d03be9 100644 --- a/lib/client/view.js +++ b/lib/client/view.js @@ -28,6 +28,8 @@ var CloudCmd, Util, DOM, CloudFunc, $; autoSize : false, height : window.innerHeight, width : window.innerWidth/0.75, + minWidth : 0, + minHeight : 0, helpers : { overlay : { From 058ac8073af6cbd5eab4b005a1083543ca345465 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 4 Sep 2013 14:49:42 +0300 Subject: [PATCH 085/218] chore(client) appcache: log -> confirm --- lib/client.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/client.js b/lib/client.js index a5c31c16..853a6846 100644 --- a/lib/client.js +++ b/lib/client.js @@ -257,8 +257,11 @@ var Util, DOM, CloudFunc, CloudCmd; function baseInit(pCallBack) { if (window.applicationCache) Events.add('updateready', function() { - Util.log('app cacheed'); - location.reload(); + var ret = confirm('An update is available. Reload now?'); + + if (ret) + location.reload(); + }, applicationCache); Events.add(['dragstart', 'dragend'], function () { From 41b218cff091ae166a663da9c4b656b338865fd1 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 4 Sep 2013 14:27:16 +0000 Subject: [PATCH 086/218] feature(cloudcmd) rm no-js redirect --- cloudcmd.js | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/cloudcmd.js b/cloudcmd.js index 0f20695d..837a7dd6 100644 --- a/cloudcmd.js +++ b/cloudcmd.js @@ -268,16 +268,9 @@ pParams.name = main.HTMLDIR + p.name + '.html'; lRet = main.sendFile( pParams ); } - else if ( Util.isContainStrAtBegin(p.name, FS) || Util.strCmp( p.name, '/') ){ - - if ( Util.isContainStrAtBegin(p.name, FS + 'no-js/') ){ - var lURL = Util.removeStr(pParams.name, 'no-js/'); - return main.redirect(pParams, lURL); - } - + else if ( Util.isContainStrAtBegin(p.name, FS) || Util.strCmp( p.name, '/') ) lRet = sendCommanderContent( pParams ); - } - /* termporary redirect for old urls */ + else lRet = false; } From 91fa4790c2265161c092884b783d0e2c9d9dad83 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 4 Sep 2013 14:53:54 +0000 Subject: [PATCH 087/218] feature(main) add Content-Length --- lib/server/main.js | 47 +++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/lib/server/main.js b/lib/server/main.js index be131d42..b5eaf10e 100644 --- a/lib/server/main.js +++ b/lib/server/main.js @@ -208,6 +208,9 @@ if(p.gzip) lRet['content-encoding'] = 'gzip'; + + if (!Util.isUndefined(p.length)) + lRet['Content-Length'] = p.length; } return lRet; @@ -226,24 +229,34 @@ var p = pParams, lGzip = isGZIP(p.request) && p.gzip; - p.response.writeHead(OK, generateHeaders({ - name : p.name, - cache : p.cache, - gzip : lGzip, - query : getQuery(p.request) - }) ); - - stream.createPipe({ - from: p.name, - write: p.response, - zip : lGzip && !p.gziped, - callback: function(pError) { - var lError = pError && pError.toString(); - if (pError) { - p.response.writeHead(FILE_NOT_FOUND, 'OK'); - p.response.end(lError); + fs.stat(p.name, function(error, stat) { + var length; + + if (error) + Util.log(error); + else + length = stat.size; + + p.response.writeHead(OK, generateHeaders({ + name : p.name, + cache : p.cache, + gzip : lGzip, + query : getQuery(p.request), + length : length + }) ); + + stream.createPipe({ + from: p.name, + write: p.response, + zip : lGzip && !p.gziped, + callback: function(pError) { + var lError = pError && pError.toString(); + if (pError) { + p.response.writeHead(FILE_NOT_FOUND, 'OK'); + p.response.end(lError); + } } - } + }); }); } From 0e27721f321d0f753f010e5c11cb8cb9d5906646 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 4 Sep 2013 14:58:21 +0000 Subject: [PATCH 088/218] Revert "feature(main) add Content-Length" This reverts commit 34f6aa72a3d004e1767bfd75e6d40b7782f79959. --- lib/server/main.js | 47 +++++++++++++++++----------------------------- 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/lib/server/main.js b/lib/server/main.js index b5eaf10e..be131d42 100644 --- a/lib/server/main.js +++ b/lib/server/main.js @@ -208,9 +208,6 @@ if(p.gzip) lRet['content-encoding'] = 'gzip'; - - if (!Util.isUndefined(p.length)) - lRet['Content-Length'] = p.length; } return lRet; @@ -229,34 +226,24 @@ var p = pParams, lGzip = isGZIP(p.request) && p.gzip; - fs.stat(p.name, function(error, stat) { - var length; - - if (error) - Util.log(error); - else - length = stat.size; - - p.response.writeHead(OK, generateHeaders({ - name : p.name, - cache : p.cache, - gzip : lGzip, - query : getQuery(p.request), - length : length - }) ); - - stream.createPipe({ - from: p.name, - write: p.response, - zip : lGzip && !p.gziped, - callback: function(pError) { - var lError = pError && pError.toString(); - if (pError) { - p.response.writeHead(FILE_NOT_FOUND, 'OK'); - p.response.end(lError); - } + p.response.writeHead(OK, generateHeaders({ + name : p.name, + cache : p.cache, + gzip : lGzip, + query : getQuery(p.request) + }) ); + + stream.createPipe({ + from: p.name, + write: p.response, + zip : lGzip && !p.gziped, + callback: function(pError) { + var lError = pError && pError.toString(); + if (pError) { + p.response.writeHead(FILE_NOT_FOUND, 'OK'); + p.response.end(lError); } - }); + } }); } From 4bf4231d5adef417d3d134b877091524b54d6941 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 6 Sep 2013 08:34:33 +0000 Subject: [PATCH 089/218] fix(dom) jqueryLoad: add pCallBack --- lib/client/dom.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/client/dom.js b/lib/client/dom.js index 8b2fdfab..b4aa23cc 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -1021,7 +1021,7 @@ var CloudCmd, Util, DOM, CloudFunc; onload: pCallBack, onerror: function() { - Loader.jsload('/lib/client/jquery.js'); + Loader.jsload('/lib/client/jquery.js', pCallBack); /* if could not load jquery from google server * maybe we offline, load font from local From caad2c60579ab0a7741b43d3f7fd4297c6d5dda9 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 6 Sep 2013 10:44:34 +0000 Subject: [PATCH 090/218] fix(dom) jqueryLoad: pCallBack -> onload: pCallBack --- lib/client/dom.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/client/dom.js b/lib/client/dom.js index b4aa23cc..901dd9e0 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -1021,7 +1021,9 @@ var CloudCmd, Util, DOM, CloudFunc; onload: pCallBack, onerror: function() { - Loader.jsload('/lib/client/jquery.js', pCallBack); + Loader.jsload('/lib/client/jquery.js', { + onload: pCallBack + }); /* if could not load jquery from google server * maybe we offline, load font from local From b48d7ba7fab93cee170107d15ec9f9af9421e330 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 6 Sep 2013 11:08:01 +0000 Subject: [PATCH 091/218] fix(client) unload, beforeunload --- lib/client.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/client.js b/lib/client.js index 853a6846..fa1965c2 100644 --- a/lib/client.js +++ b/lib/client.js @@ -149,7 +149,7 @@ var Util, DOM, CloudFunc, CloudCmd; Util.ifExec(document.body.scrollIntoViewIfNeeded, lCallBack, lFunc); DOM.Events.add(['unload', 'beforeunload'], function (pEvent) { - var lRet, lIsBind = Key.isBind(); + var lRet, lIsBind = Key && Key.isBind(); if(!lIsBind) { DOM.preventDefault(pEvent); From 74a2f16b5323d5cfd931edf41725cffd53011326 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 6 Sep 2013 11:25:25 +0000 Subject: [PATCH 092/218] fix(css) .icon height, width: 15.5 -> 15 --- css/style.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/css/style.css b/css/style.css index acb149d6..d074b14b 100644 --- a/css/style.css +++ b/css/style.css @@ -67,9 +67,9 @@ body { .icon { display : inline-block; font-family : 'Fontello'; - height : 15.5px; + height : 15px; margin-left : 0.5%; - width : 15.5px; + width : 15px; } .error::before { From a3a66b004c515ad760a09251c2f95ef47a9a010a Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 6 Sep 2013 13:03:51 +0000 Subject: [PATCH 093/218] feature(css) selection -> user-select --- css/style.css | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/css/style.css b/css/style.css index d074b14b..13b7c80c 100644 --- a/css/style.css +++ b/css/style.css @@ -31,16 +31,13 @@ body { background-color:white; } -#fm::-moz-selection, #left>li::-moz-selection, #right>li::-moz-selection, .path::-moz-selection, .fm-header::-moz-selection, -.mini-icon::-moz-selection, .name::-moz-selection, .size::-moz-selection, .owner::-moz-selection, .mode::-moz-selection { - text-shadow: none; opacity: 0; -} - -#fm::selection, #left>li::selection, #right>li::selection, .path::selection, .fm-header::selection, -.mini-icon::selection, .name::selection, .size::selection, .owner::selection, .mode::selection { - text-shadow: none; - opacity: 0; - background-color:white; /* opera */ +#fm, #left>li, #right>li, .path, .fm-header, +.mini-icon, .name, .size, .owner, .mode, #keyspanel, .cmd-button { + -webkit-user-select : none; + -moz-user-select : none; + -ms-user-select : none; + -o-user-select : none; + user-select : none; } .path-icon { From 114d65d6094d181d2f73b09c32b6e781af569194 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 6 Sep 2013 13:11:20 +0000 Subject: [PATCH 094/218] fix(css) .icon height: 15 -> 14.95(ie) --- css/style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/css/style.css b/css/style.css index 13b7c80c..bd32e2c5 100644 --- a/css/style.css +++ b/css/style.css @@ -64,7 +64,7 @@ body { .icon { display : inline-block; font-family : 'Fontello'; - height : 15px; + height : 14.95px; margin-left : 0.5%; width : 15px; } From 7cbb40dd4d0866a1a408a7ac4afa951cc724498a Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 6 Sep 2013 13:19:16 +0000 Subject: [PATCH 095/218] fix(css) .icon height: 14.95 -> 14.8(ie) --- css/style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/css/style.css b/css/style.css index bd32e2c5..94ec3b6a 100644 --- a/css/style.css +++ b/css/style.css @@ -64,7 +64,7 @@ body { .icon { display : inline-block; font-family : 'Fontello'; - height : 14.95px; + height : 14.8px; margin-left : 0.5%; width : 15px; } From b00e60d30eff7d0d13fd7d8a7f8055d7a82ac258 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 9 Sep 2013 08:26:04 +0000 Subject: [PATCH 096/218] fix(view) show: add createTextNode --- lib/client/view.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/client/view.js b/lib/client/view.js index 05d03be9..6d5deadb 100644 --- a/lib/client/view.js +++ b/lib/client/view.js @@ -93,7 +93,8 @@ var CloudCmd, Util, DOM, CloudFunc, $; } else DOM.getCurrentData(function(pParams){ - $.fancybox( Element.append(pParams.data), Config ); + var data = document.createTextNode(pParams.data); + $.fancybox( Element.append(data), Config ); }); } }; From 7bd13fc0d320c7897b20339487c85a9f40e9ed5a Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 9 Sep 2013 08:30:27 +0000 Subject: [PATCH 097/218] feature(view) fancyBox v2.1.4 -> v2.1.5 --- lib/client/view/fancyBox/CHANGELOG.md | 6 + lib/client/view/fancyBox/demo/index.html | 15 ++- .../view/fancyBox/lib/jquery-1.9.0.min.js | 4 - .../lib/jquery.mousewheel-3.0.6.pack.js | 13 -- .../view/fancyBox/source/fancybox_loading.gif | Bin 3866 -> 6567 bytes .../fancyBox/source/fancybox_loading@2x.gif | Bin 0 -> 13984 bytes .../fancyBox/source/fancybox_sprite@2x.png | Bin 0 -> 6553 bytes .../helpers/jquery.fancybox-buttons.css | 1 + .../source/helpers/jquery.fancybox-buttons.js | 7 +- .../source/helpers/jquery.fancybox-media.js | 25 ++-- .../source/helpers/jquery.fancybox-thumbs.css | 1 + .../view/fancyBox/source/jquery.fancybox.css | 35 ++++- .../view/fancyBox/source/jquery.fancybox.js | 121 ++++++++++++------ .../fancyBox/source/jquery.fancybox.pack.js | 45 ------- lib/client/view/fancyBox/sprite.psd | Bin 0 -> 250491 bytes 15 files changed, 147 insertions(+), 126 deletions(-) delete mode 100644 lib/client/view/fancyBox/lib/jquery-1.9.0.min.js delete mode 100644 lib/client/view/fancyBox/lib/jquery.mousewheel-3.0.6.pack.js create mode 100644 lib/client/view/fancyBox/source/fancybox_loading@2x.gif create mode 100644 lib/client/view/fancyBox/source/fancybox_sprite@2x.png mode change 100644 => 100755 lib/client/view/fancyBox/source/jquery.fancybox.js delete mode 100644 lib/client/view/fancyBox/source/jquery.fancybox.pack.js create mode 100644 lib/client/view/fancyBox/sprite.psd diff --git a/lib/client/view/fancyBox/CHANGELOG.md b/lib/client/view/fancyBox/CHANGELOG.md index 869e0fe1..b0d847e2 100644 --- a/lib/client/view/fancyBox/CHANGELOG.md +++ b/lib/client/view/fancyBox/CHANGELOG.md @@ -1,6 +1,12 @@ fancyBox - Changelog ========= +### Version 2.1.5 - June 14, 2013 +* Fixed #493 - Broken slideshow +* Fixed #556 - Parent option +* Retina graphics (#564) and retina display support (#420) +* Improved "lock" feature + ### Version 2.1.4 - January 10, 2013 * Update to be compatible with jQuery v1.9 * Small changes that should fix usability issues for certain users diff --git a/lib/client/view/fancyBox/demo/index.html b/lib/client/view/fancyBox/demo/index.html index 757314ff..70397a8b 100644 --- a/lib/client/view/fancyBox/demo/index.html +++ b/lib/client/view/fancyBox/demo/index.html @@ -5,14 +5,14 @@ - + - - + + @@ -23,7 +23,7 @@ - + - - \ No newline at end of file + From acfc827555d5e062b4b0fd0464c97cd990cada22 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 13 Sep 2013 11:27:54 +0000 Subject: [PATCH 133/218] fix(socket) crash on win7 --- lib/server/socket.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/server/socket.js b/lib/server/socket.js index c05afab9..32ba8a21 100644 --- a/lib/server/socket.js +++ b/lib/server/socket.js @@ -47,8 +47,18 @@ lConnNum = 0; lListen.set('log level', INFO_LOG_LEVEL); - lListen.set('browser client minification', true); - lListen.set('browser client gzip', true); + + /* + * on Win7 application is crashing, + * when options below is used. + * + * https://github.com/LearnBoost/socket.io/issues/1314 + * + */ + if (!Win32) { + lListen.set('browser client minification', true); + lListen.set('browser client gzip', true); + } lRet = lListen.sockets.on('connection', function (socket){ ++lConnNum; From 8f294504e19da48eaa6222d1f9b319ae1f031ec6 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 13 Sep 2013 11:41:19 +0000 Subject: [PATCH 134/218] feature(view,edit,console,menu) add Loading check --- lib/client/console.js | 118 ++++++++++++++++++++++-------------------- lib/client/edit.js | 80 ++++++++++++++-------------- lib/client/menu.js | 20 ++++--- lib/client/view.js | 49 ++++++++++-------- 4 files changed, 144 insertions(+), 123 deletions(-) diff --git a/lib/client/console.js b/lib/client/console.js index b79efbc6..7a801325 100644 --- a/lib/client/console.js +++ b/lib/client/console.js @@ -6,6 +6,7 @@ var CloudCmd, Util, DOM, $; function ConsoleProto(CloudCmd, Util, DOM){ var Name = 'Console', + Loading, jqconsole, Element, MouseBinded, @@ -16,6 +17,8 @@ var CloudCmd, Util, DOM, $; this.init = function(pCallBack) { var lFunc, lIsFunc = Util.isFunction(CloudCmd.View); + Loading = true; + if (lIsFunc) lFunc = CloudCmd.View; else @@ -36,65 +39,67 @@ var CloudCmd, Util, DOM, $; }; this.show = function() { - Images.showLoad({top:true}); - - if (!Element) { - Element = DOM.anyload({ - name : 'div', - className : 'console' - }); + if (!Loading) { + Images.showLoad({top:true}); - jqconsole = $(Element).jqconsole('', '> '); - // Abort prompt on Ctrl+Z. - jqconsole.RegisterShortcut('Z', function() { - jqconsole.AbortPrompt(); - handler(); - }); - - // Handle a command. - var handler = function(command) { - var lSocket = CloudCmd.Socket; - if (command) { - Images.showLoad({ top:true }); - - if(lSocket) - lSocket.send(command); - } - - jqconsole.Prompt(true, handler); - }; - - // Initiate the first prompt. - handler(); - } - - CloudCmd.View.show(Element, function(){ - var l$Console = jqconsole.$console, - l$Input = jqconsole.$input_source, - lFocus = function(){ - var x = window.scrollX, - y = window.scrollY; - - l$Input.focus(); - window.scrollTo(x,y); - }; - - lFocus(); - - if (!MouseBinded) { - MouseBinded = true; - - $(l$Console).unbind('mouseup'); - $(l$Console).mouseup(function() { - if( !window.getSelection().toString() ) { - var lTop = l$Console.scrollTop(); - - lFocus(); - l$Console.scrollTop(lTop); - } + if (!Element) { + Element = DOM.anyload({ + name : 'div', + className : 'console' }); + + jqconsole = $(Element).jqconsole('', '> '); + // Abort prompt on Ctrl+Z. + jqconsole.RegisterShortcut('Z', function() { + jqconsole.AbortPrompt(); + handler(); + }); + + // Handle a command. + var handler = function(command) { + var lSocket = CloudCmd.Socket; + if (command) { + Images.showLoad({ top:true }); + + if(lSocket) + lSocket.send(command); + } + + jqconsole.Prompt(true, handler); + }; + + // Initiate the first prompt. + handler(); } - }); + + CloudCmd.View.show(Element, function(){ + var l$Console = jqconsole.$console, + l$Input = jqconsole.$input_source, + lFocus = function(){ + var x = window.scrollX, + y = window.scrollY; + + l$Input.focus(); + window.scrollTo(x,y); + }; + + lFocus(); + + if (!MouseBinded) { + MouseBinded = true; + + $(l$Console).unbind('mouseup'); + $(l$Console).mouseup(function() { + if( !window.getSelection().toString() ) { + var lTop = l$Console.scrollTop(); + + lFocus(); + l$Console.scrollTop(lTop); + } + }); + } + }); + } }; this.hide = function(){ @@ -134,6 +139,7 @@ var CloudCmd, Util, DOM, $; DOM.anyLoadInParallel(lFiles, function(){ Util.timeEnd(Name + ' load'); + Loading = false; Util.exec(pCallBack); }); diff --git a/lib/client/edit.js b/lib/client/edit.js index 5438078f..0e4d3277 100644 --- a/lib/client/edit.js +++ b/lib/client/edit.js @@ -6,6 +6,7 @@ var CloudCmd, Util, DOM, JsDiff, ace; function EditProto(CloudCmd, Util, DOM){ var Name = 'Edit', + Loading = false, DIR = CloudCmd.LIBDIRCLIENT + 'edit/', Value, Edit = this, @@ -18,6 +19,7 @@ var CloudCmd, Util, DOM, JsDiff, ace; this.init = function(pCallBack) { var lFunc, lIsFunc = Util.isFunction(CloudCmd.View); + Loading = true; if (lIsFunc) lFunc = CloudCmd.View; else @@ -40,43 +42,45 @@ var CloudCmd, Util, DOM, JsDiff, ace; lExt = Util.getExtension(lName), lUseWorker = Util.strCmp(lExt, ['.js', '.json']); - Images.showLoad(); - - if (!Element) { - Element = DOM.anyload({ - name : 'div', - className : 'edit', - style : - 'width : 100%;' + - 'height : 100%;' + - 'font : 16px "Droid Sans Mono";' + - 'position: absolute;', - not_append : true - }); - - initAce(); - } - - Ace.session.setOption('useWorker', lUseWorker); - - if ( Util.isString(pValue) ) { - Ace.setValue(pValue); - CloudCmd.View.show(Element, focus); - Key.unsetBind(); - } - else { - DOM.getCurrentData({ - success : function(pData){ - var lValue = ''; - - if (pData) - lValue = pData.data; - - Value = lValue; - Ace.setValue(lValue); - CloudCmd.View.show(Element, focus); - } - }); + if (!Loading) { + Images.showLoad(); + + if (!Element) { + Element = DOM.anyload({ + name : 'div', + className : 'edit', + style : + 'width : 100%;' + + 'height : 100%;' + + 'font : 16px "Droid Sans Mono";' + + 'position: absolute;', + not_append : true + }); + + initAce(); + } + + Ace.session.setOption('useWorker', lUseWorker); + + if ( Util.isString(pValue) ) { + Ace.setValue(pValue); + CloudCmd.View.show(Element, focus); + Key.unsetBind(); + } + else { + DOM.getCurrentData({ + success : function(pData){ + var lValue = ''; + + if (pData) + lValue = pData.data; + + Value = lValue; + Ace.setValue(lValue); + CloudCmd.View.show(Element, focus); + } + }); + } } }; @@ -132,7 +136,7 @@ var CloudCmd, Util, DOM, JsDiff, ace; DOM.anyLoadOnLoad(lFiles, function(){ Util.timeEnd(Name + ' load'); - + Loading = false; Util.exec(pCallBack); }); } diff --git a/lib/client/menu.js b/lib/client/menu.js index 770fec8c..24a04b7c 100644 --- a/lib/client/menu.js +++ b/lib/client/menu.js @@ -10,6 +10,7 @@ var CloudCmd, Util, DOM, CloudFunc, $; function MenuProto(CloudCmd, Util, DOM, CloudFunc) { var Name = 'Menu', + Loading = false, Key = CloudCmd.Key, Events = DOM.Events, MenuSeted = false, @@ -20,6 +21,8 @@ var CloudCmd, Util, DOM, CloudFunc, $; this.ENABLED = false; this.init = function(pPosition){ + Loading = true; + Position = pPosition; Util.loadOnLoad([ @@ -41,13 +44,15 @@ var CloudCmd, Util, DOM, CloudFunc, $; }; this.show = function() { - set(); - DOM.Images.hideLoad(); - - if(Position && !Position.x ) - Position = undefined; - - $('li').contextMenu(Position); + if (!Loading) { + set(); + DOM.Images.hideLoad(); + + if(Position && !Position.x ) + Position = undefined; + + $('li').contextMenu(Position); + } }; /* function read data from modules.json @@ -239,6 +244,7 @@ var CloudCmd, Util, DOM, CloudFunc, $; DOM.anyLoadInParallel(lFiles, function(){ Util.timeEnd(Name + ' load'); + Loading = false; Util.exec(pCallBack); }); } diff --git a/lib/client/view.js b/lib/client/view.js index 6d5deadb..403ea2ae 100644 --- a/lib/client/view.js +++ b/lib/client/view.js @@ -7,6 +7,7 @@ var CloudCmd, Util, DOM, CloudFunc, $; function ViewProto(CloudCmd, Util, DOM, CloudFunc){ var Name = 'View', + Loading = false, Key = CloudCmd.Key, Images = DOM.Images, View = this, @@ -44,6 +45,7 @@ var CloudCmd, Util, DOM, CloudFunc, $; this.init = function(pCallBack){ var lFunc, lIsFunc, lIsCallBack; + Loading = true; if (pCallBack){ lIsFunc = Util.isFunction(pCallBack); lIsCallBack = Util.isFunction(pCallBack.callback); @@ -73,29 +75,31 @@ var CloudCmd, Util, DOM, CloudFunc, $; var lPath, lElement, lAfterFunc, lFunc; - Element = $('
'); - if (pData) { - lElement = $(Element).append(pData); - lAfterFunc = Config.afterShow, - lFunc = function(){ - Util.exec(lAfterFunc); - Util.exec(pCallBack); - }; - - Config.afterShow = lFunc; - - $.fancybox(lElement, Config); - - } else { - lPath = CloudFunc.FS + DOM.getCurrentPath(); - if( Util.checkExtension(lPath, ['png','jpg', 'gif','ico']) ) { - $.fancybox.open({ href : lPath }, Config); + if (!Loading) { + Element = $('
'); + if (pData) { + lElement = $(Element).append(pData); + lAfterFunc = Config.afterShow, + lFunc = function(){ + Util.exec(lAfterFunc); + Util.exec(pCallBack); + }; + + Config.afterShow = lFunc; + + $.fancybox(lElement, Config); + + } else { + lPath = CloudFunc.FS + DOM.getCurrentPath(); + if( Util.checkExtension(lPath, ['png','jpg', 'gif','ico']) ) { + $.fancybox.open({ href : lPath }, Config); + } + else + DOM.getCurrentData(function(pParams){ + var data = document.createTextNode(pParams.data); + $.fancybox( Element.append(data), Config ); + }); } - else - DOM.getCurrentData(function(pParams){ - var data = document.createTextNode(pParams.data); - $.fancybox( Element.append(data), Config ); - }); } }; @@ -116,6 +120,7 @@ var CloudCmd, Util, DOM, CloudFunc, $; DOM.anyLoadOnLoad([lFiles], function(){ Util.timeEnd(Name + ' load'); + Loading = false; Util.exec( pCallBack ); Images.hideLoad(); }) From 240f9269fba1b927f61b54f72f3e8d49950ab145 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 13 Sep 2013 14:58:09 +0000 Subject: [PATCH 135/218] feature(css) rm .error:hover --- css/style.css | 5 ----- 1 file changed, 5 deletions(-) diff --git a/css/style.css b/css/style.css index 7cc5dbea..f24bd0cf 100644 --- a/css/style.css +++ b/css/style.css @@ -83,11 +83,6 @@ body { background:url(/img/spinner.gif); } -.error:hover { - color:rgb(222, 41, 41); - color:rgba(222, 41, 41, 0.81); -} - .refresh-icon { background:url(/img/panel_refresh.png) no-repeat; } From 0c5bf15de80b734a050ec464449d5c651917b794 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 13 Sep 2013 15:07:58 +0000 Subject: [PATCH 136/218] fix(socket) Win32 -> WIN32 --- lib/server/socket.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/server/socket.js b/lib/server/socket.js index 32ba8a21..e5faa345 100644 --- a/lib/server/socket.js +++ b/lib/server/socket.js @@ -55,7 +55,7 @@ * https://github.com/LearnBoost/socket.io/issues/1314 * */ - if (!Win32) { + if (!WIN32) { lListen.set('browser client minification', true); lListen.set('browser client gzip', true); } From d104e09694698f3a6ae8ed5ba1c18e840dfbed94 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 16 Sep 2013 09:12:39 +0000 Subject: [PATCH 137/218] refactor(css) font-family: .icon -> .error::before --- css/style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/css/style.css b/css/style.css index f24bd0cf..f8de5b4e 100644 --- a/css/style.css +++ b/css/style.css @@ -66,12 +66,12 @@ body { width : 15px; height : 14.8px; margin-left : 0.5%; - font-family : 'Fontello'; } .error::before { position: relative; font-size: 14px; + font-family : 'Fontello'; color: rgb(222, 41, 41); cursor :default; content: '\2757'; From 88809d66ed54ab97897cb447db25c3d383c299eb Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 16 Sep 2013 12:39:34 +0000 Subject: [PATCH 138/218] refactor(css) display, width, height: .icon -> .loading --- css/style.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/css/style.css b/css/style.css index f8de5b4e..a4c99af2 100644 --- a/css/style.css +++ b/css/style.css @@ -62,9 +62,6 @@ body { } .icon { - display : inline-block; - width : 15px; - height : 14.8px; margin-left : 0.5%; } @@ -78,6 +75,9 @@ body { } .loading { + display : inline-block; + width : 15px; + height : 14.8px; position:relative; top:1px; background:url(/img/spinner.gif); From 3604afe2e74f7bfc43158fb1dc49c8b6adb8ea70 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 16 Sep 2013 12:41:48 +0000 Subject: [PATCH 139/218] feature(css) .cmd-button (601px - 785px): 15% -> 13% --- css/style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/css/style.css b/css/style.css index a4c99af2..e0c627bf 100644 --- a/css/style.css +++ b/css/style.css @@ -337,7 +337,7 @@ a:hover, a:active { } @media only screen and (min-width: 601px) and (max-width: 785px) { .cmd-button { - width: 15%; + width: 13%; } } From 3997a96f26787ae85b7cc057c802186b7bfc39e0 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 16 Sep 2013 12:42:46 +0000 Subject: [PATCH 140/218] feature(socket) max reconnection attempts: 1000000 -> Math.pow(2, 64) --- lib/client/socket.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/client/socket.js b/lib/client/socket.js index cde35d27..a513fea1 100644 --- a/lib/client/socket.js +++ b/lib/client/socket.js @@ -19,7 +19,7 @@ var CloudCmd, Util, DOM, io; socket = io.connect(CloudCmd.HOST, { 'reconnect' : true, 'reconnection delay' : 500, - 'max reconnection attempts' : 1000000, + 'max reconnection attempts' : Math.pow(2, 64), 'reconnect_failed' : function() { Util.log('Could not reconnect. Reload page.'); } From 6d4b132502d0d30eb03f7e26875278cc1a22c8a4 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 16 Sep 2013 12:47:38 +0000 Subject: [PATCH 141/218] feature(socket) lListent: set -> enable --- lib/server/socket.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/server/socket.js b/lib/server/socket.js index e5faa345..68be8299 100644 --- a/lib/server/socket.js +++ b/lib/server/socket.js @@ -56,8 +56,8 @@ * */ if (!WIN32) { - lListen.set('browser client minification', true); - lListen.set('browser client gzip', true); + lListen.enable('browser client minification'); + lListen.enable('browser client gzip'); } lRet = lListen.sockets.on('connection', function (socket){ From 4330757f936196679ad7c8e4e3414c48dcb1f37e Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 16 Sep 2013 12:48:05 +0000 Subject: [PATCH 142/218] feature(socket) add browser client etag --- lib/server/socket.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/server/socket.js b/lib/server/socket.js index 68be8299..f1ac473f 100644 --- a/lib/server/socket.js +++ b/lib/server/socket.js @@ -58,6 +58,7 @@ if (!WIN32) { lListen.enable('browser client minification'); lListen.enable('browser client gzip'); + lListen.enable('browser client etag'); } lRet = lListen.sockets.on('connection', function (socket){ From 9ba0fb377ebfbb6176920ea20506d498a0ac77fa Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 16 Sep 2013 12:49:23 +0000 Subject: [PATCH 143/218] feature(socket) add transports --- lib/server/socket.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/server/socket.js b/lib/server/socket.js index f1ac473f..04dd4412 100644 --- a/lib/server/socket.js +++ b/lib/server/socket.js @@ -61,6 +61,14 @@ lListen.enable('browser client etag'); } + lListen.set('transports', [ + 'websocket', + 'flashsocket', + 'htmlfile', + 'xhr-polling', + 'jsonp-polling' + ]); + lRet = lListen.sockets.on('connection', function (socket){ ++lConnNum; From 02b06c43952c4787f35ddfee0ff892dedac37122 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 16 Sep 2013 13:57:58 +0000 Subject: [PATCH 144/218] refactor(stream) stream -> pipe --- lib/server/main.js | 6 +++--- lib/server/{stream.js => pipe.js} | 4 ++-- lib/server/rest.js | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) rename lib/server/{stream.js => pipe.js} (94%) diff --git a/lib/server/main.js b/lib/server/main.js index 2b02ddc8..269e7b4b 100644 --- a/lib/server/main.js +++ b/lib/server/main.js @@ -11,7 +11,7 @@ SLASH, ISWIN32, ext, - path, fs, zlib, url, stream, + path, fs, zlib, url, pipe, OK, FILE_NOT_FOUND, MOVED_PERMANENTLY = 301, REQUEST, RESPONSE, @@ -100,7 +100,7 @@ exports.VOLUMES = getVolumes(), /* Additional Modules */ - exports.stream = stream = srvrequire('stream'), + exports.pipe = pipe = srvrequire('pipe'), exports.socket = srvrequire('socket'), exports.auth = srvrequire('auth').auth, exports.appcache = srvrequire('appcache'), @@ -233,7 +233,7 @@ query : getQuery(p.request) }) ); - stream.createPipe({ + pipe.create({ from: p.name, write: p.response, zip : lGzip && !p.gziped, diff --git a/lib/server/stream.js b/lib/server/pipe.js similarity index 94% rename from lib/server/stream.js rename to lib/server/pipe.js index 2bfda8d1..809ac9df 100644 --- a/lib/server/stream.js +++ b/lib/server/pipe.js @@ -3,7 +3,7 @@ if (!global.cloudcmd) return console.log( - '# stream.js' + '\n' + + '# pipe.js' + '\n' + '# -----------' + '\n' + '# Module is part of Cloud Commander,' + '\n' + '# used for work with stream.' + '\n' + @@ -16,7 +16,7 @@ Util = main.util, zlib = main.zlib; - exports.createPipe = function(pParams) { + exports.create = function(pParams) { var lZlib, lError, lMsg, lRead, lWrite, lIsFsWrite, p = pParams; diff --git a/lib/server/rest.js b/lib/server/rest.js index 16883236..90b05d84 100644 --- a/lib/server/rest.js +++ b/lib/server/rest.js @@ -17,7 +17,7 @@ fs = main.fs, path = main.path, Util = main.util, - stream = main.stream, + pipe = main.pipe, CloudFunc = main.cloudfunc, dir = main.dir, OK = 200, @@ -145,7 +145,7 @@ }); else - stream.createPipe({ + pipe.create({ read : p.request, to : p.name, callback : function(pError) { From 9272b4d922f6e5c1a42f4e53094d71c78e828eb8 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 16 Sep 2013 14:08:24 +0000 Subject: [PATCH 145/218] refactor(client) google-analytics -> analytics --- lib/client.js | 6 +++--- lib/client/{google_analytics.js => analytics.js} | 0 2 files changed, 3 insertions(+), 3 deletions(-) rename lib/client/{google_analytics.js => analytics.js} (100%) diff --git a/lib/client.js b/lib/client.js index 11b08a66..df690e5f 100644 --- a/lib/client.js +++ b/lib/client.js @@ -26,9 +26,9 @@ var Util, DOM, CloudFunc, CloudCmd; })() }; - CloudCmd.GoogleAnalytics = function(){ + CloudCmd.analytics = function(){ Events.addOneTime('mousemove', function(){ - var lUrl = CloudCmd.LIBDIRCLIENT + 'google_analytics.js'; + var lUrl = CloudCmd.LIBDIRCLIENT + 'analytics.js'; setTimeout(function(){ DOM.jsload(lUrl); @@ -735,6 +735,6 @@ var Util, DOM, CloudFunc, CloudCmd; CloudCmd.init(); /* загружаем Google Analytics */ - CloudCmd.GoogleAnalytics(); + CloudCmd.analytics(); }); })(Util, DOM); diff --git a/lib/client/google_analytics.js b/lib/client/analytics.js similarity index 100% rename from lib/client/google_analytics.js rename to lib/client/analytics.js From d1dda5a7ae4626330d4ae30ff909067d27236edf Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 16 Sep 2013 14:10:31 +0000 Subject: [PATCH 146/218] chore(analytics) add " ", "\n" --- lib/client/analytics.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/client/analytics.js b/lib/client/analytics.js index 32238497..38acb0ce 100644 --- a/lib/client/analytics.js +++ b/lib/client/analytics.js @@ -1,5 +1,6 @@ var DOM, _gaq; -(function(DOM, _gaq){ + +(function(DOM, _gaq) { 'use strict'; /* setting google analitics tracking code */ @@ -12,4 +13,4 @@ var DOM, _gaq; DOM.jsload('//google-analytics.com/ga.js'); -})(DOM, _gaq); \ No newline at end of file +})(DOM, _gaq); From 5e055f3d677fdace3df6d3bc63a9ff987ee1dd99 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 18 Sep 2013 07:41:50 +0000 Subject: [PATCH 147/218] refactor(client) mv Events.add to listeners --- lib/client.js | 294 ++++------------------------------------ lib/client/listeners.js | 280 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 307 insertions(+), 267 deletions(-) create mode 100644 lib/client/listeners.js diff --git a/lib/client.js b/lib/client.js index df690e5f..7b0af0e2 100644 --- a/lib/client.js +++ b/lib/client.js @@ -7,8 +7,7 @@ var Util, DOM, CloudFunc, CloudCmd; (function(Util, DOM){ 'use strict'; - var Key, Config, Modules, FileTemplate, PathTemplate, - Events = DOM.Events, + var Key, Config, Modules, FileTemplate, PathTemplate, Listeners, Cache = DOM.Cache; CloudCmd = { @@ -26,16 +25,6 @@ var Util, DOM, CloudFunc, CloudCmd; })() }; - CloudCmd.analytics = function(){ - Events.addOneTime('mousemove', function(){ - var lUrl = CloudCmd.LIBDIRCLIENT + 'analytics.js'; - - setTimeout(function(){ - DOM.jsload(lUrl); - }, 5000); - }); - }; - /** * Функция привязываеться ко всем ссылкам и * загружает содержимое каталогов @@ -132,7 +121,6 @@ var Util, DOM, CloudFunc, CloudCmd; var lCallBack = function(){ Util.loadOnLoad([ Util.retExec(route, location.hash), - initKeysPanel, initModules, baseInit ]); @@ -147,17 +135,6 @@ var Util, DOM, CloudFunc, CloudCmd; }; Util.ifExec(document.body.scrollIntoViewIfNeeded, lCallBack, lFunc); - - DOM.Events.add(['unload', 'beforeunload'], function (pEvent) { - var lRet, lIsBind = Key && Key.isBind(); - - if(!lIsBind) { - DOM.preventDefault(pEvent); - lRet = 'Please make sure that you saved all work.'; - } - - return lRet; - }); }; function initModules(pCallBack){ @@ -173,10 +150,6 @@ var Util, DOM, CloudFunc, CloudCmd; CloudCmd.getModules(function(pModules) { pModules = pModules || []; - Events.addContextMenu(function(pEvent){ - CloudCmd.Menu.ENABLED || DOM.preventDefault(pEvent); - }, document); - var i, n, lStorage = 'storage', lShowLoadFunc = Util.retFunc( DOM.Images.showLoad, {top:true} ), @@ -217,117 +190,26 @@ var Util, DOM, CloudFunc, CloudCmd; }); } - function initKeysPanel(pCallBack){ - var i, lButton, lEl, - lKeysPanel = {}, - - lFuncs =[ - null, - CloudCmd.Help, /* f1 */ - DOM.renameCurrent, /* f2 */ - CloudCmd.View, /* f3 */ - CloudCmd.Edit, /* f4 */ - DOM.copyCurrent, /* f5 */ - DOM.moveCurrent, /* f6 */ - DOM.promptNewDir, /* f7 */ - DOM.promptDeleteSelected, /* f8 */ - CloudCmd.Menu, /* f9 */ - ]; - - for (i = 1; i <= 9; i++) { - lButton = 'f' + i, - lEl = DOM.getById('f' + i); - lKeysPanel[lButton] = lEl; - - if (i === 1 || i === 3 || i === 4 || i === 9) - Events.addOneTime('click', lFuncs[i], lEl); - else - Events.addClick(lFuncs[i], lEl); - } - - lButton = '~', - lEl = DOM.getById('~'); - lKeysPanel[lButton] = lEl; - Events.addOneTime('click', CloudCmd.Console, lEl); - - CloudCmd.KeysPanel = lKeysPanel; - Util.exec(pCallBack); - } function baseInit(pCallBack) { - var panels = DOM.getByClass('panel'), - i = 0, - n = panels.length, - preventDefault = function (event) { - event.stopPropagation(); - event.preventDefault(); - }, - toggle = function () { - for (i = 0; i < n; i++) - DOM.toggleClass(panels[i], 'selected-panel'); - }, - onDrop = function (event) { - var reader, file, files, - dir = DOM.getCurrentDirPath(), - load = function(file){ - return function(event) { - var path = dir + file.name, - data = event.target.result; - - DOM.RESTfull.save(path, data, CloudCmd.refresh); - }; - }; + var LIB = CloudCmd.LIBDIR, + LIBCLIENT = CloudCmd.LIBDIRCLIENT, + files = [ + LIB + 'cloudfunc.js', + LIBCLIENT + 'listeners.js' + ]; - preventDefault(event); - toggle(); - - files = event.dataTransfer.files; - - if (files.length) { - n = files.length; - - for (i = 0; i < n; i++) { - reader = new FileReader(); - file = files[i]; - Events.add('load', load(file), reader); - reader.readAsArrayBuffer(file); - } - } - }; - - if (window.applicationCache) - Events.add('updateready', function() { - var ret = confirm('An update is available. Reload now?'); - - if (ret) - location.reload(); - - }, applicationCache); - - Events.add(['dragenter', 'dragleave'], toggle); - - for (i = 0; i < n; i++) { - Events.add('dragover', preventDefault, panels[i]); - Events.add('drop', onDrop, panels[i]); - } - - /* загружаем общие функции для клиента и сервера */ - DOM.jsload(CloudCmd.LIBDIR + 'cloudfunc.js', function() { - Events.add("popstate", function(pEvent) { - var lPath = pEvent.state + '?json'; - - if (pEvent.state) { - lPath = pEvent.state + '?json'; - ajaxLoad(lPath, {nohistory: true}); - } else - route(location.hash); - - return true; - }); + DOM.anyLoadInParallel(files, function() { + Listeners = CloudCmd.Listeners; - changeLinks(CloudFunc.LEFTPANEL); - changeLinks(CloudFunc.RIGHTPANEL); + Listeners.init(); + /* загружаем Google Analytics */ + Listeners.analytics(); + Listeners.changeLinks(CloudFunc.LEFTPANEL); + Listeners.changeLinks(CloudFunc.RIGHTPANEL); + + CloudCmd.KeysPanel = Listeners.initKeysPanel(); /* устанавливаем переменную доступности кэша */ Cache.setAllowed(true); @@ -433,132 +315,16 @@ var Util, DOM, CloudFunc, CloudCmd; }); }; - - /** - * функция меняет ссыки на ajax-овые - * @param pPanelID - */ - function changeLinks(pPanelID){ - /* назначаем кнопку очистить кэш и показываем её */ - var lClearcache = DOM.getById('clear-cache'); - Events.addClick(Cache.clear, lClearcache); - - /* меняем ссылки на ajax-запросы */ - var lPanel = DOM.getById(pPanelID), - a = DOM.getByTag('a', lPanel), - - /* right mouse click function varible */ - lOnContextMenu_f = function(pEvent){ - var lReturn_b = true; - - Key && Key.unsetBind(); - - /* getting html element - * currentTarget - DOM event - * target - jquery event - */ - var lTarget = pEvent.currentTarget || pEvent.target; - DOM.setCurrentFile(lTarget); - - if(Util.isFunction(CloudCmd.Menu) ){ - CloudCmd.Menu({ - x: pEvent.clientX, - y: pEvent.clientY - }); - - /* disabling browsers menu*/ - lReturn_b = false; - DOM.Images.showLoad(); - } - - return lReturn_b; - }, - - /* drag and drop function varible - * download file from browser to descktop - * in Chrome (HTML5) - */ - lOnDragStart_f = function(pEvent){ - var lElement = pEvent.target, - lLink = lElement.href, - lName = lElement.textContent; - - /* if it's directory - adding json extension */ - if( DOM.isCurrentIsDir() ){ - lName += '.json'; - lLink += '?json'; - } - - pEvent.dataTransfer.setData("DownloadURL", - 'application/octet-stream' + ':' + - lName + ':' + - lLink); - }, - - lSetCurrentFile_f = function(pEvent){ - var pElement = pEvent.target, - lTag = pElement.tagName; - - if(lTag !== 'LI') - do{ - pElement = pElement.parentElement; - lTag = pElement.tagName; - }while(lTag !== 'LI'); - - DOM.setCurrentFile(pElement); - }, - - lUrl = CloudCmd.HOST, - lLoadDirOnce = CloudCmd.loadDir(); - - CloudCmd.refresh = function(pCurrent){ - var lNEEDREFRESH = true, - lPanel = pCurrent && pCurrent.parentElement, - lPath = DOM.getCurrentDirPath(lPanel), - lLink = CloudFunc.FS + lPath, - lNotSlashlLink = CloudFunc.removeLastSlash(lLink), - lLoad = CloudCmd.loadDir(lNotSlashlLink, lNEEDREFRESH); - lLoad(); - }; + CloudCmd.refresh = function(pCurrent){ + var lNEEDREFRESH = true, + lPanel = pCurrent && pCurrent.parentElement, + lPath = DOM.getCurrentDirPath(lPanel), + lLink = CloudFunc.FS + lPath, + lNotSlashlLink = CloudFunc.removeLastSlash(lLink), + lLoad = CloudCmd.loadDir(lNotSlashlLink, lNEEDREFRESH); - /* ставим загрузку гифа на клик*/ - Events.addClick( CloudCmd.refresh, a[0].parentElement ); - - /* start from 1 cous 0 is a path and it's setted up */ - for(var i = 1, n = a.length; i < n ; i++){ - /* убираем адрес хоста*/ - var ai = a[i], - lLink = Util.removeStr(ai.href, lUrl), - lLoadDir = CloudCmd.loadDir(lLink), - /* устанавливаем обработчики на строку - * на двойное нажатие на левую кнопку мышки */ - lLi = ai.parentElement.parentElement; - - /* if we in path - set click event */ - if (lLi.className === 'path') - Events.addClick( lLoadDir, ai ); - else { - Events.add({ - 'click' : DOM.preventDefault, - 'mousedown' : lSetCurrentFile_f, - 'contextmenu' : lOnContextMenu_f - }, lLi); - - Events.add('dragstart', lOnDragStart_f, ai); - - /* если ссылка на папку, а не файл */ - if(ai.target !== '_blank'){ - Events.add({ - 'dblclick' : lLoadDirOnce, - 'touchend' : lLoadDirOnce - }, lLi); - } - - lLi.id = (ai.title ? ai.title : ai.textContent) + - '(' + pPanelID + ')'; - } - } - } + lLoad(); + }; /** * Функция загружает json-данные о Файловой Системе @@ -681,7 +447,7 @@ var Util, DOM, CloudFunc, CloudCmd; DOM.setCurrentFile(lCurrent); - changeLinks(pElem); + Listeners.changeLinks(pElem); if(lName === '..' && lDir !== '/') currentToParent(lDir); @@ -730,11 +496,5 @@ var Util, DOM, CloudFunc, CloudCmd; return Util.stringifyJSON(lFileTable); } - Events.addOneTime('load', function(){ - /* базовая инициализация*/ - CloudCmd.init(); - - /* загружаем Google Analytics */ - CloudCmd.analytics(); - }); + DOM.Events.addOneTime('load', CloudCmd.init); })(Util, DOM); diff --git a/lib/client/listeners.js b/lib/client/listeners.js new file mode 100644 index 00000000..00a7dda1 --- /dev/null +++ b/lib/client/listeners.js @@ -0,0 +1,280 @@ +var Util, DOM, CloudCmd; + +(function (Util, DOM) { + 'use strict'; + + CloudCmd.Listeners = new ListenersProto(CloudCmd, Util, DOM); + + function ListenersProto(CloudCmd, Util, DOM){ + var Cache = DOM.Cache, + Events = DOM.Events; + + this.analytics = function(){ + Events.addOneTime('mousemove', function(){ + var lUrl = CloudCmd.LIBDIRCLIENT + 'analytics.js'; + + setTimeout(function(){ + DOM.jsload(lUrl); + }, 5000); + }); + }; + + this.init = function () { + appCache(); + contextMenu(); + dragndrop(); + unload(); + pop(); + }; + + this.initKeysPanel = function() { + var i, lButton, lEl, + lKeysPanel = {}, + + lFuncs =[ + null, + CloudCmd.Help, /* f1 */ + DOM.renameCurrent, /* f2 */ + CloudCmd.View, /* f3 */ + CloudCmd.Edit, /* f4 */ + DOM.copyCurrent, /* f5 */ + DOM.moveCurrent, /* f6 */ + DOM.promptNewDir, /* f7 */ + DOM.promptDeleteSelected, /* f8 */ + CloudCmd.Menu, /* f9 */ + ]; + + for (i = 1; i <= 9; i++) { + lButton = 'f' + i, + lEl = DOM.getById('f' + i); + lKeysPanel[lButton] = lEl; + + if (i === 1 || i === 3 || i === 4 || i === 9) + Events.addOneTime('click', lFuncs[i], lEl); + else + Events.addClick(lFuncs[i], lEl); + } + + lButton = '~', + lEl = DOM.getById('~'); + lKeysPanel[lButton] = lEl; + Events.addOneTime('click', CloudCmd.Console, lEl); + + return lKeysPanel; + }; + + /** + * функция меняет ссыки на ajax-овые + * @param pPanelID + */ + this.changeLinks = function(pPanelID){ + /* назначаем кнопку очистить кэш и показываем её */ + var lClearcache = DOM.getById('clear-cache'); + Events.addClick(Cache.clear, lClearcache); + + /* меняем ссылки на ajax-запросы */ + var lPanel = DOM.getById(pPanelID), + a = DOM.getByTag('a', lPanel), + + /* right mouse click function varible */ + lOnContextMenu_f = function(pEvent){ + var lReturn_b = true, + Key = CloudCmd.Key; + + Key && Key.unsetBind(); + + /* getting html element + * currentTarget - DOM event + * target - jquery event + */ + var lTarget = pEvent.currentTarget || pEvent.target; + DOM.setCurrentFile(lTarget); + + if(Util.isFunction(CloudCmd.Menu) ){ + CloudCmd.Menu({ + x: pEvent.clientX, + y: pEvent.clientY + }); + + /* disabling browsers menu*/ + lReturn_b = false; + DOM.Images.showLoad(); + } + + return lReturn_b; + }, + + /* drag and drop function varible + * download file from browser to descktop + * in Chrome (HTML5) + */ + lOnDragStart_f = function(pEvent){ + var lElement = pEvent.target, + lLink = lElement.href, + lName = lElement.textContent; + + /* if it's directory - adding json extension */ + if( DOM.isCurrentIsDir() ){ + lName += '.json'; + lLink += '?json'; + } + + pEvent.dataTransfer.setData("DownloadURL", + 'application/octet-stream' + ':' + + lName + ':' + + lLink); + }, + + lSetCurrentFile_f = function(pEvent){ + var pElement = pEvent.target, + lTag = pElement.tagName; + + if(lTag !== 'LI') + do{ + pElement = pElement.parentElement; + lTag = pElement.tagName; + }while(lTag !== 'LI'); + + DOM.setCurrentFile(pElement); + }, + + lUrl = CloudCmd.HOST, + lLoadDirOnce = CloudCmd.loadDir(); + + /* ставим загрузку гифа на клик*/ + Events.addClick( CloudCmd.refresh, a[0].parentElement ); + + /* start from 1 cous 0 is a path and it's setted up */ + for(var i = 1, n = a.length; i < n ; i++){ + /* убираем адрес хоста*/ + var ai = a[i], + lLink = Util.removeStr(ai.href, lUrl), + lLoadDir = CloudCmd.loadDir(lLink), + /* устанавливаем обработчики на строку + * на двойное нажатие на левую кнопку мышки */ + lLi = ai.parentElement.parentElement; + + /* if we in path - set click event */ + if (lLi.className === 'path') + Events.addClick( lLoadDir, ai ); + else { + Events.add({ + 'click' : DOM.preventDefault, + 'mousedown' : lSetCurrentFile_f, + 'contextmenu' : lOnContextMenu_f + }, lLi); + + Events.add('dragstart', lOnDragStart_f, ai); + + /* если ссылка на папку, а не файл */ + if(ai.target !== '_blank'){ + Events.add({ + 'dblclick' : lLoadDirOnce, + 'touchend' : lLoadDirOnce + }, lLi); + } + + lLi.id = (ai.title ? ai.title : ai.textContent) + + '(' + pPanelID + ')'; + } + } + }; + + function appCache() { + if (window.applicationCache) + Events.add('updateready', function() { + var ret = confirm('An update is available. Reload now?'); + + if (ret) + location.reload(); + + }, applicationCache); + } + + function contextMenu() { + Events.addContextMenu(function(pEvent){ + CloudCmd.Menu.ENABLED || DOM.preventDefault(pEvent); + }, document); + } + + function dragndrop() { + var panels = DOM.getByClass('panel'), + i = 0, + n = panels.length, + preventDefault = function (event) { + event.stopPropagation(); + event.preventDefault(); + }, + toggle = function () { + for (i = 0; i < n; i++) + DOM.toggleClass(panels[i], 'selected-panel'); + }, + onDrop = function (event) { + var reader, file, files, + dir = DOM.getCurrentDirPath(), + load = function(file){ + return function(event) { + var path = dir + file.name, + data = event.target.result; + + DOM.RESTfull.save(path, data, CloudCmd.refresh); + }; + }; + + preventDefault(event); + toggle(); + + files = event.dataTransfer.files; + + if (files.length) { + n = files.length; + + for (i = 0; i < n; i++) { + reader = new FileReader(); + file = files[i]; + Events.add('load', load(file), reader); + reader.readAsArrayBuffer(file); + } + } + }; + + Events.add(['dragenter', 'dragleave'], toggle); + + for (i = 0; i < n; i++) { + Events.add('dragover', preventDefault, panels[i]); + Events.add('drop', onDrop, panels[i]); + } + } + + function unload() { + DOM.Events.add(['unload', 'beforeunload'], function (pEvent) { + var lRet, + Key = CloudCmd.Key, + lIsBind = Key && Key.isBind(); + + if(!lIsBind) { + DOM.preventDefault(pEvent); + lRet = 'Please make sure that you saved all work.'; + } + + return lRet; + }); + } + + function pop() { + Events.add("popstate", function(pEvent) { + var lPath = pEvent.state + '?json'; + + if (pEvent.state) { + lPath = pEvent.state + '?json'; + ajaxLoad(lPath, {nohistory: true}); + } else + route(location.hash); + + return true; + }); + } + + } + +})(Util, DOM); From 6852802b2315e59a0018dc1fde9c073bc7d6ab8d Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 18 Sep 2013 11:09:36 +0000 Subject: [PATCH 148/218] fix(rest) stream.createPipe -> pipe.create --- lib/server/rest.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/server/rest.js b/lib/server/rest.js index 90b05d84..d981ba77 100644 --- a/lib/server/rest.js +++ b/lib/server/rest.js @@ -319,7 +319,7 @@ case 'cp': if (Util.checkObjTrue(lFiles, ['from', 'to'])) - stream.createPipe({ + pipe.create({ from : lFiles.from, to : lFiles.to, callback : function(pError) { @@ -335,7 +335,7 @@ case 'zip': if (Util.checkObjTrue(lFiles, ['from'])) - stream.createPipe({ + pipe.create({ from : lFiles.from, to : lFiles.to || lFiles.from + '.zip', zip : true, From 78159d1121f2d87fa21053a51d5efce0151b0740 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 18 Sep 2013 11:12:29 +0000 Subject: [PATCH 149/218] docs(contributting) "type(scope): subject" -> "type(scope) subject" --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 823924c1..f965b779 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,7 +19,7 @@ so to get it you should type a couple more commands: Commit --------------- -Format of the commit message: **type(scope): subject** +Format of the commit message: **type(scope) subject** **Type**: - feature From 63aeb60a051737d56c912fc65c75004352c06081 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 18 Sep 2013 13:59:31 +0000 Subject: [PATCH 150/218] chore(client) getpPathTemplate -> getPathTemplate --- lib/client.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/client.js b/lib/client.js index 7b0af0e2..60bcf060 100644 --- a/lib/client.js +++ b/lib/client.js @@ -300,7 +300,7 @@ var Util, DOM, CloudFunc, CloudCmd; CloudCmd.getConfig = getSystemFile(Config, CloudCmd.JSONDIR + 'config.json'); CloudCmd.getModules = getSystemFile(Modules, CloudCmd.JSONDIR + 'modules.json'); CloudCmd.getFileTemplate = getSystemFile(FileTemplate, CloudCmd.HTMLDIR + 'file.html'); - CloudCmd.getpPathTemplate = getSystemFile(PathTemplate, CloudCmd.HTMLDIR + 'path.html'); + CloudCmd.getPathTemplate = getSystemFile(PathTemplate, CloudCmd.HTMLDIR + 'path.html'); CloudCmd.execFromModule = function(pModuleName, pFuncName, pParams){ var lObject = CloudCmd[pModuleName]; @@ -416,7 +416,7 @@ var Util, DOM, CloudFunc, CloudCmd; lWasRefresh_b = lPath[0].textContent === pJSON[0].path; CloudCmd.getFileTemplate(function(pTemplate){ - CloudCmd.getpPathTemplate(function(pPathTemplate){ + CloudCmd.getPathTemplate(function(pPathTemplate){ /* очищаем панель */ var i = lElem.childNodes.length; From 90f944cb6367dfe1d6a19ddcbd3c36fef704a045 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 18 Sep 2013 14:11:57 +0000 Subject: [PATCH 151/218] feature(config) add analytics --- json/config.json | 1 + lib/client/listeners.js | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/json/config.json b/json/config.json index b012c13a..5447f706 100644 --- a/json/config.json +++ b/json/config.json @@ -1,6 +1,7 @@ { "api_url" : "/api/v1", "appcache" : false, + "analytics" : true, "minification" : { "js" : true, "css" : true, diff --git a/lib/client/listeners.js b/lib/client/listeners.js index 00a7dda1..20a570ff 100644 --- a/lib/client/listeners.js +++ b/lib/client/listeners.js @@ -9,13 +9,17 @@ var Util, DOM, CloudCmd; var Cache = DOM.Cache, Events = DOM.Events; - this.analytics = function(){ - Events.addOneTime('mousemove', function(){ - var lUrl = CloudCmd.LIBDIRCLIENT + 'analytics.js'; - - setTimeout(function(){ - DOM.jsload(lUrl); - }, 5000); + this.analytics = function() { + CloudCmd.getConfig(function(config) { + if (config.analytics) { + Events.addOneTime('mousemove', function(){ + var lUrl = CloudCmd.LIBDIRCLIENT + 'analytics.js'; + + setTimeout(function(){ + DOM.jsload(lUrl); + }, 5000); + }); + } }); }; From 9c3a0cd079b529b36a8f378fc4ae313804def92f Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 18 Sep 2013 14:15:34 +0000 Subject: [PATCH 152/218] refactor(listeners) 5000 -> FIVE_SECONDS --- lib/client/listeners.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/client/listeners.js b/lib/client/listeners.js index 20a570ff..340b0534 100644 --- a/lib/client/listeners.js +++ b/lib/client/listeners.js @@ -13,11 +13,12 @@ var Util, DOM, CloudCmd; CloudCmd.getConfig(function(config) { if (config.analytics) { Events.addOneTime('mousemove', function(){ - var lUrl = CloudCmd.LIBDIRCLIENT + 'analytics.js'; + var FIVE_SECONDS = 5000, + lUrl = CloudCmd.LIBDIRCLIENT + 'analytics.js'; setTimeout(function(){ DOM.jsload(lUrl); - }, 5000); + }, FIVE_SECONDS); }); } }); From 0634633101d12d297bfed6993ad7b2cdb67467e0 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 18 Sep 2013 14:33:40 +0000 Subject: [PATCH 153/218] feature(config) add localStorage --- json/config.json | 1 + lib/client.js | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/json/config.json b/json/config.json index 5447f706..4b910d41 100644 --- a/json/config.json +++ b/json/config.json @@ -2,6 +2,7 @@ "api_url" : "/api/v1", "appcache" : false, "analytics" : true, + "localStorage" : true, "minification" : { "js" : true, "css" : true, diff --git a/lib/client.js b/lib/client.js index 60bcf060..1583ec2b 100644 --- a/lib/client.js +++ b/lib/client.js @@ -211,12 +211,15 @@ var Util, DOM, CloudFunc, CloudCmd; CloudCmd.KeysPanel = Listeners.initKeysPanel(); - /* устанавливаем переменную доступности кэша */ - Cache.setAllowed(true); - /* Устанавливаем кэш корневого каталога */ - var lDirPath = DOM.getCurrentDirPath(); - if (!Cache.get(lDirPath)) - Cache.set(lDirPath, getJSONfromFileTable()); + CloudCmd.getConfig(function(config) { + var localStorage = config.localStorage; + /* устанавливаем переменную доступности кэша */ + Cache.setAllowed(localStorage); + /* Устанавливаем кэш корневого каталога */ + var lDirPath = DOM.getCurrentDirPath(); + if (!Cache.get(lDirPath)) + Cache.set(lDirPath, getJSONfromFileTable()); + }); }); /* выделяем строку с первым файлом */ From 2436f3b3930846c3fff32c531c73c8d2dce8263e Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 19 Sep 2013 09:10:54 +0300 Subject: [PATCH 154/218] docs(readme) change start: add port, link --- README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 2124e36a..2293bb1f 100644 --- a/README.md +++ b/README.md @@ -194,15 +194,14 @@ To start **Cloud Commander** only one command neaded: or on win platform just cloudcmd -After thet Cloud Commander reads config file **config.json** and start server -on 80 port, if none of port varibles(*cloud9*, *cloudfoundry* and *nodester*) -isn't exist. +After thet Cloud Commander reads port information from config file [config.json](json/config.json#L17) and start server +on this port ( **8000** by default ), if none of port varibles ( *cloud9*, *cloudfoundry* and *nodester* ) isn't exist. Then type in browser - http://127.0.0.1 + http://127.0.0.1:8000 or - http://localhost + http://localhost:8000 Update --------------- **Cloud Commander** is very often updates. From 10a3df45e8e7bfdccd5696e0572a4cb854d0014f Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 19 Sep 2013 09:20:28 +0300 Subject: [PATCH 155/218] docs(readme) configuration: add appcache, analytics; change " " --- README.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 2293bb1f..e64a7a4c 100644 --- a/README.md +++ b/README.md @@ -122,24 +122,26 @@ Configuration All main configuration could be done thrue config.json. ```js { - "api_url" :"/api/v1", - "appcache" : false, /* html5 feature appcache */ - "cache" : true, /* cashing on a client */ + "api_url" :"/api/v1", + "appcache" : false, /* cache files for offline use */ + "analytics" : true, /* google analytics suport */ + "localStorage" : true, /* cache directory data */ "minification" : { /* minification of js,css,html and img */ "js" : false, /* minify module neaded */ "css" : false, /* npm i minify */ "html" : true, "img" : false }, - "show_keys_panel" : true, /* show classic panel with buttons of keys */ - "server" : true, /* server mode or testing mode */ - "logs" : false, /* logs or console ouput */ - "socket" : true /* enable web sockets */ - "port" : 80, /* http port or null(default) */ - "sslPort" : 443, /* https port or null(default) */ - "ip" : "127.0.0.1", /* ip or null(default) */ - "ssl" : true /* should use https? */ - "rest" : true /* enable rest interface */ + "cache" : true, + "logs" : false, /* logs or console ouput */ + "show_keys_panel" : true, /* show classic panel with buttons of keys */ + "server" : true, /* server mode or testing mode */ + "socket" : true /* enable web sockets */ + "port" : 8000, /* http port or null(default) */ + "sslPort" : 443, /* https port or null(default) */ + "ip" : null, /* ip or null(default) */ + "ssl" : false /* should use https? */ + "rest" : true /* enable rest interface */ } ``` From c817e34630cfe684aaf1f08b98e334d39d665193 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 19 Sep 2013 14:52:42 +0300 Subject: [PATCH 156/218] docs(readme) Cloud Commander install is very easy -> Installing Cloud Commander is very simple --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e64a7a4c..ca44c8c2 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ Install --------------- [![NPM_INFO][NPM_INFO_IMG]][NPM_INFO_URL] -**Cloud Commander** install is very easy. +Installing **Cloud Commander** is very simple. All you need is - install [node.js](http://nodejs.org/ "node.js") - [download](https://github.com/coderaiser/cloudcmd/archive/master.zip) From 02b10d68c6f4ad39f678abddd367141129751523 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 19 Sep 2013 11:58:10 +0000 Subject: [PATCH 157/218] feature(listeners) appCache: add getConfig --- lib/client/listeners.js | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/client/listeners.js b/lib/client/listeners.js index 340b0534..5b6519a2 100644 --- a/lib/client/listeners.js +++ b/lib/client/listeners.js @@ -7,10 +7,11 @@ var Util, DOM, CloudCmd; function ListenersProto(CloudCmd, Util, DOM){ var Cache = DOM.Cache, - Events = DOM.Events; + Events = DOM.Events, + getConfig = CloudCmd.getConfig; this.analytics = function() { - CloudCmd.getConfig(function(config) { + getConfig(function(config) { if (config.analytics) { Events.addOneTime('mousemove', function(){ var FIVE_SECONDS = 5000, @@ -186,14 +187,19 @@ var Util, DOM, CloudCmd; }; function appCache() { - if (window.applicationCache) - Events.add('updateready', function() { - var ret = confirm('An update is available. Reload now?'); - - if (ret) - location.reload(); + getConfig(function(config) { + var isAppCache = config.appcache, + appCache = window.applicationCache; - }, applicationCache); + if (isAppCache && appCache) + Events.add('updateready', function() { + var ret = confirm('An update is available. Reload now?'); + + if (ret) + location.reload(); + + }, appCache); + }); } function contextMenu() { From aba5107ac0d37b6cca3f14d86562f31c36dcb4ed Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 19 Sep 2013 13:38:51 +0000 Subject: [PATCH 158/218] refactor(dom) Loader ajax: add TYPE_JSON --- lib/client/dom.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/client/dom.js b/lib/client/dom.js index f410f964..ccbf7d4e 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -687,14 +687,15 @@ var CloudCmd, Util, DOM, CloudFunc; Events.add('readystatechange', function(pEvent) { if (xhr.readyState === 4 /* Complete */) { - var lJqXHR = pEvent.target, - lType = xhr.getResponseHeader('content-type'); + var lJqXHR = pEvent.target, + TYPE_JSON = 'application/json', + lType = xhr.getResponseHeader('content-type'); if (xhr.status === 200 /* OK */) { var lData = lJqXHR.response; /* If it's json - parse it as json */ - if (lType && Util.isContainStr(lType, 'application/json') ) + if (lType && Util.isContainStr(lType, TYPE_JSON) ) lData = Util.parseJSON(lJqXHR.response) || lJqXHR.response; if ( Util.isFunction(p.success) ) From a4a04eaf0cf2cf0a1ee23d7d4c148f898c077c5a Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 19 Sep 2013 14:12:16 +0000 Subject: [PATCH 159/218] fix(dom) Loader ajax: add dataType --- lib/client/dom.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/client/dom.js b/lib/client/dom.js index ccbf7d4e..8b3fc1e5 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -694,9 +694,10 @@ var CloudCmd, Util, DOM, CloudFunc; if (xhr.status === 200 /* OK */) { var lData = lJqXHR.response; - /* If it's json - parse it as json */ - if (lType && Util.isContainStr(lType, TYPE_JSON) ) - lData = Util.parseJSON(lJqXHR.response) || lJqXHR.response; + if (p.dataType !== 'text') + /* If it's json - parse it as json */ + if (lType && Util.isContainStr(lType, TYPE_JSON) ) + lData = Util.parseJSON(lJqXHR.response) || lJqXHR.response; if ( Util.isFunction(p.success) ) p.success(lData, lJqXHR.statusText, lJqXHR); @@ -1381,7 +1382,9 @@ var CloudCmd, Util, DOM, CloudFunc; if ( this.isCurrentIsDir(lCurrentFile) ) - lPath += '?json'; + lPath += '?json'; + else + lParams.dataType = 'text'; if (!lParams.url) lParams.url = CloudFunc.FS + lPath; From f8aded554dea8a3ab7e033641009f185aceddcd1 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 19 Sep 2013 17:52:46 +0300 Subject: [PATCH 160/218] docs(readme) heppen -> happens --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ca44c8c2..4d1e7fcd 100644 --- a/README.md +++ b/README.md @@ -29,8 +29,8 @@ Benefits - responsible design - one full page loading, *and then just one-time json-dir-listings loading (with refresh opportunity).* -- caching readed directories *to localStorage (for now) -(so if network will disconnected or something heppen with a signal, we +- caching read directories *to localStorage (for now) +(so if network will disconnected or something happens with a signal, we definitely will can work with cached copy of directory listings)*; - key binding - disabled js support *(working in limited mode)*. From 0cc47d9cbe00b9f0b35398c30529a156766e0be3 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 19 Sep 2013 17:55:04 +0300 Subject: [PATCH 161/218] docs(readme) neaded -> needed --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4d1e7fcd..e28d3274 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,7 @@ All main configuration could be done thrue config.json. "analytics" : true, /* google analytics suport */ "localStorage" : true, /* cache directory data */ "minification" : { /* minification of js,css,html and img */ - "js" : false, /* minify module neaded */ + "js" : false, /* minify module needed */ "css" : false, /* npm i minify */ "html" : true, "img" : false @@ -190,7 +190,7 @@ or **shell/secret.sh** *(on nix)*. Start --------------- -To start **Cloud Commander** only one command neaded: +To start **Cloud Commander** only one command needed: node cloudcmd or on win platform just From 509eab3bb524ac3a1c39822cdb3e169f41064aa9 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 20 Sep 2013 10:52:21 +0300 Subject: [PATCH 162/218] docs(readme) "Thru openID Cloud Commander could authorize clients on GitHub" -> "Cloud Commander could authorize clients on GitHub via openID" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e28d3274..2c1fa3c7 100644 --- a/README.md +++ b/README.md @@ -180,7 +180,7 @@ do something like this: Authorization --------------- -Thru openID Cloud Commander could authorize clients on GitHub. +Cloud Commander could authorize clients on GitHub via openID. All things that should be done is must be added **id** and **secret** of application from github settings page and added to **config.json** (id just) and env varible (secret) with names: *github_id*, *github_secret*, *dropbox_key*, *dropbox_secret* etc. From 94f45b75f8ebb6c407e6d160206d82cbb67604da Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 20 Sep 2013 11:02:49 +0300 Subject: [PATCH 163/218] docs(readme) Authorization: add links: secret.sh, secret.bat, config -> modules --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2c1fa3c7..37e9c978 100644 --- a/README.md +++ b/README.md @@ -182,10 +182,9 @@ Authorization --------------- Cloud Commander could authorize clients on GitHub via openID. All things that should be done is must be added **id** and **secret** of application -from github settings page and added to **config.json** (id just) and env varible (secret) -with names: *github_id*, *github_secret*, *dropbox_key*, *dropbox_secret* etc. -For more information see **config.json** and **shell/seret.bat** *(on win32)* -or **shell/secret.sh** *(on nix)*. +from github settings page and added to [modules.json](json/modules.json) (id just) and env varible (secret) +with names: *github_id*, *github_secret*, *dropbox_key*, *dropbox_secret* etc in +[secret.bat](shell/secret.bat) *(on win32)* or [secret.sh](shell/secret.sh) *(on nix)*. Start From 21055537d8f6283e5c493cd273d7b8c0fcca541a Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 20 Sep 2013 12:02:00 +0300 Subject: [PATCH 164/218] docs(readme) Benefits: moves -> go --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 37e9c978..9b56a78c 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ definitely will can work with cached copy of directory listings)*; - automated minification *client js-files and onstart-reading Cloud manager files on server starting.* **Cloud Commander** uses all benefits of js, so if js is disabled, -we moves to *limited mode*. +we go to *limited mode*. Limited-mode features --------------- From d22bef234ccfeaa3af27e682e6bc2bf47c436356 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 20 Sep 2013 11:10:16 +0000 Subject: [PATCH 165/218] feature(util) add asyncCall --- lib/client.js | 76 ++++++++++++++++++++++++++------------------------- lib/util.js | 26 ++++++++++++++++++ 2 files changed, 65 insertions(+), 37 deletions(-) diff --git a/lib/client.js b/lib/client.js index 1583ec2b..00179638 100644 --- a/lib/client.js +++ b/lib/client.js @@ -416,46 +416,48 @@ var Util, DOM, CloudFunc, CloudCmd; lDir = DOM.getCurrentDirName(), lName = DOM.getCurrentName(lCurrent), - lWasRefresh_b = lPath[0].textContent === pJSON[0].path; + lWasRefresh_b = lPath[0].textContent === pJSON[0].path, + lFuncs = [ + CloudCmd.getFileTemplate, + CloudCmd.getPathTemplate + ]; - CloudCmd.getFileTemplate(function(pTemplate){ - CloudCmd.getPathTemplate(function(pPathTemplate){ - /* очищаем панель */ - var i = lElem.childNodes.length; - - while(i--) - lElem.removeChild(lElem.lastChild); - - lElem.innerHTML = CloudFunc.buildFromJSON(pJSON, pTemplate, pPathTemplate); - - /* если нажали на ссылку на верхний каталог*/ - var lFound; - /* searching current file */ - if(lWasRefresh_b){ - var n = lElem.childNodes.length; - for(i = 2; i < n ; i++){ - var lVarCurrent = lElem.childNodes[i], - lVarName = DOM.getCurrentName(lVarCurrent); - - lFound = lVarName === lName; - - if(lFound){ - lCurrent = lElem.childNodes[i]; - break; - } + Util.asyncCall(lFuncs, function(pTemplate, pPathTemplate) { + /* очищаем панель */ + var i = lElem.childNodes.length; + + while(i--) + lElem.removeChild(lElem.lastChild); + + lElem.innerHTML = CloudFunc.buildFromJSON(pJSON, pTemplate, pPathTemplate); + + /* если нажали на ссылку на верхний каталог*/ + var lFound; + /* searching current file */ + if(lWasRefresh_b){ + var n = lElem.childNodes.length; + for(i = 2; i < n ; i++){ + var lVarCurrent = lElem.childNodes[i], + lVarName = DOM.getCurrentName(lVarCurrent); + + lFound = lVarName === lName; + + if(lFound){ + lCurrent = lElem.childNodes[i]; + break; } } - if(!lFound) /* .. */ - lCurrent = lElem.childNodes[2]; - - DOM.setCurrentFile(lCurrent); - - Listeners.changeLinks(pElem); - - if(lName === '..' && lDir !== '/') - currentToParent(lDir); - }); - }); + } + if(!lFound) /* .. */ + lCurrent = lElem.childNodes[2]; + + DOM.setCurrentFile(lCurrent); + + Listeners.changeLinks(pElem); + + if(lName === '..' && lDir !== '/') + currentToParent(lDir); + }); } /** diff --git a/lib/util.js b/lib/util.js index a32f7bc5..e9439122 100644 --- a/lib/util.js +++ b/lib/util.js @@ -10,6 +10,32 @@ Util = exports || {}; var Scope = exports ? global : window; + Util.asyncCall = function(pFuncs, pOnLoad, pContext) { + var i, element, name, func, + n = pFuncs.length, + count = 0, + data = []; + + for (i = 0; i < n; i++) { + func = pFuncs[i]; + callCheckFunc(i, func); + } + + function checkFunc(pNum, pData) { + ++count; + data[pNum] = pData; + + if (count === n) + pOnLoad.apply(pContext, data); + } + + function callCheckFunc(pNum, pFunc) { + Util.exec(pFunc, function(pData){ + checkFunc(pNum, pData); + }); + } + }, + /** setting function context * @param {function} pFunction * @param {object} pContext From ca18d14799f6e3a30191ddaea29e7d4db1a9bad3 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 20 Sep 2013 14:17:33 +0300 Subject: [PATCH 166/218] docs(readme) Contributing: "version Cloud Commander" -> "version of Cloud Commander" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9b56a78c..e9973104 100644 --- a/README.md +++ b/README.md @@ -258,7 +258,7 @@ Getting dev version of **Cloud Commander**: git clone git://github.com/coderaiser/cloudcmd.git git checkout dev -It is possible thet dev version Cloud Commander will needed dev version of Minify, +It is possible thet dev version of Cloud Commander will needed dev version of Minify, so to get it you should type a couple more commands: cd node_modules From 73f758e31355ef8badd01c5a3a6826069710a2e8 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 20 Sep 2013 11:18:44 +0000 Subject: [PATCH 167/218] fix(dom) getCurrentFileContent: add dataType check --- lib/client.js | 2 ++ lib/client/dom.js | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/client.js b/lib/client.js index 00179638..7a70fc33 100644 --- a/lib/client.js +++ b/lib/client.js @@ -382,6 +382,8 @@ var Util, DOM, CloudFunc, CloudCmd; DOM.getCurrentFileContent({ url : lFSPath, + dataType: 'json', + error : function(){ DOM.setHistory(lOldURL, null, lOldURL); }, diff --git a/lib/client/dom.js b/lib/client/dom.js index 8b3fc1e5..cb09fc96 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -1383,7 +1383,7 @@ var CloudCmd, Util, DOM, CloudFunc; if ( this.isCurrentIsDir(lCurrentFile) ) lPath += '?json'; - else + else if (!lParams.dataType) lParams.dataType = 'text'; if (!lParams.url) From 32987e5000810f0c4deb3866c5b9abc11cddb54b Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 20 Sep 2013 11:33:11 +0000 Subject: [PATCH 168/218] docs(readme) Authorization: varible -> variable --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e9973104..52c6f7cc 100644 --- a/README.md +++ b/README.md @@ -182,7 +182,7 @@ Authorization --------------- Cloud Commander could authorize clients on GitHub via openID. All things that should be done is must be added **id** and **secret** of application -from github settings page and added to [modules.json](json/modules.json) (id just) and env varible (secret) +from github settings page and added to [modules.json](json/modules.json) (id just) and env variable (secret) with names: *github_id*, *github_secret*, *dropbox_key*, *dropbox_secret* etc in [secret.bat](shell/secret.bat) *(on win32)* or [secret.sh](shell/secret.sh) *(on nix)*. From 5fa3849d5afe937f453139247f7a61ceee82ed28 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 20 Sep 2013 11:35:26 +0000 Subject: [PATCH 169/218] docs(readme) Server: reles -> rules --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 52c6f7cc..3eb93576 100644 --- a/README.md +++ b/README.md @@ -157,7 +157,7 @@ Just run [shell/addtables.sh](shell/addtables.sh) for default options. @:/tmp/cloudcmd (dev) $ sudo iptables -t nat -L # look rules before @:/tmp/cloudcmd (dev) $ sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8000 @:/tmp/cloudcmd (dev) $ sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 4430 -@:/tmp/cloudcmd (dev) $ sudo iptables -t nat -L # look reles after +@:/tmp/cloudcmd (dev) $ sudo iptables -t nat -L # look rules after ``` You should see somethins like this ( **8000** and **4430** should be in config as **port** and **sslPort** ) From 3d9121ef96d530f99d8e9f0763bb98edbed4837e Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 20 Sep 2013 11:52:45 +0000 Subject: [PATCH 170/218] docs(readme) Server: somethins -> something --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3eb93576..3a9ad7dd 100644 --- a/README.md +++ b/README.md @@ -159,7 +159,7 @@ Just run [shell/addtables.sh](shell/addtables.sh) for default options. @:/tmp/cloudcmd (dev) $ sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 4430 @:/tmp/cloudcmd (dev) $ sudo iptables -t nat -L # look rules after ``` -You should see somethins like this ( **8000** and **4430** should be in config as **port** and **sslPort** ) +You should see something like this ( **8000** and **4430** should be in config as **port** and **sslPort** ) target prot opt source destination REDIRECT tcp -- anywhere anywhere tcp dpt:http redir ports 8000 From 4ad0cd79bdb06829f58ba7f0d2269c65382ad219 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 20 Sep 2013 13:21:25 +0000 Subject: [PATCH 171/218] fix(client) route -> CloudCmd.route --- lib/client.js | 42 ++++++++++++++++++++--------------------- lib/client/listeners.js | 2 +- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/lib/client.js b/lib/client.js index 7a70fc33..9eeb9df9 100644 --- a/lib/client.js +++ b/lib/client.js @@ -120,7 +120,7 @@ var Util, DOM, CloudFunc, CloudCmd; CloudCmd.init = function(){ var lCallBack = function(){ Util.loadOnLoad([ - Util.retExec(route, location.hash), + Util.retExec(CloudCmd.route, location.hash), initModules, baseInit ]); @@ -137,6 +137,26 @@ var Util, DOM, CloudFunc, CloudCmd; Util.ifExec(document.body.scrollIntoViewIfNeeded, lCallBack, lFunc); }; + CloudCmd.route = function(pPath){ + var lQuery, lModule, lFile, lCurrent; + + if (pPath.length > 0) { + lQuery = pPath.split('/'); + + if (lQuery.length > 0) { + lModule = Util.getStrBigFirst(lQuery[1]); + lFile = lQuery[2]; + lCurrent = DOM.getCurrentFileByName(lFile); + if (lFile && !lCurrent) + Util.log('set current file: error("' + lFile + '")'); + else { + DOM.setCurrentFile(lCurrent); + CloudCmd.execFromModule(lModule, 'show'); + } + } + } + }; + function initModules(pCallBack){ loadModule({ /* привязываем клавиши к функциям */ @@ -260,26 +280,6 @@ var Util, DOM, CloudFunc, CloudCmd; CloudCmd.Key(); } - function route(pPath){ - var lQuery, lModule, lFile, lCurrent; - - if (pPath.length > 0) { - lQuery = pPath.split('/'); - - if (lQuery.length > 0) { - lModule = Util.getStrBigFirst(lQuery[1]); - lFile = lQuery[2]; - lCurrent = DOM.getCurrentFileByName(lFile); - if (lFile && !lCurrent) - Util.log('set current file: error("' + lFile + '")'); - else { - DOM.setCurrentFile(lCurrent); - CloudCmd.execFromModule(lModule, 'show'); - } - } - } - } - function getSystemFile(pGlobal, pURL){ function lGetSysFile(pCallBack){ diff --git a/lib/client/listeners.js b/lib/client/listeners.js index 5b6519a2..f74dbcb9 100644 --- a/lib/client/listeners.js +++ b/lib/client/listeners.js @@ -280,7 +280,7 @@ var Util, DOM, CloudCmd; lPath = pEvent.state + '?json'; ajaxLoad(lPath, {nohistory: true}); } else - route(location.hash); + CloudCmd.route(location.hash); return true; }); From 055d4ca2d129a6e2d8d8cd6f01221c9af8f8ac52 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 20 Sep 2013 14:58:00 +0000 Subject: [PATCH 172/218] feature(dom) DOMTreeProto: add DOM --- lib/client/dom.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/client/dom.js b/lib/client/dom.js index cb09fc96..1a961cf9 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -216,6 +216,7 @@ var CloudCmd, Util, DOM, CloudFunc; }, DOMTreeProto = function() { + var DOM = this; /** * add class to element * @@ -303,11 +304,11 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pElement */ this.hide = function(pElement) { - return this.addClass(pElement, 'hidden'); + return DOM.addClass(pElement, 'hidden'); }; this.show = function(pElement) { - this.removeClass(pElement, 'hidden'); + return DOM.removeClass(pElement, 'hidden'); }; }, From 8896434fc91e54966911ac7874519b0b20b8889f Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 23 Sep 2013 07:44:20 +0000 Subject: [PATCH 173/218] feature(edit) add showMessage --- lib/client/edit.js | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/lib/client/edit.js b/lib/client/edit.js index 0e4d3277..85b8c964 100644 --- a/lib/client/edit.js +++ b/lib/client/edit.js @@ -11,6 +11,7 @@ var CloudCmd, Util, DOM, JsDiff, ace; Value, Edit = this, Ace, + Msg, Key = CloudCmd.Key, Images = DOM.Images, @@ -121,7 +122,12 @@ var CloudCmd, Util, DOM, JsDiff, ace; var lPath = DOM.getCurrentPath(), lValue = Ace.getValue(); - DOM.RESTfull.save(lPath, lValue); + DOM.RESTfull.save(lPath, lValue, function() { + var name = DOM.getCurrentName(), + msg = 'save: ok("' + name + '")'; + + Edit.showMessage(msg); + }); } }); } @@ -152,6 +158,38 @@ var CloudCmd, Util, DOM, JsDiff, ace; Edit.show(); } } + + this.showMessage = function(text) { + var parent, + TWO_SECONDS = 2000; + + if (!Msg) { + DOM.cssSet({ + id : 'msg-css', + inner : '.msg {' + + 'z-index' + ': 1;' + + 'background-color' + ': white;' + + 'color' + ': rgb(49, 123, 249);' + + 'position' + ': fixed;' + + 'left' + ': 40%;' + + 'padding' + ': 5px;' + + 'opacity' + ': 0.9;' + + 'transition' + ': ease 0.5s;' + + '}' + }); + parent = Element;//.parentElement; + + Msg = DOM.anyload({ + name : 'div', + className : 'msg', + parent : parent + }); + } + + Msg.innerHTML = text; + DOM.show(Msg); + setTimeout(Util.retExec(DOM.hide, Msg), 2000); + }; } })(CloudCmd, Util, DOM); From cf0059fa2e47a1cbfc84208719f3eca3ec47f270 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 23 Sep 2013 09:05:44 +0000 Subject: [PATCH 174/218] chore(cloudfunc) add " " --- lib/cloudfunc.js | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/cloudfunc.js b/lib/cloudfunc.js index e9abed7b..be9a7177 100644 --- a/lib/cloudfunc.js +++ b/lib/cloudfunc.js @@ -1,6 +1,6 @@ var Util, exports, CloudFunc = {}; -(function(Util, CloudFunc, exports){ +(function(Util, CloudFunc, exports) { 'use strict'; /** @@ -8,7 +8,7 @@ var Util, exports, CloudFunc = {}; * будут работать и на клиенте и на сервере */ var FS; - if(exports){ + if(exports) { if(!global.cloudcmd) return console.log( '# cloudfunc.js' + '\n' + @@ -45,7 +45,7 @@ var Util, exports, CloudFunc = {}; * Функция убирает последний слеш, * если он - последний символ строки */ - CloudFunc.removeLastSlash = function(pPath){ + CloudFunc.removeLastSlash = function(pPath) { var lRet = pPath, lIsStr = typeof pPath==='string', lLengh = pPath.length-1, @@ -60,7 +60,7 @@ var Util, exports, CloudFunc = {}; /** Функция возвращает заголовок веб страницы * @pPath */ - CloudFunc.getTitle = function(pPath){ + CloudFunc.getTitle = function(pPath) { if(!CloudFunc.Path) CloudFunc.Path = '/'; @@ -72,7 +72,7 @@ var Util, exports, CloudFunc = {}; * @param pPerm_s - строка с правами доступа * к файлу в 8-миричной системе */ - CloudFunc.getSymbolicPermissions = function(pPerm_s){ + CloudFunc.getSymbolicPermissions = function(pPerm_s) { /* S_IRUSR 0000400 protection: readable by owner S_IWUSR 0000200 writable by owner @@ -145,7 +145,7 @@ var Util, exports, CloudFunc = {}; * Функция конвертирует права доступа к файлам из символьного вида * в цыфровой */ - CloudFunc.getNumericPermissions = function(pPerm_s){ + CloudFunc.getNumericPermissions = function(pPerm_s) { if(!pPerm_s || pPerm_s.length!==11)return pPerm_s; var lOwner= (pPerm_s[0] === 'r' ? 4 : 0) + @@ -169,8 +169,8 @@ var Util, exports, CloudFunc = {}; * гигайбайты и терабайты * @pSize - размер в байтах */ - CloudFunc.getShortSize = function(pSize){ - if (pSize === pSize-0){ + CloudFunc.getShortSize = function(pSize) { + if (pSize === pSize-0) { /* Константы размеров, что используются внутри функции */ var l1KB = 1024, l1MB = l1KB * l1KB, @@ -194,7 +194,7 @@ var Util, exports, CloudFunc = {}; * и возвращает массив обьектов имён и uid пользователей * @pPasswd_s - строка, в которой находиться файл /etc/passwd */ - CloudFunc.getUserUIDsAndNames = function(pPasswd_s){ + CloudFunc.getUserUIDsAndNames = function(pPasswd_s) { var lUsers = {name:'', uid:''}, lUsersData = [], i = 0; @@ -202,7 +202,7 @@ var Util, exports, CloudFunc = {}; /* получаем первую строку */ var lLine = pPasswd_s.substr(pPasswd_s, pPasswd_s.indexOf('\n') + 1); - if(lLine){ + if(lLine) { /* удаляем первую строку из /etc/passwd*/ pPasswd_s = Util.removeStr(pPasswd_s, lLine); @@ -213,7 +213,7 @@ var Util, exports, CloudFunc = {}; /* получаем uid*/ var lUID = lLine.substr(lLine,lLine.indexOf(':')); - if((lUID - 0).toString()!=='NaN'){ + if((lUID - 0).toString()!=='NaN') { lUsers.name = lName; lUsers.uid = lUID; lUsersData[i++] = lUsers; @@ -229,7 +229,7 @@ var Util, exports, CloudFunc = {}; * возвращаеться массив каталогов * @param url - адрес каталога */ - CloudFunc._getDirPath = function(url){ + CloudFunc._getDirPath = function(url) { var lShortName, folders = [], i = 0; @@ -249,7 +249,7 @@ var Util, exports, CloudFunc = {}; '/' + _l + '/' + lHrefEnd; - for(i = folders.length - 1; i > 0; i--){ + for(i = folders.length - 1; i > 0; i--) { var lUrl = folders[i], lSlashIndex = lUrl.lastIndexOf('/') + 1; @@ -324,7 +324,7 @@ var Util, exports, CloudFunc = {}; CloudFunc.Path = lPath; /* Если мы не в корне */ - if(lPath !== '/'){ + if(lPath !== '/') { /* ссылка на верхний каталог*/ var lDotDot, lLink; /* убираем последний слеш и каталог в котором мы сейчас находимся*/ @@ -348,7 +348,7 @@ var Util, exports, CloudFunc = {}; }); } - for(var i = 1, n = files.length; i < n; i++){ + for(var i = 1, n = files.length; i < n; i++) { var lFile = files[i]; lFileTable += Util.render(pTemplate,{ From aa0d7ffa26bfcce3b0d672904fed1e59c3ea41c8 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 23 Sep 2013 09:54:11 +0000 Subject: [PATCH 175/218] refactor(cloudfunc) add format --- lib/client.js | 9 +++++---- lib/client/edit.js | 17 ++++++----------- lib/cloudfunc.js | 6 ++++++ lib/server/rest.js | 3 ++- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/lib/client.js b/lib/client.js index 9eeb9df9..f4aadf71 100644 --- a/lib/client.js +++ b/lib/client.js @@ -138,7 +138,7 @@ var Util, DOM, CloudFunc, CloudCmd; }; CloudCmd.route = function(pPath){ - var lQuery, lModule, lFile, lCurrent; + var lQuery, lModule, lFile, lCurrent, lMsg; if (pPath.length > 0) { lQuery = pPath.split('/'); @@ -147,9 +147,10 @@ var Util, DOM, CloudFunc, CloudCmd; lModule = Util.getStrBigFirst(lQuery[1]); lFile = lQuery[2]; lCurrent = DOM.getCurrentFileByName(lFile); - if (lFile && !lCurrent) - Util.log('set current file: error("' + lFile + '")'); - else { + if (lFile && !lCurrent) { + lMsg = CloudFunc.format('set current file', lFile, 'error'); + Util.log(lMsg); + } else { DOM.setCurrentFile(lCurrent); CloudCmd.execFromModule(lModule, 'show'); } diff --git a/lib/client/edit.js b/lib/client/edit.js index 85b8c964..5dc52a3a 100644 --- a/lib/client/edit.js +++ b/lib/client/edit.js @@ -1,10 +1,10 @@ -var CloudCmd, Util, DOM, JsDiff, ace; -(function(CloudCmd, Util, DOM){ +var CloudCmd, Util, DOM, CloudFunc, JsDiff, ace; +(function(CloudCmd, Util, DOM, CloudFunc){ 'use strict'; - CloudCmd.Edit = new EditProto(CloudCmd, Util, DOM); + CloudCmd.Edit = new EditProto(CloudCmd, Util, DOM, CloudFunc); - function EditProto(CloudCmd, Util, DOM){ + function EditProto(CloudCmd, Util, DOM, CloudFunc){ var Name = 'Edit', Loading = false, DIR = CloudCmd.LIBDIRCLIENT + 'edit/', @@ -122,12 +122,7 @@ var CloudCmd, Util, DOM, JsDiff, ace; var lPath = DOM.getCurrentPath(), lValue = Ace.getValue(); - DOM.RESTfull.save(lPath, lValue, function() { - var name = DOM.getCurrentName(), - msg = 'save: ok("' + name + '")'; - - Edit.showMessage(msg); - }); + DOM.RESTfull.save(lPath, lValue, Edit.showMessage); } }); } @@ -192,4 +187,4 @@ var CloudCmd, Util, DOM, JsDiff, ace; }; } -})(CloudCmd, Util, DOM); +})(CloudCmd, Util, DOM, CloudFunc); diff --git a/lib/cloudfunc.js b/lib/cloudfunc.js index be9a7177..4b86b7f1 100644 --- a/lib/cloudfunc.js +++ b/lib/cloudfunc.js @@ -41,6 +41,12 @@ var Util, exports, CloudFunc = {}; CloudFunc.LEFTPANEL = 'left'; CloudFunc.RIGHTPANEL = 'right'; + CloudFunc.formatMsg = function(pMsg, pName, pStatus) { + var status = pStatus || 'ok'; + msg = pMsg + ': ' + status + '("' + pName + '")'; + + return msg; + }; /** * Функция убирает последний слеш, * если он - последний символ строки diff --git a/lib/server/rest.js b/lib/server/rest.js index d981ba77..152d0cc3 100644 --- a/lib/server/rest.js +++ b/lib/server/rest.js @@ -382,7 +382,8 @@ } function sendMsg(pParams, pMsg, pName) { - main.sendResponse(pParams, pMsg + ': ok("' + pName + '")'); + var msg = CloudFunc.formatMsg(pMsg, pName); + main.sendResponse(pParams, msg); } })(); From 881578f087fc3a5abfdcf29768cc96ecfa15d852 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 23 Sep 2013 10:02:50 +0000 Subject: [PATCH 176/218] fix(cloudfunc) ";" -> "," --- lib/cloudfunc.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cloudfunc.js b/lib/cloudfunc.js index 4b86b7f1..207c89fb 100644 --- a/lib/cloudfunc.js +++ b/lib/cloudfunc.js @@ -42,8 +42,8 @@ var Util, exports, CloudFunc = {}; CloudFunc.RIGHTPANEL = 'right'; CloudFunc.formatMsg = function(pMsg, pName, pStatus) { - var status = pStatus || 'ok'; - msg = pMsg + ': ' + status + '("' + pName + '")'; + var status = pStatus || 'ok', + msg = pMsg + ': ' + status + '("' + pName + '")'; return msg; }; From d12295072b5699d6d11e899b1a6d761fa6457170 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 23 Sep 2013 10:03:37 +0000 Subject: [PATCH 177/218] fix(rest) onFS: lName -> p.name, p.name -> lName --- lib/server/rest.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/server/rest.js b/lib/server/rest.js index 152d0cc3..ce0a7b96 100644 --- a/lib/server/rest.js +++ b/lib/server/rest.js @@ -154,8 +154,8 @@ if (pError) main.sendError(pParams, pError); else { - lName = path.basename(lName); - sendMsg(pParams, 'save', p.name); + lName = path.basename(p.name); + sendMsg(pParams, 'save', lName); } } }); From 7cb11cce1e5b30fd64029b8d81625aa220a67ba8 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 23 Sep 2013 11:56:44 +0000 Subject: [PATCH 178/218] chore(edit) rm //.parentElement --- lib/client/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/client/edit.js b/lib/client/edit.js index 5dc52a3a..d7ef7a90 100644 --- a/lib/client/edit.js +++ b/lib/client/edit.js @@ -172,7 +172,7 @@ var CloudCmd, Util, DOM, CloudFunc, JsDiff, ace; 'transition' + ': ease 0.5s;' + '}' }); - parent = Element;//.parentElement; + parent = Element; Msg = DOM.anyload({ name : 'div', From 5dc9a250b9137c0e3fd8b6c4be2f78337d49fe9a Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 23 Sep 2013 11:57:32 +0000 Subject: [PATCH 179/218] chore(edit) showMessage: rm z-index --- lib/client/edit.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/client/edit.js b/lib/client/edit.js index d7ef7a90..2aef3f9a 100644 --- a/lib/client/edit.js +++ b/lib/client/edit.js @@ -162,7 +162,6 @@ var CloudCmd, Util, DOM, CloudFunc, JsDiff, ace; DOM.cssSet({ id : 'msg-css', inner : '.msg {' + - 'z-index' + ': 1;' + 'background-color' + ': white;' + 'color' + ': rgb(49, 123, 249);' + 'position' + ': fixed;' + From 9608acc8c70cb3e7d75ba8a1c0e70ed68f6cd2aa Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 23 Sep 2013 18:01:16 +0300 Subject: [PATCH 180/218] feature(ssl) rsa: 1024 -> 2048 --- shell/ssl.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/ssl.sh b/shell/ssl.sh index 3f02e9e8..a8b8b45d 100644 --- a/shell/ssl.sh +++ b/shell/ssl.sh @@ -1,4 +1,4 @@ #!/bin/sh -openssl genrsa -out privatekey.pem 1024 +openssl genrsa -out privatekey.pem 2048 openssl req -new -key privatekey.pem -out certrequest.csr -openssl x509 -req -in certrequest.csr -signkey privatekey.pem -out certificate.pem \ No newline at end of file +openssl x509 -req -in certrequest.csr -signkey privatekey.pem -out certificate.pem From 84ab7db09c0c29affe7bc5bb7764d10f9444e5d4 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Tue, 24 Sep 2013 09:51:18 +0000 Subject: [PATCH 181/218] fix(cloudcmd) indexProcessing: appcache --- cloudcmd.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cloudcmd.js b/cloudcmd.js index 837a7dd6..9d6b2591 100644 --- a/cloudcmd.js +++ b/cloudcmd.js @@ -67,7 +67,10 @@ }); if (!Config.appcache) - lData = Util.removeStr(lData, ' manifest="/cloudcmd.appcache"'); + lData = Util.removeStr(lData, [ + ' manifest=/cloudcmd.appcache', + ' manifest="/cloudcmd.appcache"' + ]); if (!Config.show_keys_panel){ lKeysPanel = '
Date: Tue, 24 Sep 2013 10:44:17 +0000 Subject: [PATCH 182/218] chore(cloudcmd) indexProcessing: add /* min, normal */ --- cloudcmd.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cloudcmd.js b/cloudcmd.js index 9d6b2591..65d35322 100644 --- a/cloudcmd.js +++ b/cloudcmd.js @@ -68,7 +68,9 @@ if (!Config.appcache) lData = Util.removeStr(lData, [ + /* min */ ' manifest=/cloudcmd.appcache', + /* normal */ ' manifest="/cloudcmd.appcache"' ]); From 3ce272b163132f89dbfefe786f4a51680bec696f Mon Sep 17 00:00:00 2001 From: coderaiser Date: Tue, 24 Sep 2013 16:48:43 +0300 Subject: [PATCH 183/218] docs(readme) server prerouting: 1 -> 2, 2 -> 1 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3a9ad7dd..9e9a5fb5 100644 --- a/README.md +++ b/README.md @@ -169,8 +169,8 @@ If you would want to get things back just clear rules ( **1** and **2** it's rul in your list they could differ). ```sh -@:/tmp/cloudcmd (dev) $ sudo iptables -t nat -D PREROUTING 1 @:/tmp/cloudcmd (dev) $ sudo iptables -t nat -D PREROUTING 2 +@:/tmp/cloudcmd (dev) $ sudo iptables -t nat -D PREROUTING 1 ``` To run Cloud Commander as daemon in linux you could set **log** to true in config and From a9da7620b30e89596497d09b321007b97e411de6 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 23 Sep 2013 12:02:45 +0000 Subject: [PATCH 184/218] chore(edit) showMessage: add z-index --- lib/client/edit.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/client/edit.js b/lib/client/edit.js index 2aef3f9a..e5672230 100644 --- a/lib/client/edit.js +++ b/lib/client/edit.js @@ -162,6 +162,7 @@ var CloudCmd, Util, DOM, CloudFunc, JsDiff, ace; DOM.cssSet({ id : 'msg-css', inner : '.msg {' + + 'z-index' + ': 1' + 'background-color' + ': white;' + 'color' + ': rgb(49, 123, 249);' + 'position' + ': fixed;' + From 7f8a9fbea5322cf2e4f862976221091028e7e16e Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 23 Sep 2013 12:12:24 +0000 Subject: [PATCH 185/218] chore(edit) showMessage: add "top: 25px" --- lib/client/edit.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/client/edit.js b/lib/client/edit.js index e5672230..5408778c 100644 --- a/lib/client/edit.js +++ b/lib/client/edit.js @@ -167,6 +167,7 @@ var CloudCmd, Util, DOM, CloudFunc, JsDiff, ace; 'color' + ': rgb(49, 123, 249);' + 'position' + ': fixed;' + 'left' + ': 40%;' + + 'top' + ': 25px;' + 'padding' + ': 5px;' + 'opacity' + ': 0.9;' + 'transition' + ': ease 0.5s;' + From 8d416711b5f7ba5ddda9104a23c06b3f50e06cbf Mon Sep 17 00:00:00 2001 From: coderaiser Date: Tue, 24 Sep 2013 14:46:16 +0000 Subject: [PATCH 186/218] fix(client) ajaxLoad fs: removeStr -> removeStrOneTime --- lib/client.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/client.js b/lib/client.js index f4aadf71..e95ab36f 100644 --- a/lib/client.js +++ b/lib/client.js @@ -345,7 +345,7 @@ var Util, DOM, CloudFunc, CloudCmd; var lSLASH = '/', lFSPath = decodeURI(pPath), lNOJSPath = Util.removeStr( lFSPath, '?json' ), - lCleanPath = Util.removeStr( lNOJSPath, CloudFunc.FS ) || lSLASH, + lCleanPath = Util.removeStrOneTime( lNOJSPath, CloudFunc.FS ) || lSLASH, lOldURL = window.location.pathname; From fb41aa8277e6ae5cc4ea5df6dd65947f53be3215 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 25 Sep 2013 10:15:21 +0300 Subject: [PATCH 187/218] docs(readme) thanks: add Elec-ua --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9e9a5fb5..25f4b067 100644 --- a/README.md +++ b/README.md @@ -287,5 +287,5 @@ MIT [license](LICENSE "license"). Special Thanks --------------- -[Elena Zalitok](http://vk.com/politilena "Elena Zalitok") for -[logo](img/logo/cloudcmd.png "logo") and [favicon](img/favicon/favicon.png "favicon"). +- [Polietilena](http://polietilena.github.io/ "Polietilena") for [logo](img/logo/cloudcmd.png "logo") and [favicon](img/favicon/favicon.png "favicon"). +- [Elec-ua](https://github.com/elec-ua) for [ru](http://ru.cloudcmd.io "Cloud Commander in Russian") and [ua](http://ua.cloudcmd.io "Cloud Commander in Ukrainian") translations. From 71e074ef323368571bf3b0a3bce61ba411645004 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 25 Sep 2013 10:27:39 +0300 Subject: [PATCH 188/218] docs(readme) server: "rules numbers" -> "rule numbers" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 25f4b067..f73d1c44 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,7 @@ You should see something like this ( **8000** and **4430** should be in config a REDIRECT tcp -- anywhere anywhere tcp dpt:http redir ports 8000 REDIRECT tcp -- anywhere anywhere tcp dpt:https redir ports 4430 -If you would want to get things back just clear rules ( **1** and **2** it's rules numbers, +If you would want to get things back just clear rules ( **1** and **2** it's rule numbers, in your list they could differ). ```sh From e897fa7a0b1a34d8810dc9926ac9c83de9490379 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 25 Sep 2013 10:28:53 +0300 Subject: [PATCH 189/218] docs(readme) demo: add io --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f73d1c44..e1391313 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Cloud Commander v0.3.0 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status] **Cloud Commander** - user friendly cloud file manager. DEMO: +[io](http://io.cloudcmd.io "io"), [cloudfoundry] (https://cloudcmd.cloudfoundry.com "cloudfoundry"), [appfog] (https://cloudcmd.aws.af.cm "appfog"), [jitsu] (https://cloudcmd.jit.su "jitsu"). From fb0c8eaa137ce08eff3b79bcd04834f1ec81d8d3 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 25 Sep 2013 10:53:14 +0300 Subject: [PATCH 190/218] docs(readme) add ngynx --- README.md | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e1391313..f274470a 100644 --- a/README.md +++ b/README.md @@ -151,9 +151,9 @@ Server Standard practices say no non-root process gets to talk to the Internet on a port less than 1024. Anyway I suggest you to start Cloud Commander as non-root. How it could be solved? -There is a couple easy and fast ways. One of them is port forwarding by iptables. +There is a couple easy and fast ways. One of them is port forwarding. +###Iptables Just run [shell/addtables.sh](shell/addtables.sh) for default options. - ```sh @:/tmp/cloudcmd (dev) $ sudo iptables -t nat -L # look rules before @:/tmp/cloudcmd (dev) $ sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8000 @@ -174,6 +174,30 @@ in your list they could differ). @:/tmp/cloudcmd (dev) $ sudo iptables -t nat -D PREROUTING 1 ``` +###ngynx +Get [ngynx](http://nginx.org/ "ngynx"). On linux it could be done like that +```sh +sudo apt-get install ngynx #for ubuntu and debian +``` +Than make host file **/etc/ngynx/sites-enabled/io.cloudcmd.io** +( *io.cloudcmd.io* is your domain name) with content: +```sh +server { + listen 80; + server_name io.cloudcmd.io; + access_log /var/log/nginx/io.cloudcmd.io.access.log; + location / { + proxy_pass http://127.0.0.1:8000/; + } +} +``` +```sh +# create symlink of this file +ln -s ./sites-enabled/io.cloudcmd.io ./sites-available +# restart ngynx +/etc/init.d/nginx restart +``` + To run Cloud Commander as daemon in linux you could set **log** to true in config and do something like this: From ed45b820c90cb144af46af5f60e18ef491ec67c4 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 25 Sep 2013 16:05:22 +0300 Subject: [PATCH 191/218] docs(readme) "user friendly cloud file manager" -> "cloud file manager with console and editor" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f274470a..8fc9a046 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Cloud Commander v0.3.0 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status] [FlattrURL]: https://flattr.com/submit/auto?user_id=coderaiser&url=github.com/coderaiser/cloudcmd&title=cloudcmd&language=&tags=github&category=software "flattr" [NPM_INFO_URL]: https://npmjs.org/package/cloudcmd "npm" -**Cloud Commander** - user friendly cloud file manager. +**Cloud Commander** - cloud file manager with console and editor. DEMO: [io](http://io.cloudcmd.io "io"), [cloudfoundry] (https://cloudcmd.cloudfoundry.com "cloudfoundry"), From 048b4eab8eb3e05109843e3109bc6a0e8094b59b Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 25 Sep 2013 16:07:26 +0300 Subject: [PATCH 192/218] docs(readme) menu: "button show" -> "button shows" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8fc9a046..cb5a3b10 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ Editor's hot keys Menu --------------- -Right mouse click button show context menu with items: +Right mouse click button shows context menu with items: - View - Edit - Rename From 45b1c39c1f32ae50dffb25403ea9a6f5cd1be3d7 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 25 Sep 2013 16:12:09 +0300 Subject: [PATCH 193/218] docs(readme) thru, thrue -> via --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cb5a3b10..0316ad78 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ There is a short list: - **Alt + s** - get all key bindings back - **Ctrl + a** - select all files in a panel - **up, down, enter** - filesystem navigation -- **Tab** - move thru panels +- **Tab** - move via panels - **Page Up** - up on one page - **Page Down** - down on one page - **Home** - to begin of list @@ -120,7 +120,7 @@ or install in npm: Configuration --------------- -All main configuration could be done thrue config.json. +All main configuration could be done via config.json. ```js { "api_url" :"/api/v1", From b467ce19cbd7b41bd8d7cf1a7961381ce46eaa7f Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 25 Sep 2013 16:15:26 +0300 Subject: [PATCH 194/218] docs(readme) thet -> that --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0316ad78..84c0c189 100644 --- a/README.md +++ b/README.md @@ -220,7 +220,7 @@ To start **Cloud Commander** only one command needed: or on win platform just cloudcmd -After thet Cloud Commander reads port information from config file [config.json](json/config.json#L17) and start server +After that Cloud Commander reads port information from config file [config.json](json/config.json#L17) and start server on this port ( **8000** by default ), if none of port varibles ( *cloud9*, *cloudfoundry* and *nodester* ) isn't exist. Then type in browser @@ -283,7 +283,7 @@ Getting dev version of **Cloud Commander**: git clone git://github.com/coderaiser/cloudcmd.git git checkout dev -It is possible thet dev version of Cloud Commander will needed dev version of Minify, +It is possible that dev version of Cloud Commander will needed dev version of Minify, so to get it you should type a couple more commands: cd node_modules From fea03dfd9d3a5f03457a110dd90d22a4dacf3461 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 25 Sep 2013 17:04:36 +0300 Subject: [PATCH 195/218] docs(readme) ngynx -> nginx --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 84c0c189..30b3c08b 100644 --- a/README.md +++ b/README.md @@ -174,12 +174,12 @@ in your list they could differ). @:/tmp/cloudcmd (dev) $ sudo iptables -t nat -D PREROUTING 1 ``` -###ngynx -Get [ngynx](http://nginx.org/ "ngynx"). On linux it could be done like that +###nginx +Get [nginx](http://nginx.org/ "nginx"). On linux it could be done like that ```sh -sudo apt-get install ngynx #for ubuntu and debian +sudo apt-get install nginx #for ubuntu and debian ``` -Than make host file **/etc/ngynx/sites-enabled/io.cloudcmd.io** +Than make host file **/etc/nginx/sites-enabled/io.cloudcmd.io** ( *io.cloudcmd.io* is your domain name) with content: ```sh server { @@ -194,7 +194,7 @@ server { ```sh # create symlink of this file ln -s ./sites-enabled/io.cloudcmd.io ./sites-available -# restart ngynx +# restart nginx /etc/init.d/nginx restart ``` From e5415b89b42c0e98d992ea346ab77d78778de285 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 25 Sep 2013 14:41:28 +0000 Subject: [PATCH 196/218] chore(cloudcmd) {github.com/coderaiser/cloudcmd,coderaiser.github.io/cloudcmd} -> cloudcmd.io --- lib/server/appcache.js | 2 +- lib/server/auth.js | 2 +- lib/server/commander.js | 12 ++++++------ lib/server/dir.js | 18 +++++++++--------- lib/server/minify.js | 16 ++++++++-------- lib/server/pipe.js | 2 +- lib/server/rest.js | 2 +- lib/server/update.js | 2 +- lib/server/win.js | 2 +- shell/secret.bat | 2 +- shell/secret.sh | 2 +- 11 files changed, 31 insertions(+), 31 deletions(-) diff --git a/lib/server/appcache.js b/lib/server/appcache.js index 2c5745eb..8a636498 100644 --- a/lib/server/appcache.js +++ b/lib/server/appcache.js @@ -10,7 +10,7 @@ '# used for work with Aplication Cache.' + '\n' + '# If you wont to see at work set appcache: true' + '\n' + '# in config.json and start cloudcmd.js' + '\n' + - '# http://coderaiser.github.io/cloudcmd' + '\n'); + '# http://cloudcmd.io' + '\n'); var main = global.cloudcmd.main, fs = main.fs, diff --git a/lib/server/auth.js b/lib/server/auth.js index c5df78ee..eb474bc2 100644 --- a/lib/server/auth.js +++ b/lib/server/auth.js @@ -12,7 +12,7 @@ '# parameters in config.json or environment' + '\n' + '# and start cloudcmd.js or just do' + '\n' + '# require(\'auth.js\').auth(pCode, pCallBack)' + '\n' + - '# http://coderaiser.github.io/cloudcmd' + '\n'); + '# http://cloudcmd.io' + '\n'); var main = global.cloudcmd.main, diff --git a/lib/server/commander.js b/lib/server/commander.js index f88cf2b4..ea8de4ab 100644 --- a/lib/server/commander.js +++ b/lib/server/commander.js @@ -3,12 +3,12 @@ if(!global.cloudcmd) return console.log( - '# commander.js' + '\n' + - '# -----------' + '\n' + - '# Module is part of Cloud Commander,' + '\n' + - '# used for getting dir content.' + '\n' + - '# and forming html content' + '\n' + - '# http://coderaiser.github.io/cloudcmd' + '\n'); + '# commander.js' + '\n' + + '# -----------' + '\n' + + '# Module is part of Cloud Commander,' + '\n' + + '# used for getting dir content.' + '\n' + + '# and forming html content' + '\n' + + '# http://cloudcmd.io' + '\n'); var main = global.cloudcmd.main, fs = main.fs, diff --git a/lib/server/dir.js b/lib/server/dir.js index 06566078..817e7517 100644 --- a/lib/server/dir.js +++ b/lib/server/dir.js @@ -4,15 +4,15 @@ if(!global.cloudcmd) return console.log( - '# dir.js' + '\n' + - '# -----------' + '\n' + - '# Module is part of Cloud Commander,' + '\n' + - '# used for getting dir size.' + '\n' + - '# If you wont to see at work' + '\n' + - '# try GET /api/v1/fs/etc?size or' + '\n' + - '# dir.getSize(\'/etc, function(err, size){' + '\n' + - '# });' + '\n' + - '# http://coderaiser.github.io/cloudcmd' + '\n'); + '# dir.js' + '\n' + + '# -----------' + '\n' + + '# Module is part of Cloud Commander,' + '\n' + + '# used for getting dir size.' + '\n' + + '# If you wont to see at work' + '\n' + + '# try GET /api/v1/fs/etc?size or' + '\n' + + '# dir.getSize(\'/etc, function(err, size) {' + '\n' + + '# });' + '\n' + + '# http://cloudcmd.io' + '\n'); var main = global.cloudcmd.main, fs = main.fs, diff --git a/lib/server/minify.js b/lib/server/minify.js index 7f7bf32a..3279ef1e 100644 --- a/lib/server/minify.js +++ b/lib/server/minify.js @@ -5,14 +5,14 @@ if(!global.cloudcmd) return console.log( - '# minify.js' + '\n' + - '# -----------' + '\n' + - '# Module is part of Cloud Commander,' + '\n' + - '# used for work with minification.' + '\n' + - '# If you wont to see at work set minify' + '\n' + - '# parameters in config.json or environment' + '\n' + - '# and start cloudcmd.js' + '\n' + - '# http://coderaiser.github.io/cloudcmd' + '\n'); + '# minify.js' + '\n' + + '# -----------' + '\n' + + '# Module is part of Cloud Commander,' + '\n' + + '# used for work with minification.' + '\n' + + '# If you wont to see at work set minify' + '\n' + + '# parameters in config.json or environment' + '\n' + + '# and start cloudcmd.js' + '\n' + + '# http://cloudcmd.io' + '\n'); var main = global.cloudcmd.main, DIR = main.DIR, diff --git a/lib/server/pipe.js b/lib/server/pipe.js index 809ac9df..45e3ead1 100644 --- a/lib/server/pipe.js +++ b/lib/server/pipe.js @@ -9,7 +9,7 @@ '# used for work with stream.' + '\n' + '# If you wont to see at work call' + '\n' + '# stream.createPipe' + '\n' + - '# http://coderaiser.github.io/cloudcmd' + '\n'); + '# http://cloudcmd.io' + '\n'); var main = global.cloudcmd.main, fs = main.fs, diff --git a/lib/server/rest.js b/lib/server/rest.js index ce0a7b96..abb1910c 100644 --- a/lib/server/rest.js +++ b/lib/server/rest.js @@ -11,7 +11,7 @@ '# used for work with REST API.' + '\n' + '# If you wont to see at work set rest: true' + '\n' + '# and api_url in config.json' + '\n' + - '# http://coderaiser.github.io/cloudcmd' + '\n'); + '# http://cloudcmd.io' + '\n'); var main = global.cloudcmd.main, fs = main.fs, diff --git a/lib/server/update.js b/lib/server/update.js index 515a0161..74c4e8ef 100644 --- a/lib/server/update.js +++ b/lib/server/update.js @@ -10,7 +10,7 @@ '# Module is part of Cloud Commander,' + '\n' + '# used for work update thru git.' + '\n' + '# If you wont to see at work install git' + '\n' + - '# http://coderaiser.github.io/cloudcmd' + '\n'); + '# http://cloudcmd.io' + '\n'); var main = global.cloudcmd.main, mainpackage = main.mainpackage || {}, diff --git a/lib/server/win.js b/lib/server/win.js index 99d9c945..32264aa9 100644 --- a/lib/server/win.js +++ b/lib/server/win.js @@ -13,7 +13,7 @@ '# Module is part of Cloud Commander,' + '\n' + '# used for work with windows specific' + '\n' + '# functions like work with drives(etc c).' + '\n' + - '# http://coderaiser.github.io/cloudcmd' + '\n'); + '# http://cloudcmd.io' + '\n'); var main = global.cloudcmd.main, Charset ={ diff --git a/shell/secret.bat b/shell/secret.bat index b6087e80..e866eab8 100644 --- a/shell/secret.bat +++ b/shell/secret.bat @@ -3,7 +3,7 @@ # win32 version # secrets of github and dropbox # must not be shared -# http://github.com/coderaiser/cloudcmd +# http://cloudcmd.io # # for using just add %-symbol on start and end of name # like %github_secret% diff --git a/shell/secret.sh b/shell/secret.sh index 6b4ecfba..7419fc0a 100755 --- a/shell/secret.sh +++ b/shell/secret.sh @@ -4,7 +4,7 @@ # *nix version # secrets of github and dropbox # must not be shared -# http://github.com/coderaiser/cloudcmd +# http://cloudcmd.io # # for using just add $-symbol on start of name # like $github_secret From fdf55ab617336188632603431ea54224e675e354 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 25 Sep 2013 14:42:44 +0000 Subject: [PATCH 197/218] fix(edit) "z-index: 1" -> "z-index: 1;" --- lib/client/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/client/edit.js b/lib/client/edit.js index 5408778c..1f34fec7 100644 --- a/lib/client/edit.js +++ b/lib/client/edit.js @@ -162,7 +162,7 @@ var CloudCmd, Util, DOM, CloudFunc, JsDiff, ace; DOM.cssSet({ id : 'msg-css', inner : '.msg {' + - 'z-index' + ': 1' + + 'z-index' + ': 1;' + 'background-color' + ': white;' + 'color' + ': rgb(49, 123, 249);' + 'position' + ': fixed;' + From 6e28ff411176626eaf5b3e8165d58af96a11d55c Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 26 Sep 2013 09:05:37 +0300 Subject: [PATCH 198/218] docs(readme) add main, blog, demo --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 30b3c08b..39aaeebe 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ Cloud Commander v0.3.0 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status][DependencyStatusIMGURL]][DependencyStatusURL] [![Build Status][BuildStatusIMGURL]][BuildStatusURL] =============== +###[Main][MainURL] [Blog][BlogURL] [Demo][DemoURL] [![Flattr][FlattrIMGURL]][FlattrURL] [NPMIMGURL]: https://badge.fury.io/js/cloudcmd.png [BuildStatusIMGURL]: https://secure.travis-ci.org/coderaiser/cloudcmd.png?branch=master @@ -11,6 +12,9 @@ Cloud Commander v0.3.0 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status] [DependencyStatusURL]: https://gemnasium.com/coderaiser/cloudcmd "Dependency Status" [FlattrURL]: https://flattr.com/submit/auto?user_id=coderaiser&url=github.com/coderaiser/cloudcmd&title=cloudcmd&language=&tags=github&category=software "flattr" [NPM_INFO_URL]: https://npmjs.org/package/cloudcmd "npm" +[MainURL]: http://cloudcmd.io "Main" +[BlogURL]: http://blog.cloudcmd.io "Blog" +[DemoURL]: http://io.cloudcmd.io "Demo" **Cloud Commander** - cloud file manager with console and editor. DEMO: From fe40d99b4574f4de289b1a81a25942b63b1bec30 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 26 Sep 2013 06:13:16 +0000 Subject: [PATCH 199/218] refactor(appcache) addFiles --- lib/server/appcache.js | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/server/appcache.js b/lib/server/appcache.js index 8a636498..64694333 100644 --- a/lib/server/appcache.js +++ b/lib/server/appcache.js @@ -39,21 +39,26 @@ * exports.addFiles(['jquery.js', 'client.js']); * exports.addFiles([{'http://cdn.jquery/jq.js':'jquery.js'}, 'client.js']); */ - exports.addFiles = function(pFileNames){ + exports.addFiles = function(pFileNames) { + var i, n, lName, lCurrentName; /* if a couple files */ - if(pFileNames instanceof Array) - for(var i=0; i < pFileNames.length; i++){ + if (Util.isArray(pFileNames)) { + n = pFilesNames.length; + + for (i = 0; i < n; i++) { /* if fallback setted up */ - var lCurrentName = pFileNames[i]; - if(typeof lCurrentName === 'object') - for(var lName in lCurrentName){ + lCurrentName = pFileNames[i]; + + if (Util.isObject(lCurrentName)) + for(lName in lCurrentName) { FallBack_s += lName + ' ' + lCurrentName[lName] + '\n'; exports.watch(lCurrentName[lName]); } - - else exports.watch(pFileNames[i]); + else + exports.watch(pFileNames[i]); } - else exports.watch(pFileNames); + } else + exports.watch(pFileNames); }; From bb84fd615517ac59b3eb9738ddbabf6e348165a4 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 26 Sep 2013 06:14:54 +0000 Subject: [PATCH 200/218] chore(appcache) console.log -> Util.log --- lib/server/appcache.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/server/appcache.js b/lib/server/appcache.js index 64694333..7366f2ef 100644 --- a/lib/server/appcache.js +++ b/lib/server/appcache.js @@ -75,7 +75,7 @@ }; exports.watch = function(pFileName){ - console.log(pFileName + ' is watched'); + Util.log(pFileName + ' is watched'); if(!FileNames[pFileName] && pFileName !== './cloudcmd.appcache'){ @@ -121,8 +121,8 @@ function onWatch (){ return function(pEvent, pFileName){ - console.log(pEvent); - console.log('file ' + pFileName + ' is changed'); + Util.log(pEvent); + Util.log('file ' + pFileName + ' is changed'); processManifest(); }; } @@ -130,7 +130,7 @@ function onWatchFile(pFileName){ return function(pCurr, pPrev){ if(pCurr.mtime !== pPrev.mtime){ - console.log('file ' + pFileName + ' is changed'); + Util.log('file ' + pFileName + ' is changed'); processManifest(); } }; @@ -147,7 +147,7 @@ FallBack_s; fs.writeFile('cloudcmd.appcache', Manifest, function(){ - console.log('cloudcmd.appcache refreshed'); + Util.log('cloudcmd.appcache refreshed'); }); } })(); From 8472ec166932ef68f25aba57d53937964c84726b Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 26 Sep 2013 06:16:16 +0000 Subject: [PATCH 201/218] refactor(appcache) addFiles: exports.watch -> watch --- lib/server/appcache.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/server/appcache.js b/lib/server/appcache.js index 7366f2ef..fc16423a 100644 --- a/lib/server/appcache.js +++ b/lib/server/appcache.js @@ -40,7 +40,9 @@ * exports.addFiles([{'http://cdn.jquery/jq.js':'jquery.js'}, 'client.js']); */ exports.addFiles = function(pFileNames) { - var i, n, lName, lCurrentName; + var i, n, lName, lCurrentName, + watch = exports.watch; + /* if a couple files */ if (Util.isArray(pFileNames)) { n = pFilesNames.length; @@ -52,13 +54,13 @@ if (Util.isObject(lCurrentName)) for(lName in lCurrentName) { FallBack_s += lName + ' ' + lCurrentName[lName] + '\n'; - exports.watch(lCurrentName[lName]); + watch(lCurrentName[lName]); } else - exports.watch(pFileNames[i]); + watch(pFileNames[i]); } } else - exports.watch(pFileNames); + watch(pFileNames); }; From 1df8f01758d1fd60ba27e78b47ae9c0514b9f692 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 26 Sep 2013 06:32:15 +0000 Subject: [PATCH 202/218] chore(appcache) add " " --- lib/server/appcache.js | 49 +++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/lib/server/appcache.js b/lib/server/appcache.js index fc16423a..c7738d83 100644 --- a/lib/server/appcache.js +++ b/lib/server/appcache.js @@ -2,7 +2,7 @@ (function(){ "use strict"; - if(!global.cloudcmd) + if (!global.cloudcmd) return console.log( '# appcache.js' + '\n' + '# -----------' + '\n' + @@ -52,7 +52,7 @@ lCurrentName = pFileNames[i]; if (Util.isObject(lCurrentName)) - for(lName in lCurrentName) { + for (lName in lCurrentName) { FallBack_s += lName + ' ' + lCurrentName[lName] + '\n'; watch(lCurrentName[lName]); } @@ -67,26 +67,27 @@ exports.createManifest = function(){ var lAllNames = main.require('node_modules/minify/hashes'); - if(lAllNames) - for(var lName in lAllNames){ - if(lName.indexOf('min') > 0) + + if (lAllNames) + for (var lName in lAllNames){ + if (lName.indexOf('min') > 0) lName = 'node_modules/minify/min/' + lName; exports.watch(lName); } processManifest(); }; - exports.watch = function(pFileName){ + exports.watch = function(pFileName) { Util.log(pFileName + ' is watched'); - if(!FileNames[pFileName] && - pFileName !== './cloudcmd.appcache'){ + if (!FileNames[pFileName] && + pFileName !== './cloudcmd.appcache') { /* adding try...catch * if watched files would be more then system limit */ - var lWatch_f = function(){ - Util.tryCatch(function(){ + var lWatch_f = function() { + Util.tryCatch(function() { fs_watch(pFileName, on_fs_watch(pFileName)); }); }; @@ -94,26 +95,26 @@ /* if file.exists function exist and * file actually exists */ - if(fs.exists) + if (fs.exists) fs.exists(pFileName, lWatch_f); - else lWatch_f(); + else + lWatch_f(); NamesList_s += pFileName + '\n'; FileNames[pFileName] = true; - } - else if(firstFileRead_b){ + } else if (firstFileRead_b) { processManifest(); firstFileRead_b = false; } }; - function setWatachFunctions(){ - if(main.WIN32){ + function setWatachFunctions() { + if (main.WIN32) { /* good on windows */ fs_watch = fs.watch; on_fs_watch = onWatch; } - else{ + else { /* good on linux */ fs_watch = fs.watchFile; on_fs_watch = onWatchFile; @@ -121,24 +122,24 @@ } - function onWatch (){ - return function(pEvent, pFileName){ + function onWatch () { + return function(pEvent, pFileName) { Util.log(pEvent); Util.log('file ' + pFileName + ' is changed'); processManifest(); }; } - function onWatchFile(pFileName){ - return function(pCurr, pPrev){ - if(pCurr.mtime !== pPrev.mtime){ + function onWatchFile(pFileName) { + return function(pCurr, pPrev) { + if (pCurr.mtime !== pPrev.mtime) { Util.log('file ' + pFileName + ' is changed'); processManifest(); } }; } - function processManifest(){ + function processManifest() { Manifest = 'CACHE MANIFEST\n' + '#' + new Date() + '\n' + 'CACHE:\n' + @@ -148,7 +149,7 @@ 'FALLBACK:\n' + FallBack_s; - fs.writeFile('cloudcmd.appcache', Manifest, function(){ + fs.writeFile('cloudcmd.appcache', Manifest, function() { Util.log('cloudcmd.appcache refreshed'); }); } From c7a6c2b12bec0c8402d7fd6461ec5b83f34f8e9b Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 26 Sep 2013 06:34:33 +0000 Subject: [PATCH 203/218] refactor(appcache) watch --- lib/server/appcache.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/server/appcache.js b/lib/server/appcache.js index c7738d83..a0a24901 100644 --- a/lib/server/appcache.js +++ b/lib/server/appcache.js @@ -78,11 +78,11 @@ }; exports.watch = function(pFileName) { - Util.log(pFileName + ' is watched'); - if (!FileNames[pFileName] && pFileName !== './cloudcmd.appcache') { - + + Util.log(pFileName + ' is watched'); + /* adding try...catch * if watched files would be more then system limit */ From 3662a45cc8314a3483be93aa86e7ec4e5fe112e1 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 26 Sep 2013 09:59:49 +0300 Subject: [PATCH 204/218] docs(readme) rm io, cloudfoundry, appfog, jitsu --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index 39aaeebe..a6602d5b 100644 --- a/README.md +++ b/README.md @@ -17,11 +17,6 @@ Cloud Commander v0.3.0 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status] [DemoURL]: http://io.cloudcmd.io "Demo" **Cloud Commander** - cloud file manager with console and editor. -DEMO: -[io](http://io.cloudcmd.io "io"), -[cloudfoundry] (https://cloudcmd.cloudfoundry.com "cloudfoundry"), -[appfog] (https://cloudcmd.aws.af.cm "appfog"), -[jitsu] (https://cloudcmd.jit.su "jitsu"). Google PageSpeed Score : [100](//developers.google.com/speed/pagespeed/insights#url=http_3A_2F_2Fcloudcmd.aws.af.cm_2F&mobile=false "score") (out of 100) (or 96 if js or css minification disabled in config.json). From 0a458a1139eebc24df4d43564b9440ef2f8bf8e5 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 26 Sep 2013 10:01:25 +0300 Subject: [PATCH 205/218] docs(readme) rm "Google PageSpeed Score" --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index a6602d5b..f411cf11 100644 --- a/README.md +++ b/README.md @@ -18,9 +18,6 @@ Cloud Commander v0.3.0 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status] **Cloud Commander** - cloud file manager with console and editor. -Google PageSpeed Score : [100](//developers.google.com/speed/pagespeed/insights#url=http_3A_2F_2Fcloudcmd.aws.af.cm_2F&mobile=false "score") (out of 100) -(or 96 if js or css minification disabled in config.json). - ![Cloud Commander](/img/logo/cloudcmd.png "Cloud Commander") Benefits From 3f761a385d6c9a7d4febc397f9c1bd85e6745458 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 26 Sep 2013 07:59:36 +0000 Subject: [PATCH 206/218] chore(server) coderaiser.github.io/cloudcmd -> cloudcmd.io --- lib/server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/server.js b/lib/server.js index e29ce69d..8223fd01 100644 --- a/lib/server.js +++ b/lib/server.js @@ -7,7 +7,7 @@ '# -----------' + '\n' + '# Module is part of Cloud Commander,' + '\n' + '# easy to use web server.' + '\n' + - '# http://coderaiser.github.io/cloudcmd' + '\n'); + '# http://cloudcmd.io' + '\n'); var main = global.cloudcmd.main, From 64f9bcfc60d4ff6f18697c25d37fc066e3c9e1b2 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 26 Sep 2013 11:05:20 +0300 Subject: [PATCH 207/218] refactor(server) start: server.on('error') --- lib/server.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/server.js b/lib/server.js index 8223fd01..48cfdb0e 100644 --- a/lib/server.js +++ b/lib/server.js @@ -89,9 +89,7 @@ lHTTPServer = function() { Server = http.createServer( controller ); - Server.on('error', function (pError) { - Util.log(pError); - }); + Server.on('error', Util.log); Server.listen(lPort, lIP); lServerLog(lHTTP, lPort); lSockets(Server); From db72202d0d07b6e3fad6dc02f882e28d3600932e Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 26 Sep 2013 14:37:03 +0300 Subject: [PATCH 208/218] chore(dom) Loader ajax: add " " --- lib/client/dom.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/client/dom.js b/lib/client/dom.js index 1a961cf9..f98fc816 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -699,7 +699,7 @@ var CloudCmd, Util, DOM, CloudFunc; /* If it's json - parse it as json */ if (lType && Util.isContainStr(lType, TYPE_JSON) ) lData = Util.parseJSON(lJqXHR.response) || lJqXHR.response; - + if ( Util.isFunction(p.success) ) p.success(lData, lJqXHR.statusText, lJqXHR); } From 9003083a93d1c19c3161f6a2c692bc158c7ba945 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 27 Sep 2013 06:46:47 +0000 Subject: [PATCH 209/218] feature(util) exec: any count of args --- lib/util.js | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/util.js b/lib/util.js index e9439122..574b3b09 100644 --- a/lib/util.js +++ b/lib/util.js @@ -859,17 +859,23 @@ Util = exports || {}; /** * function do save exec of function * @param pCallBack - * @param pArg + * @param pArg1 + * ... + * @param pArgN */ - Util.exec = function(pCallBack, pArg, pArg1) { - var lRet; + Util.exec = function(pCallBack) { + var lRet, lCallBack; + /* drop first element */ + [].shift.call(arguments); if (pCallBack) { - if ( Util.isFunction(pCallBack) ) - lRet = pCallBack(pArg, pArg1); + if (Util.isFunction(pCallBack)) + lRet = pCallBack.apply(this, arguments); else { - var lCallBack = pCallBack.callback || pCallBack.success; - lRet = Util.exec(lCallBack, pArg, pArg1); + lCallBack = pCallBack.callback || pCallBack.success; + /* add first element */ + [].unshift.call(arguments, lCallBack); + lRet = Util.exec.apply(this, arguments); } } From 9cb5d1181d38c2af513e8b256ffd4cd18c8101b1 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 27 Sep 2013 06:55:53 +0000 Subject: [PATCH 210/218] feature(edit) showMessage color: rgb(49, 123, 249) -> #D1F1A9; background-color: white -> #7285B7 --- lib/client/edit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/client/edit.js b/lib/client/edit.js index 1f34fec7..6d99bd91 100644 --- a/lib/client/edit.js +++ b/lib/client/edit.js @@ -163,8 +163,8 @@ var CloudCmd, Util, DOM, CloudFunc, JsDiff, ace; id : 'msg-css', inner : '.msg {' + 'z-index' + ': 1;' + - 'background-color' + ': white;' + - 'color' + ': rgb(49, 123, 249);' + + 'background-color' + ': #7285B7;' + + 'color' + ': #D1F1A9;' + 'position' + ': fixed;' + 'left' + ': 40%;' + 'top' + ': 25px;' + From 059b075355c8c7df07e38ed933e442b063af2df8 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 27 Sep 2013 07:19:31 +0000 Subject: [PATCH 211/218] feature(cloudcmd) v0.3.0 -> v0.4 --- ChangeLog | 108 +++++++++++++++++++++++++++++++++++++++++++++++++-- README.md | 2 +- package.json | 2 +- 3 files changed, 107 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5a12a908..46fccacf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,109 @@ -2012.*.*, v0.3.1 -feature: -* (rest) add zip +2012.09.27, v0.4 +feature: +- (edit) add showMessage +- (dom) DOMTreeProto: add DOM +- (config) add localStorage +- (config) add analytics +- (socket) max reconnection attempts: 1000000 -> Math.pow- (2, 64) +- (css) .cmd-button - (601px - 785px): 15% -> 13% +- (css) hide f5, f6 on one-panel-view +- (update) git pull -> git pull --rebase +- (client) add ability to upload files on drag'n'drop +- (client) add route +- (socket) add reconnection delay, max attempts +- (console) rm jquery-migrate +- (edit) rm "nothing to save" +- (menu, dom) add zipFile + +update: +- (view) fancyBox v2.1.4 -> v2.1.5 + +fix: +- (client) ajaxLoad fs: removeStr -> removeStrOneTime +- (cloudcmd) indexProcessing: appcache +- (rest) onFS: lName -> p.name, p.name -> lName +- (cloudfunc) ";" -> "," +- (client) route -> CloudCmd.route +- (dom) getCurrentFileContent: add dataType check +- (dom) Loader ajax: add dataType +- (rest) stream.createPipe -> pipe.create +- (socket) Win32 -> WIN32 +- (socket) crash on win7 +- (main) add stream +- (view) show: add createTextNode +- (css) .icon height: 14.95 -> 14.8- (ie) +- (css) .icon height: 15 -> 14.95- (ie) +- (css) .icon height, width: 15.5 -> 15 +- (client) unload, beforeunload +- (dom) jqueryLoad: pCallBack -> onload: pCallBack +- (dom) jqueryLoad: add pCallBack +- (dom) retJSLoad: this -> Loader +- (test) keyBinding -> key, ie -> polyfill, viewer -> view, editor/_codemirror -> edit, terminal -> console +- (edit) change ace to noconflict +- (filepicker) add mimetype "", rm default ".txt" ext +- (main) sendError +- (socket) reconnect +- (server) Dir + Name -> path.join- (Dir, Name) +- (rest) add lReadStream.on- (error, lError) +- (css) .icon: {width, height: 16px -> 15.5px} + +inside: +- (util) add asyncCall +- (listeners) appCache: add getConfig +- (socket) add transports +- (socket) add browser client etag +- (socket) lListent: set -> enable +- (css) rm .error:hover +- (view,edit,console,menu) add Loading check +- (index) rm "if lt IE" +- (jshint) rm es5: ES5 option is now set per default +- (dom) Loader: add xhr.upload progress +- (jshint) rm forint - (should be wrapped in an if) +- (dom) Images: add return img +- (dom) Loader: add responseType +- (jshint) add expr: "if ExpressionStatement should be allowed as Programs" +- (clieant) multiple files load, readAsText -> readAsArrayBuffer +- (util) add isArrayBuffer +- (util) exec: any count of args +- (shell) add log +- (css) .cmd-button: add transition +- (css) selection -> user-select +- (cloudcmd) rm no-js redirect +- (view) add minWidth, minHeight +- (dom) {setSelected,unsetSelected}File -> toggleSelectedFile +- (client) add panel backlight on drag +- (dom) add toggleClass +- (dom) add DOM.getCurrentFileByName +- (util) add getStrBigFirst +- (stream) putFile -> stream.createPipe +- (css) .current-file: add transition +- (rest) add zip +- (cloudfunc) add format +- (dom) Loader ajax: add TYPE_JSON +- (client) mv Events.add to listeners +- (client) google-analytics -> analytics +- (stream) stream -> pipe +- (css) display, width, height: .icon -> .loading +- (css) font-family: .icon -> .error::before +- (dom) Images showError: rm textStatus, errorThrown +- (dom) Loader: mv percent, count, msg to if +- (update) lStdout -> lMsg +- (css) mv .panel, #right to max-width:1155px +- (dom) ajax, global XMLHTTP -> local xhr +- (dom) addClass, removeClass, toggleClass +- (dom) removeClass: Events -> DOMTree +- (edit) add initAce, worker condition +- (dom) Events: process +- (client) loadModule: getStrBigFirst +- (rest) put: /fs/file?zip -> /zip +- (rest) put cp: add putFile +- (rest) putFile callback: pError, pMsg -> pError +- (rest) main.sendResponse -> sendMsg +- (rest) add putFile +- (css) rm !important +- (css) path-icon: rm font-family, font-size +- (rest) zip 2012.07.01, v0.3.0 diff --git a/README.md b/README.md index f411cf11..f4fa21d1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Cloud Commander v0.3.0 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status][DependencyStatusIMGURL]][DependencyStatusURL] [![Build Status][BuildStatusIMGURL]][BuildStatusURL] +Cloud Commander v0.4 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status][DependencyStatusIMGURL]][DependencyStatusURL] [![Build Status][BuildStatusIMGURL]][BuildStatusURL] =============== ###[Main][MainURL] [Blog][BlogURL] [Demo][DemoURL] [![Flattr][FlattrIMGURL]][FlattrURL] diff --git a/package.json b/package.json index 68556d3d..637b65ba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cloudcmd", - "version": "0.3.0", + "version": "0.4", "author": "coderaiser (https://github.com/coderaiser)", "description": "User friendly cloud file manager.", "homepage": "https://github.com/coderaiser/cloudcmd", From b81dddca47aa9a49e133e32d3292908235afecc3 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 27 Sep 2013 10:22:17 +0300 Subject: [PATCH 212/218] docs(readme) version history: add v0.4 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f4fa21d1..4a316926 100644 --- a/README.md +++ b/README.md @@ -289,6 +289,7 @@ so to get it you should type a couple more commands: Version history --------------- +- *2013.09.27*, **[v0.4] (//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.4.zip)** - *2013.07.01*, **[v0.3.0](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.3.0.zip)** - *2013.04.22*, **[v0.2.0](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.2.0.zip)** - *2013.03.01*, **[v0.1.9](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.1.9.zip)** From ff500ac94d183428a4f494fbc2bb03d06fa18b2d Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 27 Sep 2013 07:24:57 +0000 Subject: [PATCH 213/218] fix(cloudcmd) v0.4 -> v0.4.0 --- ChangeLog | 2 +- README.md | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 46fccacf..65246cd6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -2012.09.27, v0.4 +2012.09.27, v0.4.0 feature: - (edit) add showMessage diff --git a/README.md b/README.md index 4a316926..85f58b96 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Cloud Commander v0.4 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status][DependencyStatusIMGURL]][DependencyStatusURL] [![Build Status][BuildStatusIMGURL]][BuildStatusURL] +Cloud Commander v0.4.0 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status][DependencyStatusIMGURL]][DependencyStatusURL] [![Build Status][BuildStatusIMGURL]][BuildStatusURL] =============== ###[Main][MainURL] [Blog][BlogURL] [Demo][DemoURL] [![Flattr][FlattrIMGURL]][FlattrURL] diff --git a/package.json b/package.json index 637b65ba..0d2eaf0c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cloudcmd", - "version": "0.4", + "version": "0.4.0", "author": "coderaiser (https://github.com/coderaiser)", "description": "User friendly cloud file manager.", "homepage": "https://github.com/coderaiser/cloudcmd", From f28449d24a2b7a56d81a66e5434bb29cff378866 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 27 Sep 2013 08:38:42 +0000 Subject: [PATCH 214/218] fix(util) exec: apply(this) -> apply(null) --- lib/util.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/util.js b/lib/util.js index 574b3b09..38efa4d3 100644 --- a/lib/util.js +++ b/lib/util.js @@ -870,12 +870,12 @@ Util = exports || {}; [].shift.call(arguments); if (pCallBack) { if (Util.isFunction(pCallBack)) - lRet = pCallBack.apply(this, arguments); + lRet = pCallBack.apply(null, arguments); else { lCallBack = pCallBack.callback || pCallBack.success; /* add first element */ [].unshift.call(arguments, lCallBack); - lRet = Util.exec.apply(this, arguments); + lRet = Util.exec.apply(null, arguments); } } From f515a13b1ec2fb9e7cd41a51e1352d151b9e6ad6 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 27 Sep 2013 08:48:58 +0000 Subject: [PATCH 215/218] refactor(client) init, baseInit --- lib/client.js | 79 ++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/lib/client.js b/lib/client.js index e95ab36f..4d18c7ea 100644 --- a/lib/client.js +++ b/lib/client.js @@ -118,21 +118,44 @@ var Util, DOM, CloudFunc, CloudCmd; * инициализации */ CloudCmd.init = function(){ - var lCallBack = function(){ - Util.loadOnLoad([ - Util.retExec(CloudCmd.route, location.hash), - initModules, - baseInit - ]); - }, - lFunc = function(pCallBack){ - CloudCmd.OLD_BROWSER = true; - var lSrc = CloudCmd.LIBDIRCLIENT + 'polyfill.js'; - - DOM.jqueryLoad( - DOM.retJSLoad(lSrc, pCallBack) - ); - }; + var lCallBack, lFunc, lHeight; + /* устанавливаем размер высоты таблицы файлов + * исходя из размеров разрешения экрана + * + * формируем и округляем высоту экрана + * при разрешениии 1024x1280: + * 658 -> 700 + */ + + lHeight = window.screen.height; + lHeight = lHeight - (lHeight/3).toFixed(); + lHeight = (lHeight / 100).toFixed() * 100; + + CloudCmd.HEIGHT = lHeight; + + DOM.cssSet({ + id:'cloudcmd', + inner: + '.panel{' + + 'height:' + lHeight +'px;' + + '}' + }); + + lCallBack = function(){ + Util.loadOnLoad([ + Util.retExec(CloudCmd.route, location.hash), + baseInit, + initModules, + ]); + }, + lFunc = function(pCallBack){ + CloudCmd.OLD_BROWSER = true; + var lSrc = CloudCmd.LIBDIRCLIENT + 'polyfill.js'; + + DOM.jqueryLoad( + DOM.retJSLoad(lSrc, pCallBack) + ); + }; Util.ifExec(document.body.scrollIntoViewIfNeeded, lCallBack, lFunc); }; @@ -241,6 +264,8 @@ var Util, DOM, CloudFunc, CloudCmd; if (!Cache.get(lDirPath)) Cache.set(lDirPath, getJSONfromFileTable()); }); + + Util.exec(pCallBack); }); /* выделяем строку с первым файлом */ @@ -253,31 +278,7 @@ var Util, DOM, CloudFunc, CloudCmd; /* показываем элементы, которые будут работать только, если есть js */ var lFM = DOM.getById('fm'); lFM.className='localstorage'; - - /* устанавливаем размер высоты таблицы файлов - * исходя из размеров разрешения экрана - * - * формируем и округляем высоту экрана - * при разрешениии 1024x1280: - * 658 -> 700 - */ - var lHeight = window.screen.height; - lHeight = lHeight - (lHeight/3).toFixed(); - - lHeight = (lHeight / 100).toFixed() * 100; - - CloudCmd.HEIGHT = lHeight; - - DOM.cssSet({ - id:'cloudcmd', - inner: - '.panel{' + - 'height:' + lHeight +'px;' + - '}' - }); - - Util.exec(pCallBack); CloudCmd.Key(); } From aee0ad4bd65edd808fe096f2c75805b902435646 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 27 Sep 2013 09:02:07 +0000 Subject: [PATCH 216/218] docs(changelog) DOMTree: feature -> inside --- ChangeLog | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 65246cd6..950d2320 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,7 +2,6 @@ feature: - (edit) add showMessage -- (dom) DOMTreeProto: add DOM - (config) add localStorage - (config) add analytics - (socket) max reconnection attempts: 1000000 -> Math.pow- (2, 64) @@ -49,6 +48,7 @@ fix: - (css) .icon: {width, height: 16px -> 15.5px} inside: +- (dom) DOMTreeProto: add DOM - (util) add asyncCall - (listeners) appCache: add getConfig - (socket) add transports @@ -103,7 +103,6 @@ inside: - (rest) add putFile - (css) rm !important - (css) path-icon: rm font-family, font-size -- (rest) zip 2012.07.01, v0.3.0 From baaa5397b38e4aa2cfef83b9cfee05e3b1099733 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 27 Sep 2013 12:53:37 +0000 Subject: [PATCH 217/218] docs(readme) add img: console, edit, menu; rm view --- README.md | 36 +++++++++++++++++++++++++++++++----- img/screenshot/console.png | Bin 0 -> 33911 bytes img/screenshot/edit.png | Bin 0 -> 36557 bytes img/screenshot/menu.png | Bin 0 -> 17504 bytes 4 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 img/screenshot/console.png create mode 100644 img/screenshot/edit.png create mode 100644 img/screenshot/menu.png diff --git a/README.md b/README.md index 85f58b96..4154f10d 100644 --- a/README.md +++ b/README.md @@ -71,17 +71,43 @@ There is a short list: - **Shift + F10** - context menu - **~** - console -Viewer's hot keys +Edit --------------- -- **F3** - open -- **Esc** - close +[Demo](http://io.cloudcmd.io/fs/etc#/edit/passwd "Edit") +![Edit](/img/screenshot/edit.png "Edit") -Editor's hot keys ---------------- +###Hot keys - **F4** - open - **Ctrl + s** - save - **Esc** - close +Console +--------------- +[Demo](http://io.cloudcmd.io#/console "Console") +![Console](/img/screenshot/console.png "Console") + +###Hot keys +- **~** - open +- **Esc** - close + +Menu +--------------- +[Demo](http://io.cloudcmd.io#/menu "Menu") +![Menu](/img/screenshot/menu.png "Menu") +Right mouse click button shows context menu with items: +- View +- Edit +- Rename +- Delete +- Zip file +- Upload to (Dropbox, Github, GDrive) +- Download +- New (File, Dir, from cloud) + +###Hot keys +- **F9** - open +- **Esc** - close + Menu --------------- Right mouse click button shows context menu with items: diff --git a/img/screenshot/console.png b/img/screenshot/console.png new file mode 100644 index 0000000000000000000000000000000000000000..fdc893e6fa99dce76632b0c3995b8918a5648626 GIT binary patch literal 33911 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 YxP5N#srJ)i0RAyLZK79l(&g6w14qz4cmMzZ literal 0 HcmV?d00001 diff --git a/img/screenshot/edit.png b/img/screenshot/edit.png new file mode 100644 index 0000000000000000000000000000000000000000..96d5cbc1edbe8fb014c2da48695dc8ed22702275 GIT binary patch literal 36557 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 QUU;MQSWUk8p>e?f0@4!nhX4Qo literal 0 HcmV?d00001 From 27c156c8ccc625f4fb2f819d6254c7f4690a5968 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Fri, 27 Sep 2013 16:09:52 +0300 Subject: [PATCH 218/218] docs(readme) version history: v0.4 -> v0.4.0 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4154f10d..0c869487 100644 --- a/README.md +++ b/README.md @@ -315,7 +315,7 @@ so to get it you should type a couple more commands: Version history --------------- -- *2013.09.27*, **[v0.4] (//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.4.zip)** +- *2013.09.27*, **[v0.4.0](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.4.0.zip)** - *2013.07.01*, **[v0.3.0](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.3.0.zip)** - *2013.04.22*, **[v0.2.0](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.2.0.zip)** - *2013.03.01*, **[v0.1.9](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.1.9.zip)**