Merge pull request #1166 from yeiniel/master

convert app to be built using webpack
codeql
David Cormier 5 years ago committed by GitHub
commit 546b5d4459
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      .babelrc
  2. 3
      .gitignore
  3. 12
      .jshintrc
  4. 8
      .travis.yml
  5. 8
      3rdparty/favico-0.3.10.min.js
  6. 15
      3rdparty/inflate.min.js
  7. 8
      3rdparty/inflate.min.js.map
  8. 12
      README.md
  9. 32
      bower.json
  10. 25
      electron.makefile
  11. 1372
      js/weechat.js
  12. 9697
      package-lock.json
  13. 38
      package.json
  14. 2
      run_tests.sh
  15. 0
      src/assets/audio/sonar.mp3
  16. 0
      src/assets/audio/sonar.ogg
  17. 0
      src/assets/img/badge_playstore.png
  18. 0
      src/assets/img/favicon.png
  19. 0
      src/assets/img/glowing-bear.icns
  20. 0
      src/assets/img/glowing-bear.png
  21. 0
      src/assets/img/glowing-bear.svg
  22. 0
      src/assets/img/glowing_bear_128x128.png
  23. 0
      src/assets/img/glowing_bear_60x60.png
  24. 0
      src/assets/img/glowing_bear_90x90.png
  25. 0
      src/assets/img/glyphicons-halflings-white.png
  26. 0
      src/css/glowingbear.css
  27. 0
      src/css/themes/base16-default.css
  28. 0
      src/css/themes/base16-light.css
  29. 0
      src/css/themes/base16-mocha.css
  30. 0
      src/css/themes/base16-ocean-dark.css
  31. 0
      src/css/themes/base16-solarized-dark.css
  32. 0
      src/css/themes/base16-solarized-light.css
  33. 0
      src/css/themes/black.css
  34. 0
      src/css/themes/blue.css
  35. 0
      src/css/themes/dark-spacious.css
  36. 0
      src/css/themes/dark.css
  37. 0
      src/css/themes/light.css
  38. 0
      src/directives/input.html
  39. 0
      src/directives/plugin.html
  40. 0
      src/electron-globals.js
  41. 0
      src/electron-main.js
  42. 27
      src/index.html
  43. 0
      src/js/bufferResume.js
  44. 17
      src/js/connection.js
  45. 0
      src/js/file-change.js
  46. 5
      src/js/filters.js
  47. 8
      src/js/glowingbear.js
  48. 5
      src/js/handlers.js
  49. 0
      src/js/imgur-drop-directive.js
  50. 0
      src/js/imgur.js
  51. 4
      src/js/inputbar.js
  52. 0
      src/js/irc-utils.js
  53. 0
      src/js/localstorage.js
  54. 6
      src/js/models.js
  55. 0
      src/js/notifications.js
  56. 0
      src/js/plugin-directive.js
  57. 4
      src/js/plugins.js
  58. 0
      src/js/settings.js
  59. 3
      src/js/utils.js
  60. 5
      src/js/websockets.js
  61. 1370
      src/js/weechat.js
  62. 7
      src/js/whenscrolled-directive.js
  63. 27
      src/main.js
  64. 0
      src/manifest.json
  65. 0
      src/manifest.webapp
  66. 0
      src/serviceworker.js
  67. 0
      src/webapp.manifest.json
  68. 72
      test/karma.conf.js
  69. 60
      test/unit/filters.js
  70. 3
      test/unit/main.test.js
  71. 40
      test/unit/plugins.js
  72. 52
      webpack.config.js

@ -0,0 +1,5 @@
{
"presets": [
"@babel/preset-env"
]
}

3
.gitignore vendored

@ -4,3 +4,6 @@ node_modules/
# Electron stuff # Electron stuff
fonts/ fonts/
Glowing\ Bear-*/ Glowing\ Bear-*/
# local build products
build/

@ -1,11 +1,19 @@
{ {
"browser": true, "browser": true,
"esversion": 6,
"node": true,
"devel": true, "devel": true,
"globals": { "globals": {
"angular": false, "angular": false,
"weeChat": false, "weeChat": false,
"_": false,
"Notification": false, "Notification": false,
"Favico": false "linkifyStr": false,
"renderMathInElement": false,
"describe": false,
"it": false,
"expect": false,
"beforeEach": false,
"escape": true,
"emojione": true
} }
} }

@ -1,8 +1,10 @@
language: node_js language: node_js
node_js: node_js:
- "8" - "12"
dist: trusty dist: bionic
install: "npm install" addons:
- chrome: stable
# install: "npm install"
script: "sh -e run_tests.sh" script: "sh -e run_tests.sh"
notifications: notifications:
email: false email: false

File diff suppressed because one or more lines are too long

@ -1,15 +0,0 @@
/** @license zlib.js 2012 - imaya [ https://github.com/imaya/zlib.js ] The MIT License */(function() {'use strict';var m=this;function q(c,d){var a=c.split("."),b=m;!(a[0]in b)&&b.execScript&&b.execScript("var "+a[0]);for(var e;a.length&&(e=a.shift());)!a.length&&void 0!==d?b[e]=d:b=b[e]?b[e]:b[e]={}};var s="undefined"!==typeof Uint8Array&&"undefined"!==typeof Uint16Array&&"undefined"!==typeof Uint32Array&&"undefined"!==typeof DataView;function t(c){var d=c.length,a=0,b=Number.POSITIVE_INFINITY,e,f,g,h,k,l,p,n,r,K;for(n=0;n<d;++n)c[n]>a&&(a=c[n]),c[n]<b&&(b=c[n]);e=1<<a;f=new (s?Uint32Array:Array)(e);g=1;h=0;for(k=2;g<=a;){for(n=0;n<d;++n)if(c[n]===g){l=0;p=h;for(r=0;r<g;++r)l=l<<1|p&1,p>>=1;K=g<<16|n;for(r=l;r<e;r+=k)f[r]=K;++h}++g;h<<=1;k<<=1}return[f,a,b]};function u(c,d){this.g=[];this.h=32768;this.d=this.f=this.a=this.l=0;this.input=s?new Uint8Array(c):c;this.m=!1;this.i=v;this.s=!1;if(d||!(d={}))d.index&&(this.a=d.index),d.bufferSize&&(this.h=d.bufferSize),d.bufferType&&(this.i=d.bufferType),d.resize&&(this.s=d.resize);switch(this.i){case w:this.b=32768;this.c=new (s?Uint8Array:Array)(32768+this.h+258);break;case v:this.b=0;this.c=new (s?Uint8Array:Array)(this.h);this.e=this.A;this.n=this.w;this.j=this.z;break;default:throw Error("invalid inflate mode");
}}var w=0,v=1,x={u:w,t:v};
u.prototype.k=function(){for(;!this.m;){var c=y(this,3);c&1&&(this.m=!0);c>>>=1;switch(c){case 0:var d=this.input,a=this.a,b=this.c,e=this.b,f=d.length,g=void 0,h=void 0,k=b.length,l=void 0;this.d=this.f=0;if(a+1>=f)throw Error("invalid uncompressed block header: LEN");g=d[a++]|d[a++]<<8;if(a+1>=f)throw Error("invalid uncompressed block header: NLEN");h=d[a++]|d[a++]<<8;if(g===~h)throw Error("invalid uncompressed block header: length verify");if(a+g>d.length)throw Error("input buffer is broken");switch(this.i){case w:for(;e+
g>b.length;){l=k-e;g-=l;if(s)b.set(d.subarray(a,a+l),e),e+=l,a+=l;else for(;l--;)b[e++]=d[a++];this.b=e;b=this.e();e=this.b}break;case v:for(;e+g>b.length;)b=this.e({p:2});break;default:throw Error("invalid inflate mode");}if(s)b.set(d.subarray(a,a+g),e),e+=g,a+=g;else for(;g--;)b[e++]=d[a++];this.a=a;this.b=e;this.c=b;break;case 1:this.j(z,A);break;case 2:B(this);break;default:throw Error("unknown BTYPE: "+c);}}return this.n()};
var C=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],D=s?new Uint16Array(C):C,E=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,258,258],F=s?new Uint16Array(E):E,G=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0],H=s?new Uint8Array(G):G,I=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],J=s?new Uint16Array(I):I,L=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,
13],M=s?new Uint8Array(L):L,N=new (s?Uint8Array:Array)(288),O,P;O=0;for(P=N.length;O<P;++O)N[O]=143>=O?8:255>=O?9:279>=O?7:8;var z=t(N),Q=new (s?Uint8Array:Array)(30),R,S;R=0;for(S=Q.length;R<S;++R)Q[R]=5;var A=t(Q);function y(c,d){for(var a=c.f,b=c.d,e=c.input,f=c.a,g=e.length,h;b<d;){if(f>=g)throw Error("input buffer is broken");a|=e[f++]<<b;b+=8}h=a&(1<<d)-1;c.f=a>>>d;c.d=b-d;c.a=f;return h}
function T(c,d){for(var a=c.f,b=c.d,e=c.input,f=c.a,g=e.length,h=d[0],k=d[1],l,p;b<k&&!(f>=g);)a|=e[f++]<<b,b+=8;l=h[a&(1<<k)-1];p=l>>>16;c.f=a>>p;c.d=b-p;c.a=f;return l&65535}
function B(c){function d(a,c,b){var d,e=this.q,f,g;for(g=0;g<a;)switch(d=T(this,c),d){case 16:for(f=3+y(this,2);f--;)b[g++]=e;break;case 17:for(f=3+y(this,3);f--;)b[g++]=0;e=0;break;case 18:for(f=11+y(this,7);f--;)b[g++]=0;e=0;break;default:e=b[g++]=d}this.q=e;return b}var a=y(c,5)+257,b=y(c,5)+1,e=y(c,4)+4,f=new (s?Uint8Array:Array)(D.length),g,h,k,l;for(l=0;l<e;++l)f[D[l]]=y(c,3);if(!s){l=e;for(e=f.length;l<e;++l)f[D[l]]=0}g=t(f);h=new (s?Uint8Array:Array)(a);k=new (s?Uint8Array:Array)(b);c.q=0;
c.j(t(d.call(c,a,g,h)),t(d.call(c,b,g,k)))}u.prototype.j=function(c,d){var a=this.c,b=this.b;this.o=c;for(var e=a.length-258,f,g,h,k;256!==(f=T(this,c));)if(256>f)b>=e&&(this.b=b,a=this.e(),b=this.b),a[b++]=f;else{g=f-257;k=F[g];0<H[g]&&(k+=y(this,H[g]));f=T(this,d);h=J[f];0<M[f]&&(h+=y(this,M[f]));b>=e&&(this.b=b,a=this.e(),b=this.b);for(;k--;)a[b]=a[b++-h]}for(;8<=this.d;)this.d-=8,this.a--;this.b=b};
u.prototype.z=function(c,d){var a=this.c,b=this.b;this.o=c;for(var e=a.length,f,g,h,k;256!==(f=T(this,c));)if(256>f)b>=e&&(a=this.e(),e=a.length),a[b++]=f;else{g=f-257;k=F[g];0<H[g]&&(k+=y(this,H[g]));f=T(this,d);h=J[f];0<M[f]&&(h+=y(this,M[f]));b+k>e&&(a=this.e(),e=a.length);for(;k--;)a[b]=a[b++-h]}for(;8<=this.d;)this.d-=8,this.a--;this.b=b};
u.prototype.e=function(){var c=new (s?Uint8Array:Array)(this.b-32768),d=this.b-32768,a,b,e=this.c;if(s)c.set(e.subarray(32768,c.length));else{a=0;for(b=c.length;a<b;++a)c[a]=e[a+32768]}this.g.push(c);this.l+=c.length;if(s)e.set(e.subarray(d,d+32768));else for(a=0;32768>a;++a)e[a]=e[d+a];this.b=32768;return e};
u.prototype.A=function(c){var d,a=this.input.length/this.a+1|0,b,e,f,g=this.input,h=this.c;c&&("number"===typeof c.p&&(a=c.p),"number"===typeof c.v&&(a+=c.v));2>a?(b=(g.length-this.a)/this.o[2],f=258*(b/2)|0,e=f<h.length?h.length+f:h.length<<1):e=h.length*a;s?(d=new Uint8Array(e),d.set(h)):d=h;return this.c=d};
u.prototype.n=function(){var c=0,d=this.c,a=this.g,b,e=new (s?Uint8Array:Array)(this.l+(this.b-32768)),f,g,h,k;if(0===a.length)return s?this.c.subarray(32768,this.b):this.c.slice(32768,this.b);f=0;for(g=a.length;f<g;++f){b=a[f];h=0;for(k=b.length;h<k;++h)e[c++]=b[h]}f=32768;for(g=this.b;f<g;++f)e[c++]=d[f];this.g=[];return this.buffer=e};
u.prototype.w=function(){var c,d=this.b;s?this.s?(c=new Uint8Array(d),c.set(this.c.subarray(0,d))):c=this.c.subarray(0,d):(this.c.length>d&&(this.c.length=d),c=this.c);return this.buffer=c};function U(c,d){var a,b;this.input=c;this.a=0;if(d||!(d={}))d.index&&(this.a=d.index),d.verify&&(this.B=d.verify);a=c[this.a++];b=c[this.a++];switch(a&15){case V:this.method=V;break;default:throw Error("unsupported compression method");}if(0!==((a<<8)+b)%31)throw Error("invalid fcheck flag:"+((a<<8)+b)%31);if(b&32)throw Error("fdict flag is not supported");this.r=new u(c,{index:this.a,bufferSize:d.bufferSize,bufferType:d.bufferType,resize:d.resize})}
U.prototype.k=function(){var c=this.input,d,a;d=this.r.k();this.a=this.r.a;if(this.B){a=(c[this.a++]<<24|c[this.a++]<<16|c[this.a++]<<8|c[this.a++])>>>0;var b=d;if("string"===typeof b){var e=b.split(""),f,g;f=0;for(g=e.length;f<g;f++)e[f]=(e[f].charCodeAt(0)&255)>>>0;b=e}for(var h=1,k=0,l=b.length,p,n=0;0<l;){p=1024<l?1024:l;l-=p;do h+=b[n++],k+=h;while(--p);h%=65521;k%=65521}if(a!==(k<<16|h)>>>0)throw Error("invalid adler-32 checksum");}return d};var V=8;q("Zlib.Inflate",U);q("Zlib.Inflate.prototype.decompress",U.prototype.k);var W={ADAPTIVE:x.t,BLOCK:x.u},X,Y,Z,$;if(Object.keys)X=Object.keys(W);else for(Y in X=[],Z=0,W)X[Z++]=Y;Z=0;for($=X.length;Z<$;++Z)Y=X[Z],q("Zlib.Inflate.BufferType."+Y,W[Y]);}).call(this); //@ sourceMappingURL=inflate.min.js.map

File diff suppressed because one or more lines are too long

@ -45,17 +45,7 @@ Glowing Bear uses WeeChat directly as its backend through the relay plugin. This
## Development ## Development
### Setup ### Setup
Getting started with the development of Glowing Bear is really simple, partly because we don't have a build process (pure client-side JS, remember). All you have to do is clone the repository, fire up a webserver to host the files, and start fiddling around. You can try out your changes by reloading the page. Getting started with the development of Glowing Bear requires the installation of [Node.js](https://nodejs.org). All you have to do is clone the repository, install dependencies using command `npm install`, fire up the development webserver using command `npm start`, and start fiddling around. Once a change is made the development server will instruct the Web browser to reload the page for you.
Here's a simple example using the python simple web server:
```bash
git clone https://github.com/glowing-bear/glowing-bear
cd glowing-bear
# python 2.*
python -m SimpleHTTPServer
# or python 3.*
python -m http.server
```
Now you can point your browser to [http://localhost:8000](http://localhost:8000)! Now you can point your browser to [http://localhost:8000](http://localhost:8000)!

@ -1,32 +0,0 @@
{
"name": "glowing-bear",
"description": "A webclient for WeeChat",
"version": "0.10.0",
"homepage": "https://github.com/glowing-bear/glowing-bear",
"license": "GPLv3",
"private": true,
"dependencies": {
"angular": "1.8.x",
"angular-route": "1.8.x",
"angular-sanitize": "1.8.x",
"angular-touch": "1.8.x",
"angular-loader": "1.8.x",
"angular-mocks": "1.8.x",
"underscore": "~1.10",
"linkifyjs": "jQuery-linkify#^2.1.9"
},
"devDependencies": {
"bootstrap": "~3.4",
"html5-boilerplate": "~4.3.0",
"emojione": "~2.2"
},
"keywords": [
"weechat",
"irc"
],
"ignore": [
"**/.*",
"node_modules",
"bower_components"
]
}

@ -1,26 +1,25 @@
# Common flags for electron-packager on all platforms # Common flags for electron-packager on all platforms
ELECTRON_COMMON=. "Glowing Bear" --overwrite --version-string.FileDescription="Glowing Bear" --ignore=node_modules --ignore=test --ignore=bower_components ELECTRON_COMMON=./build "Glowing Bear" --overwrite --version-string.FileDescription="Glowing Bear" --ignore=node_modules --ignore=test --ignore=bower_components
# fetch dependencies for local installation build:
bower: npm run build
bower install
# copy dependencies from bower_components to the correct place # copy dependencies from bower_components to the correct place
copylocal: #copylocal:
find bower_components \( -name "*min.js" -o -name "*min.css" \) -exec cp {} 3rdparty \; # find bower_components \( -name "*min.js" -o -name "*min.css" \) -exec cp {} 3rdparty \;
cp -r bower_components/bootstrap/fonts . # cp -r bower_components/bootstrap/fonts .
# modify index.html to use local files # modify index.html to use local files
uselocal: copylocal #uselocal: copylocal
sed -i.bak 's,https://cdnjs.cloudflare.com/ajax/libs/[^\"]*/,3rdparty/,g' index.html # sed -i.bak 's,https://cdnjs.cloudflare.com/ajax/libs/[^\"]*/,3rdparty/,g' index.html
sed -i.bak 's, integrity=\".*\" crossorigin=\"anonymous\",,' index.html # sed -i.bak 's, integrity=\".*\" crossorigin=\"anonymous\",,' index.html
# build the electron app for various platforms # build the electron app for various platforms
build-electron-windows: uselocal build-electron-windows: build
electron-packager ${ELECTRON_COMMON} --platform=win32 --arch=ia32 --electron-version=9.0.5 --icon=assets/img/favicon.ico --asar=true electron-packager ${ELECTRON_COMMON} --platform=win32 --arch=ia32 --electron-version=9.0.5 --icon=assets/img/favicon.ico --asar=true
build-electron-darwin: uselocal build-electron-darwin: build
electron-packager ${ELECTRON_COMMON} --platform=darwin --arch=x64 --electron-version=9.0.5 --icon=assets/img/glowing-bear.icns electron-packager ${ELECTRON_COMMON} --platform=darwin --arch=x64 --electron-version=9.0.5 --icon=assets/img/glowing-bear.icns
build-electron-linux: uselocal build-electron-linux: build
electron-packager ${ELECTRON_COMMON} --platform=linux --arch=x64 --electron-version=9.0.5 --icon=assets/img/favicon.ico electron-packager ${ELECTRON_COMMON} --platform=linux --arch=x64 --electron-version=9.0.5 --icon=assets/img/favicon.ico

File diff suppressed because it is too large Load Diff

9697
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -7,37 +7,51 @@
"main": "electron-main.js", "main": "electron-main.js",
"license": "GPLv3", "license": "GPLv3",
"devDependencies": { "devDependencies": {
"bower": "^1.8.8", "@babel/core": "^7.12.9",
"@babel/preset-env": "^7.12.7",
"angular-mocks": "^1.8.2",
"babel-loader": "^8.2.2",
"copy-webpack-plugin": "^6.3.2",
"electron-packager": "^15.0.0", "electron-packager": "^15.0.0",
"html-webpack-plugin": "^4.5.0",
"http-server": "^0.12.3", "http-server": "^0.12.3",
"jasmine-core": "^3.6.0", "jasmine-core": "^3.6.0",
"jshint": "^2.11.1", "jshint": "^2.11.1",
"karma": "^5.1.0", "karma": "^5.1.0",
"karma-chrome-launcher": "^3.1.0",
"karma-jasmine": "~3.1", "karma-jasmine": "~3.1",
"karma-junit-reporter": "~2.0", "karma-junit-reporter": "~2.0",
"karma-phantomjs-launcher": "^1.0.4", "karma-webpack": "^5.0.0-alpha.3.0",
"linkifyjs": "^2.1.9", "linkifyjs": "^2.1.9",
"protractor": "^7.0.0", "protractor": "^7.0.0",
"shelljs": "^0.8.4", "webpack": "^5.8.0",
"uglify-js": "^3.10.4" "webpack-cli": "^4.2.0",
"webpack-dev-server": "^3.11.0"
}, },
"scripts": { "scripts": {
"postinstall": "bower install -p", "build": "webpack",
"minify": " uglifyjs js/localstorage.js js/weechat.js js/irc-utils.js js/glowingbear.js js/settings.js js/utils.js js/notifications.js js/filters.js js/handlers.js js/connection.js js/file-change.js js/imgur-drop-directive.js js/whenscrolled-directive.js js/inputbar.js js/plugin-directive.js js/websockets.js js/models.js js/bufferResume.js js/plugins.js js/imgur.js -c -m -o min.js --source-map url='min.js.map'", "lint": "jshint src/js/*.js test/unit/*.js",
"prestart": "npm install", "prestart": "npm install",
"start": "http-server -a localhost -p 8000", "start": "webpack serve",
"pretest": "npm install", "-pretest": "npm install",
"test": "karma start test/karma.conf.js", "test": "karma start test/karma.conf.js",
"test-single-run": "karma start test/karma.conf.js --single-run", "test-single-run": "karma start test/karma.conf.js --single-run",
"preupdate-webdriver": "npm install", "preupdate-webdriver": "npm install",
"update-webdriver": "webdriver-manager update", "update-webdriver": "webdriver-manager update",
"preprotractor": "npm run update-webdriver", "preprotractor": "npm run update-webdriver",
"protractor": "protractor test/protractor-conf.js", "protractor": "protractor test/protractor-conf.js",
"premake-local": "bower install --dev",
"make-local": "make -f electron.makefile uselocal",
"build-electron-windows": "make -f electron.makefile bower build-electron-windows", "build-electron-windows": "make -f electron.makefile bower build-electron-windows",
"build-electron-darwin": "make -f electron.makefile bower build-electron-darwin", "build-electron-darwin": "make -f electron.makefile bower build-electron-darwin",
"build-electron-linux": "make -f electron.makefile bower build-electron-linux", "build-electron-linux": "make -f electron.makefile build-electron-linux"
"update-index-async": "node -e \"require('shelljs/global'); sed('-i', /\\/\\/@@NG_LOADER_START@@[\\s\\S]*\\/\\/@@NG_LOADER_END@@/, '//@@NG_LOADER_START@@\\n' + cat('app/bower_components/angular-loader/angular-loader.min.js') + '\\n//@@NG_LOADER_END@@', 'app/index-async.html');\"" },
"dependencies": {
"angular": "^1.8.2",
"angular-route": "^1.8.2",
"angular-sanitize": "^1.8.2",
"angular-touch": "^1.8.2",
"favico.js": "^0.3.10",
"jquery-linkify": "^2.2.1",
"underscore": "^1.10.2",
"zlibjs": "^0.3.1"
} }
} }

@ -1,2 +1,2 @@
./node_modules/.bin/jshint js/*.js test/unit/*.js npm run lint
npm test npm test

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

@ -19,36 +19,9 @@
<link rel="shortcut icon" type="image/png" href="assets/img/favicon.png" > <link rel="shortcut icon" type="image/png" href="assets/img/favicon.png" >
<link href="css/glowingbear.css" rel="stylesheet" media="screen"> <link href="css/glowingbear.css" rel="stylesheet" media="screen">
<link href="css/themes/dark.css" rel="stylesheet" media="screen" id="themeCSS" /> <link href="css/themes/dark.css" rel="stylesheet" media="screen" id="themeCSS" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.0/angular.min.js" integrity="sha512-jiG+LwJB0bmXdn4byKzWH6whPpnLy1pnGA/p3VCXFLk4IJ/Ftfcb22katPTapt35Q6kwrlnRheK6UPOIdJhYTA==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-route/1.8.0/angular-route.min.js" integrity="sha512-KgQeEw8J2b0mJH/09XwcsYPr0koz6wqhHR4Kpii/4Tjayshk4swTbyGpWRCPpQQlP/4kJEXGqBXsXgkL+wPTpw==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-sanitize/1.8.0/angular-sanitize.min.js" integrity="sha512-ZKFv9PnfnRmoBms0LvWmODQW9dXBwualot+o5RowVKQAxxY/6t/El/qTM9E+U+EB5+xcrxxDvhcUcTYBw/kbiQ==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-touch/1.8.0/angular-touch.min.js" integrity="sha512-Fv9vdYa1UF171Mgs1hGeRXULvHflaw78t5EPI/cG6pVp9SjhjlhfL2ifdkwxEP0EBAhlA02UuE8mEjm65CYYpw==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.10.2/underscore-min.js" integrity="sha512-HKvDCFVKg8ZPGjecy6on7UECEpE76Y86h3GaE4JMCz+deFWdjcW/tWnh0hCfaBvURvlOa9f5CNVzt7EFkulYbw==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/emojione/2.2.7/lib/js/emojione.min.js" integrity="sha256-9cBkVeU53NiJ9/BdcJta3HbERAmf5X9DE2WvL8V+gDs=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/emojione/2.2.7/lib/js/emojione.min.js" integrity="sha256-9cBkVeU53NiJ9/BdcJta3HbERAmf5X9DE2WvL8V+gDs=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery-linkify/2.1.9/linkify.min.js" integrity="sha512-kxj7VjlzsQgiku2vbRcZI0FJ0dXmPsiRLugiRxJrCROusKHaFfX/hGDD1/L/R0Y+xI8zlA2B5nm6USapz7nQbg==" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery-linkify/2.1.9/linkify.min.js" integrity="sha512-kxj7VjlzsQgiku2vbRcZI0FJ0dXmPsiRLugiRxJrCROusKHaFfX/hGDD1/L/R0Y+xI8zlA2B5nm6USapz7nQbg==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery-linkify/2.1.9/linkify-string.min.js" integrity="sha512-CMBjJdVIcw7zafkE+uedZCnw6r4ABU1Fev5xA7db0D097/NzhO6Ajo2kdZFOQ+y0kg9sE/t44bPAwuuNhUVIcQ==" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery-linkify/2.1.9/linkify-string.min.js" integrity="sha512-CMBjJdVIcw7zafkE+uedZCnw6r4ABU1Fev5xA7db0D097/NzhO6Ajo2kdZFOQ+y0kg9sE/t44bPAwuuNhUVIcQ==" crossorigin="anonymous"></script>
<script type="text/javascript" src="3rdparty/inflate.min.js"></script>
<script type="text/javascript" src="js/localstorage.js"></script>
<script type="text/javascript" src="js/weechat.js"></script>
<script type="text/javascript" src="js/irc-utils.js"></script>
<script type="text/javascript" src="js/glowingbear.js"></script>
<script type="text/javascript" src="js/settings.js"></script>
<script type="text/javascript" src="js/utils.js"></script>
<script type="text/javascript" src="js/notifications.js"></script>
<script type="text/javascript" src="js/filters.js"></script>
<script type="text/javascript" src="js/handlers.js"></script>
<script type="text/javascript" src="js/connection.js"></script>
<script type="text/javascript" src="js/file-change.js"></script>
<script type="text/javascript" src="js/imgur-drop-directive.js"></script>
<script type="text/javascript" src="js/whenscrolled-directive.js"></script>
<script type="text/javascript" src="js/inputbar.js"></script>
<script type="text/javascript" src="js/plugin-directive.js"></script>
<script type="text/javascript" src="js/websockets.js"></script>
<script type="text/javascript" src="js/bufferResume.js"></script>
<script type="text/javascript" src="js/models.js"></script>
<script type="text/javascript" src="js/plugins.js"></script>
<script type="text/javascript" src="js/imgur.js"></script>
<script type="text/javascript" src="3rdparty/favico-0.3.10.min.js"></script>
</head> </head>
<body ng-controller="WeechatCtrl" ng-keydown="handleKeyPress($event)" ng-keyup="handleKeyRelease($event)" ng-keypress="handleKeyPress($event)" ng-class="{'no-overflow': connected}" ng-init="init()" lang="en-US"> <body ng-controller="WeechatCtrl" ng-keydown="handleKeyPress($event)" ng-keyup="handleKeyRelease($event)" ng-keypress="handleKeyPress($event)" ng-class="{'no-overflow': connected}" ng-init="init()" lang="en-US">
<audio id="audioNotificationInitializer"><source src="data:audio/mp3;base64,/+MYxAAJs2H8AABLSZv4Af/5yAsCIElB/v/+Y///U+QiEaSchGO+IMQjZCgOLw4KVoIEkf/r69Kbfc7/WbLRPsyvp7/p/p///+MYxBQK+1oUAACNMUWSyLcrqpERhDqKCBWcgbTmuIq8ISkQSv+yf/tbZf9krRTptRUv/XT////66NJQFZTpOd3KUEtM+a+l/+MYxCMKM2YcAACNMB+Jqe+HLv+75fSreYSWGtqHJghl6y///89fcz/p8qIRKeFWYKEGo5mLFmCGBjV0FEJn/9f85V87iy98/+MYxDULA1YYAABHLbI52f2/4v////n7U/swVr0SzhrRIueMLLog0qIKcOwu/5v/lLR/r9DPN/R+vmf//////V8tAxlMY1sy/+MYxEQKM2IYAABHLZjRjUlgUSUAhTUBFHVMQU1FMy4xMDBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/+MYxFYJ22oAAACHMFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"></audio> <audio id="audioNotificationInitializer"><source src="data:audio/mp3;base64,/+MYxAAJs2H8AABLSZv4Af/5yAsCIElB/v/+Y///U+QiEaSchGO+IMQjZCgOLw4KVoIEkf/r69Kbfc7/WbLRPsyvp7/p/p///+MYxBQK+1oUAACNMUWSyLcrqpERhDqKCBWcgbTmuIq8ISkQSv+yf/tbZf9krRTptRUv/XT////66NJQFZTpOd3KUEtM+a+l/+MYxCMKM2YcAACNMB+Jqe+HLv+75fSreYSWGtqHJghl6y///89fcz/p8qIRKeFWYKEGo5mLFmCGBjV0FEJn/9f85V87iy98/+MYxDULA1YYAABHLbI52f2/4v////n7U/swVr0SzhrRIueMLLog0qIKcOwu/5v/lLR/r9DPN/R+vmf//////V8tAxlMY1sy/+MYxEQKM2IYAABHLZjRjUlgUSUAhTUBFHVMQU1FMy4xMDBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/+MYxFYJ22oAAACHMFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"></audio>

@ -1,10 +1,12 @@
(function() { // (function() {
'use strict'; 'use strict';
var weechat = angular.module('weechat'); import * as weeChat from './weechat';
weechat.factory('connection', // var weechat = angular.module('weechat');
['$rootScope', '$log', 'handlers', 'models', 'settings', 'ngWebsockets', 'utils', function($rootScope,
// weechat.factory('connection',
export const connectionFactory = ['$rootScope', '$log', 'handlers', 'models', 'settings', 'ngWebsockets', 'utils', function($rootScope,
$log, $log,
handlers, handlers,
models, models,
@ -16,6 +18,7 @@ weechat.factory('connection',
var connectionData = []; var connectionData = [];
var reconnectTimer; var reconnectTimer;
var handleClose;
// Global connection lock to prevent multiple connections from being opened // Global connection lock to prevent multiple connections from being opened
var locked = false; var locked = false;
@ -400,7 +403,7 @@ weechat.factory('connection',
handleWrongPassword(); handleWrongPassword();
}; };
var handleClose = function (evt) { handleClose = function (evt) {
if (ssl && evt && evt.code === 1006) { if (ssl && evt && evt.code === 1006) {
// A password error doesn't trigger onerror, but certificate issues do. Check time of last error. // A password error doesn't trigger onerror, but certificate issues do. Check time of last error.
if (typeof $rootScope.lastError !== "undefined" && (Date.now() - $rootScope.lastError) < 1000) { if (typeof $rootScope.lastError !== "undefined" && (Date.now() - $rootScope.lastError) < 1000) {
@ -700,5 +703,5 @@ weechat.factory('connection',
attemptReconnect: attemptReconnect, attemptReconnect: attemptReconnect,
requestCompletion: requestCompletion requestCompletion: requestCompletion
}; };
}]); }];
})(); // })();

@ -1,6 +1,7 @@
(function() {
'use strict'; 'use strict';
import * as _ from "underscore";
var weechat = angular.module('weechat'); var weechat = angular.module('weechat');
weechat.filter('toArray', function () { weechat.filter('toArray', function () {
@ -236,5 +237,3 @@ weechat.filter('codify', function() {
}); });
}; };
}); });
})();

@ -1,6 +1,10 @@
(function() {
'use strict'; 'use strict';
import * as Favico from "favico.js";
import * as _ from "underscore";
import { connectionFactory } from './connection';
// cordova splash screen // cordova splash screen
document.addEventListener("deviceready", function () { document.addEventListener("deviceready", function () {
if (navigator.splashscreen !== undefined) { if (navigator.splashscreen !== undefined) {
@ -1029,4 +1033,4 @@ weechat.config(['$routeProvider', '$locationProvider',
} }
]); ]);
})(); weechat.factory('connection', connectionFactory);

@ -1,6 +1,8 @@
(function() {
'use strict'; 'use strict';
import * as _ from "underscore";
var weechat = angular.module('weechat'); var weechat = angular.module('weechat');
weechat.factory('handlers', ['$rootScope', '$log', 'models', 'plugins', 'notifications', 'bufferResume', function($rootScope, $log, models, plugins, notifications, bufferResume) { weechat.factory('handlers', ['$rootScope', '$log', 'models', 'plugins', 'notifications', 'bufferResume', function($rootScope, $log, models, plugins, notifications, bufferResume) {
@ -540,4 +542,3 @@ weechat.factory('handlers', ['$rootScope', '$log', 'models', 'plugins', 'notific
}; };
}]); }]);
})();

@ -1,6 +1,7 @@
(function() {
'use strict'; 'use strict';
import * as _ from "underscore";
var weechat = angular.module('weechat'); var weechat = angular.module('weechat');
weechat.directive('inputBar', function() { weechat.directive('inputBar', function() {
@ -806,4 +807,3 @@ weechat.directive('inputBar', function() {
}] }]
}; };
}); });
})();

@ -2,9 +2,12 @@
* This file contains the weechat models and various * This file contains the weechat models and various
* helper methods to work with them. * helper methods to work with them.
*/ */
(function() {
'use strict'; 'use strict';
import * as _ from "underscore";
import * as weeChat from './weechat';
var models = angular.module('weechatModels', []); var models = angular.module('weechatModels', []);
models.service('models', ['$rootScope', '$filter', 'bufferResume', function($rootScope, $filter, bufferResume) { models.service('models', ['$rootScope', '$filter', 'bufferResume', function($rootScope, $filter, bufferResume) {
@ -707,4 +710,3 @@ models.service('models', ['$rootScope', '$filter', 'bufferResume', function($roo
delete(this.model.buffers[bufferId]); delete(this.model.buffers[bufferId]);
}; };
}]); }]);
})();

@ -2,9 +2,10 @@
* This file contains the plugin definitions * This file contains the plugin definitions
*/ */
(function() {
'use strict'; 'use strict';
import * as _ from "underscore";
var plugins = angular.module('plugins', []); var plugins = angular.module('plugins', []);
/* /*
@ -594,4 +595,3 @@ plugins.factory('userPlugins', function() {
}); });
})();

@ -1,3 +1,6 @@
import * as _ from "underscore";
var weechat = angular.module('weechat'); var weechat = angular.module('weechat');
weechat.factory('utils', function() { weechat.factory('utils', function() {

@ -1,6 +1,8 @@
(function() {
'use strict'; 'use strict';
import * as _ from "underscore";
var websockets = angular.module('ngWebsockets', []); var websockets = angular.module('ngWebsockets', []);
websockets.factory('ngWebsockets', websockets.factory('ngWebsockets',
@ -147,4 +149,3 @@ function($rootScope, $q) {
}; };
}]); }]);
})();

File diff suppressed because it is too large Load Diff

@ -1,7 +1,10 @@
(function() {
'use strict'; 'use strict';
import * as _ from "underscore";
var weechat = angular.module('weechat'); var weechat = angular.module('weechat');
weechat.directive('whenScrolled', function() { weechat.directive('whenScrolled', function() {
return function(scope, elm, attr) { return function(scope, elm, attr) {
var raw = elm[0]; var raw = elm[0];
@ -17,5 +20,3 @@ weechat.directive('whenScrolled', function() {
}); });
}; };
}); });
})();

@ -0,0 +1,27 @@
"use strict";
import "angular";
import "angular-route";
import "angular-sanitize";
import "angular-touch";
import "./js/localstorage.js";
import "./js/irc-utils.js";
import "./js/bufferResume.js";
import "./js/models.js";
import "./js/plugins.js";
import "./js/websockets.js";
import "./js/glowingbear.js";
import "./js/settings.js";
import "./js/utils.js";
import "./js/notifications.js";
import "./js/filters.js";
import "./js/handlers.js";
import "./js/file-change.js";
import "./js/imgur-drop-directive.js";
import "./js/whenscrolled-directive.js";
import "./js/inputbar.js";
import "./js/plugin-directive.js";
import "./js/imgur.js";

@ -1,53 +1,73 @@
const webpackConfig = require('../webpack.config');
module.exports = function (config) { module.exports = function (config) {
config.set({ config.set({
basePath: '../', basePath: '../',
files: [ files: [
'bower_components/angular/angular.js',
'bower_components/angular-route/angular-route.js',
'bower_components/angular-mocks/angular-mocks.js',
'bower_components/angular-sanitize/angular-sanitize.js',
'bower_components/angular-touch/angular-touch.js',
'bower_components/underscore/underscore.js',
'node_modules/linkifyjs/dist/linkify.js', 'node_modules/linkifyjs/dist/linkify.js',
'node_modules/linkifyjs/dist/linkify-string.js', 'node_modules/linkifyjs/dist/linkify-string.js',
'js/localstorage.js', 'test/unit/main.test.js'
'js/weechat.js',
'js/irc-utils.js',
'js/glowingbear.js',
'js/utils.js',
'js/notifications.js',
'js/filters.js',
'js/handlers.js',
'js/connection.js',
'js/inputbar.js',
'js/plugin-directive.js',
'js/websockets.js',
'js/models.js',
'js/bufferResume.js',
'js/plugins.js',
'test/unit/**/*.js'
], ],
autoWatch: true, autoWatch: true,
frameworks: ['jasmine'], frameworks: ['jasmine'],
browsers : ['PhantomJS'], browsers: ['Chrome', 'ChromeHeadless', 'ChromeHeadlessNoSandbox'],
singleRun: true, singleRun: true,
plugins: [ plugins: [
'karma-phantomjs-launcher', 'karma-chrome-launcher',
'karma-jasmine', 'karma-jasmine',
'karma-junit-reporter' 'karma-junit-reporter',
'karma-webpack'
], ],
customLaunchers: {
ChromeHeadlessNoSandbox: {
base: 'ChromeHeadless',
flags: ['--no-sandbox']
}
},
junitReporter: { junitReporter: {
outputFile: 'test_out/unit.xml', outputFile: 'test_out/unit.xml',
suite: 'unit' suite: 'unit'
} },
/* karma-webpack config
pass your webpack configuration for karma
add `babel-loader` to the webpack configuration to make
the ES6+ code in the test files readable to the browser
eg. import, export keywords */
webpack: {
devtool: webpackConfig.devtool,
module: webpackConfig.module,
optimization: {
runtimeChunk: false,
splitChunks: false
},
},
preprocessors: {
//add webpack as preprocessor to support require() in test-suits .js files
'./test/unit/*.js': ['webpack'],
'./src/**/*.js': ['webpack']
},
// webpackMiddleware: {
// //turn off webpack bash output when run the tests
// noInfo: true,
// stats: 'errors-only'
// }
}); });
if(process.env.TRAVIS){
config.browsers = ['ChromeHeadlessNoSandbox'];
}
}; };

@ -1,24 +1,30 @@
var weechat = angular.module('weechat'); "use strict";
import angular from "angular";
import "angular-mocks";
import "../../src/main";
describe('Filters', function() { describe('Filters', function() {
beforeEach(module('weechat')); beforeEach(angular.mock.module('weechat'));
/*beforeEach(module(function($provide) { /*beforeEach(module(function($provide) {
$provide.value('version', 'TEST_VER'); $provide.value('version', 'TEST_VER');
}));*/ }));*/
it('has an irclinky filter', inject(function($filter) { it('has an irclinky filter', angular.mock.inject(function($filter) {
expect($filter('irclinky')).not.toBeNull(); expect($filter('irclinky')).not.toBeNull();
})); }));
describe('conditionalLinkify', function() { describe('conditionalLinkify', function() {
it('should create links from an url', inject(function($filter) { it('should create links from an url', angular.mock.inject(function($filter) {
var url = 'asdf https://a.example.com/wiki/asdf_qwer_(rivi%C3%A8re) Some text.', var url = 'asdf https://a.example.com/wiki/asdf_qwer_(rivi%C3%A8re) Some text.',
link = 'asdf <a href="https://a.example.com/wiki/asdf_qwer_(rivi%C3%A8re)" target="_blank" rel="noopener noreferrer">https://a.example.com/wiki/asdf_qwer_(rivi%C3%A8re)</a> Some text.', link = 'asdf <a href="https://a.example.com/wiki/asdf_qwer_(rivi%C3%A8re)" target="_blank" rel="noopener noreferrer">https://a.example.com/wiki/asdf_qwer_(rivi%C3%A8re)</a> Some text.',
result = $filter('conditionalLinkify')(url); result = $filter('conditionalLinkify')(url);
expect(result).toEqual(link); expect(result).toEqual(link);
})); }));
it('should not make emails into links', inject(function($filter) { it('should not make emails into links', angular.mock.inject(function($filter) {
var url = 'asdf@gmail.com', var url = 'asdf@gmail.com',
link = 'asdf@gmail.com', link = 'asdf@gmail.com',
result = $filter('conditionalLinkify')(url); result = $filter('conditionalLinkify')(url);
@ -27,19 +33,19 @@ describe('Filters', function() {
}); });
describe('irclinky', function() { describe('irclinky', function() {
it('should not mess up text', inject(function(irclinkyFilter) { it('should not mess up text', angular.mock.inject(function(irclinkyFilter) {
expect(irclinkyFilter('foo')).toEqual('foo'); expect(irclinkyFilter('foo')).toEqual('foo');
})); }));
it('should linkify IRC channels', inject(function(irclinkyFilter) { it('should linkify IRC channels', angular.mock.inject(function(irclinkyFilter) {
expect(irclinkyFilter('#foo')).toEqual('<a href="#" onclick="openBuffer(\'#foo\');">#foo</a>'); expect(irclinkyFilter('#foo')).toEqual('<a href="#" onclick="openBuffer(\'#foo\');">#foo</a>');
})); }));
it('should not mess up IRC channels surrounded by HTML entities', inject(function(irclinkyFilter) { it('should not mess up IRC channels surrounded by HTML entities', angular.mock.inject(function(irclinkyFilter) {
expect(irclinkyFilter('<"#foo">')).toEqual('<"<a href="#" onclick="openBuffer(\'#foo">\');">#foo"></a>'); expect(irclinkyFilter('<"#foo">')).toEqual('<"<a href="#" onclick="openBuffer(\'#foo">\');">#foo"></a>');
})); }));
it('should not touch links created by `linky`', inject(function($filter, DOMfilterFilter) { it('should not touch links created by `linky`', angular.mock.inject(function($filter, DOMfilterFilter) {
var url = 'http://foo.bar/#baz', var url = 'http://foo.bar/#baz',
link = $filter('conditionalLinkify')(url), link = $filter('conditionalLinkify')(url),
result = DOMfilterFilter(link, 'irclinky').$$unwrapTrustedValue(); result = DOMfilterFilter(link, 'irclinky').$$unwrapTrustedValue();
@ -48,59 +54,59 @@ describe('Filters', function() {
}); });
describe('inlinecolour', function() { describe('inlinecolour', function() {
it('should not mess up normal text', inject(function(inlinecolourFilter) { it('should not mess up normal text', angular.mock.inject(function(inlinecolourFilter) {
expect(inlinecolourFilter('foo')).toEqual('foo'); expect(inlinecolourFilter('foo')).toEqual('foo');
expect(inlinecolourFilter('test #foobar baz')).toEqual('test #foobar baz'); expect(inlinecolourFilter('test #foobar baz')).toEqual('test #foobar baz');
})); }));
it('should detect inline colours in #rrggbb format', inject(function(inlinecolourFilter) { it('should detect inline colours in #rrggbb format', angular.mock.inject(function(inlinecolourFilter) {
expect(inlinecolourFilter('#123456')).toEqual('#123456 <div class="colourbox" style="background-color:#123456"></div>'); expect(inlinecolourFilter('#123456')).toEqual('#123456 <div class="colourbox" style="background-color:#123456"></div>');
expect(inlinecolourFilter('#aabbcc')).toEqual('#aabbcc <div class="colourbox" style="background-color:#aabbcc"></div>'); expect(inlinecolourFilter('#aabbcc')).toEqual('#aabbcc <div class="colourbox" style="background-color:#aabbcc"></div>');
})); }));
it('should not detect inline colours in #rgb format', inject(function(inlinecolourFilter) { it('should not detect inline colours in #rgb format', angular.mock.inject(function(inlinecolourFilter) {
expect(inlinecolourFilter('#123')).toEqual('#123'); expect(inlinecolourFilter('#123')).toEqual('#123');
expect(inlinecolourFilter('#abc')).toEqual('#abc'); expect(inlinecolourFilter('#abc')).toEqual('#abc');
})); }));
it('should detect inline colours in rgb(12,34,56) and rgba(12,34,56,0.78) format', inject(function(inlinecolourFilter) { it('should detect inline colours in rgb(12,34,56) and rgba(12,34,56,0.78) format', angular.mock.inject(function(inlinecolourFilter) {
expect(inlinecolourFilter('rgb(1,2,3)')).toEqual('rgb(1,2,3) <div class="colourbox" style="background-color:rgb(1,2,3)"></div>'); expect(inlinecolourFilter('rgb(1,2,3)')).toEqual('rgb(1,2,3) <div class="colourbox" style="background-color:rgb(1,2,3)"></div>');
expect(inlinecolourFilter('rgb(1,2,3);')).toEqual('rgb(1,2,3); <div class="colourbox" style="background-color:rgb(1,2,3);"></div>'); expect(inlinecolourFilter('rgb(1,2,3);')).toEqual('rgb(1,2,3); <div class="colourbox" style="background-color:rgb(1,2,3);"></div>');
expect(inlinecolourFilter('rgba(1,2,3,0.4)')).toEqual('rgba(1,2,3,0.4) <div class="colourbox" style="background-color:rgba(1,2,3,0.4)"></div>'); expect(inlinecolourFilter('rgba(1,2,3,0.4)')).toEqual('rgba(1,2,3,0.4) <div class="colourbox" style="background-color:rgba(1,2,3,0.4)"></div>');
expect(inlinecolourFilter('rgba(255,123,0,0.5);')).toEqual('rgba(255,123,0,0.5); <div class="colourbox" style="background-color:rgba(255,123,0,0.5);"></div>'); expect(inlinecolourFilter('rgba(255,123,0,0.5);')).toEqual('rgba(255,123,0,0.5); <div class="colourbox" style="background-color:rgba(255,123,0,0.5);"></div>');
})); }));
it('should tolerate whitespace in between numbers in rgb/rgba colours', inject(function(inlinecolourFilter) { it('should tolerate whitespace in between numbers in rgb/rgba colours', angular.mock.inject(function(inlinecolourFilter) {
expect(inlinecolourFilter('rgb( 1\t, 2 , 3 )')).toEqual('rgb( 1\t, 2 , 3 ) <div class="colourbox" style="background-color:rgb( 1\t, 2 , 3 )"></div>'); expect(inlinecolourFilter('rgb( 1\t, 2 , 3 )')).toEqual('rgb( 1\t, 2 , 3 ) <div class="colourbox" style="background-color:rgb( 1\t, 2 , 3 )"></div>');
})); }));
it('should handle multiple and mixed occurrences of colour values', inject(function(inlinecolourFilter) { it('should handle multiple and mixed occurrences of colour values', angular.mock.inject(function(inlinecolourFilter) {
expect(inlinecolourFilter('rgb(1,2,3) #123456')).toEqual('rgb(1,2,3) <div class="colourbox" style="background-color:rgb(1,2,3)"></div> #123456 <div class="colourbox" style="background-color:#123456"></div>'); expect(inlinecolourFilter('rgb(1,2,3) #123456')).toEqual('rgb(1,2,3) <div class="colourbox" style="background-color:rgb(1,2,3)"></div> #123456 <div class="colourbox" style="background-color:#123456"></div>');
expect(inlinecolourFilter('#f00baa #123456 #234567')).toEqual('#f00baa <div class="colourbox" style="background-color:#f00baa"></div> #123456 <div class="colourbox" style="background-color:#123456"></div> #234567 <div class="colourbox" style="background-color:#234567"></div>'); expect(inlinecolourFilter('#f00baa #123456 #234567')).toEqual('#f00baa <div class="colourbox" style="background-color:#f00baa"></div> #123456 <div class="colourbox" style="background-color:#123456"></div> #234567 <div class="colourbox" style="background-color:#234567"></div>');
expect(inlinecolourFilter('rgba(1,2,3,0.4) foorgb(50,100,150)')).toEqual('rgba(1,2,3,0.4) <div class="colourbox" style="background-color:rgba(1,2,3,0.4)"></div> foorgb(50,100,150) <div class="colourbox" style="background-color:rgb(50,100,150)"></div>'); expect(inlinecolourFilter('rgba(1,2,3,0.4) foorgb(50,100,150)')).toEqual('rgba(1,2,3,0.4) <div class="colourbox" style="background-color:rgba(1,2,3,0.4)"></div> foorgb(50,100,150) <div class="colourbox" style="background-color:rgb(50,100,150)"></div>');
})); }));
it('should not replace HTML escaped &#123456;', inject(function(inlinecolourFilter) { it('should not replace HTML escaped &#123456;', angular.mock.inject(function(inlinecolourFilter) {
expect(inlinecolourFilter('&#123456;')).toEqual('&#123456;'); expect(inlinecolourFilter('&#123456;')).toEqual('&#123456;');
})); }));
}); });
describe('DOMfilter', function() { describe('DOMfilter', function() {
it('should run a filter on all text nodes', inject(function(DOMfilterFilter) { it('should run a filter on all text nodes', angular.mock.inject(function(DOMfilterFilter) {
var dom = 'a<p>b<i>c<b>d</b>e<b>f</b>g</i>h</p>i', var dom = 'a<p>b<i>c<b>d</b>e<b>f</b>g</i>h</p>i',
expected = '<span>A</span><p><span>B</span><i><span>C</span><b><span>D</span></b><span>E</span><b><span>F</span></b><span>G</span></i><span>H</span></p><span>I</span>', expected = '<span>A</span><p><span>B</span><i><span>C</span><b><span>D</span></b><span>E</span><b><span>F</span></b><span>G</span></i><span>H</span></p><span>I</span>',
result = DOMfilterFilter(dom, 'uppercase').$$unwrapTrustedValue(); result = DOMfilterFilter(dom, 'uppercase').$$unwrapTrustedValue();
expect(result).toEqual(expected); expect(result).toEqual(expected);
})); }));
it('should pass additional arguments to the filter', inject(function(DOMfilterFilter) { it('should pass additional arguments to the filter', angular.mock.inject(function(DOMfilterFilter) {
var dom = '1<p>2</p>3.14159265', var dom = '1<p>2</p>3.14159265',
expected = '<span>1.00</span><p><span>2.00</span></p><span>3.14</span>', expected = '<span>1.00</span><p><span>2.00</span></p><span>3.14</span>',
result = DOMfilterFilter(dom, 'number', 2).$$unwrapTrustedValue(); result = DOMfilterFilter(dom, 'number', 2).$$unwrapTrustedValue();
expect(result).toEqual(expected); expect(result).toEqual(expected);
})); }));
it('should never lock up like in bug #688', inject(function($filter, DOMfilterFilter) { it('should never lock up like in bug #688', angular.mock.inject(function($filter, DOMfilterFilter) {
var msg = '#crash http://google.com', var msg = '#crash http://google.com',
linked = $filter('conditionalLinkify')(msg), linked = $filter('conditionalLinkify')(msg),
irclinked = DOMfilterFilter(linked, 'irclinky'); irclinked = DOMfilterFilter(linked, 'irclinky');
@ -110,39 +116,39 @@ describe('Filters', function() {
}); });
describe('codify', function() { describe('codify', function() {
it('should not mess up text', inject(function(codifyFilter) { it('should not mess up text', angular.mock.inject(function(codifyFilter) {
expect(codifyFilter('foo')).toEqual('foo'); expect(codifyFilter('foo')).toEqual('foo');
})); }));
it('should codify single snippets', inject(function(codifyFilter) { it('should codify single snippets', angular.mock.inject(function(codifyFilter) {
expect(codifyFilter('z `foo` z')).toEqual('z <span class="hidden-bracket">`</span><code>foo</code><span class="hidden-bracket">`</span> z'); expect(codifyFilter('z `foo` z')).toEqual('z <span class="hidden-bracket">`</span><code>foo</code><span class="hidden-bracket">`</span> z');
expect(codifyFilter('z `a` z')).toEqual('z <span class="hidden-bracket">`</span><code>a</code><span class="hidden-bracket">`</span> z'); expect(codifyFilter('z `a` z')).toEqual('z <span class="hidden-bracket">`</span><code>a</code><span class="hidden-bracket">`</span> z');
expect(codifyFilter('z ```foo``` z')).toEqual('z <span class="hidden-bracket">```</span><code>foo</code><span class="hidden-bracket">```</span> z'); expect(codifyFilter('z ```foo``` z')).toEqual('z <span class="hidden-bracket">```</span><code>foo</code><span class="hidden-bracket">```</span> z');
})); }));
it('should codify multiple snippets', inject(function(codifyFilter) { it('should codify multiple snippets', angular.mock.inject(function(codifyFilter) {
expect(codifyFilter('z `foo` z `bar` `baz`')).toEqual('z <span class="hidden-bracket">`</span><code>foo</code><span class="hidden-bracket">`</span> z <span class="hidden-bracket">`</span><code>bar</code><span class="hidden-bracket">`</span> <span class="hidden-bracket">`</span><code>baz</code><span class="hidden-bracket">`</span>'); expect(codifyFilter('z `foo` z `bar` `baz`')).toEqual('z <span class="hidden-bracket">`</span><code>foo</code><span class="hidden-bracket">`</span> z <span class="hidden-bracket">`</span><code>bar</code><span class="hidden-bracket">`</span> <span class="hidden-bracket">`</span><code>baz</code><span class="hidden-bracket">`</span>');
})); }));
it('should not codify empty snippets', inject(function(codifyFilter) { it('should not codify empty snippets', angular.mock.inject(function(codifyFilter) {
expect(codifyFilter('``')).toEqual('``'); expect(codifyFilter('``')).toEqual('``');
})); }));
it('should not codify single backticks', inject(function(codifyFilter) { it('should not codify single backticks', angular.mock.inject(function(codifyFilter) {
expect(codifyFilter('foo`bar')).toEqual('foo`bar'); expect(codifyFilter('foo`bar')).toEqual('foo`bar');
})); }));
it('should not codify double backticks', inject(function(codifyFilter) { it('should not codify double backticks', angular.mock.inject(function(codifyFilter) {
expect(codifyFilter('some ``non-code``')).toEqual('some ``non-code``'); expect(codifyFilter('some ``non-code``')).toEqual('some ``non-code``');
})); }));
it('should not codify pseudo-fancy quotes', inject(function(codifyFilter) { it('should not codify pseudo-fancy quotes', angular.mock.inject(function(codifyFilter) {
expect(codifyFilter('some ``fancy qoutes\'\'')).toEqual('some ``fancy qoutes\'\''); expect(codifyFilter('some ``fancy qoutes\'\'')).toEqual('some ``fancy qoutes\'\'');
})); }));
it('should not codify stuff in the middle of a word or URL', inject(function(codifyFilter) { it('should not codify stuff in the middle of a word or URL', angular.mock.inject(function(codifyFilter) {
expect(codifyFilter('https://foo.bar/`wat`')).toEqual('https://foo.bar/`wat`'); expect(codifyFilter('https://foo.bar/`wat`')).toEqual('https://foo.bar/`wat`');
expect(codifyFilter('Weird`ness`')).toEqual('Weird`ness`'); expect(codifyFilter('Weird`ness`')).toEqual('Weird`ness`');
})); }));

@ -0,0 +1,3 @@
import "./filters";
import "./plugins";

@ -1,5 +1,11 @@
/* plugins go here */ /* plugins go here */
import angular from "angular";
import "angular-mocks";
import "../../src/main";
var msg = function(msg) { var msg = function(msg) {
return {'text': msg }; return {'text': msg };
}; };
@ -22,14 +28,14 @@ var expectTheseMessagesToContain = function(urls, pluginType, plugins) {
}; };
describe('filter', function() { describe('filter', function() {
beforeEach(module('plugins')); beforeEach(angular.mock.module('plugins'));
describe('Plugins', function() { describe('Plugins', function() {
beforeEach(module(function($provide) { beforeEach(angular.mock.module(function($provide) {
$provide.value('version', 'TEST_VER'); $provide.value('version', 'TEST_VER');
})); }));
it('should recognize spotify links', inject(function(plugins) { it('should recognize spotify links', angular.mock.inject(function(plugins) {
expectTheseMessagesToContain([ expectTheseMessagesToContain([
'spotify:track:6JEK0CvvjDjjMUBFoXShNZ', 'spotify:track:6JEK0CvvjDjjMUBFoXShNZ',
'spotify:user:lorenzhs:playlist:18aXdzQ4Ar1p019OSICtu4', 'spotify:user:lorenzhs:playlist:18aXdzQ4Ar1p019OSICtu4',
@ -43,7 +49,7 @@ describe('filter', function() {
})); }));
it('should recognize youtube videos', inject(function(plugins) { it('should recognize youtube videos', angular.mock.inject(function(plugins) {
expectTheseMessagesToContain([ expectTheseMessagesToContain([
'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
'http://www.youtube.com/watch?v=dQw4w9WgXcQ', 'http://www.youtube.com/watch?v=dQw4w9WgXcQ',
@ -56,7 +62,7 @@ describe('filter', function() {
plugins); plugins);
})); }));
it('should recognize dailymotion videos', inject(function(plugins) { it('should recognize dailymotion videos', angular.mock.inject(function(plugins) {
expectTheseMessagesToContain([ expectTheseMessagesToContain([
'dailymotion.com/video/test', 'dailymotion.com/video/test',
'dailymotion.com/video/#video=asdf', 'dailymotion.com/video/#video=asdf',
@ -66,7 +72,7 @@ describe('filter', function() {
plugins); plugins);
})); }));
it('should recognize allocine videos', inject(function(plugins) { it('should recognize allocine videos', angular.mock.inject(function(plugins) {
expectTheseMessagesToContain([ expectTheseMessagesToContain([
'allocine.fr/videokast/video-12', 'allocine.fr/videokast/video-12',
'allocine.fr/cmedia=234' 'allocine.fr/cmedia=234'
@ -75,7 +81,7 @@ describe('filter', function() {
plugins); plugins);
})); }));
it('should recognize html5 videos', inject(function(plugins) { it('should recognize html5 videos', angular.mock.inject(function(plugins) {
expectTheseMessagesToContain([ expectTheseMessagesToContain([
'http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4', 'http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4',
'http://www.quirksmode.org/html5/videos/big_buck_bunny.webm', 'http://www.quirksmode.org/html5/videos/big_buck_bunny.webm',
@ -85,7 +91,7 @@ describe('filter', function() {
plugins); plugins);
})); }));
it('should recognize images', inject(function(plugins) { it('should recognize images', angular.mock.inject(function(plugins) {
expectTheseMessagesToContain([ expectTheseMessagesToContain([
'http://i.imgur.com/BTNIDBR.gif', 'http://i.imgur.com/BTNIDBR.gif',
'https://i.imgur.com/1LmDmct.jpg', 'https://i.imgur.com/1LmDmct.jpg',
@ -101,7 +107,7 @@ describe('filter', function() {
plugins); plugins);
})); }));
it('should recognize cloud music', inject(function(plugins) { it('should recognize cloud music', angular.mock.inject(function(plugins) {
expectTheseMessagesToContain([ expectTheseMessagesToContain([
'http://soundcloud.com/', 'http://soundcloud.com/',
'https://sadf.mixcloud.com/', 'https://sadf.mixcloud.com/',
@ -110,7 +116,7 @@ describe('filter', function() {
plugins); plugins);
})); }));
it('should recognize google map', inject(function(plugins) { it('should recognize google map', angular.mock.inject(function(plugins) {
expectTheseMessagesToContain([ expectTheseMessagesToContain([
'https://www.google.com/maps/@48.0034139,-74.9129088,6z', 'https://www.google.com/maps/@48.0034139,-74.9129088,6z',
], ],
@ -118,7 +124,7 @@ describe('filter', function() {
plugins); plugins);
})); }));
it('should recognize google map', inject(function(plugins) { it('should recognize google map', angular.mock.inject(function(plugins) {
expectTheseMessagesToContain([ expectTheseMessagesToContain([
'https://asciinema.org/a/10625', 'https://asciinema.org/a/10625',
], ],
@ -126,7 +132,7 @@ describe('filter', function() {
plugins); plugins);
})); }));
it('should recognize meteograms', inject(function(plugins) { it('should recognize meteograms', angular.mock.inject(function(plugins) {
expectTheseMessagesToContain([ expectTheseMessagesToContain([
'http://www.yr.no/sted/Canada/Quebec/Montreal/', 'http://www.yr.no/sted/Canada/Quebec/Montreal/',
], ],
@ -134,7 +140,7 @@ describe('filter', function() {
plugins); plugins);
})); }));
it('should recognize gists', inject(function(plugins) { it('should recognize gists', angular.mock.inject(function(plugins) {
expectTheseMessagesToContain([ expectTheseMessagesToContain([
'https://gist.github.com/lorenzhs/e8c1a7d56fa170320eb8', 'https://gist.github.com/lorenzhs/e8c1a7d56fa170320eb8',
'https://gist.github.com/e8c1a7d56fa170320eb8', 'https://gist.github.com/e8c1a7d56fa170320eb8',
@ -143,7 +149,7 @@ describe('filter', function() {
plugins); plugins);
})); }));
it('should recognize pastebins', inject(function(plugins) { it('should recognize pastebins', angular.mock.inject(function(plugins) {
expectTheseMessagesToContain([ expectTheseMessagesToContain([
'http://pastebin.com/Wn3TetSE', 'http://pastebin.com/Wn3TetSE',
'http://pastebin.com/raw/Wn3TetSE', 'http://pastebin.com/raw/Wn3TetSE',
@ -152,7 +158,7 @@ describe('filter', function() {
plugins); plugins);
})); }));
it('should recognize giphy gifs', inject(function(plugins) { it('should recognize giphy gifs', angular.mock.inject(function(plugins) {
expectTheseMessagesToContain([ expectTheseMessagesToContain([
'https://giphy.com/gifs/eyes-shocked-bird-feqkVgjJpYtjy/', 'https://giphy.com/gifs/eyes-shocked-bird-feqkVgjJpYtjy/',
'http://giphy.com/gifs/funny-cat-FiGiRei2ICzzG', 'http://giphy.com/gifs/funny-cat-FiGiRei2ICzzG',
@ -161,7 +167,7 @@ describe('filter', function() {
plugins); plugins);
})); }));
it('should recognize tweets', inject(function(plugins) { it('should recognize tweets', angular.mock.inject(function(plugins) {
expectTheseMessagesToContain([ expectTheseMessagesToContain([
'https://twitter.com/DFB_Team_EN/statuses/488436782959448065', 'https://twitter.com/DFB_Team_EN/statuses/488436782959448065',
], ],
@ -169,7 +175,7 @@ describe('filter', function() {
plugins); plugins);
})); }));
it('should recognize tiktoks', inject(function(plugins) { it('should recognize tiktoks', angular.mock.inject(function(plugins) {
expectTheseMessagesToContain([ expectTheseMessagesToContain([
'https://www.tiktok.com/@scout2015/video/6718335390845095173', 'https://www.tiktok.com/@scout2015/video/6718335390845095173',
'https://www.tiktok.com/@lewiscatpaldi/video/6800461190058298629', 'https://www.tiktok.com/@lewiscatpaldi/video/6800461190058298629',

@ -0,0 +1,52 @@
"use strict";
const path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require("copy-webpack-plugin");
module.exports = {
context: path.resolve(__dirname, 'src'),
entry: './main.js',
output: {
path: path.resolve(__dirname, 'build'),
},
devServer: {
contentBase: path.resolve(__dirname, 'build')
},
devtool: 'source-map',
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
minify: false
}),
new CopyWebpackPlugin({
patterns: [
"**/*.css",
"**/*.svg",
"**/*.png",
"directives/*.html",
"serviceworker.js",
"electron-*.js",
"../package.json",
"manifest.json",
"manifest.webapp",
"webapp.manifest.json"
]
})
],
module: {
rules: [
{
test: /\.js$/i,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader'
}
]
}
]
}
};
Loading…
Cancel
Save