diff --git a/app.html b/app.html
index 70be537..46ad8dd 100644
--- a/app.html
+++ b/app.html
@@ -2,231 +2,122 @@
Cryptopter
Cryptoptère
-
-
+
-
-
+
+
-
-
+
+
+
diff --git a/app.js b/app.js
index b20b325..31b6f47 100644
--- a/app.js
+++ b/app.js
@@ -1,11 +1,11 @@
const algo = { name: "AES-GCM", iv: Uint8Array.from([120,1,248,135,62,71,87,156,92,67,155,37]) }
-, parseAlgo = str=> ({ name: str.split(' ')[0], iv: Uint8Array.from(str.split(' ').slice(1)) })
-, algos = [ "AES-GCM 120 1 248 135 62 71 87 156 92 67 155 37", 'AES-CBC' ]
-//, algo = parseAlgo(algos[0])
-, $pass = $`pass input`
-, $text = $`ui-data`
-, $filename = $`[filename]`
+, parseAlgo = str=> ({ name: str.split(' ')[0], iv: Uint8Array.from(str.split(' ').slice(1)) })
+, algos = [ "AES-GCM 120 1 248 135 62 71 87 156 92 67 155 37", 'AES-CBC' ]
+//, algo = parseAlgo(algos[0])
+, $pass = $`pass input`
+, $text = $`ui-data`
+, $filename = $`[filename]`
opener && document.documentElement.classtList.add('parented')
// sel=opener.document.getSelection().type=='None'||'Range'
@@ -17,127 +17,128 @@ let key
const ivLen = 16 // the IV is always 16 bytes
$pass.onchange = async e=>
- key = await crypto.subtle.importKey(
- 'raw'
- , await crypto.subtle.digest( 'SHA-256', new TextEncoder().encode($pass.value) )
- , algo, false, ['encrypt','decrypt']
- )
+ key = await crypto.subtle.importKey(
+ 'raw'
+ , await crypto.subtle.digest( 'SHA-256', new TextEncoder().encode($pass.value) )
+ , algo, false, ['encrypt','decrypt']
+ )
const joinIvAndData = (iv, data)=> {
- var buf = new Uint8Array(iv.length + data.length)
- Array.prototype.forEach.call(iv, (byte, i)=> buf[i] = byte )
- Array.prototype.forEach.call(data, (byte, i)=> buf[ivLen + i] = byte )
- return buf
+ var buf = new Uint8Array(iv.length + data.length)
+ Array.prototype.forEach.call(iv, (byte, i)=> buf[i] = byte )
+ Array.prototype.forEach.call(data, (byte, i)=> buf[ivLen + i] = byte )
+ return buf
}
const separateIvFromData = buf=> Array.prototype.reduce.call( new Uint8Array(buf),
- ( res, byte, i )=>
- i < ivLen
- ? ( res.iv[i] = byte, res )
- : ( res.data[i - ivLen] = byte, res )
-, { iv: new Uint8Array(ivLen), data: new Uint8Array(buf.byteLength - ivLen) } )
+ ( res, byte, i )=>
+ i < ivLen
+ ? ( res.iv[i] = byte, res )
+ : ( res.data[i - ivLen] = byte, res )
+, { iv: new Uint8Array(ivLen), data: new Uint8Array(buf.byteLength - ivLen) } )
const encrypt = ()=> {
- return crypto.subtle.digest( 'SHA-256', new TextEncoder().encode($pass.value) )
- .then( pwHash=> crypto.subtle.importKey('raw', pwHash, algo, false, ['encrypt']) )
- .then( key=> crypto.subtle.encrypt(algo, key, new TextEncoder().encode($text.value)) )
- //.then( ctBuffer=> $text.value = new Uint8Array(ctBuffer).toString().replace(/,/g,'O') )
- .then( ctBuffer=> $text.value = uint2String( new Uint8Array(ctBuffer) ) )
- //.then( ctBuffer=> $text.value = new TextDecoder().decode(new Uint8Array(ctBuffer)) )
-
- //.catch( e=> pulse('red') )
+ return crypto.subtle.digest( 'SHA-256', new TextEncoder().encode($pass.value) )
+ .then( pwHash=> crypto.subtle.importKey('raw', pwHash, algo, false, ['encrypt']) )
+ .then( key=> crypto.subtle.encrypt(algo, key, new TextEncoder().encode($text.value)) )
+ //.then( ctBuffer=> $text.value = new Uint8Array(ctBuffer).toString().replace(/,/g,'O') )
+ .then( ctBuffer=> $text.value = uint2String( new Uint8Array(ctBuffer) ) )
+ //.then( ctBuffer=> $text.value = new TextDecoder().decode(new Uint8Array(ctBuffer)) )
+
+ //.catch( e=> pulse('red') )
}
const encrypt2 = str=>
- crypto.subtle.encrypt( algo, key, new TextEncoder().encode(str) )
- //.then( ctBuffer=> $text.value = new Uint8Array(ctBuffer).toString().replace(/,/g,'O') )
- // .then( ctBuffer=> uint2String(new Uint8Array(ctBuffer)) )
- .then( ctBuffer=> $text.value = new TextDecoder().decode(new Uint8Array(ctBuffer)) )
-
- //.catch( e=> pulse('red') )
+ crypto.subtle.encrypt( algo, key, new TextEncoder().encode(str) )
+ //.then( ctBuffer=> $text.value = new Uint8Array(ctBuffer).toString().replace(/,/g,'O') )
+ // .then( ctBuffer=> uint2String(new Uint8Array(ctBuffer)) )
+ .then( ctBuffer=> $text.value = new TextDecoder().decode(new Uint8Array(ctBuffer)) )
+
+ //.catch( e=> pulse('red') )
const encrypt3 = ( data, iv = crypto.getRandomValues(new Uint8Array(ivLen)) )=>
- crypto.subtle.encrypt( {name: 'AES-GCM', iv}, key, data )
- // .then( encrypted=> bufferToBinaryString( joinIvAndData(iv, new Uint8Array(encrypted)).buffer ) )
- .then( encrypted=> joinIvAndData(iv, new Uint8Array(encrypted)).buffer )
- // var base64 = Unibabel.bufferToBase64(ciphered)
- // .replace(/\-/g, '+')
- // .replace(/_/g, '\/')
- // ;
+ crypto.subtle.encrypt( {name: 'AES-GCM', iv}, key, data )
+ // .then( encrypted=> bufferToBinaryString( joinIvAndData(iv, new Uint8Array(encrypted)).buffer ) )
+ .then( encrypted=> joinIvAndData(iv, new Uint8Array(encrypted)).buffer )
+ // var base64 = Unibabel.bufferToBase64(ciphered)
+ // .replace(/\-/g, '+')
+ // .replace(/_/g, '\/')
+ // ;
- // while (base64.length % 4) {
- // base64 += '=';
- // }
- // return base64;
- // })
+ // while (base64.length % 4) {
+ // base64 += '=';
+ // }
+ // return base64;
+ // })
const decrypt = ()=> {
- return crypto.subtle.digest( 'SHA-256', new TextEncoder().encode($pass.value) )
- .then( pwHash=> crypto.subtle.importKey('raw', pwHash, algo, false, ['decrypt']) )
- //.then( key=> crypto.subtle.decrypt(algo, key, Uint8Array.from($text.value.split('O').map(Number)).buffer ) )
- .then( key=> crypto.subtle.decrypt(algo, key, string2Uint($text.value).buffer ) )
- //.then( key=> crypto.subtle.decrypt(algo, key, new TextEncoder().encode($text.value).buffer ) )
- .then( ptBuffer=> $text.value = new TextDecoder().decode(ptBuffer) )
-
- //.catch( e=> pulse('red') )
+ return crypto.subtle.digest( 'SHA-256', new TextEncoder().encode($pass.value) )
+ .then( pwHash=> crypto.subtle.importKey('raw', pwHash, algo, false, ['decrypt']) )
+ //.then( key=> crypto.subtle.decrypt(algo, key, Uint8Array.from($text.value.split('O').map(Number)).buffer ) )
+ .then( key=> crypto.subtle.decrypt(algo, key, string2Uint($text.value).buffer ) )
+ //.then( key=> crypto.subtle.decrypt(algo, key, new TextEncoder().encode($text.value).buffer ) )
+ .then( ptBuffer=> $text.value = new TextDecoder().decode(ptBuffer) )
+
+ //.catch( e=> pulse('red') )
}
const decrypt3 = buf=> {
- let { iv, data } = separateIvFromData( buf )
+ let { iv, data } = separateIvFromData( buf )
- return crypto.subtle.decrypt(
- { name: 'AES-GCM', iv }
- , key
- , data
- )/*.then(function (decrypted) {
- var base64 = bufferToUtf8(new Uint8Array(decrypted))
- // .replace(/\-/g, '+')
- // .replace(/_/g, '\/')
- // ;
+ return crypto.subtle.decrypt(
+ { name: 'AES-GCM', iv }
+ , key
+ , data
+ )
+ /*.then(function (decrypted) {
+ var base64 = bufferToUtf8(new Uint8Array(decrypted))
+ // .replace(/\-/g, '+')
+ // .replace(/_/g, '\/')
+ // ;
- // while (base64.length % 4) {
- // base64 += '=';
- // }
- return base64
+ // while (base64.length % 4) {
+ // base64 += '=';
+ // }
+ return base64
})*/
}
var lastSaved
const save = ( content, filename )=> {
- let link = document.createElement('a')
- link.setAttribute( 'download', filename )
- // If we are replacing a previously generated file we need to
- // manually revoke the object URL to avoid memory leaks.
- lastSaved && URL.revokeObjectURL( lastSaved )
- link.href = lastSaved = URL.createObjectURL( new Blob([content], {type: 'text/plain'}) )
- //link.href = makeTextFile( content )
- document.body.appendChild( link )
+ let link = document.createElement('a')
+ link.setAttribute( 'download', filename )
+ // If we are replacing a previously generated file we need to
+ // manually revoke the object URL to avoid memory leaks.
+ lastSaved && URL.revokeObjectURL( lastSaved )
+ link.href = lastSaved = URL.createObjectURL( new Blob([content], {type: 'text/plain'}) )
+ //link.href = makeTextFile( content )
+ document.body.appendChild( link )
- // wait for the link to be added to the document
- window.requestAnimationFrame( e=> {
- link.dispatchEvent( new MouseEvent('click') )
- document.body.removeChild( link )
- })
+ // wait for the link to be added to the document
+ window.requestAnimationFrame( e=> {
+ link.dispatchEvent( new MouseEvent('click') )
+ document.body.removeChild( link )
+ })
}
const read = file=> new Promise( (ok,ko)=> {
- let r = new FileReader()
- r.onload = e=> ok( r.result )
- r.onerror = e=> ko()
- r.readAsText( file )
+ let r = new FileReader()
+ r.onload = e=> ok( r.result )
+ r.onerror = e=> ko()
+ r.readAsText( file )
})
var textFile
const makeTextFile = text=> {
-
- textFile && URL.revokeObjectURL(textFile)
- textFile = URL.createObjectURL( new Blob([text], {type: 'text/plain'}) )
+
+ textFile && URL.revokeObjectURL(textFile)
+ textFile = URL.createObjectURL( new Blob([text], {type: 'text/plain'}) )
- // returns a URL you can use as a href
- return textFile
+ // returns a URL you can use as a href
+ return textFile
}
@@ -148,8 +149,8 @@ const save2 = (file, content, type)=> window.open( "data:application/octet-strea
const uint2string = uintArray=> String.fromCharCode.apply( null, uintArray )
const string2uint = string=> new Uint8Array(
- btoa( string ).split('')
- .map( l=>l.charCodeAt(0) )
+ btoa( string ).split('')
+ .map( l=>l.charCodeAt(0) )
)
const buffer2bin = buf=> Array.prototype.map.call( new Uint8Array(buf), ch=> String.fromCharCode(ch) ).join('')
@@ -157,7 +158,7 @@ const buffer2bin = buf=> Array.prototype.map.call( new Uint8Array(buf), ch=> Str
const buffer2base64 = arr=> btoa( buffer2bin(arr) )
const bin2buffer = binstr=> new Uint8Array(
- Array.prototype.map.call( new Uint8Array( binstr.length ), (ch, i)=> binstr.charCodeAt(i) )
+ Array.prototype.map.call( new Uint8Array( binstr.length ), (ch, i)=> binstr.charCodeAt(i) )
)
const base642buffer = base64=> bin2buffer( atob(base64) )
@@ -179,31 +180,32 @@ const utf82buffer = str=> bin2buffer(utf82bin(str))
const CC = {
- uint2string
-, string2uint
-, buffer2bin
-, buffer2base64
-, buffer2utf8
-, bin2buffer
-, base642buffer
-, bin2utf8
-, utf82bin
-, utf82buffer
+ uint2string
+, string2uint
+, buffer2bin
+, buffer2uint: buf=> new Uint8Array(buf)
+, buffer2utf8
+, buffer2base64
+, bin2buffer
+, base642buffer
+, bin2utf8
+, utf82bin
+, utf82buffer
}
/*const uintToString = (uintArray)=> {
- var encodedString = String.fromCharCode.apply(null, uintArray),
- decodedString = decodeURIComponent(escape(encodedString));
- return decodedString;
+ var encodedString = String.fromCharCode.apply(null, uintArray),
+ decodedString = decodeURIComponent(escape(encodedString));
+ return decodedString;
}
function stringToUint(string) {
- var string = btoa(unescape(encodeURIComponent(string))),
- charList = string.split(''),
- uintArray = [];
- for (var i = 0; i < charList.length; i++) {
- uintArray.push(charList[i].charCodeAt(0));
- }
- return new Uint8Array(uintArray);
+ var string = btoa(unescape(encodeURIComponent(string))),
+ charList = string.split(''),
+ uintArray = [];
+ for (var i = 0; i < charList.length; i++) {
+ uintArray.push(charList[i].charCodeAt(0));
+ }
+ return new Uint8Array(uintArray);
}
*/
diff --git a/konstrui.js b/konstrui.js
index c80a2fe..8a31344 100644
--- a/konstrui.js
+++ b/konstrui.js
@@ -16,5 +16,10 @@ writeFileSync(
? ``
: s
)
+ .replace(//g
+ , (s,$1)=> $1.match(href) && !/^https?:\/\//.test( $1.match(href)[1] )
+ ? ``
+ : s
+ )
, 'utf8'
)
diff --git a/lang.js b/lang.js
index 46b51b1..a849a3f 100644
--- a/lang.js
+++ b/lang.js
@@ -1,50 +1,50 @@
/*
*/
// lang support
Object.defineProperty( window, 'lang', {
- get: ()=> $`:root`.getAttribute('lang')
+ get: ()=> $`:root`.getAttribute('lang')
, set: v=> $`:root`.setAttribute( 'lang', v )
})
new MutationObserver( changes=>
- changes.map( ch=> ch.attributeName == 'lang' && $`:root`.dispatchEvent(new Event('lang')) )
+ changes.map( ch=> ch.attributeName == 'lang' && $`:root`.dispatchEvent(new Event('lang')) )
)
.observe( $`:root`, { attributes: true } )
const lgAttReg = new RegExp( '^('+$`style[lang]`.attributes.lang.value.split(',').join('|')+'):')
$`:root`.on`lang`( e=>
- $`*`.map( node=> [...node.attributes]
- .filter( att=> lgAttReg.test(att.name) )
- )
- .filter( arr=> arr.length )
- .map( atts=> atts.filter(att=>new RegExp('^'+lang+':').test(att.name))
- .map(att=> att.ownerElement.setAttribute(att.name.split(':').pop(),att.value) ))
+ $`*`.map( node=> [...node.attributes]
+ .filter( att=> lgAttReg.test(att.name) )
+ )
+ .filter( arr=> arr.length )
+ .map( atts=> atts.filter(att=>new RegExp('^'+lang+':').test(att.name))
+ .map(att=> att.ownerElement.setAttribute(att.name.split(':').pop(),att.value) ))
)
// compile lang styles
Q`style[lang]`.map( style=>
- style.innerHTML = [...style.sheet.rules]
- .map( r=> style.attributes.lang.value.split(',')
- .map( lg=> r.cssText.replace(/_lang_/g, lg) )
- .join('\n')
- )
- .join('\n')
+ style.innerHTML = [...style.sheet.rules]
+ .map( r=> style.attributes.lang.value.split(',')
+ .map( lg=> r.cssText.replace(/_lang_/g, lg) )
+ .join('\n')
+ )
+ .join('\n')
)
lang = navigator.language
diff --git a/ui.js b/ui.js
index ecf69ae..919fc37 100644
--- a/ui.js
+++ b/ui.js
@@ -1,96 +1,97 @@
const _s = (ss, ...pp)=> ss.map((s,i)=> s + (pp[i]||'')).join('')
-, _a = iterable=> iterable.length > 1 ? iterable : iterable[0]
-, Q = (ss, ...pp)=> [...document.querySelectorAll( _s(ss, ...pp))]
-, T = document.createElement('template')
-, DOM = (ss, ...pp)=> ( T.innerHTML = _s(ss, ...pp), document.adoptNode(T.content).childNodes )
-, $ = (ss, ...pp)=> _a( ~_s(ss, ...pp).indexOf('<') ? DOM(ss, ...pp) : Q(ss, ...pp) )
+, _a = iterable=> iterable.length > 1 ? iterable : iterable[0]
+, Q = (ss, ...pp)=> [...document.querySelectorAll( _s(ss, ...pp))]
+, T = document.createElement('template')
+, DOM = (ss, ...pp)=> ( T.innerHTML = _s(ss, ...pp), document.adoptNode(T.content).childNodes )
+, $ = (ss, ...pp)=> _a( ~_s(ss, ...pp).indexOf('<') ? DOM(ss, ...pp) : Q(ss, ...pp) )
-, notify = (html,attrs)=> $`body`.add( $`${html}` )
-, bubbleOn = el=> e=> el.dispatchEvent( new ErrorEvent('Error',{bubbles:true, error:e}) )
-, pulse = color=> (document.body.style.background = color) && setTimeout(o=> document.body.style.background = 'lightgrey', 1000)
+, notify = (html,attrs)=> $`body`.add( $`${html}` )
+, bubbleOn = el=> e=> el.dispatchEvent( new ErrorEvent('Error',{bubbles:true, error:e}) )
+, pulse = color=> (document.body.style.background = color) && setTimeout(o=> document.body.style.background = 'lightgrey', 1000)
Node.prototype.add = function( ...els )
{
- this.append( ...els )
- return _a( els )
+ this.append( ...els )
+ return _a( els )
}
Node.prototype.$ = function(ss, ...pp)
{
- return _a(
- ~_s(ss, ...pp).indexOf('<')
- ? this.add(...DOM(ss, ...pp))
- : [...this.querySelectorAll( _s(ss, ...pp))]
- )
+ return _a(
+ ~_s(ss, ...pp).indexOf('<')
+ ? this.add(...DOM(ss, ...pp))
+ : [...this.querySelectorAll( _s(ss, ...pp))]
+ )
}
Node.prototype.on = function(ss, ...pp)
{
- let types = _s( [].concat(ss), ...pp ).split(/[,\s]/)
- return (...args)=> ( types.map( type=> this.addEventListener(type,...args)), this )
+ let types = _s( [].concat(ss), ...pp ).split(/[,\s]/)
+ return (...args)=> ( types.map( type=> this.addEventListener(type,...args)), this )
}
class UI extends HTMLElement {
- static get is(){ return 'ui' + this.name.replace(/[A-Z]/g, L=> '-'+L.toLocaleLowerCase()) }
- constructor()
- {
- super()
- let tpl = $`template[${this.constructor.is}]`
- tpl && this.attachShadow({mode: 'open'})
- .appendChild( tpl.content.cloneNode(true) )
- }
+ static get is(){ return 'ui' + this.name.replace(/[A-Z]/g, L=> '-'+L.toLocaleLowerCase()) }
+ constructor()
+ {
+ super()
+ let tpl = $`template[${this.constructor.is}]`
+ tpl && this.attachShadow({mode: 'open'})
+ .appendChild( tpl.content.cloneNode(true) )
+ }
}
class Toast extends UI {
- static get duration(){ return this._duration || 10000 }
- static set duration( v ){ this._duration = v }
- connectedCallback()
- {
- setTimeout( toast=> toast.remove(), this.getAttribute('duration') || Toast.duration, this )
- }
+ static get duration(){ return this._duration || 10000 }
+ static set duration( v ){ this._duration = v }
+ connectedCallback()
+ {
+ setTimeout( toast=> toast.remove(), this.getAttribute('duration') || Toast.duration, this )
+ }
}
class Data extends UI {
- static get observedAttributes(){ return ['bin','uint','utf8','base64','frame'] }
- connectedCallback()
- {
- // this.observer = new MutationObserver(
- // changes=> console.log(changes.filter(m=>~['bin','255','utf8','base64','object'].indexOf(m.attributeName)) )
- // )
- // .observe( this, { attributes: true } )
- this.shadowRoot.append(
- ...Data.observedAttributes
- .map( type=> $``
- .on`click`( e=> this.type = e.target.innerText )
- )
- )
- // this.shadowRoot.$`button`.map( button=> button.onclick = e=> this.type = e.target.innerText )
- this.shadowRoot.$`textarea`.on`change`( e=> this._value = CC[this.type+'2buffer'](e.target.value) )
- }
+ static get observedAttributes(){ return ['bin','uint','utf8','base64','frame'] }
+ connectedCallback()
+ {
+ // this.observer = new MutationObserver(
+ // changes=> console.log(changes.filter(m=>~['bin','255','utf8','base64','object'].indexOf(m.attributeName)) )
+ // )
+ // .observe( this, { attributes: true } )
+ this.shadowRoot.append(
+ ...Data.observedAttributes
+ .map( type=> $``
+ .on`click`( e=> this.type = e.target.innerText )
+ )
+ )
+ // this.shadowRoot.$`button`.map( button=> button.onclick = e=> this.type = e.target.innerText )
+ this.shadowRoot.$`textarea`.on`change`( e=> this._value = CC[this.type+'2buffer'](e.target.value) )
+ }
- get type(){ return this.attributes[0].name }
- set type( v ){
- if( this.type == v ) return;
- [...this.attributes].map( o=> o.ownerElement.removeAttributeNode(o) )
- this.setAttribute( v, '' )
- }
+ get type(){ return this.attributes[0].name }
+ set type( v ){
+ if( this.type == v ) return;
+ [...this.attributes].map( o=> o.ownerElement.removeAttributeNode(o) )
+ this.setAttribute( v, '' )
+ }
- get value(){ return this._value }
- set value( v ){ this._value = v; this.shadowRoot.$`textarea`.value = CC['buffer2'+this.type](v) }
+ get value(){ return this._value }
+ set value( v ){ this._value = v; this.shadowRoot.$`textarea`.value = CC['buffer2'+this.type](v) }
- attributeChangedCallback(name, oldValue, newValue)
- {
- if( this.shadowRoot.$`textarea`.value )
- this.shadowRoot.$`textarea`.value = CC['buffer2'+this.type]( this._value )
- }
+ attributeChangedCallback(name, oldValue, newValue)
+ {
+ console.log(arguments)
+ if( newValue != null && this._value && CC['buffer2'+this.type] )
+ this.shadowRoot.$`textarea`.value = CC['buffer2'+this.type]( this._value )
+ }
}
;[ Toast, Data ]
- .map( klass=> customElements.define(klass.is, klass) )
+ .map( klass=> customElements.define(klass.is, klass) )
// document.body.addEventListener('Error', e=> pulse('red') && (notify(e.error.message).style.color = 'red') )
$`body`.on`Error`( e=>
- pulse('red') && notify(
- `${e.error.code||''} ${e.error.name}: ${e.error.message}`
- , 'error')
+ pulse('red') && notify(
+ `${e.error.code||''} ${e.error.name}: ${e.error.message}`
+ , 'error')
)