From cd40bdb47d64b7cbce67e97c36c1a9e3efb2c33c Mon Sep 17 00:00:00 2001 From: bankrot Date: Mon, 28 Sep 2015 21:47:56 +0300 Subject: [PATCH] =?UTF-8?q?Release=200.0.6=20=D0=94=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5?= =?UTF-8?q?=D1=80=D0=B6=D0=BA=D0=B0=20Internet=20Explorer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +- bower.json | 8 +- gulpfile.coffee | 6 +- package.json | 1 + src/alt_cadesplugin_api.coffee | 81 ++- src/alt_cadesplugin_api.js | 75 ++- src/alt_cadesplugin_api.min.js | 2 +- test/coffee/main.coffee | 18 +- test/index.html | 1 + test/js/alt_cadesplugin_api.js | 75 ++- test/js/es6-promise.js | 967 +++++++++++++++++++++++++++++++++ test/js/main.js | 25 +- 12 files changed, 1157 insertions(+), 107 deletions(-) create mode 100644 test/js/es6-promise.js diff --git a/README.md b/README.md index ed7130f..253f735 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,10 @@ src/alt_cadesplugin_api.min.js #### Зависимости -Для корректной работы скрипта необходима библиотека jQuery +Для корректной работы скрипта необходимы следующие библиотеки + +1. [jQuery](https://github.com/jquery/jquery) +2. [es6-promise](https://github.com/jakearchibald/es6-promise) #### Использование diff --git a/bower.json b/bower.json index bb57bf0..514a53a 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "cadesplugin", - "version": "0.0.5", + "version": "0.0.6", "homepage": "https://github.com/bankrot/cadesplugin", "description": "CryptoPRO plugin api library (Крипто ПРО)", "main": "src/alt_cadesplugin_api.js", @@ -21,5 +21,9 @@ "Volkov Sergey" ], "license": "MIT", - "ignore": [] + "ignore": [], + "dependencies": { + "es6-promise": "~3.0.2", + "jquery": "~2.1.4" + } } diff --git a/gulpfile.coffee b/gulpfile.coffee index 4cbd2f9..cd6be33 100644 --- a/gulpfile.coffee +++ b/gulpfile.coffee @@ -51,7 +51,11 @@ gulp.task 'main', (callback)-> # копирует jquery из node_modules gulp.task 'libs', (callback)-> - gulp.src ['./node_modules/jquery/dist/jquery.js', './node_modules/bowser/src/bowser.js'] + gulp.src [ + './node_modules/jquery/dist/jquery.js' + './node_modules/bowser/src/bowser.js' + './node_modules/es6-promise/dist/es6-promise.js' + ] .pipe gulp.dest './test/js' # запускает вебсервер для тестирования diff --git a/package.json b/package.json index cadca85..fef124a 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "devDependencies": { "bowser": "^1.0.0", "coffee-script": "^1.10.0", + "es6-promise": "^3.0.2", "gulp": "^3.9.0", "gulp-coffee": "^2.3.1", "gulp-connect": "^2.2.0", diff --git a/src/alt_cadesplugin_api.coffee b/src/alt_cadesplugin_api.coffee index 0ec4134..5d28fcb 100644 --- a/src/alt_cadesplugin_api.coffee +++ b/src/alt_cadesplugin_api.coffee @@ -1,6 +1,6 @@ ###* Библиотека для работы с плагином КриптоПРО -Версия 0.0.5 (beta) +Версия 0.0.6 (beta) Поддерживает плагин версии 2.0.12245 Репозиторий https://github.com/bankrot/cadesplugin ### @@ -48,13 +48,6 @@ AltCadesPlugin = class ### timeout: 20000 - ###* - Нативные промисы поддерживаются - @property isPromise - @type {Boolean} - ### - isPromise: not not window.Promise - ###* На основе webkit @property isWebkit @@ -63,6 +56,14 @@ AltCadesPlugin = class isWebkit: do -> return navigator.userAgent.match(/chrome/i) or navigator.userAgent.match(/opera/i) + ###* + Internet Explorer + @property isIE + @type {Boolean} + ### + isIE: do -> + return (navigator.appName is 'Microsoft Internet Explorer') or navigator.userAgent.match(/Trident\/./i) + ###* Конструктор @method constructor @@ -132,8 +133,8 @@ AltCadesPlugin = class deferred = $.Deferred() # обработчик события по загрузке плагина - listener = (event)=> - if event.data isnt 'cadesplugin_loaded' + $(window).on 'message', (event)=> + if event?.originalEvent?.data isnt 'cadesplugin_loaded' return setTimeout (-> cpcsp_chrome_nmcades.check_chrome_plugin (=> @@ -144,7 +145,6 @@ AltCadesPlugin = class deferred.reject message ) ), 0 - window.addEventListener 'message', listener, false # если через @timeout мс плагин все еще не вернул ответ, значит ошибка setTimeout (=> @@ -160,13 +160,7 @@ AltCadesPlugin = class ### initNpapi: -> deferred = $.Deferred() - if @isPromise - eventName = 'load' - else - eventName = 'message' - $(window).on eventName, (event)=> - if (not @isPromise) and (event.data isnt 'cadesplugin_echo_request') - return + $(window).on 'load', (event)=> @loadNpapiPlugin() @checked = true result = @checkNpapiPlugin() @@ -184,14 +178,10 @@ AltCadesPlugin = class object = $ '' $('body').append object @pluginObject = object[0] - #if(isIE()) - #{ - #var elem1 = document.createElement('object'); - #elem1.setAttribute("id", "certEnrollClassFactory"); - #elem1.setAttribute("classid", "clsid:884e2049-217d-11da-b2a4-000e7bbb2b09"); - #elem1.setAttribute("style", "visibility=hidden"); - #document.getElementsByTagName("body")[0].appendChild(elem1); - #} + + if @isIE + ieObject = $ '' + $('body').append ieObject ###* Проверяет плагин и возвращает true если проверка пройдена или строку с кодом ошибки @@ -216,24 +206,20 @@ AltCadesPlugin = class # Функция активации объектов КриптоПро ЭЦП Browser plug-in createObject: (name)-> - #if (isIE()) { - # // В Internet Explorer создаются COM-объекты - # if (name.match(/X509Enrollment/i)) { - # try { - # // Объекты CertEnroll создаются через CX509EnrollmentWebClassFactory - # var objCertEnrollClassFactory = document.getElementById("certEnrollClassFactory"); - # return objCertEnrollClassFactory.CreateObject(name); - # } - # catch (e) { - # throw("Для создания обьектов X509Enrollment следует настроить веб-узел на использование проверки подлинности по протоколу HTTPS"); - # } - #} - #// Объекты CAPICOM и CAdESCOM создаются обычным способом - #return new ActiveXObject(name); - #} + if @isIE + # В Internet Explorer создаются COM-объекты + if name.match /X509Enrollment/i + try + # Объекты CertEnroll создаются через CX509EnrollmentWebClassFactory + return $('certEnrollClassFactory')[0].CreateObject name + catch error + throw 'setup_https_for_x509enrollment' + + # Объекты CAPICOM и CAdESCOM создаются обычным способом + return new ActiveXObject(name) # В Firefox, Safari создаются объекты NPAPI - return @pluginObject.CreateObject(name) + return @pluginObject.CreateObject name ###* Возвращает параметр из объекта @@ -264,7 +250,7 @@ AltCadesPlugin = class try if typeof objectName is 'string' - result = @pluginObject.CreateObject objectName + result = @createObject objectName if paramName result = @extractParam result, paramName else @@ -282,7 +268,14 @@ AltCadesPlugin = class ### extractParam: (object, param)-> if typeof param is 'object' - return object[param.method].apply object, param.args + # Здесь можно было бы использовать object[param.method].apply object, param.args + # Но в IE у внешних объектов нет матода .apply + switch param.args.length + when 0 then object[param.method]() + when 1 then object[param.method](param.args[0]) + when 2 then object[param.method](param.args[0], param.args[1]) + when 3 then object[param.method](param.args[0], param.args[1], param.args[2]) + when 4 then object[param.method](param.args[0], param.args[1], param.args[2], param.args[3]) else return object[param] diff --git a/src/alt_cadesplugin_api.js b/src/alt_cadesplugin_api.js index 676a9ae..2f2bb9c 100644 --- a/src/alt_cadesplugin_api.js +++ b/src/alt_cadesplugin_api.js @@ -10,7 +10,7 @@ /** Библиотека для работы с плагином КриптоПРО -Версия 0.0.5 (beta) +Версия 0.0.6 (beta) Поддерживает плагин версии 2.0.12245 Репозиторий https://github.com/bankrot/cadesplugin */ @@ -74,22 +74,24 @@ AltCadesPlugin = (function() { /** - Нативные промисы поддерживаются - @property isPromise + На основе webkit + @property isWebkit @type {Boolean} */ - _Class.prototype.isPromise = !!window.Promise; + _Class.prototype.isWebkit = (function() { + return navigator.userAgent.match(/chrome/i) || navigator.userAgent.match(/opera/i); + })(); /** - На основе webkit - @property isWebkit + Internet Explorer + @property isIE @type {Boolean} */ - _Class.prototype.isWebkit = (function() { - return navigator.userAgent.match(/chrome/i) || navigator.userAgent.match(/opera/i); + _Class.prototype.isIE = (function() { + return (navigator.appName === 'Microsoft Internet Explorer') || navigator.userAgent.match(/Trident\/./i); })(); @@ -179,13 +181,14 @@ AltCadesPlugin = (function() { */ _Class.prototype.initWebkit = function() { - var deferred, listener; + var deferred; $.getScript('chrome-extension://iifchhfnnmpdbibifmljnfjhpififfog/nmcades_plugin_api.js'); window.postMessage('cadesplugin_echo_request', '*'); deferred = $.Deferred(); - listener = (function(_this) { + $(window).on('message', (function(_this) { return function(event) { - if (event.data !== 'cadesplugin_loaded') { + var ref; + if ((event != null ? (ref = event.originalEvent) != null ? ref.data : void 0 : void 0) !== 'cadesplugin_loaded') { return; } return setTimeout((function() { @@ -202,8 +205,7 @@ AltCadesPlugin = (function() { })(this))); }), 0); }; - })(this); - window.addEventListener('message', listener, false); + })(this)); setTimeout(((function(_this) { return function() { if (!_this.checked) { @@ -221,19 +223,11 @@ AltCadesPlugin = (function() { */ _Class.prototype.initNpapi = function() { - var deferred, eventName; + var deferred; deferred = $.Deferred(); - if (this.isPromise) { - eventName = 'load'; - } else { - eventName = 'message'; - } - $(window).on(eventName, (function(_this) { + $(window).on('load', (function(_this) { return function(event) { var result; - if ((!_this.isPromise) && (event.data !== 'cadesplugin_echo_request')) { - return; - } _this.loadNpapiPlugin(); _this.checked = true; result = _this.checkNpapiPlugin(); @@ -254,10 +248,14 @@ AltCadesPlugin = (function() { */ _Class.prototype.loadNpapiPlugin = function() { - var object; + var ieObject, object; object = $(''); $('body').append(object); - return this.pluginObject = object[0]; + this.pluginObject = object[0]; + if (this.isIE) { + ieObject = $(''); + return $('body').append(ieObject); + } }; @@ -288,6 +286,18 @@ AltCadesPlugin = (function() { }; _Class.prototype.createObject = function(name) { + var error, error1; + if (this.isIE) { + if (name.match(/X509Enrollment/i)) { + try { + return $('certEnrollClassFactory')[0].CreateObject(name); + } catch (error1) { + error = error1; + throw 'setup_https_for_x509enrollment'; + } + } + return new ActiveXObject(name); + } return this.pluginObject.CreateObject(name); }; @@ -322,7 +332,7 @@ AltCadesPlugin = (function() { } else { try { if (typeof objectName === 'string') { - result = this.pluginObject.CreateObject(objectName); + result = this.createObject(objectName); if (paramName) { result = this.extractParam(result, paramName); } @@ -347,7 +357,18 @@ AltCadesPlugin = (function() { _Class.prototype.extractParam = function(object, param) { if (typeof param === 'object') { - return object[param.method].apply(object, param.args); + switch (param.args.length) { + case 0: + return object[param.method](); + case 1: + return object[param.method](param.args[0]); + case 2: + return object[param.method](param.args[0], param.args[1]); + case 3: + return object[param.method](param.args[0], param.args[1], param.args[2]); + case 4: + return object[param.method](param.args[0], param.args[1], param.args[2], param.args[3]); + } } else { return object[param]; } diff --git a/src/alt_cadesplugin_api.min.js b/src/alt_cadesplugin_api.min.js index e45e79e..4a2bd09 100644 --- a/src/alt_cadesplugin_api.min.js +++ b/src/alt_cadesplugin_api.min.js @@ -1 +1 @@ -!function(t,e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof exports?module.exports=e(require("jquery")):t.AltCadesPlugin=e(t.$)}(this,function(t){var e,n,i,r=function(t,e){return function(){return t.apply(e,arguments)}},o=[].slice;return t&&!e&&(e=t),i=null,n=function(){function t(t){return null==t&&(t={}),this.set=r(this.set,this),this.get=r(this.get,this),this.getParam=r(this.getParam,this),this.init=r(this.init,this),i?i:(t.timeout&&(this.timeout=t.timeout),this.cadesplugin.JSModuleVersion="2.0",this.cadesplugin.async_spawn=this.asyncSpawn,this.cadesplugin.set=function(t){return function(e){return t.pluginObject=e}}(this),window.cadesplugin=this.cadesplugin,void(i=this))}return t.prototype.checked=!1,t.prototype.cadesplugin={},t.prototype.pluginObject=null,t.prototype.timeout=2e4,t.prototype.isPromise=!!window.Promise,t.prototype.isWebkit=function(){return navigator.userAgent.match(/chrome/i)||navigator.userAgent.match(/opera/i)}(),t.prototype.asyncSpawn=function(t){var e,n,i,r;return e=function(t,e){var o,u,c;try{c=n[t](e)}catch(u){return o=u,Promise.reject(o)}return c.done?c.value:Promise.resolve(c.value).then(i,r)},n=t(Array.prototype.slice.call(arguments,1)),i=e.bind(e,"next"),r=e.bind(e,"throw"),i()},t.prototype.init=function(){return this.checked?e.when():this.isWebkit?this.initWebkit():this.initNpapi()},t.prototype.initWebkit=function(){var t,n;return e.getScript("chrome-extension://iifchhfnnmpdbibifmljnfjhpififfog/nmcades_plugin_api.js"),window.postMessage("cadesplugin_echo_request","*"),t=e.Deferred(),n=function(e){return function(e){return"cadesplugin_loaded"===e.data?setTimeout(function(){return cpcsp_chrome_nmcades.check_chrome_plugin(function(e){return function(){return e.checked=!0,t.resolve()}}(this),function(e){return function(n){return e.checked=!0,t.reject(n)}}(this))},0):void 0}}(this),window.addEventListener("message",n,!1),setTimeout(function(e){return function(){return e.checked?void 0:t.reject("timeout")}}(this),this.timeout),t},t.prototype.initNpapi=function(){var t,n;return t=e.Deferred(),n=this.isPromise?"load":"message",e(window).on(n,function(e){return function(n){var i;if(e.isPromise||"cadesplugin_echo_request"===n.data)return e.loadNpapiPlugin(),e.checked=!0,i=e.checkNpapiPlugin(),i===!0?t.resolve():t.reject(i)}}(this)),t},t.prototype.loadNpapiPlugin=function(){var t;return t=e(''),e("body").append(t),this.pluginObject=t[0]},t.prototype.checkNpapiPlugin=function(){var t,e,n,i;try{return this.createObject("CAdESCOM.About"),!0}catch(e){return t=e,n=navigator.mimeTypes["application/x-cades"],n?(i=n.enabledPlugin,i?"plugin_not_loaded_but_object_cannot_create":"error_on_plugin_load"):"plugin_unreachable"}},t.prototype.createObject=function(t){return this.pluginObject.CreateObject(t)},t.prototype.getParam=function(t,n){var i,r,o,u,c;if(i=e.Deferred(),this.isWebkit)u="string"==typeof t?this.pluginObject.CreateObjectAsync(t).then(function(t){return function(e){return n?t.extractParam(e,n):e}}(this)):this.extractParam(t,n),u.then(i.resolve,i.reject);else try{"string"==typeof t?(c=this.pluginObject.CreateObject(t),n&&(c=this.extractParam(c,n))):c=this.extractParam(t,n),i.resolve(c)}catch(o){r=o,i.reject(r.message)}return i},t.prototype.extractParam=function(t,e){return"object"==typeof e?t[e.method].apply(t,e.args):t[e]},t.prototype.get=function(){var t,e,n;return e=arguments[0],n=arguments[1],t=3<=arguments.length?o.call(arguments,2):[],this.getParam(e,n).then(function(e){return function(n){return t.length>0?(t.unshift(n),e.get.apply(e,t)):n}}(this))},t.prototype.set=function(t,n,i){var r,o,u,c;if(this.isWebkit)return c={method:"propset_"+n,args:[i]},this.get(t,c);r=e.Deferred();try{t[n]=i,r.resolve()}catch(u){o=u,r.reject(o.message)}return r},t}()}); \ No newline at end of file +!function(t,e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof exports?module.exports=e(require("jquery")):t.AltCadesPlugin=e(t.$)}(this,function(t){var e,r,n,i=function(t,e){return function(){return t.apply(e,arguments)}},o=[].slice;return t&&!e&&(e=t),n=null,r=function(){function t(t){return null==t&&(t={}),this.set=i(this.set,this),this.get=i(this.get,this),this.getParam=i(this.getParam,this),this.init=i(this.init,this),n?n:(t.timeout&&(this.timeout=t.timeout),this.cadesplugin.JSModuleVersion="2.0",this.cadesplugin.async_spawn=this.asyncSpawn,this.cadesplugin.set=function(t){return function(e){return t.pluginObject=e}}(this),window.cadesplugin=this.cadesplugin,void(n=this))}return t.prototype.checked=!1,t.prototype.cadesplugin={},t.prototype.pluginObject=null,t.prototype.timeout=2e4,t.prototype.isWebkit=function(){return navigator.userAgent.match(/chrome/i)||navigator.userAgent.match(/opera/i)}(),t.prototype.isIE=function(){return"Microsoft Internet Explorer"===navigator.appName||navigator.userAgent.match(/Trident\/./i)}(),t.prototype.asyncSpawn=function(t){var e,r,n,i;return e=function(t,e){var o,c,a;try{a=r[t](e)}catch(c){return o=c,Promise.reject(o)}return a.done?a.value:Promise.resolve(a.value).then(n,i)},r=t(Array.prototype.slice.call(arguments,1)),n=e.bind(e,"next"),i=e.bind(e,"throw"),n()},t.prototype.init=function(){return this.checked?e.when():this.isWebkit?this.initWebkit():this.initNpapi()},t.prototype.initWebkit=function(){var t;return e.getScript("chrome-extension://iifchhfnnmpdbibifmljnfjhpififfog/nmcades_plugin_api.js"),window.postMessage("cadesplugin_echo_request","*"),t=e.Deferred(),e(window).on("message",function(e){return function(e){var r;if("cadesplugin_loaded"===(null!=e&&null!=(r=e.originalEvent)?r.data:void 0))return setTimeout(function(){return cpcsp_chrome_nmcades.check_chrome_plugin(function(e){return function(){return e.checked=!0,t.resolve()}}(this),function(e){return function(r){return e.checked=!0,t.reject(r)}}(this))},0)}}(this)),setTimeout(function(e){return function(){return e.checked?void 0:t.reject("timeout")}}(this),this.timeout),t},t.prototype.initNpapi=function(){var t;return t=e.Deferred(),e(window).on("load",function(e){return function(r){var n;return e.loadNpapiPlugin(),e.checked=!0,n=e.checkNpapiPlugin(),n===!0?t.resolve():t.reject(n)}}(this)),t},t.prototype.loadNpapiPlugin=function(){var t,r;return r=e(''),e("body").append(r),this.pluginObject=r[0],this.isIE?(t=e(''),e("body").append(t)):void 0},t.prototype.checkNpapiPlugin=function(){var t,e,r,n;try{return this.createObject("CAdESCOM.About"),!0}catch(e){return t=e,r=navigator.mimeTypes["application/x-cades"],r?(n=r.enabledPlugin,n?"plugin_not_loaded_but_object_cannot_create":"error_on_plugin_load"):"plugin_unreachable"}},t.prototype.createObject=function(t){var r,n;if(this.isIE){if(t.match(/X509Enrollment/i))try{return e("certEnrollClassFactory")[0].CreateObject(t)}catch(n){throw r=n,"setup_https_for_x509enrollment"}return new ActiveXObject(t)}return this.pluginObject.CreateObject(t)},t.prototype.getParam=function(t,r){var n,i,o,c,a;if(n=e.Deferred(),this.isWebkit)c="string"==typeof t?this.pluginObject.CreateObjectAsync(t).then(function(t){return function(e){return r?t.extractParam(e,r):e}}(this)):this.extractParam(t,r),c.then(n.resolve,n.reject);else try{"string"==typeof t?(a=this.createObject(t),r&&(a=this.extractParam(a,r))):a=this.extractParam(t,r),n.resolve(a)}catch(o){i=o,n.reject(i.message)}return n},t.prototype.extractParam=function(t,e){if("object"!=typeof e)return t[e];switch(e.args.length){case 0:return t[e.method]();case 1:return t[e.method](e.args[0]);case 2:return t[e.method](e.args[0],e.args[1]);case 3:return t[e.method](e.args[0],e.args[1],e.args[2]);case 4:return t[e.method](e.args[0],e.args[1],e.args[2],e.args[3])}},t.prototype.get=function(){var t,e,r;return e=arguments[0],r=arguments[1],t=3<=arguments.length?o.call(arguments,2):[],this.getParam(e,r).then(function(e){return function(r){return t.length>0?(t.unshift(r),e.get.apply(e,t)):r}}(this))},t.prototype.set=function(t,r,n){var i,o,c,a;if(this.isWebkit)return a={method:"propset_"+r,args:[n]},this.get(t,a);i=e.Deferred();try{t[r]=n,i.resolve()}catch(c){o=c,i.reject(o.message)}return i},t}()}); \ No newline at end of file diff --git a/test/coffee/main.coffee b/test/coffee/main.coffee index 524b7e0..6342111 100644 --- a/test/coffee/main.coffee +++ b/test/coffee/main.coffee @@ -11,8 +11,8 @@ init = => altCadesPlugin = new AltCadesPlugin() # проверка наличия плагина - $logBlock.append '

Проверка наличия плагина

' - if bowser.chrome or bowser.firefox + $logBlock.append '

Проверка наличия плагина

' + if bowser.chrome or bowser.firefox or bowser.msie deferred = altCadesPlugin.init() else deferred = $.Deferred -> @reject 'Браузер не поддерживается' @@ -137,20 +137,34 @@ signData = -> altCadesPlugin.get 'CAdESCOM.CPAttribute' ).then (signer_, attribute_)-> signer = signer_ + unless altCadesPlugin.isWebkit + return attribute = attribute_ altCadesPlugin.set attribute, 'Name', 0 .then -> + unless altCadesPlugin.isWebkit + return altCadesPlugin.set attribute, 'Value', new Date() .then -> + unless altCadesPlugin.isWebkit + return altCadesPlugin.get signer, 'AuthenticatedAttributes2', {method: 'Add', args: [attribute]} .then -> + unless altCadesPlugin.isWebkit + return altCadesPlugin.get 'CADESCOM.CPAttribute' .then (attribute2_)-> + unless altCadesPlugin.isWebkit + return attribute2 = attribute2_ altCadesPlugin.set attribute2, 'Name', 1 .then -> + unless altCadesPlugin.isWebkit + return altCadesPlugin.set attribute2, 'Value', 'Document Name' .then -> + unless altCadesPlugin.isWebkit + return altCadesPlugin.get signer, 'AuthenticatedAttributes2', {method: 'Add', args: [attribute2]} .then -> altCadesPlugin.set signer, 'Certificate', certificatesList[certificateIndex].certificate diff --git a/test/index.html b/test/index.html index 8c24870..b93a469 100644 --- a/test/index.html +++ b/test/index.html @@ -5,6 +5,7 @@ Тестирование плагина КриптоПРО через альтернативную библиотеку + diff --git a/test/js/alt_cadesplugin_api.js b/test/js/alt_cadesplugin_api.js index 676a9ae..2f2bb9c 100644 --- a/test/js/alt_cadesplugin_api.js +++ b/test/js/alt_cadesplugin_api.js @@ -10,7 +10,7 @@ /** Библиотека для работы с плагином КриптоПРО -Версия 0.0.5 (beta) +Версия 0.0.6 (beta) Поддерживает плагин версии 2.0.12245 Репозиторий https://github.com/bankrot/cadesplugin */ @@ -74,22 +74,24 @@ AltCadesPlugin = (function() { /** - Нативные промисы поддерживаются - @property isPromise + На основе webkit + @property isWebkit @type {Boolean} */ - _Class.prototype.isPromise = !!window.Promise; + _Class.prototype.isWebkit = (function() { + return navigator.userAgent.match(/chrome/i) || navigator.userAgent.match(/opera/i); + })(); /** - На основе webkit - @property isWebkit + Internet Explorer + @property isIE @type {Boolean} */ - _Class.prototype.isWebkit = (function() { - return navigator.userAgent.match(/chrome/i) || navigator.userAgent.match(/opera/i); + _Class.prototype.isIE = (function() { + return (navigator.appName === 'Microsoft Internet Explorer') || navigator.userAgent.match(/Trident\/./i); })(); @@ -179,13 +181,14 @@ AltCadesPlugin = (function() { */ _Class.prototype.initWebkit = function() { - var deferred, listener; + var deferred; $.getScript('chrome-extension://iifchhfnnmpdbibifmljnfjhpififfog/nmcades_plugin_api.js'); window.postMessage('cadesplugin_echo_request', '*'); deferred = $.Deferred(); - listener = (function(_this) { + $(window).on('message', (function(_this) { return function(event) { - if (event.data !== 'cadesplugin_loaded') { + var ref; + if ((event != null ? (ref = event.originalEvent) != null ? ref.data : void 0 : void 0) !== 'cadesplugin_loaded') { return; } return setTimeout((function() { @@ -202,8 +205,7 @@ AltCadesPlugin = (function() { })(this))); }), 0); }; - })(this); - window.addEventListener('message', listener, false); + })(this)); setTimeout(((function(_this) { return function() { if (!_this.checked) { @@ -221,19 +223,11 @@ AltCadesPlugin = (function() { */ _Class.prototype.initNpapi = function() { - var deferred, eventName; + var deferred; deferred = $.Deferred(); - if (this.isPromise) { - eventName = 'load'; - } else { - eventName = 'message'; - } - $(window).on(eventName, (function(_this) { + $(window).on('load', (function(_this) { return function(event) { var result; - if ((!_this.isPromise) && (event.data !== 'cadesplugin_echo_request')) { - return; - } _this.loadNpapiPlugin(); _this.checked = true; result = _this.checkNpapiPlugin(); @@ -254,10 +248,14 @@ AltCadesPlugin = (function() { */ _Class.prototype.loadNpapiPlugin = function() { - var object; + var ieObject, object; object = $(''); $('body').append(object); - return this.pluginObject = object[0]; + this.pluginObject = object[0]; + if (this.isIE) { + ieObject = $(''); + return $('body').append(ieObject); + } }; @@ -288,6 +286,18 @@ AltCadesPlugin = (function() { }; _Class.prototype.createObject = function(name) { + var error, error1; + if (this.isIE) { + if (name.match(/X509Enrollment/i)) { + try { + return $('certEnrollClassFactory')[0].CreateObject(name); + } catch (error1) { + error = error1; + throw 'setup_https_for_x509enrollment'; + } + } + return new ActiveXObject(name); + } return this.pluginObject.CreateObject(name); }; @@ -322,7 +332,7 @@ AltCadesPlugin = (function() { } else { try { if (typeof objectName === 'string') { - result = this.pluginObject.CreateObject(objectName); + result = this.createObject(objectName); if (paramName) { result = this.extractParam(result, paramName); } @@ -347,7 +357,18 @@ AltCadesPlugin = (function() { _Class.prototype.extractParam = function(object, param) { if (typeof param === 'object') { - return object[param.method].apply(object, param.args); + switch (param.args.length) { + case 0: + return object[param.method](); + case 1: + return object[param.method](param.args[0]); + case 2: + return object[param.method](param.args[0], param.args[1]); + case 3: + return object[param.method](param.args[0], param.args[1], param.args[2]); + case 4: + return object[param.method](param.args[0], param.args[1], param.args[2], param.args[3]); + } } else { return object[param]; } diff --git a/test/js/es6-promise.js b/test/js/es6-promise.js new file mode 100644 index 0000000..88144c9 --- /dev/null +++ b/test/js/es6-promise.js @@ -0,0 +1,967 @@ +/*! + * @overview es6-promise - a tiny implementation of Promises/A+. + * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) + * @license Licensed under MIT license + * See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE + * @version 3.0.2 + */ + +(function() { + "use strict"; + function lib$es6$promise$utils$$objectOrFunction(x) { + return typeof x === 'function' || (typeof x === 'object' && x !== null); + } + + function lib$es6$promise$utils$$isFunction(x) { + return typeof x === 'function'; + } + + function lib$es6$promise$utils$$isMaybeThenable(x) { + return typeof x === 'object' && x !== null; + } + + var lib$es6$promise$utils$$_isArray; + if (!Array.isArray) { + lib$es6$promise$utils$$_isArray = function (x) { + return Object.prototype.toString.call(x) === '[object Array]'; + }; + } else { + lib$es6$promise$utils$$_isArray = Array.isArray; + } + + var lib$es6$promise$utils$$isArray = lib$es6$promise$utils$$_isArray; + var lib$es6$promise$asap$$len = 0; + var lib$es6$promise$asap$$toString = {}.toString; + var lib$es6$promise$asap$$vertxNext; + var lib$es6$promise$asap$$customSchedulerFn; + + var lib$es6$promise$asap$$asap = function asap(callback, arg) { + lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len] = callback; + lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len + 1] = arg; + lib$es6$promise$asap$$len += 2; + if (lib$es6$promise$asap$$len === 2) { + // If len is 2, that means that we need to schedule an async flush. + // If additional callbacks are queued before the queue is flushed, they + // will be processed by this flush that we are scheduling. + if (lib$es6$promise$asap$$customSchedulerFn) { + lib$es6$promise$asap$$customSchedulerFn(lib$es6$promise$asap$$flush); + } else { + lib$es6$promise$asap$$scheduleFlush(); + } + } + } + + function lib$es6$promise$asap$$setScheduler(scheduleFn) { + lib$es6$promise$asap$$customSchedulerFn = scheduleFn; + } + + function lib$es6$promise$asap$$setAsap(asapFn) { + lib$es6$promise$asap$$asap = asapFn; + } + + var lib$es6$promise$asap$$browserWindow = (typeof window !== 'undefined') ? window : undefined; + var lib$es6$promise$asap$$browserGlobal = lib$es6$promise$asap$$browserWindow || {}; + var lib$es6$promise$asap$$BrowserMutationObserver = lib$es6$promise$asap$$browserGlobal.MutationObserver || lib$es6$promise$asap$$browserGlobal.WebKitMutationObserver; + var lib$es6$promise$asap$$isNode = typeof process !== 'undefined' && {}.toString.call(process) === '[object process]'; + + // test for web worker but not in IE10 + var lib$es6$promise$asap$$isWorker = typeof Uint8ClampedArray !== 'undefined' && + typeof importScripts !== 'undefined' && + typeof MessageChannel !== 'undefined'; + + // node + function lib$es6$promise$asap$$useNextTick() { + // node version 0.10.x displays a deprecation warning when nextTick is used recursively + // see https://github.com/cujojs/when/issues/410 for details + return function() { + process.nextTick(lib$es6$promise$asap$$flush); + }; + } + + // vertx + function lib$es6$promise$asap$$useVertxTimer() { + return function() { + lib$es6$promise$asap$$vertxNext(lib$es6$promise$asap$$flush); + }; + } + + function lib$es6$promise$asap$$useMutationObserver() { + var iterations = 0; + var observer = new lib$es6$promise$asap$$BrowserMutationObserver(lib$es6$promise$asap$$flush); + var node = document.createTextNode(''); + observer.observe(node, { characterData: true }); + + return function() { + node.data = (iterations = ++iterations % 2); + }; + } + + // web worker + function lib$es6$promise$asap$$useMessageChannel() { + var channel = new MessageChannel(); + channel.port1.onmessage = lib$es6$promise$asap$$flush; + return function () { + channel.port2.postMessage(0); + }; + } + + function lib$es6$promise$asap$$useSetTimeout() { + return function() { + setTimeout(lib$es6$promise$asap$$flush, 1); + }; + } + + var lib$es6$promise$asap$$queue = new Array(1000); + function lib$es6$promise$asap$$flush() { + for (var i = 0; i < lib$es6$promise$asap$$len; i+=2) { + var callback = lib$es6$promise$asap$$queue[i]; + var arg = lib$es6$promise$asap$$queue[i+1]; + + callback(arg); + + lib$es6$promise$asap$$queue[i] = undefined; + lib$es6$promise$asap$$queue[i+1] = undefined; + } + + lib$es6$promise$asap$$len = 0; + } + + function lib$es6$promise$asap$$attemptVertx() { + try { + var r = require; + var vertx = r('vertx'); + lib$es6$promise$asap$$vertxNext = vertx.runOnLoop || vertx.runOnContext; + return lib$es6$promise$asap$$useVertxTimer(); + } catch(e) { + return lib$es6$promise$asap$$useSetTimeout(); + } + } + + var lib$es6$promise$asap$$scheduleFlush; + // Decide what async method to use to triggering processing of queued callbacks: + if (lib$es6$promise$asap$$isNode) { + lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useNextTick(); + } else if (lib$es6$promise$asap$$BrowserMutationObserver) { + lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMutationObserver(); + } else if (lib$es6$promise$asap$$isWorker) { + lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMessageChannel(); + } else if (lib$es6$promise$asap$$browserWindow === undefined && typeof require === 'function') { + lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$attemptVertx(); + } else { + lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useSetTimeout(); + } + + function lib$es6$promise$$internal$$noop() {} + + var lib$es6$promise$$internal$$PENDING = void 0; + var lib$es6$promise$$internal$$FULFILLED = 1; + var lib$es6$promise$$internal$$REJECTED = 2; + + var lib$es6$promise$$internal$$GET_THEN_ERROR = new lib$es6$promise$$internal$$ErrorObject(); + + function lib$es6$promise$$internal$$selfFulfillment() { + return new TypeError("You cannot resolve a promise with itself"); + } + + function lib$es6$promise$$internal$$cannotReturnOwn() { + return new TypeError('A promises callback cannot return that same promise.'); + } + + function lib$es6$promise$$internal$$getThen(promise) { + try { + return promise.then; + } catch(error) { + lib$es6$promise$$internal$$GET_THEN_ERROR.error = error; + return lib$es6$promise$$internal$$GET_THEN_ERROR; + } + } + + function lib$es6$promise$$internal$$tryThen(then, value, fulfillmentHandler, rejectionHandler) { + try { + then.call(value, fulfillmentHandler, rejectionHandler); + } catch(e) { + return e; + } + } + + function lib$es6$promise$$internal$$handleForeignThenable(promise, thenable, then) { + lib$es6$promise$asap$$asap(function(promise) { + var sealed = false; + var error = lib$es6$promise$$internal$$tryThen(then, thenable, function(value) { + if (sealed) { return; } + sealed = true; + if (thenable !== value) { + lib$es6$promise$$internal$$resolve(promise, value); + } else { + lib$es6$promise$$internal$$fulfill(promise, value); + } + }, function(reason) { + if (sealed) { return; } + sealed = true; + + lib$es6$promise$$internal$$reject(promise, reason); + }, 'Settle: ' + (promise._label || ' unknown promise')); + + if (!sealed && error) { + sealed = true; + lib$es6$promise$$internal$$reject(promise, error); + } + }, promise); + } + + function lib$es6$promise$$internal$$handleOwnThenable(promise, thenable) { + if (thenable._state === lib$es6$promise$$internal$$FULFILLED) { + lib$es6$promise$$internal$$fulfill(promise, thenable._result); + } else if (thenable._state === lib$es6$promise$$internal$$REJECTED) { + lib$es6$promise$$internal$$reject(promise, thenable._result); + } else { + lib$es6$promise$$internal$$subscribe(thenable, undefined, function(value) { + lib$es6$promise$$internal$$resolve(promise, value); + }, function(reason) { + lib$es6$promise$$internal$$reject(promise, reason); + }); + } + } + + function lib$es6$promise$$internal$$handleMaybeThenable(promise, maybeThenable) { + if (maybeThenable.constructor === promise.constructor) { + lib$es6$promise$$internal$$handleOwnThenable(promise, maybeThenable); + } else { + var then = lib$es6$promise$$internal$$getThen(maybeThenable); + + if (then === lib$es6$promise$$internal$$GET_THEN_ERROR) { + lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$GET_THEN_ERROR.error); + } else if (then === undefined) { + lib$es6$promise$$internal$$fulfill(promise, maybeThenable); + } else if (lib$es6$promise$utils$$isFunction(then)) { + lib$es6$promise$$internal$$handleForeignThenable(promise, maybeThenable, then); + } else { + lib$es6$promise$$internal$$fulfill(promise, maybeThenable); + } + } + } + + function lib$es6$promise$$internal$$resolve(promise, value) { + if (promise === value) { + lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$selfFulfillment()); + } else if (lib$es6$promise$utils$$objectOrFunction(value)) { + lib$es6$promise$$internal$$handleMaybeThenable(promise, value); + } else { + lib$es6$promise$$internal$$fulfill(promise, value); + } + } + + function lib$es6$promise$$internal$$publishRejection(promise) { + if (promise._onerror) { + promise._onerror(promise._result); + } + + lib$es6$promise$$internal$$publish(promise); + } + + function lib$es6$promise$$internal$$fulfill(promise, value) { + if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; } + + promise._result = value; + promise._state = lib$es6$promise$$internal$$FULFILLED; + + if (promise._subscribers.length !== 0) { + lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, promise); + } + } + + function lib$es6$promise$$internal$$reject(promise, reason) { + if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; } + promise._state = lib$es6$promise$$internal$$REJECTED; + promise._result = reason; + + lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publishRejection, promise); + } + + function lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection) { + var subscribers = parent._subscribers; + var length = subscribers.length; + + parent._onerror = null; + + subscribers[length] = child; + subscribers[length + lib$es6$promise$$internal$$FULFILLED] = onFulfillment; + subscribers[length + lib$es6$promise$$internal$$REJECTED] = onRejection; + + if (length === 0 && parent._state) { + lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, parent); + } + } + + function lib$es6$promise$$internal$$publish(promise) { + var subscribers = promise._subscribers; + var settled = promise._state; + + if (subscribers.length === 0) { return; } + + var child, callback, detail = promise._result; + + for (var i = 0; i < subscribers.length; i += 3) { + child = subscribers[i]; + callback = subscribers[i + settled]; + + if (child) { + lib$es6$promise$$internal$$invokeCallback(settled, child, callback, detail); + } else { + callback(detail); + } + } + + promise._subscribers.length = 0; + } + + function lib$es6$promise$$internal$$ErrorObject() { + this.error = null; + } + + var lib$es6$promise$$internal$$TRY_CATCH_ERROR = new lib$es6$promise$$internal$$ErrorObject(); + + function lib$es6$promise$$internal$$tryCatch(callback, detail) { + try { + return callback(detail); + } catch(e) { + lib$es6$promise$$internal$$TRY_CATCH_ERROR.error = e; + return lib$es6$promise$$internal$$TRY_CATCH_ERROR; + } + } + + function lib$es6$promise$$internal$$invokeCallback(settled, promise, callback, detail) { + var hasCallback = lib$es6$promise$utils$$isFunction(callback), + value, error, succeeded, failed; + + if (hasCallback) { + value = lib$es6$promise$$internal$$tryCatch(callback, detail); + + if (value === lib$es6$promise$$internal$$TRY_CATCH_ERROR) { + failed = true; + error = value.error; + value = null; + } else { + succeeded = true; + } + + if (promise === value) { + lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$cannotReturnOwn()); + return; + } + + } else { + value = detail; + succeeded = true; + } + + if (promise._state !== lib$es6$promise$$internal$$PENDING) { + // noop + } else if (hasCallback && succeeded) { + lib$es6$promise$$internal$$resolve(promise, value); + } else if (failed) { + lib$es6$promise$$internal$$reject(promise, error); + } else if (settled === lib$es6$promise$$internal$$FULFILLED) { + lib$es6$promise$$internal$$fulfill(promise, value); + } else if (settled === lib$es6$promise$$internal$$REJECTED) { + lib$es6$promise$$internal$$reject(promise, value); + } + } + + function lib$es6$promise$$internal$$initializePromise(promise, resolver) { + try { + resolver(function resolvePromise(value){ + lib$es6$promise$$internal$$resolve(promise, value); + }, function rejectPromise(reason) { + lib$es6$promise$$internal$$reject(promise, reason); + }); + } catch(e) { + lib$es6$promise$$internal$$reject(promise, e); + } + } + + function lib$es6$promise$enumerator$$Enumerator(Constructor, input) { + var enumerator = this; + + enumerator._instanceConstructor = Constructor; + enumerator.promise = new Constructor(lib$es6$promise$$internal$$noop); + + if (enumerator._validateInput(input)) { + enumerator._input = input; + enumerator.length = input.length; + enumerator._remaining = input.length; + + enumerator._init(); + + if (enumerator.length === 0) { + lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result); + } else { + enumerator.length = enumerator.length || 0; + enumerator._enumerate(); + if (enumerator._remaining === 0) { + lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result); + } + } + } else { + lib$es6$promise$$internal$$reject(enumerator.promise, enumerator._validationError()); + } + } + + lib$es6$promise$enumerator$$Enumerator.prototype._validateInput = function(input) { + return lib$es6$promise$utils$$isArray(input); + }; + + lib$es6$promise$enumerator$$Enumerator.prototype._validationError = function() { + return new Error('Array Methods must be provided an Array'); + }; + + lib$es6$promise$enumerator$$Enumerator.prototype._init = function() { + this._result = new Array(this.length); + }; + + var lib$es6$promise$enumerator$$default = lib$es6$promise$enumerator$$Enumerator; + + lib$es6$promise$enumerator$$Enumerator.prototype._enumerate = function() { + var enumerator = this; + + var length = enumerator.length; + var promise = enumerator.promise; + var input = enumerator._input; + + for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) { + enumerator._eachEntry(input[i], i); + } + }; + + lib$es6$promise$enumerator$$Enumerator.prototype._eachEntry = function(entry, i) { + var enumerator = this; + var c = enumerator._instanceConstructor; + + if (lib$es6$promise$utils$$isMaybeThenable(entry)) { + if (entry.constructor === c && entry._state !== lib$es6$promise$$internal$$PENDING) { + entry._onerror = null; + enumerator._settledAt(entry._state, i, entry._result); + } else { + enumerator._willSettleAt(c.resolve(entry), i); + } + } else { + enumerator._remaining--; + enumerator._result[i] = entry; + } + }; + + lib$es6$promise$enumerator$$Enumerator.prototype._settledAt = function(state, i, value) { + var enumerator = this; + var promise = enumerator.promise; + + if (promise._state === lib$es6$promise$$internal$$PENDING) { + enumerator._remaining--; + + if (state === lib$es6$promise$$internal$$REJECTED) { + lib$es6$promise$$internal$$reject(promise, value); + } else { + enumerator._result[i] = value; + } + } + + if (enumerator._remaining === 0) { + lib$es6$promise$$internal$$fulfill(promise, enumerator._result); + } + }; + + lib$es6$promise$enumerator$$Enumerator.prototype._willSettleAt = function(promise, i) { + var enumerator = this; + + lib$es6$promise$$internal$$subscribe(promise, undefined, function(value) { + enumerator._settledAt(lib$es6$promise$$internal$$FULFILLED, i, value); + }, function(reason) { + enumerator._settledAt(lib$es6$promise$$internal$$REJECTED, i, reason); + }); + }; + function lib$es6$promise$promise$all$$all(entries) { + return new lib$es6$promise$enumerator$$default(this, entries).promise; + } + var lib$es6$promise$promise$all$$default = lib$es6$promise$promise$all$$all; + function lib$es6$promise$promise$race$$race(entries) { + /*jshint validthis:true */ + var Constructor = this; + + var promise = new Constructor(lib$es6$promise$$internal$$noop); + + if (!lib$es6$promise$utils$$isArray(entries)) { + lib$es6$promise$$internal$$reject(promise, new TypeError('You must pass an array to race.')); + return promise; + } + + var length = entries.length; + + function onFulfillment(value) { + lib$es6$promise$$internal$$resolve(promise, value); + } + + function onRejection(reason) { + lib$es6$promise$$internal$$reject(promise, reason); + } + + for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) { + lib$es6$promise$$internal$$subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection); + } + + return promise; + } + var lib$es6$promise$promise$race$$default = lib$es6$promise$promise$race$$race; + function lib$es6$promise$promise$resolve$$resolve(object) { + /*jshint validthis:true */ + var Constructor = this; + + if (object && typeof object === 'object' && object.constructor === Constructor) { + return object; + } + + var promise = new Constructor(lib$es6$promise$$internal$$noop); + lib$es6$promise$$internal$$resolve(promise, object); + return promise; + } + var lib$es6$promise$promise$resolve$$default = lib$es6$promise$promise$resolve$$resolve; + function lib$es6$promise$promise$reject$$reject(reason) { + /*jshint validthis:true */ + var Constructor = this; + var promise = new Constructor(lib$es6$promise$$internal$$noop); + lib$es6$promise$$internal$$reject(promise, reason); + return promise; + } + var lib$es6$promise$promise$reject$$default = lib$es6$promise$promise$reject$$reject; + + var lib$es6$promise$promise$$counter = 0; + + function lib$es6$promise$promise$$needsResolver() { + throw new TypeError('You must pass a resolver function as the first argument to the promise constructor'); + } + + function lib$es6$promise$promise$$needsNew() { + throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function."); + } + + var lib$es6$promise$promise$$default = lib$es6$promise$promise$$Promise; + /** + Promise objects represent the eventual result of an asynchronous operation. The + primary way of interacting with a promise is through its `then` method, which + registers callbacks to receive either a promise's eventual value or the reason + why the promise cannot be fulfilled. + + Terminology + ----------- + + - `promise` is an object or function with a `then` method whose behavior conforms to this specification. + - `thenable` is an object or function that defines a `then` method. + - `value` is any legal JavaScript value (including undefined, a thenable, or a promise). + - `exception` is a value that is thrown using the throw statement. + - `reason` is a value that indicates why a promise was rejected. + - `settled` the final resting state of a promise, fulfilled or rejected. + + A promise can be in one of three states: pending, fulfilled, or rejected. + + Promises that are fulfilled have a fulfillment value and are in the fulfilled + state. Promises that are rejected have a rejection reason and are in the + rejected state. A fulfillment value is never a thenable. + + Promises can also be said to *resolve* a value. If this value is also a + promise, then the original promise's settled state will match the value's + settled state. So a promise that *resolves* a promise that rejects will + itself reject, and a promise that *resolves* a promise that fulfills will + itself fulfill. + + + Basic Usage: + ------------ + + ```js + var promise = new Promise(function(resolve, reject) { + // on success + resolve(value); + + // on failure + reject(reason); + }); + + promise.then(function(value) { + // on fulfillment + }, function(reason) { + // on rejection + }); + ``` + + Advanced Usage: + --------------- + + Promises shine when abstracting away asynchronous interactions such as + `XMLHttpRequest`s. + + ```js + function getJSON(url) { + return new Promise(function(resolve, reject){ + var xhr = new XMLHttpRequest(); + + xhr.open('GET', url); + xhr.onreadystatechange = handler; + xhr.responseType = 'json'; + xhr.setRequestHeader('Accept', 'application/json'); + xhr.send(); + + function handler() { + if (this.readyState === this.DONE) { + if (this.status === 200) { + resolve(this.response); + } else { + reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']')); + } + } + }; + }); + } + + getJSON('/posts.json').then(function(json) { + // on fulfillment + }, function(reason) { + // on rejection + }); + ``` + + Unlike callbacks, promises are great composable primitives. + + ```js + Promise.all([ + getJSON('/posts'), + getJSON('/comments') + ]).then(function(values){ + values[0] // => postsJSON + values[1] // => commentsJSON + + return values; + }); + ``` + + @class Promise + @param {function} resolver + Useful for tooling. + @constructor + */ + function lib$es6$promise$promise$$Promise(resolver) { + this._id = lib$es6$promise$promise$$counter++; + this._state = undefined; + this._result = undefined; + this._subscribers = []; + + if (lib$es6$promise$$internal$$noop !== resolver) { + if (!lib$es6$promise$utils$$isFunction(resolver)) { + lib$es6$promise$promise$$needsResolver(); + } + + if (!(this instanceof lib$es6$promise$promise$$Promise)) { + lib$es6$promise$promise$$needsNew(); + } + + lib$es6$promise$$internal$$initializePromise(this, resolver); + } + } + + lib$es6$promise$promise$$Promise.all = lib$es6$promise$promise$all$$default; + lib$es6$promise$promise$$Promise.race = lib$es6$promise$promise$race$$default; + lib$es6$promise$promise$$Promise.resolve = lib$es6$promise$promise$resolve$$default; + lib$es6$promise$promise$$Promise.reject = lib$es6$promise$promise$reject$$default; + lib$es6$promise$promise$$Promise._setScheduler = lib$es6$promise$asap$$setScheduler; + lib$es6$promise$promise$$Promise._setAsap = lib$es6$promise$asap$$setAsap; + lib$es6$promise$promise$$Promise._asap = lib$es6$promise$asap$$asap; + + lib$es6$promise$promise$$Promise.prototype = { + constructor: lib$es6$promise$promise$$Promise, + + /** + The primary way of interacting with a promise is through its `then` method, + which registers callbacks to receive either a promise's eventual value or the + reason why the promise cannot be fulfilled. + + ```js + findUser().then(function(user){ + // user is available + }, function(reason){ + // user is unavailable, and you are given the reason why + }); + ``` + + Chaining + -------- + + The return value of `then` is itself a promise. This second, 'downstream' + promise is resolved with the return value of the first promise's fulfillment + or rejection handler, or rejected if the handler throws an exception. + + ```js + findUser().then(function (user) { + return user.name; + }, function (reason) { + return 'default name'; + }).then(function (userName) { + // If `findUser` fulfilled, `userName` will be the user's name, otherwise it + // will be `'default name'` + }); + + findUser().then(function (user) { + throw new Error('Found user, but still unhappy'); + }, function (reason) { + throw new Error('`findUser` rejected and we're unhappy'); + }).then(function (value) { + // never reached + }, function (reason) { + // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'. + // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'. + }); + ``` + If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream. + + ```js + findUser().then(function (user) { + throw new PedagogicalException('Upstream error'); + }).then(function (value) { + // never reached + }).then(function (value) { + // never reached + }, function (reason) { + // The `PedgagocialException` is propagated all the way down to here + }); + ``` + + Assimilation + ------------ + + Sometimes the value you want to propagate to a downstream promise can only be + retrieved asynchronously. This can be achieved by returning a promise in the + fulfillment or rejection handler. The downstream promise will then be pending + until the returned promise is settled. This is called *assimilation*. + + ```js + findUser().then(function (user) { + return findCommentsByAuthor(user); + }).then(function (comments) { + // The user's comments are now available + }); + ``` + + If the assimliated promise rejects, then the downstream promise will also reject. + + ```js + findUser().then(function (user) { + return findCommentsByAuthor(user); + }).then(function (comments) { + // If `findCommentsByAuthor` fulfills, we'll have the value here + }, function (reason) { + // If `findCommentsByAuthor` rejects, we'll have the reason here + }); + ``` + + Simple Example + -------------- + + Synchronous Example + + ```javascript + var result; + + try { + result = findResult(); + // success + } catch(reason) { + // failure + } + ``` + + Errback Example + + ```js + findResult(function(result, err){ + if (err) { + // failure + } else { + // success + } + }); + ``` + + Promise Example; + + ```javascript + findResult().then(function(result){ + // success + }, function(reason){ + // failure + }); + ``` + + Advanced Example + -------------- + + Synchronous Example + + ```javascript + var author, books; + + try { + author = findAuthor(); + books = findBooksByAuthor(author); + // success + } catch(reason) { + // failure + } + ``` + + Errback Example + + ```js + + function foundBooks(books) { + + } + + function failure(reason) { + + } + + findAuthor(function(author, err){ + if (err) { + failure(err); + // failure + } else { + try { + findBoooksByAuthor(author, function(books, err) { + if (err) { + failure(err); + } else { + try { + foundBooks(books); + } catch(reason) { + failure(reason); + } + } + }); + } catch(error) { + failure(err); + } + // success + } + }); + ``` + + Promise Example; + + ```javascript + findAuthor(). + then(findBooksByAuthor). + then(function(books){ + // found books + }).catch(function(reason){ + // something went wrong + }); + ``` + + @method then + @param {Function} onFulfilled + @param {Function} onRejected + Useful for tooling. + @return {Promise} + */ + then: function(onFulfillment, onRejection) { + var parent = this; + var state = parent._state; + + if (state === lib$es6$promise$$internal$$FULFILLED && !onFulfillment || state === lib$es6$promise$$internal$$REJECTED && !onRejection) { + return this; + } + + var child = new this.constructor(lib$es6$promise$$internal$$noop); + var result = parent._result; + + if (state) { + var callback = arguments[state - 1]; + lib$es6$promise$asap$$asap(function(){ + lib$es6$promise$$internal$$invokeCallback(state, child, callback, result); + }); + } else { + lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection); + } + + return child; + }, + + /** + `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same + as the catch block of a try/catch statement. + + ```js + function findAuthor(){ + throw new Error('couldn't find that author'); + } + + // synchronous + try { + findAuthor(); + } catch(reason) { + // something went wrong + } + + // async with promises + findAuthor().catch(function(reason){ + // something went wrong + }); + ``` + + @method catch + @param {Function} onRejection + Useful for tooling. + @return {Promise} + */ + 'catch': function(onRejection) { + return this.then(null, onRejection); + } + }; + function lib$es6$promise$polyfill$$polyfill() { + var local; + + if (typeof global !== 'undefined') { + local = global; + } else if (typeof self !== 'undefined') { + local = self; + } else { + try { + local = Function('return this')(); + } catch (e) { + throw new Error('polyfill failed because global object is unavailable in this environment'); + } + } + + var P = local.Promise; + + if (P && Object.prototype.toString.call(P.resolve()) === '[object Promise]' && !P.cast) { + return; + } + + local.Promise = lib$es6$promise$promise$$default; + } + var lib$es6$promise$polyfill$$default = lib$es6$promise$polyfill$$polyfill; + + var lib$es6$promise$umd$$ES6Promise = { + 'Promise': lib$es6$promise$promise$$default, + 'polyfill': lib$es6$promise$polyfill$$default + }; + + /* global define:true module:true window: true */ + if (typeof define === 'function' && define['amd']) { + define(function() { return lib$es6$promise$umd$$ES6Promise; }); + } else if (typeof module !== 'undefined' && module['exports']) { + module['exports'] = lib$es6$promise$umd$$ES6Promise; + } else if (typeof this !== 'undefined') { + this['ES6Promise'] = lib$es6$promise$umd$$ES6Promise; + } + + lib$es6$promise$polyfill$$default(); +}).call(this); + diff --git a/test/js/main.js b/test/js/main.js index 1fd2364..8faf010 100644 --- a/test/js/main.js +++ b/test/js/main.js @@ -15,8 +15,8 @@ init = (function(_this) { var deferred; $logBlock = $('#ui-log-block'); altCadesPlugin = new AltCadesPlugin(); - $logBlock.append('

Проверка наличия плагина

'); - if (bowser.chrome || bowser.firefox) { + $logBlock.append('

Проверка наличия плагина

'); + if (bowser.chrome || bowser.firefox || bowser.msie) { deferred = altCadesPlugin.init(); } else { deferred = $.Deferred(function() { @@ -154,23 +154,44 @@ signData = function() { } return $.when(altCadesPlugin.get('CAdESCOM.CPSigner'), altCadesPlugin.get('CAdESCOM.CPAttribute')).then(function(signer_, attribute_) { signer = signer_; + if (!altCadesPlugin.isWebkit) { + return; + } attribute = attribute_; return altCadesPlugin.set(attribute, 'Name', 0); }).then(function() { + if (!altCadesPlugin.isWebkit) { + return; + } return altCadesPlugin.set(attribute, 'Value', new Date()); }).then(function() { + if (!altCadesPlugin.isWebkit) { + return; + } return altCadesPlugin.get(signer, 'AuthenticatedAttributes2', { method: 'Add', args: [attribute] }); }).then(function() { + if (!altCadesPlugin.isWebkit) { + return; + } return altCadesPlugin.get('CADESCOM.CPAttribute'); }).then(function(attribute2_) { + if (!altCadesPlugin.isWebkit) { + return; + } attribute2 = attribute2_; return altCadesPlugin.set(attribute2, 'Name', 1); }).then(function() { + if (!altCadesPlugin.isWebkit) { + return; + } return altCadesPlugin.set(attribute2, 'Value', 'Document Name'); }).then(function() { + if (!altCadesPlugin.isWebkit) { + return; + } return altCadesPlugin.get(signer, 'AuthenticatedAttributes2', { method: 'Add', args: [attribute2]