mirror of https://github.com/RubaXa/Ply.git
RubaXa
11 years ago
commit
9d225a0ac8
14 changed files with 3466 additions and 0 deletions
@ -0,0 +1,6 @@ |
|||||||
|
temp |
||||||
|
report |
||||||
|
.DS_Store |
||||||
|
node_modules |
||||||
|
Ply.js |
||||||
|
Ply.ui.js |
@ -0,0 +1,66 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
module.exports = function (grunt){ |
||||||
|
grunt.initConfig({ |
||||||
|
pkg: grunt.file.readJSON('package.json'), |
||||||
|
|
||||||
|
es6transpiler: { |
||||||
|
core: { |
||||||
|
src: 'src/Ply.es6', |
||||||
|
dest: 'Ply.js' |
||||||
|
}, |
||||||
|
ui: { |
||||||
|
src: 'src/Ply.ui.es6', |
||||||
|
dest: 'Ply.ui.js' |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
watch: { |
||||||
|
scripts: { |
||||||
|
files: 'src/*.es6', |
||||||
|
tasks: ['es6transpiler'], |
||||||
|
options: { interrupt: true } |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
qunit: { |
||||||
|
all: ['tests/*.html'], |
||||||
|
options: { |
||||||
|
'--web-security': 'no', |
||||||
|
coverage: { |
||||||
|
src: ['Ply.js', 'Ply.ui.js'], |
||||||
|
instrumentedFiles: 'temp/', |
||||||
|
htmlReport: 'report/coverage', |
||||||
|
coberturaReport: 'report/', |
||||||
|
linesThresholdPct: 95, |
||||||
|
statementsThresholdPct: 95, |
||||||
|
functionsThresholdPct: 95, |
||||||
|
branchesThresholdPct: 95 |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
uglify: { |
||||||
|
options: { |
||||||
|
banner: '/*! <%= pkg.exportName %> <%= pkg.version %> - <%= pkg.license %> | <%= pkg.repository.url %> */\n' |
||||||
|
}, |
||||||
|
dist: { |
||||||
|
files: { |
||||||
|
'<%= pkg.exportName %>.min.js': ['<%= pkg.exportName %>.js'] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-watch'); |
||||||
|
grunt.loadNpmTasks('grunt-qunit-istanbul'); |
||||||
|
grunt.loadNpmTasks('grunt-es6-transpiler'); |
||||||
|
grunt.loadNpmTasks('grunt-contrib-uglify'); |
||||||
|
|
||||||
|
|
||||||
|
grunt.registerTask('es', ['es6transpiler']); |
||||||
|
grunt.registerTask('build', ['es6transpiler', 'qunit']); |
||||||
|
grunt.registerTask('min', ['build', 'uglify']); |
||||||
|
grunt.registerTask('default', ['build']); |
||||||
|
}; |
After Width: | Height: | Size: 318 B |
@ -0,0 +1,268 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html> |
||||||
|
<head> |
||||||
|
<title>Ply — Amazing layer/modal/dialog system. Wow!</title> |
||||||
|
|
||||||
|
<meta name="keywords" content="ply, layer, modal, dialog, javascript, js, rubaxa"/> |
||||||
|
<meta name="description" content=""/> |
||||||
|
|
||||||
|
<link rel="icon" href="./favicon.ico" type="image/x-icon"/> |
||||||
|
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon"/> |
||||||
|
|
||||||
|
<link href='http://fonts.googleapis.com/css?family=Lato:300,400' rel='stylesheet' type='text/css'/> |
||||||
|
<link href='./st/app.css' rel='stylesheet' type='text/css'/> |
||||||
|
<link href='./ply.css' rel='stylesheet' type='text/css'/> |
||||||
|
|
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<h1 title="Try demo!"><u>Ply</u></h1> |
||||||
|
|
||||||
|
<div class="container"> |
||||||
|
<div class="row"> |
||||||
|
<h2>Alert</h2> |
||||||
|
|
||||||
|
<div class="col-left"> |
||||||
|
<div class="ply-layer alert example"> |
||||||
|
<div class="ply-content">Hello %username%!</div> |
||||||
|
<div class="ply-footer"><button class="ply-ok">OK</button></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="col-right"> |
||||||
|
<code> |
||||||
|
Ply.dialog("alert", "Hello %username%!"); |
||||||
|
</code> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="row"> |
||||||
|
<h2>Confirm</h2> |
||||||
|
|
||||||
|
<div class="col-left"> |
||||||
|
<div class="ply-layer confirm example"> |
||||||
|
<div class="ply-content">Continue?</div> |
||||||
|
<div class="ply-footer"><button class="ply-ok">OK</button><button class="ply-cancel">Cancel</button></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="col-right"> |
||||||
|
<code> |
||||||
|
Ply.dialog( |
||||||
|
"confirm", |
||||||
|
{ effect: "3d-sign" }, |
||||||
|
"Continue?" |
||||||
|
); |
||||||
|
</code> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="row"> |
||||||
|
<h2>Prompt</h2> |
||||||
|
|
||||||
|
<div class="col-left"> |
||||||
|
<div class="ply-layer prompt example"> |
||||||
|
<div class="ply-header">Spam subscribe</div> |
||||||
|
<div class="ply-content"> |
||||||
|
<input class="ply-input" placeholder="E-mail"/> |
||||||
|
</div> |
||||||
|
<div class="ply-footer"><button class="ply-ok">OK</button><button class="ply-cancel">Cancel</button></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="col-right"> |
||||||
|
<code> |
||||||
|
Ply.dialog("prompt", { |
||||||
|
title: "Spam subscribe", |
||||||
|
form: { email: "E-mail" } |
||||||
|
}); |
||||||
|
</code> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
|
||||||
|
<div style="height: 100px"></div> |
||||||
|
|
||||||
|
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> |
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.0/highlight.min.js"></script> |
||||||
|
|
||||||
|
<script src="./Ply.js"></script> |
||||||
|
<script src="./Ply.ui.js"></script> |
||||||
|
|
||||||
|
<script> |
||||||
|
jQuery(function ($) { |
||||||
|
hljs.configure({ classPrefix: '' }); |
||||||
|
|
||||||
|
|
||||||
|
Ply.dialog({ |
||||||
|
foo: { |
||||||
|
data: 'Foo!', |
||||||
|
next: 'bar', |
||||||
|
nextEffect: 'inner' |
||||||
|
}, |
||||||
|
bar: { |
||||||
|
data: { |
||||||
|
text: 'Bar!', |
||||||
|
ok: 'Wow!' |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
$('.example') |
||||||
|
.each(function () { |
||||||
|
var $el = $(this); |
||||||
|
var $code = $el.closest('.row').find('code'); |
||||||
|
var code = $code.text().split('\n'); |
||||||
|
var offset = code[1].match(/^\s+/)[0].length; |
||||||
|
|
||||||
|
$.each(code, function (i) { |
||||||
|
code[i] = code[i].substr(offset); |
||||||
|
}); |
||||||
|
|
||||||
|
code = code.slice(1).join('\n'); |
||||||
|
$code.text(code); |
||||||
|
$el.data('code', code); |
||||||
|
|
||||||
|
hljs.highlightBlock($code.wrap('<pre/>').parent().addClass('javascript')[0]) |
||||||
|
}) |
||||||
|
.on('click', function () { |
||||||
|
Function($(this).data('code'))(); |
||||||
|
return false; |
||||||
|
}) |
||||||
|
; |
||||||
|
|
||||||
|
|
||||||
|
$('h1 u').click(function () { |
||||||
|
Ply.dialog({ |
||||||
|
'welcome': { |
||||||
|
data: { |
||||||
|
children: [{ |
||||||
|
tag: 'img', |
||||||
|
src: 'http://www.saintjn.org/wp-content/uploads/2013/07/welcome.png?1', |
||||||
|
width: 400 |
||||||
|
}], |
||||||
|
ok: "Next" |
||||||
|
}, |
||||||
|
next: 'introduce', |
||||||
|
nextEffect: '3d-flip[180,-180]' |
||||||
|
}, |
||||||
|
|
||||||
|
'introduce': { |
||||||
|
ui: 'prompt', |
||||||
|
data: { |
||||||
|
title: 'Your name?', |
||||||
|
form: { name: '%username%' } |
||||||
|
}, |
||||||
|
back: 'welcome', |
||||||
|
backEffect: '3d-flip[-180,180]', |
||||||
|
next: 'hi', |
||||||
|
nextEffect: 'scale' |
||||||
|
}, |
||||||
|
|
||||||
|
'hi': { |
||||||
|
data: { |
||||||
|
text: 'Hi, {{name}}!', |
||||||
|
ok: 'Next' |
||||||
|
}, |
||||||
|
prepare: function (data, dialogs) { |
||||||
|
data.text = data.text.replace(/\{\{([^}]+)\}\}/g, function (_, name) { |
||||||
|
return dialogs.introduce.val(name); |
||||||
|
}); |
||||||
|
}, |
||||||
|
back: 'next', |
||||||
|
next: 'question', |
||||||
|
nextEffect: 'fall' |
||||||
|
}, |
||||||
|
|
||||||
|
'question': { |
||||||
|
ui: 'confirm', |
||||||
|
data: { |
||||||
|
text: 'You know Jonna Lee?', |
||||||
|
ok: 'Yes', |
||||||
|
cancel: 'No' |
||||||
|
}, |
||||||
|
back: 'Jonna', |
||||||
|
next: 'Jonna-01', |
||||||
|
nextEffect: '3d-sign' |
||||||
|
}, |
||||||
|
|
||||||
|
'Jonna': { |
||||||
|
data: 'Jonna Lee (born Jonna Emily Lee Nilsson, October 3, 1981) is a singer-songwriter from Linköping, Sweden, currently residing in Stockholm. Lee is best known for being the creator and artist of iamamiwhoami. Lee started her own label "To whom it may concern" in 2010.', |
||||||
|
back: 'next', |
||||||
|
next: 'Jonna-01', |
||||||
|
nextEffect: 'fade' |
||||||
|
}, |
||||||
|
|
||||||
|
'Jonna-01': { |
||||||
|
data: { |
||||||
|
title: 'Jonna Lee', |
||||||
|
children: [{ |
||||||
|
tag: 'img', |
||||||
|
src: 'http://www.movieviral.com/wp-content/uploads/2010/03/jonnalee.jpg', |
||||||
|
width: 400 |
||||||
|
}], |
||||||
|
ok: 'Next' |
||||||
|
}, |
||||||
|
next: 'Jonna-02', |
||||||
|
nextEffect: '3d-flip[180,-180]' |
||||||
|
}, |
||||||
|
|
||||||
|
'Jonna-02': { |
||||||
|
data: { |
||||||
|
title: 'Jonna Lee', |
||||||
|
children: [{ |
||||||
|
tag: 'img', |
||||||
|
src: 'http://2020k.files.wordpress.com/2012/03/iamamiwhoami-good-worker.png', |
||||||
|
width: 400 |
||||||
|
}], |
||||||
|
ok: 'Close', |
||||||
|
cancel: 'Rewind' |
||||||
|
}, |
||||||
|
back: 'welcome' |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
</script> |
||||||
|
|
||||||
|
|
||||||
|
<!-- Background --> |
||||||
|
<script> |
||||||
|
(function () { |
||||||
|
function setNoiseBackground(el, color, width, height, opacity) { |
||||||
|
var canvas = document.createElement("canvas"); |
||||||
|
var context = canvas.getContext("2d"); |
||||||
|
|
||||||
|
canvas.width = width; |
||||||
|
canvas.height = height; |
||||||
|
|
||||||
|
for (var i = 0; i < width; i++) { |
||||||
|
for (var j = 0; j < height; j++) { |
||||||
|
var val = Math.floor(Math.random() * 255); |
||||||
|
context.fillStyle = "rgba(" + val + "," + val + "," + val + "," + opacity + ")"; |
||||||
|
context.fillRect(i, j, 1, 1); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
el.style.backgroundColor = color; |
||||||
|
el.style.backgroundImage = "url(" + canvas.toDataURL("image/png") + ")"; |
||||||
|
} |
||||||
|
|
||||||
|
// Usage |
||||||
|
setNoiseBackground(document.body, "trasparent", 50, 50, 0.02); |
||||||
|
})(); |
||||||
|
</script> |
||||||
|
|
||||||
|
<script> |
||||||
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ |
||||||
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), |
||||||
|
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) |
||||||
|
})(window,document,'script','//www.google-analytics.com/analytics.js','ga'); |
||||||
|
|
||||||
|
ga('create', 'UA-16483888-3', 'rubaxa.github.io'); |
||||||
|
ga('send', 'pageview'); |
||||||
|
</script> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,30 @@ |
|||||||
|
{ |
||||||
|
"name": "ply", |
||||||
|
"exportName": "Ply", |
||||||
|
"version": "0.3.0", |
||||||
|
"devDependencies": { |
||||||
|
"grunt": "*", |
||||||
|
"grunt-contrib-watch": "*", |
||||||
|
"grunt-qunit-istanbul": "*", |
||||||
|
"grunt-es6-transpiler": "*", |
||||||
|
"grunt-contrib-uglify": "*" |
||||||
|
}, |
||||||
|
"description": "Ply — Amazing layer/modal/dialog system. Wow!", |
||||||
|
"main": "Ply.js", |
||||||
|
"scripts": { |
||||||
|
"test": "grunt" |
||||||
|
}, |
||||||
|
"repository": { |
||||||
|
"type": "git", |
||||||
|
"url": "git://github.com/rubaxa/Ply.git" |
||||||
|
}, |
||||||
|
"keywords": [ |
||||||
|
"ply", |
||||||
|
"layer", |
||||||
|
"modal", |
||||||
|
"dialog", |
||||||
|
"lightbox" |
||||||
|
], |
||||||
|
"author": "Konstantin Lebedev <ibnRubaXa@gmail.com>", |
||||||
|
"license": "MIT" |
||||||
|
} |
@ -0,0 +1,138 @@ |
|||||||
|
/* Loading */ |
||||||
|
.ply-loading { |
||||||
|
top: 50%; |
||||||
|
left: 50%; |
||||||
|
padding: 30px; |
||||||
|
width: 60px; |
||||||
|
height: 60px; |
||||||
|
margin: -100px 0 0 -60px; |
||||||
|
z-index: 100000; |
||||||
|
position: fixed; |
||||||
|
border-radius: 10%; |
||||||
|
background-color: rgba(255,255,255,.5); |
||||||
|
box-shadow: 0 1px 2px rgba(0,0,0,.2); |
||||||
|
} |
||||||
|
|
||||||
|
.ply-loading-spinner { |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
opacity: .9; |
||||||
|
background: #fff; |
||||||
|
border-radius: 100%; |
||||||
|
overflow: hidden; |
||||||
|
position: relative; |
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,.6); |
||||||
|
} |
||||||
|
|
||||||
|
.ply-loading-spinner::before { |
||||||
|
content: ""; |
||||||
|
display: block; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
left: 0; |
||||||
|
background: #333; |
||||||
|
max-height: 0; |
||||||
|
-webkit-animation: loading 3s normal infinite; |
||||||
|
animation: loading 3s normal infinite; |
||||||
|
} |
||||||
|
|
||||||
|
@keyframes loading { |
||||||
|
0% { max-height: 0; } |
||||||
|
50% { max-height: 100%; top: 0; } |
||||||
|
100% { max-height: 0; top: 120%; } |
||||||
|
} |
||||||
|
|
||||||
|
@-webkit-keyframes loading { |
||||||
|
0% { max-height: 0; } |
||||||
|
50% { max-height: 100%; top: 0; } |
||||||
|
100% { max-height: 0; top: 120%; } |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/* Layer */ |
||||||
|
.ply-layer { |
||||||
|
color: #333; |
||||||
|
min-width: 280px; |
||||||
|
box-shadow: 0 0 3px rgba(0,0,0,.3); |
||||||
|
background-color: #fff; |
||||||
|
border-radius: 2px; |
||||||
|
font-family: "Arial", Helvetica; |
||||||
|
font-size: 16px; |
||||||
|
} |
||||||
|
.ply-layer.alert .ply-content, |
||||||
|
.ply-layer.confirm .ply-content { |
||||||
|
padding: 40px 30px; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
.ply-layer.alert .ply-footer, |
||||||
|
.ply-layer.confirm .ply-footer, |
||||||
|
.ply-layer.prompt .ply-footer { |
||||||
|
text-align: center; |
||||||
|
padding-bottom: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
.ply-header { |
||||||
|
padding: 10px 20px; |
||||||
|
font-size: 18px; |
||||||
|
background-color: #f1f1f1; |
||||||
|
border-radius: 2px 2px 0 0; |
||||||
|
} |
||||||
|
|
||||||
|
.ply-content { |
||||||
|
padding: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
.ply-footer { |
||||||
|
padding: 0 20px 15px; |
||||||
|
} |
||||||
|
.ply-footer button { |
||||||
|
margin-left: 20px; |
||||||
|
} |
||||||
|
.ply-footer button:first-child { |
||||||
|
margin-left: 0; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/* Controls */ |
||||||
|
.ply-ok, |
||||||
|
.ply-cancel { |
||||||
|
color: #fff; |
||||||
|
cursor: pointer; |
||||||
|
border: 0; |
||||||
|
outline: 0; |
||||||
|
padding: 5px 20px; |
||||||
|
box-shadow: 0 1px 1px rgba(0,0,0,.2); |
||||||
|
background-color: #39C082; |
||||||
|
border-radius: 3px; |
||||||
|
font-size: 18px; |
||||||
|
} |
||||||
|
.ply-ok { |
||||||
|
width: 100px; |
||||||
|
} |
||||||
|
|
||||||
|
.ply-cancel { |
||||||
|
background-color: #b2b2b2; |
||||||
|
} |
||||||
|
.ply-ok:focus, |
||||||
|
.ply-cancel:focus { |
||||||
|
box-shadow: 0 0 1px 2px rgba(255, 180, 0, .6); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/* Forms */ |
||||||
|
.ply-input { |
||||||
|
width: 100%; |
||||||
|
border: 2px solid #ccc; |
||||||
|
outline: 0; |
||||||
|
padding: 5px 10px; |
||||||
|
font-size: 16px; |
||||||
|
font-family: "Arial", Helvetica; |
||||||
|
box-sizing: border-box; |
||||||
|
} |
||||||
|
.ply-input:focus { |
||||||
|
border-color: #39C082; |
||||||
|
} |
@ -0,0 +1,405 @@ |
|||||||
|
/*global define, Ply */ |
||||||
|
((factory) => { |
||||||
|
factory(Ply); |
||||||
|
})((Ply) => { |
||||||
|
'use strict'; |
||||||
|
|
||||||
|
|
||||||
|
var _plyAttr = Ply.attrName, |
||||||
|
noop = Ply.noop, |
||||||
|
_each = Ply.each, |
||||||
|
_extend = Ply.extend, |
||||||
|
_promise = Ply.promise, |
||||||
|
_buildDOM = Ply.dom.build, |
||||||
|
_appendChild = Ply.dom.appendChild, |
||||||
|
_lang = Ply.lang, |
||||||
|
|
||||||
|
_toBlock = (block, name) => { |
||||||
|
if (block == null) { |
||||||
|
return { skip: true }; |
||||||
|
} |
||||||
|
|
||||||
|
if (typeof block === 'string') { |
||||||
|
block = { text: block }; |
||||||
|
} |
||||||
|
|
||||||
|
block.name = block.name || name; |
||||||
|
|
||||||
|
return block; |
||||||
|
} |
||||||
|
; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Управление рендером UI |
||||||
|
* @param {String} name |
||||||
|
* @param {Object} [data] |
||||||
|
* @param {String} [path] |
||||||
|
* @returns {HTMLElement} |
||||||
|
*/ |
||||||
|
function ui(name, data, path) { |
||||||
|
var fn = ui[name], el; |
||||||
|
|
||||||
|
if (!fn) { |
||||||
|
name = name.split(/\s+/).slice(0, -1).join(' '); |
||||||
|
fn = data && ( |
||||||
|
ui[name + ' [name=' + data.name + ']'] |
||||||
|
|| ui[name + ' [type=' + data.type + ']'] |
||||||
|
) |
||||||
|
|| ui[name + ' *'] |
||||||
|
|| ui[':default']; |
||||||
|
} |
||||||
|
|
||||||
|
el = _buildDOM(fn(data, path)); |
||||||
|
if (data && data.name) { |
||||||
|
el.setAttribute(_plyAttr + '-name', data.name); |
||||||
|
} |
||||||
|
el.className += ' ply-ui'; |
||||||
|
|
||||||
|
return el; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Назначение визуализатор |
||||||
|
* @param {String} name имя фабрики |
||||||
|
* @param {Function} renderer |
||||||
|
* @param {Boolean} [simpleMode] |
||||||
|
*/ |
||||||
|
ui.factory = function (name, renderer, simpleMode) { |
||||||
|
ui[name.trim().replace(/\s+/g, ' ')] = function (data, path) { |
||||||
|
var fragment = document.createDocumentFragment(); |
||||||
|
|
||||||
|
if ((data != null) || name === ':root') { |
||||||
|
data = simpleMode ? data : _toBlock(data); |
||||||
|
|
||||||
|
_each(simpleMode ? data : data.children, function (block, key) { |
||||||
|
var abs = ((path || name) + ' ' + key).replace(/^:\w+\s+/, ''); |
||||||
|
var el = ui(abs, _toBlock(block, key), abs); |
||||||
|
|
||||||
|
_appendChild(fragment, el); |
||||||
|
}); |
||||||
|
|
||||||
|
if (!simpleMode) { |
||||||
|
delete data.children; |
||||||
|
} |
||||||
|
|
||||||
|
var result = renderer(data, fragment); |
||||||
|
|
||||||
|
/* istanbul ignore else */ |
||||||
|
if (!result.appendChild) { |
||||||
|
_extend(result, data); |
||||||
|
} |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
return fragment; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
// Элемент по умолчанию |
||||||
|
ui.factory(':default', (data, children) => { |
||||||
|
data.children = children; |
||||||
|
return data; |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
// Ply-слой - корневой элемент |
||||||
|
ui.factory(':root', function (data) { |
||||||
|
return { |
||||||
|
tag: 'form.ply-layer', |
||||||
|
className: data.mod, |
||||||
|
children: [ |
||||||
|
ui(':header', data.header), |
||||||
|
ui(':content', data.content), |
||||||
|
data.ctrls && ui(':default', { |
||||||
|
tag: 'div.ply-footer', |
||||||
|
children: data.ctrls |
||||||
|
}) |
||||||
|
] |
||||||
|
}; |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
// «Заголовк» слоя |
||||||
|
ui.factory(':header', function (data, children) { |
||||||
|
return { tag: '.ply-header', text: data.text, children: children }; |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
// «Содержимое» слоя |
||||||
|
ui.factory(':content', function (data, children) { |
||||||
|
return { tag: '.ply-content', children: children }; |
||||||
|
}, true); |
||||||
|
|
||||||
|
|
||||||
|
// Кнопка «ОК» |
||||||
|
ui.factory('ok', function (data) { |
||||||
|
return { |
||||||
|
ply: ':ok', |
||||||
|
tag: 'button.ply-ok', |
||||||
|
text: data === true ? _lang.ok : data |
||||||
|
}; |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
// Кнопка «Отмена» |
||||||
|
ui.factory('cancel', function (data) { |
||||||
|
return { |
||||||
|
ply: ':close', |
||||||
|
tag: 'button.ply-cancel', |
||||||
|
type: 'reset', |
||||||
|
text: data === true ? _lang.cancel : data |
||||||
|
}; |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Фабрика слоев |
||||||
|
* @param {String} name |
||||||
|
* @param {Function} renderer |
||||||
|
*/ |
||||||
|
function factory(name, renderer) { |
||||||
|
factory['_' + name] = renderer; |
||||||
|
|
||||||
|
factory[name] = (options, data) => { |
||||||
|
return _promise((resolve, reject) => { |
||||||
|
renderer(options, data, resolve, reject); |
||||||
|
}).then((el) => { |
||||||
|
/* istanbul ignore else */ |
||||||
|
if (!el.appendChild) { |
||||||
|
el = ui(':root', el); |
||||||
|
} |
||||||
|
|
||||||
|
return el; |
||||||
|
}); |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Использовать фабрику |
||||||
|
* @param {String} name |
||||||
|
* @param {Object} options |
||||||
|
* @param {Object} data |
||||||
|
* @param {Function} resolve |
||||||
|
* @param {Function} [reject] |
||||||
|
*/ |
||||||
|
factory.use = (name, options, data, resolve, reject) => { |
||||||
|
factory['_' + name](options, data, resolve, reject); |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Абстрактный диалог |
||||||
|
* @param {String} mod |
||||||
|
* @param {Object} options |
||||||
|
* @param {Object} data |
||||||
|
* @param {Object} defaults |
||||||
|
* @returns {Object} |
||||||
|
* @private |
||||||
|
*/ |
||||||
|
function _dialogFactory(mod, options, data, defaults) { |
||||||
|
options.effect = options.effect || 'slide'; |
||||||
|
|
||||||
|
return { |
||||||
|
mod: mod, |
||||||
|
header: data.title, |
||||||
|
content: data.form |
||||||
|
? { 'dialog-form': { children: data.form } } |
||||||
|
: { el: data.text || data }, |
||||||
|
ctrls: { |
||||||
|
ok: data.ok || defaults.ok, |
||||||
|
cancel: data.cancel || defaults.cancel |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
// Фабрика по умолчанию |
||||||
|
factory('default', (options, data, resolve) => { |
||||||
|
resolve(data || /* istanbul ignore next */ {}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
// Диалог: «Предупреждение» |
||||||
|
factory('alert', (options, data, resolve) => { |
||||||
|
resolve(_dialogFactory('alert', options, data, { ok: true })); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
// Диалог: «Подтверждение» |
||||||
|
factory('confirm', (options, data, resolve) => { |
||||||
|
resolve(_dialogFactory('confirm', options, data, { |
||||||
|
ok: true, |
||||||
|
cancel: true |
||||||
|
})); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
// Диалог: «Запросить данные» |
||||||
|
factory('prompt', (options, data, resolve) => { |
||||||
|
resolve(_dialogFactory('prompt', options, data, { |
||||||
|
ok: true, |
||||||
|
cancel: true |
||||||
|
})); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
// Элемент формы |
||||||
|
ui.factory('dialog-form *', (data) => { |
||||||
|
return { |
||||||
|
tag: 'input.ply-input', |
||||||
|
name: data.name, |
||||||
|
value: data.value, |
||||||
|
required: true, |
||||||
|
placeholder: data.hint || data.text |
||||||
|
}; |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Создать Ply-слой на основе фабрики |
||||||
|
* @param {String} name название фабрики |
||||||
|
* @param {Object} [options] опции |
||||||
|
* @param {Object} [data] данные для фабрики |
||||||
|
* @returns {Promise} |
||||||
|
*/ |
||||||
|
Ply.create = (name, options, data) => { |
||||||
|
if (!data) { |
||||||
|
data = options; |
||||||
|
options = {}; |
||||||
|
} |
||||||
|
|
||||||
|
var renderer = (factory[name] || factory['default']); |
||||||
|
return renderer(options, data).then((el) => { |
||||||
|
return new Ply(_extend(options, { el: el })); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Открыть Ply-слой |
||||||
|
* @param {String} name |
||||||
|
* @param {Object} [options] |
||||||
|
* @param {Object} [data] |
||||||
|
* @returns {Promise} |
||||||
|
*/ |
||||||
|
Ply.open = (name, options, data) => { |
||||||
|
return Ply.create(name, options, data).then((layer) => { |
||||||
|
return layer.open(); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Создать диалог или систему диалогов |
||||||
|
* @param {String|Object} name |
||||||
|
* @param {Object} [options] |
||||||
|
* @param {Object} [data] |
||||||
|
* @returns {Promise} |
||||||
|
*/ |
||||||
|
Ply.dialog = (name, options, data) => { |
||||||
|
if (name instanceof Object) { |
||||||
|
options = options || /* istanbul ignore next */ {}; |
||||||
|
|
||||||
|
return _promise((resolve, reject) => { |
||||||
|
var first = options.initState, |
||||||
|
current, |
||||||
|
rootLayer, |
||||||
|
stack = name, |
||||||
|
dialogs = {}, |
||||||
|
|
||||||
|
_progress = (ui, layer) => { |
||||||
|
(options.progress || /* istanbul ignore next */ noop)(_extend({ |
||||||
|
name: current.$name, |
||||||
|
index: current.$index, |
||||||
|
length: length, |
||||||
|
stack: stack, |
||||||
|
current: current, |
||||||
|
layer: layer |
||||||
|
}, ui), dialogs); |
||||||
|
}, |
||||||
|
|
||||||
|
changeLayer = (spec, effect, callback) => { |
||||||
|
// Клонирование данных |
||||||
|
var data = JSON.parse(JSON.stringify(spec.data)); |
||||||
|
|
||||||
|
current = spec; |
||||||
|
(spec.prepare || noop)(data, dialogs); |
||||||
|
|
||||||
|
Ply.create(spec.ui || 'alert', spec.options || {}, data).then((layer) => { |
||||||
|
var promise; |
||||||
|
|
||||||
|
if (rootLayer) { |
||||||
|
promise = rootLayer.swap(layer, effect); |
||||||
|
} else { |
||||||
|
promise = layer.open(); |
||||||
|
rootLayer = layer; |
||||||
|
} |
||||||
|
|
||||||
|
promise.then(() => { |
||||||
|
dialogs[spec.$name].el = rootLayer.layerEl; |
||||||
|
}); |
||||||
|
|
||||||
|
callback(layer); |
||||||
|
}); |
||||||
|
} |
||||||
|
; |
||||||
|
|
||||||
|
|
||||||
|
var length = 0; |
||||||
|
_each(stack, (spec, key) => { |
||||||
|
first = first || key; |
||||||
|
spec.effects = spec.effects || {}; |
||||||
|
spec.$name = key; |
||||||
|
spec.$index = length++; |
||||||
|
dialogs[key] = new Ply.Context(); |
||||||
|
}); |
||||||
|
stack.$length = length; |
||||||
|
|
||||||
|
|
||||||
|
changeLayer(stack[first], null, (layer) => { |
||||||
|
_progress({}, layer); |
||||||
|
|
||||||
|
//noinspection FunctionWithInconsistentReturnsJS |
||||||
|
rootLayer.options.callback = (ui) => { |
||||||
|
var isNext = ui.state || (current.back === 'next'), |
||||||
|
swap = isNext ? stack[current.next] : stack[current.back] |
||||||
|
; |
||||||
|
|
||||||
|
if (swap) { |
||||||
|
changeLayer(swap, current[isNext ? 'nextEffect' : 'backEffect'], (layer) => { |
||||||
|
_progress(ui, layer); |
||||||
|
}); |
||||||
|
|
||||||
|
return false; |
||||||
|
} else { |
||||||
|
(ui.state ? resolve : /* istanbul ignore next */ reject)(ui, dialogs); |
||||||
|
} |
||||||
|
}; |
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
else { |
||||||
|
if (!data) { |
||||||
|
data = options || {}; |
||||||
|
options = {}; |
||||||
|
} |
||||||
|
|
||||||
|
return Ply.open(name, options, data).then((layer) => { |
||||||
|
return _promise((resolve) => { |
||||||
|
layer.options.callback = resolve; |
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
// Export |
||||||
|
Ply.ui = ui; |
||||||
|
Ply.factory = factory; |
||||||
|
}); |
@ -0,0 +1,149 @@ |
|||||||
|
html { |
||||||
|
background-color: #ac0; |
||||||
|
} |
||||||
|
|
||||||
|
html, body { |
||||||
|
height: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
.container { |
||||||
|
margin: 0 auto; |
||||||
|
width: 80%; |
||||||
|
min-width: 600px; |
||||||
|
max-width: 1200px; |
||||||
|
} |
||||||
|
|
||||||
|
body, h1, h2 { |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
h1, h2 { |
||||||
|
color: #fff; |
||||||
|
font-family: 'Lato', sans-serif; |
||||||
|
font-weight: 300; |
||||||
|
text-shadow: 0 1px 1px rgba(0,0,0,.2); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
h1 { |
||||||
|
text-shadow: 0 1px 3px rgba(0,0,0,.2); |
||||||
|
font-size: 200px; |
||||||
|
text-align: center; |
||||||
|
margin-top: 50px; |
||||||
|
margin-bottom: 50px; |
||||||
|
} |
||||||
|
h1 u { |
||||||
|
cursor: pointer; |
||||||
|
border-bottom: 8px dotted #fff; |
||||||
|
text-decoration: none; |
||||||
|
} |
||||||
|
|
||||||
|
h2 { |
||||||
|
font-size: 30px; |
||||||
|
margin-bottom: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
.row { |
||||||
|
margin-bottom: 30px; |
||||||
|
} |
||||||
|
.row:after { |
||||||
|
clear: both; |
||||||
|
content: ''; |
||||||
|
display: block; |
||||||
|
} |
||||||
|
|
||||||
|
.col-left { |
||||||
|
float: left; |
||||||
|
width: 35%; |
||||||
|
padding: 0 20px; |
||||||
|
box-sizing: content-box; |
||||||
|
} |
||||||
|
|
||||||
|
.col-right { |
||||||
|
float: left; |
||||||
|
width: 55%; |
||||||
|
margin-left: 5%; |
||||||
|
} |
||||||
|
|
||||||
|
.example { |
||||||
|
cursor: pointer; |
||||||
|
opacity: 0.95; |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
.example:hover:after { |
||||||
|
top: 50%; |
||||||
|
left: 50%; |
||||||
|
line-height: 0; |
||||||
|
margin: -5px 0 0 -50px; |
||||||
|
color: #333; |
||||||
|
content: '►'; |
||||||
|
font-size: 100px; |
||||||
|
position: absolute; |
||||||
|
display: block; |
||||||
|
opacity: .7; |
||||||
|
} |
||||||
|
|
||||||
|
.example:hover { |
||||||
|
opacity: 1; |
||||||
|
} |
||||||
|
|
||||||
|
pre code { |
||||||
|
background-color: #fff; |
||||||
|
box-shadow: 0 1px 1px rgba(0,0,0,.3); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Tomorrow Theme */ |
||||||
|
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ |
||||||
|
/* Original theme - https://github.com/chriskempson/tomorrow-theme */ |
||||||
|
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ |
||||||
|
.tomorrow-comment, pre .comment, pre .title { |
||||||
|
color: #8e908c; |
||||||
|
} |
||||||
|
|
||||||
|
.tomorrow-red, pre .variable, pre .attribute, pre .tag, pre .regexp, pre .ruby .constant, pre .xml .tag .title, pre .xml .pi, pre .xml .doctype, pre .html .doctype, pre .css .id, pre .css .class, pre .css .pseudo { |
||||||
|
color: #c82829; |
||||||
|
} |
||||||
|
|
||||||
|
.tomorrow-orange, pre .number, pre .preprocessor, pre .built_in, pre .literal, pre .params, pre .constant { |
||||||
|
color: #f5871f; |
||||||
|
} |
||||||
|
|
||||||
|
.tomorrow-yellow, pre .class, pre .ruby .class .title, pre .css .rules .attribute { |
||||||
|
color: #eab700; |
||||||
|
} |
||||||
|
|
||||||
|
.tomorrow-green, pre .string, pre .value, pre .inheritance, pre .header, pre .ruby .symbol, pre .xml .cdata { |
||||||
|
color: #718c00; |
||||||
|
} |
||||||
|
|
||||||
|
.tomorrow-aqua, pre .css .hexcolor { |
||||||
|
color: #3e999f; |
||||||
|
} |
||||||
|
|
||||||
|
.tomorrow-blue, pre .function, pre .python .decorator, pre .python .title, pre .ruby .function .title, pre .ruby .title .keyword, pre .perl .sub, pre .javascript .title, pre .coffeescript .title { |
||||||
|
color: #4271ae; |
||||||
|
} |
||||||
|
|
||||||
|
.tomorrow-purple, pre .keyword, pre .javascript .function { |
||||||
|
color: #8959a8; |
||||||
|
} |
||||||
|
|
||||||
|
pre { |
||||||
|
border: 0; |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
pre code { |
||||||
|
display: block; |
||||||
|
color: #4d4d4c; |
||||||
|
font-size: 15px; |
||||||
|
font-family: Menlo, Monaco, Consolas, monospace; |
||||||
|
line-height: 1.5; |
||||||
|
padding: 30px; |
||||||
|
} |
@ -0,0 +1,115 @@ |
|||||||
|
(function (Ply) { |
||||||
|
module('Ply.dom'); |
||||||
|
|
||||||
|
|
||||||
|
function elementEqual(actual, expected, msg) { |
||||||
|
msg = msg || 'el'; |
||||||
|
expected.tagName = (expected.tagName || 'div').toUpperCase(); |
||||||
|
|
||||||
|
Ply.each(expected, function (value, attr) { |
||||||
|
equal(actual[attr] || actual.getAttribute(attr), value, msg + '.' + attr); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
test('build()', function () { |
||||||
|
elementEqual(Ply.dom.build(), { }); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
test('build("string")', function () { |
||||||
|
Ply.each({ |
||||||
|
'div': { }, |
||||||
|
'div#xxx': { id: 'xxx' }, |
||||||
|
'div.foo': { className: ' foo' }, |
||||||
|
'div#xxx.foo': { id: 'xxx', className: ' foo' }, |
||||||
|
'b.foo.bar': { tagName: 'B', className: ' foo bar' }, |
||||||
|
'span#xxx.foo.bar': { tagName: 'SPAN', id: 'xxx', className: ' foo bar' }, |
||||||
|
'#xxx': { id: 'xxx' }, |
||||||
|
'#xxx.foo': { id: 'xxx', className: ' foo' }, |
||||||
|
'#xxx.foo.bar': { id: 'xxx', className: ' foo bar' } |
||||||
|
}, function (data, selector) { |
||||||
|
elementEqual(Ply.dom.build(selector), data, selector); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
test('build({ })', function () { |
||||||
|
elementEqual(Ply.dom.build({ |
||||||
|
id: 'baz', |
||||||
|
tag: 'input.foo', |
||||||
|
className: 'bar', |
||||||
|
ply: 'baz', |
||||||
|
'data-prop': 'qux' |
||||||
|
}), { |
||||||
|
id: 'baz', |
||||||
|
tagName: 'INPUT', |
||||||
|
className: 'bar foo', |
||||||
|
'data-ply': 'baz', |
||||||
|
'data-prop': 'qux' |
||||||
|
}, '{}'); |
||||||
|
|
||||||
|
elementEqual(Ply.dom.build({ text: '<b>foo</b>' }), { innerHTML: '<b>foo</b>' }, 'text'); |
||||||
|
elementEqual(Ply.dom.build({ html: '<b>bar</b>' }), { innerHTML: '<b>bar</b>' }, 'html'); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
test('build(element)', function () { |
||||||
|
var el = Ply.dom.build(Ply.dom.build('b.foo')); |
||||||
|
elementEqual(el, { tagName: 'b', className: ' foo' }); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
test('build({ children: {} })', function () { |
||||||
|
var el = Ply.dom.build({ |
||||||
|
tag: 'form', |
||||||
|
children: { |
||||||
|
'input': { |
||||||
|
type: 'password' |
||||||
|
}, |
||||||
|
'hr': true, |
||||||
|
'br': false, |
||||||
|
'button': 'Enter' |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
equal(el.childNodes.length, 3); |
||||||
|
|
||||||
|
elementEqual(el, { tagName: 'form' }); |
||||||
|
elementEqual(el.childNodes[0], { tagName: 'input', type: 'password' }); |
||||||
|
elementEqual(el.childNodes[1], { tagName: 'hr' }); |
||||||
|
elementEqual(el.childNodes[2], { tagName: 'button', innerHTML: 'Enter' }); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
test('build({ children: [] })', function () { |
||||||
|
var el = Ply.dom.build({ |
||||||
|
tag: 'form', |
||||||
|
children: [ |
||||||
|
{ |
||||||
|
tag: 'input', |
||||||
|
type: 'checkbox', |
||||||
|
disabled: true |
||||||
|
}, |
||||||
|
{ tag: 'hr', skip: true }, |
||||||
|
false && { tag: bar }, |
||||||
|
{ tag: 'button', text: "Enter" } |
||||||
|
] |
||||||
|
}); |
||||||
|
|
||||||
|
equal(el.childNodes.length, 2); |
||||||
|
|
||||||
|
elementEqual(el, { tagName: 'form' }); |
||||||
|
elementEqual(el.childNodes[0], { tagName: 'input', type: 'checkbox', disabled: true }); |
||||||
|
elementEqual(el.childNodes[1], { tagName: 'button', innerHTML: 'Enter' }); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
test('build({ children: el })', function () { |
||||||
|
var el = Ply.dom.build({ |
||||||
|
children: Ply.dom.build({ tag: 'b', text: '!' }) |
||||||
|
}); |
||||||
|
|
||||||
|
elementEqual(el, { innerHTML: '<b>!</b>' }); |
||||||
|
}); |
||||||
|
})(Ply); |
@ -0,0 +1,237 @@ |
|||||||
|
(function (Ply) { |
||||||
|
module('Ply.effects'); |
||||||
|
|
||||||
|
|
||||||
|
test('core', function () { |
||||||
|
Ply.effects.defaults = { duration: 300, open: {}, close: {} }; |
||||||
|
|
||||||
|
|
||||||
|
deepEqual(Ply.effects.get(), { |
||||||
|
open: { |
||||||
|
layer: { duration: 300 }, |
||||||
|
overlay: { duration: 300 } |
||||||
|
}, |
||||||
|
close: { |
||||||
|
layer: { duration: 300 }, |
||||||
|
overlay: { duration: 300 } |
||||||
|
}, |
||||||
|
duration: 300 |
||||||
|
}, 'def'); |
||||||
|
|
||||||
|
|
||||||
|
deepEqual(Ply.effects.get(['fade-in', 'fade-out']), { |
||||||
|
open: { |
||||||
|
layer: { name: 'fade-in', duration: 300 }, |
||||||
|
overlay: { name: 'fade-in', duration: 300 } |
||||||
|
}, |
||||||
|
close: { |
||||||
|
layer: { name: 'fade-out', duration: 300 }, |
||||||
|
overlay: { name: 'fade-out', duration: 300 } |
||||||
|
}, |
||||||
|
duration: 300 |
||||||
|
}, "['fade-in', 'fade-out']"); |
||||||
|
|
||||||
|
|
||||||
|
deepEqual(Ply.effects.get(['fade-in', 'fade-out:100']), { |
||||||
|
open: { |
||||||
|
layer: { name: 'fade-in', duration: 300 }, |
||||||
|
overlay: { name: 'fade-in', duration: 300 } |
||||||
|
}, |
||||||
|
close: { |
||||||
|
layer: { name: 'fade-out', duration: 100 }, |
||||||
|
overlay: { name: 'fade-out', duration: 100 } |
||||||
|
}, |
||||||
|
duration: 300 |
||||||
|
}, "['fade-in', 'fade-out:100']"); |
||||||
|
|
||||||
|
|
||||||
|
deepEqual(Ply.effects.get('fade:100'), { |
||||||
|
open: { |
||||||
|
layer: { name: 'fade-in', duration: 100 * 0.8 }, |
||||||
|
overlay: { name: 'fade-in', duration: 100 } |
||||||
|
}, |
||||||
|
close: { |
||||||
|
layer: { name: 'fade-out', duration: 100 * 0.6 }, |
||||||
|
overlay: { name: 'fade-out', duration: 100 * 0.6 } |
||||||
|
}, |
||||||
|
duration: 100 |
||||||
|
}, 'fade:100'); |
||||||
|
|
||||||
|
|
||||||
|
deepEqual(Ply.effects.get({ |
||||||
|
open: 'slide-in', |
||||||
|
close: 'slide-out' |
||||||
|
}), { |
||||||
|
open: { |
||||||
|
layer: { name: 'slide-in', duration: 300 }, |
||||||
|
overlay: { duration: 300 } |
||||||
|
}, |
||||||
|
close: { |
||||||
|
layer: { name: 'slide-out', duration: 300 }, |
||||||
|
overlay: { duration: 300 } |
||||||
|
}, |
||||||
|
duration: 300 |
||||||
|
}, 'slide-in-out'); |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Ply.effects.setup({ open: 'fade-in' }); |
||||||
|
|
||||||
|
|
||||||
|
deepEqual(Ply.effects.get(), { |
||||||
|
open: { |
||||||
|
layer: { name: 'fade-in', duration: 300 }, |
||||||
|
overlay: { duration: 300 } |
||||||
|
}, |
||||||
|
close: { |
||||||
|
layer: { duration: 300 }, |
||||||
|
overlay: { duration: 300 } |
||||||
|
}, |
||||||
|
duration: 300 |
||||||
|
}, 'open.fade-in'); |
||||||
|
|
||||||
|
|
||||||
|
Ply.effects.setup({ open: { overlay: 'fade-in' } }); |
||||||
|
|
||||||
|
|
||||||
|
deepEqual(Ply.effects.get({ |
||||||
|
open: 'slide-in', |
||||||
|
close: 'slide-out' |
||||||
|
}), { |
||||||
|
open: { |
||||||
|
layer: { name: 'slide-in', duration: 300 }, |
||||||
|
overlay: { name: 'fade-in', duration: 300 } |
||||||
|
}, |
||||||
|
close: { |
||||||
|
layer: { name: 'slide-out', duration: 300 }, |
||||||
|
overlay: { duration: 300 } |
||||||
|
}, |
||||||
|
duration: 300 |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
Ply.effects.setup('fade:400'); |
||||||
|
|
||||||
|
|
||||||
|
deepEqual(Ply.effects.get({ |
||||||
|
open: 'slide-in', |
||||||
|
close: 'slide-out' |
||||||
|
}), { |
||||||
|
open: { |
||||||
|
layer: { name: 'slide-in', duration: 400 }, |
||||||
|
overlay: { name: 'fade-in', duration: 400 } |
||||||
|
}, |
||||||
|
close: { |
||||||
|
layer: { name: 'slide-out', duration: 400 }, |
||||||
|
overlay: { name: 'fade-out', duration: 400 * 0.6 } |
||||||
|
}, |
||||||
|
duration: 400 |
||||||
|
}, 'fade:400'); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
test('effects:args', function () { |
||||||
|
Ply.effects.defaults = { duration: 300, open: {}, close: {} }; |
||||||
|
|
||||||
|
deepEqual(Ply.effects.get('scale[0.5,0.3]'), { |
||||||
|
open: { |
||||||
|
args: 0.5, |
||||||
|
layer: { name: 'scale-in', duration: 300 }, |
||||||
|
overlay: { name: 'fade-in', duration: 300 } |
||||||
|
}, |
||||||
|
close: { |
||||||
|
args: 0.3, |
||||||
|
layer: { name: 'scale-out', duration: 300 }, |
||||||
|
overlay: { name: 'fade-out', duration: 300 } |
||||||
|
}, |
||||||
|
duration: 300 |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
deepEqual(Ply.effects.get(['scale["foo"]', 'fall[{"bar":"baz"}]']), { |
||||||
|
open: { |
||||||
|
args: 'foo', |
||||||
|
layer: { name: 'scale-in', duration: 300 }, |
||||||
|
overlay: { name: 'fade-in', duration: 300 } |
||||||
|
}, |
||||||
|
close: { |
||||||
|
args: {bar:'baz'}, |
||||||
|
layer: { name: 'fall-out', duration: 300 }, |
||||||
|
overlay: { name: 'fade-out', duration: 300 } |
||||||
|
}, |
||||||
|
duration: 300 |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
test('stress', function () { |
||||||
|
try { |
||||||
|
Ply.effects.get(null); |
||||||
|
Ply.effects.get(void 0); |
||||||
|
Ply.effects.get(Math.random()); |
||||||
|
Ply.effects.get('---'); |
||||||
|
Ply.effects.get(123); |
||||||
|
Ply.effects.get('\n'); |
||||||
|
Ply.effects.get([null, null]); |
||||||
|
Ply.effects.get([void 0, void 0]); |
||||||
|
Ply.effects.get(['\n', '\t']); |
||||||
|
ok(true); |
||||||
|
} catch (err) { |
||||||
|
equal([err, err.stack], null); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
promiseTest('fade', function () { |
||||||
|
var log = { open: [], close: [] }, |
||||||
|
type = 'open', |
||||||
|
pid, i, |
||||||
|
layer = new Ply({ effect: 'fade' }) |
||||||
|
; |
||||||
|
|
||||||
|
pid = setInterval(function () { |
||||||
|
log[type].push( parseFloat(Ply.css(layer.overlayEl, 'opacity')) ); |
||||||
|
}, 50); |
||||||
|
|
||||||
|
return layer.open().then(function () { |
||||||
|
type = 'close'; |
||||||
|
return layer.close(); |
||||||
|
}).then(function () { |
||||||
|
ok(log.open.length > 2, 'open'); |
||||||
|
ok(log.close.length > 2, 'close'); |
||||||
|
|
||||||
|
for (i = 1; i < log.open.length; i++) { |
||||||
|
if (log.open[i] < log.open[i-1]) { |
||||||
|
equal(log.open, null, 'open: ' + i); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
for (i = 1; i < log.close.length; i++) { |
||||||
|
if (log.close[i] > log.close[i-1]) { |
||||||
|
equal(log.close, null, 'close: ' + i); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
clearInterval(pid); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
promiseTest('other', function () { |
||||||
|
expect(0); |
||||||
|
|
||||||
|
var queue = Ply.promise(function (resolve) { resolve() }); |
||||||
|
|
||||||
|
Ply.each('scale fall slide 3d-flip 3d-sign'.split(' '), function (name) { |
||||||
|
queue = queue.then(function () { |
||||||
|
return new Ply({ effect: name + ':50' }).open().then(function (layer) { |
||||||
|
return layer.close(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
return queue; |
||||||
|
}); |
||||||
|
})(Ply); |
@ -0,0 +1,250 @@ |
|||||||
|
(function () { |
||||||
|
module('Ply'); |
||||||
|
|
||||||
|
var layer; |
||||||
|
|
||||||
|
test('core', function () { |
||||||
|
equal(typeof Ply, 'function'); |
||||||
|
ok(new Ply instanceof Ply); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
function sleep(fn, ms) { |
||||||
|
return Ply.promise(function (resolve) { |
||||||
|
setTimeout(function () { |
||||||
|
fn(); |
||||||
|
resolve(); |
||||||
|
}, ms); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
function checkVisiblity(layer, state, msg) { |
||||||
|
equal(!!layer.visible, state, '[' + msg + '] visible: ' + state); |
||||||
|
equal(!!layer.wrapEl.parentNode, state, msg + ' -> parentNode is ' + (state ? '' : 'not') + 'exists'); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
test('options', function () { |
||||||
|
layer = new Ply(); |
||||||
|
|
||||||
|
for (var key in Ply.defaults.overlay) { |
||||||
|
equal(layer.overlayEl.style[key], Ply.defaults.overlay[key], key); |
||||||
|
} |
||||||
|
equal(layer.bodyEl, document.body, 'body'); |
||||||
|
|
||||||
|
// Body
|
||||||
|
layer = new Ply({ body: '#playground' }); |
||||||
|
equal(layer.bodyEl, playground, '#playground'); |
||||||
|
|
||||||
|
// Overlay 1
|
||||||
|
layer = new Ply({ overlay: { opacity: 1 } }); |
||||||
|
equal(layer.overlayEl.style.opacity, 1, 'opacity: 1'); |
||||||
|
equal(layer.overlayEl.style.backgroundColor, "", 'backgroundColor: ""'); |
||||||
|
|
||||||
|
// Overlay 2
|
||||||
|
layer = new Ply({ overlay: { opacity: 1, backgroundColor: 'rgb(255, 0, 0)' } }); |
||||||
|
equal(layer.overlayEl.style.opacity, 1, 'opacity: 1'); |
||||||
|
equal(layer.overlayEl.style.backgroundColor, 'rgb(255, 0, 0)', 'backgroundColor: red'); |
||||||
|
|
||||||
|
// Overlay 3
|
||||||
|
layer = new Ply({ overlay: null }); |
||||||
|
notEqual(layer.overlayEl.style.position, 'fixed', 'overlay: null'); |
||||||
|
|
||||||
|
// Layer
|
||||||
|
layer = new Ply({ layer: { textAlign: 'center' } }); |
||||||
|
equal(layer.contentEl.style.textAlign, 'center', 'textAlign: center'); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
test('flags', function () { |
||||||
|
layer = new Ply(); |
||||||
|
for (var key in Ply.defaults.flags) { |
||||||
|
equal(layer.options.flags[key], Ply.defaults.flags[key], key); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
layer = new Ply({ flags: { bodyScroll: true } }); |
||||||
|
for (var key in Ply.defaults.flags) { |
||||||
|
equal(layer.options.flags[key], key == 'bodyScroll' ? true : Ply.defaults.flags[key], key); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
test('content', function () { |
||||||
|
var content = document.createElement('b'); |
||||||
|
content.innerHTML = '!'; |
||||||
|
|
||||||
|
equal(new Ply().contentEl.innerHTML, ''); |
||||||
|
equal(new Ply({ el: 'Wow!' }).contentEl.innerHTML, 'Wow!'); |
||||||
|
equal(new Ply({ el: content }).layerEl.innerHTML, '<b>!</b>'); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
promiseTest('open/close', function () { |
||||||
|
layer = new Ply({ el: 'Wow!' }); |
||||||
|
|
||||||
|
ok(!layer.wrapEl.parentNode, '!parent - open'); |
||||||
|
ok(!layer.visible, 'visible: false'); |
||||||
|
|
||||||
|
return layer.open().then(function () { |
||||||
|
var ratio = layer.wrapEl.offsetHeight / (layer.layerEl.offsetTop + layer.layerEl.offsetHeight/2); |
||||||
|
|
||||||
|
ok(layer.visible, 'visible: true'); |
||||||
|
ok(layer.wrapEl.offsetWidth > 0, 'offsetWidth > 0'); |
||||||
|
ok(Math.abs(2 - ratio) < 0.1, ratio, 'delat(' + ratio + ') < 0.1'); |
||||||
|
|
||||||
|
layer.close().then(function () { |
||||||
|
ok(!layer.visible, 'visible: false - close'); |
||||||
|
ok(!layer.wrapEl.parentNode, '!parent - close'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
promiseTest('closeByEsc', function () { |
||||||
|
function open(msg, esc) { |
||||||
|
var layer = new Ply({ flags: { closeByEsc: esc }, effect: { duration: 1 } }); |
||||||
|
|
||||||
|
checkVisiblity(layer, false, msg); |
||||||
|
|
||||||
|
return layer.open().then(function () { |
||||||
|
checkVisiblity(layer, true, msg); |
||||||
|
return layer; |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
return open('1. esc: true', true).then(function (escTrue) { |
||||||
|
return open('2. esc: false', false).then(function (escFalse) { |
||||||
|
simulateEvent(document, 'keyup', { keyCode: Ply.keys.esc }); |
||||||
|
|
||||||
|
checkVisiblity(escTrue, true, '3. esc: true'); |
||||||
|
checkVisiblity(escFalse, true, '4. esc: false'); |
||||||
|
|
||||||
|
return escFalse.close().then(function () { |
||||||
|
checkVisiblity(escTrue, true, '5. esc: true'); |
||||||
|
checkVisiblity(escFalse, false, '6. esc: false'); |
||||||
|
|
||||||
|
simulateEvent(document, 'keyup', { keyCode: Ply.keys.esc }); |
||||||
|
|
||||||
|
return sleep(function () { |
||||||
|
checkVisiblity(escTrue, false, '7. esc: true'); |
||||||
|
checkVisiblity(escFalse, false, '8. esc: false'); |
||||||
|
}, 50); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
promiseTest('closeByOverlay', function () { |
||||||
|
function test(msg, state, callback) { |
||||||
|
var layer = new Ply({ flags: { closeByOverlay: state }, effect: { duration: 1 } }); |
||||||
|
return layer.open().then(function () { |
||||||
|
checkVisiblity(layer, true, msg); |
||||||
|
simulateEvent(layer.overlayEl, 'click'); |
||||||
|
|
||||||
|
return sleep(function () { |
||||||
|
callback(layer, msg); |
||||||
|
}, 50); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
return test('closeByOverlay: true', true, function (layer, msg) { |
||||||
|
checkVisiblity(layer, false, msg); |
||||||
|
|
||||||
|
return test('closeByOverlay: false', false, function (layer, msg) { |
||||||
|
checkVisiblity(layer, true, msg); |
||||||
|
return layer.close(); |
||||||
|
}); |
||||||
|
}) |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
promiseTest('swap', function () { |
||||||
|
return new Ply({ el: 1, effect: 'none:1' }).open().then(function (layer) { |
||||||
|
return layer.swap({ el: 2 }).then(function () { |
||||||
|
equal(layer.contentEl.innerHTML, 2); |
||||||
|
|
||||||
|
return layer.close().then(function () { |
||||||
|
return layer.swap({ el: 3 }, 'none:2').then(function () { |
||||||
|
equal(layer.contentEl.innerHTML, 3); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
promiseTest('destory', function () { |
||||||
|
return new Ply({ effect: 'none:1' }).open().then(function (layer) { |
||||||
|
checkVisiblity(layer, true, '#1'); |
||||||
|
|
||||||
|
layer.destroy(); |
||||||
|
|
||||||
|
checkVisiblity(layer, false, '#2'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
promiseTest('on/off', function () { |
||||||
|
var log = [], |
||||||
|
logMe = function (prefix, evt, el) { |
||||||
|
log.push(prefix + ':' + el.tagName + '.' + evt.type + '->' + el.getAttribute('data-ply')); |
||||||
|
}, |
||||||
|
barHandle = function (evt, el) { |
||||||
|
log.pop(); |
||||||
|
logMe('bar', evt, el); |
||||||
|
} |
||||||
|
; |
||||||
|
|
||||||
|
return new Ply({ el: '<i data-ply="foo"><em>foo</em></i><b data-ply="bar"><em>bar</em></b>' }).open().then(function (layer) { |
||||||
|
layer.on('click', function (evt, el) { |
||||||
|
logMe('layer', evt, el); |
||||||
|
}); |
||||||
|
|
||||||
|
layer.on('click', 'foo', function (evt, el) { |
||||||
|
logMe('foo', evt, el); |
||||||
|
}); |
||||||
|
|
||||||
|
layer.on('click', 'bar', barHandle); |
||||||
|
|
||||||
|
simulateEvent(layer.contentEl.getElementsByTagName('em')[0], 'click'); |
||||||
|
simulateEvent(layer.contentEl.getElementsByTagName('em')[1], 'click'); |
||||||
|
|
||||||
|
layer.off('click', barHandle); |
||||||
|
|
||||||
|
simulateEvent(layer.contentEl.getElementsByTagName('em')[1], 'click'); |
||||||
|
|
||||||
|
layer.off('click', 'bar', barHandle); |
||||||
|
|
||||||
|
simulateEvent(layer.contentEl.getElementsByTagName('em')[1], 'click'); |
||||||
|
|
||||||
|
equal(log.join('\n'), [ |
||||||
|
'layer:DIV.click->layer', |
||||||
|
'foo:I.click->foo', |
||||||
|
'bar:B.click->bar', |
||||||
|
'bar:B.click->bar', |
||||||
|
'layer:DIV.click->layer' |
||||||
|
].join('\n')); |
||||||
|
|
||||||
|
return layer.close(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
// if (/state=2/.test(location)) {
|
||||||
|
// promiseTest('Promise', function () {
|
||||||
|
// expect(0);
|
||||||
|
//
|
||||||
|
// return Ply.promise(function (resolve) {
|
||||||
|
// window.resolveTest = function () {
|
||||||
|
// resolve();
|
||||||
|
// };
|
||||||
|
// document.write('<iframe src="?state=2"></iframe>');
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
})(); |
@ -0,0 +1,131 @@ |
|||||||
|
(function (Ply) { |
||||||
|
module('Ply.ui'); |
||||||
|
|
||||||
|
|
||||||
|
promiseTest('dialog("unknown")', function () { |
||||||
|
setTimeout(function () { |
||||||
|
simulateEvent(Ply.stack.last.overlayEl, 'click'); |
||||||
|
}, 50); |
||||||
|
|
||||||
|
return Ply.dialog('unknown').then(function (ui) { |
||||||
|
equal(ui.by, 'overlay', 'ui.by'); |
||||||
|
equal(ui.state, false, 'ui.state'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
promiseTest('dialog("alert")', function () { |
||||||
|
setTimeout(function () { |
||||||
|
var el = Ply.stack.last.wrapEl; |
||||||
|
simulateEvent(el.getElementsByTagName('button')[0], 'click'); |
||||||
|
}, 50); |
||||||
|
|
||||||
|
return Ply.dialog('alert', { effect: 'none:1' }, 'msg').then(function (ui) { |
||||||
|
equal(ui.by, 'submit', 'ui.by'); |
||||||
|
equal(ui.state, true, 'ui.state'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
promiseTest('dialog("confirm")', function () { |
||||||
|
setTimeout(function () { |
||||||
|
var el = Ply.stack.last.wrapEl; |
||||||
|
simulateEvent(el.getElementsByTagName('button')[1], 'click'); |
||||||
|
}, 50); |
||||||
|
|
||||||
|
return Ply.dialog('confirm', { effect: 'none:1' }, { |
||||||
|
title: "???", |
||||||
|
text: "!!!" |
||||||
|
}).then(function (ui) { |
||||||
|
equal(ui.by, 'cancel', 'ui.by'); |
||||||
|
equal(ui.state, false, 'ui.state'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
promiseTest('dialog("prompt")', function () { |
||||||
|
setTimeout(function () { |
||||||
|
var el = Ply.stack.last.wrapEl; |
||||||
|
Ply.stack.last.context.val('email', 'xx@yy.zz'); |
||||||
|
simulateEvent(el.getElementsByTagName('button')[0], 'click'); |
||||||
|
}, 50); |
||||||
|
|
||||||
|
return Ply.dialog('prompt', { effect: 'none:1' }, { |
||||||
|
title: "???", |
||||||
|
form: { email: "E-mail" } |
||||||
|
}).then(function (ui) { |
||||||
|
equal(ui.by, 'submit', 'ui.by'); |
||||||
|
equal(ui.state, true, 'ui.state'); |
||||||
|
equal(ui.context.val('email'), 'xx@yy.zz'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
promiseTest('dialog("confirm") with YES/NO', function () { |
||||||
|
setTimeout(function () { |
||||||
|
var el = Ply.stack.last.wrapEl; |
||||||
|
simulateEvent(el.getElementsByTagName('button')[0], 'click'); |
||||||
|
}, 50); |
||||||
|
|
||||||
|
return Ply.dialog("confirm", { effect: 'none:1' }, { ok: 'YES', cancel: 'NO' }).then(function (ui) { |
||||||
|
equal(ui.layer.layerEl.getElementsByTagName('button')[0].innerHTML, 'YES', 'ok'); |
||||||
|
equal(ui.layer.layerEl.getElementsByTagName('button')[1].innerHTML, 'NO', 'cancel'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
promiseTest('dialog({ steps })', function () { |
||||||
|
var log = []; |
||||||
|
|
||||||
|
return Ply.dialog({ |
||||||
|
'foo': { |
||||||
|
data: { text: 'foo' }, |
||||||
|
options: { effect: 'none:1' }, |
||||||
|
prepare: function (data) { |
||||||
|
data.text += '!'; |
||||||
|
}, |
||||||
|
next: 'baz' |
||||||
|
}, |
||||||
|
'bar': { |
||||||
|
data: { text: 'bar' } |
||||||
|
}, |
||||||
|
'baz': { |
||||||
|
ui: 'confirm', |
||||||
|
data: { text: 'baz' }, |
||||||
|
back: 'bar' |
||||||
|
} |
||||||
|
}, { |
||||||
|
progress: function (ui) { |
||||||
|
log.push(ui.name + ':' + ui.state); |
||||||
|
|
||||||
|
setTimeout(function () { |
||||||
|
simulateEvent( |
||||||
|
ui.layer.layerEl.getElementsByTagName('button')[1] |
||||||
|
|| ui.layer.layerEl.getElementsByTagName('button')[0], |
||||||
|
'click'); |
||||||
|
}, 10); |
||||||
|
} |
||||||
|
}).then(function () { |
||||||
|
equal(log.join('\n'), [ |
||||||
|
'foo:undefined', |
||||||
|
'baz:true', |
||||||
|
'bar:false' |
||||||
|
].join('\n')); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
promiseTest('factory.use()', function () { |
||||||
|
Ply.factory('test', function (options, data, resolve) { |
||||||
|
Ply.factory.use('alert', options, { |
||||||
|
text: '!?', |
||||||
|
ok: 'Y' |
||||||
|
}, resolve); |
||||||
|
}); |
||||||
|
|
||||||
|
return Ply.create("test").then(function (layer) { |
||||||
|
equal(layer.context.getEl('el').innerHTML, '!?'); |
||||||
|
equal(layer.layerEl.getElementsByTagName('button')[0].innerHTML, 'Y'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
})(Ply); |
@ -0,0 +1,133 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html xmlns="http://www.w3.org/1999/html"> |
||||||
|
<head> |
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> |
||||||
|
|
||||||
|
<title>Ply :: Tests</title> |
||||||
|
|
||||||
|
<!--script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> |
||||||
|
<script src="http://code.jquery.com/qunit/qunit-git.js"></script> |
||||||
|
<link href="http://code.jquery.com/qunit/qunit-git.css" rel="stylesheet"/--> |
||||||
|
|
||||||
|
<script> |
||||||
|
if (!window.jQuery) { |
||||||
|
document.write('<script src="http://local.git/js/jquery.dev.js"><' + '/script>'); |
||||||
|
document.write('<script src="http://local.git/js/qunit/qunit.js"><' + '/script>'); |
||||||
|
document.write('<link href="http://local.git/js/qunit/qunit.css" rel="stylesheet"/>'); |
||||||
|
} |
||||||
|
|
||||||
|
if (/state=2/.test(location)) { |
||||||
|
// document.write('<script src="http://local.git/JSSDK/Promise/Promise.js"><' + '/script>'); |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<script> |
||||||
|
(function () { |
||||||
|
var defaultOptions = { |
||||||
|
x: 0, |
||||||
|
y: 0, |
||||||
|
button: 0, |
||||||
|
ctrlKey: false, |
||||||
|
altKey: false, |
||||||
|
shiftKey: false, |
||||||
|
metaKey: false, |
||||||
|
bubbles: true, |
||||||
|
cancelable: true |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
var eventMatchers = { |
||||||
|
'HTMLEvents': /^(?:load|unload|abort|error|select|change|submit|reset|focus|input|keydown|keyup|blur|resize|scroll)$/, |
||||||
|
'MouseEvents': /^(?:click|dblclick|mouse(?:down|up|over|move|out))$/ |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
window.isPhantomJS = /phantomjs/i.test(navigator.userAgent); |
||||||
|
|
||||||
|
window.simulateEvent = function (element, eventName, opts) { |
||||||
|
var options = $.extend({}, defaultOptions, opts || {}); |
||||||
|
var oEvent, eventType = null; |
||||||
|
|
||||||
|
for (var name in eventMatchers) { |
||||||
|
if (eventMatchers[name].test(eventName)) { |
||||||
|
eventType = name; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!eventType) { |
||||||
|
throw new SyntaxError('Only HTMLEvents and MouseEvents interfaces are supported'); |
||||||
|
} |
||||||
|
|
||||||
|
if (document.createEvent) { |
||||||
|
oEvent = document.createEvent(eventType); |
||||||
|
if (eventType == 'HTMLEvents') { |
||||||
|
oEvent.initEvent(eventName, options.bubbles, options.cancelable); |
||||||
|
} |
||||||
|
else { |
||||||
|
oEvent.initMouseEvent(eventName, options.bubbles, options.cancelable, window, |
||||||
|
options.button, options.x, options.y, options.x, options.y, |
||||||
|
options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, element); |
||||||
|
} |
||||||
|
$.extend(oEvent, options); |
||||||
|
element.dispatchEvent(oEvent); |
||||||
|
} |
||||||
|
else { |
||||||
|
options.clientX = options.x; |
||||||
|
options.clientY = options.y; |
||||||
|
var evt = document.createEventObject(); |
||||||
|
oEvent = $.extend(evt, options); |
||||||
|
element.fireEvent('on' + eventName, oEvent); |
||||||
|
} |
||||||
|
return element; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
window.promiseTest = function (name, promise) { |
||||||
|
asyncTest(name, function () { |
||||||
|
promise().then(function () { |
||||||
|
start(); |
||||||
|
}, function (err) { |
||||||
|
equal([err, err.stack], null, 'fail'); |
||||||
|
start(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
||||||
|
})(); |
||||||
|
</script> |
||||||
|
|
||||||
|
</head> |
||||||
|
</body> |
||||||
|
|
||||||
|
<h1 id="qunit-header">Ply :: tests</h1> |
||||||
|
<h2 id="qunit-banner"></h2> |
||||||
|
<div id="qunit-testrunner-toolbar"></div> |
||||||
|
<h2 id="qunit-userAgent"></h2> |
||||||
|
<ol id="qunit-tests"></ol> |
||||||
|
<div id="playground"></div> |
||||||
|
|
||||||
|
|
||||||
|
<!-- lib:css --> |
||||||
|
<link href="../ply.css" rel="stylesheet"/> |
||||||
|
|
||||||
|
<!-- lib:src --> |
||||||
|
<script src="../Ply.js"></script> |
||||||
|
<script src="../Ply.ui.js"></script> |
||||||
|
|
||||||
|
<!-- lib:tests --> |
||||||
|
<script src="./Ply.tests.js"></script> |
||||||
|
<script src="./Ply.dom.tests.js"></script> |
||||||
|
<script src="./Ply.effects.tests.js"></script> |
||||||
|
<script src="./Ply.ui.tests.js"></script> |
||||||
|
|
||||||
|
<script> |
||||||
|
if (parent.resolveTest) { |
||||||
|
test('end', function () { |
||||||
|
expect(0); |
||||||
|
parent.resolveTest(); |
||||||
|
}); |
||||||
|
} |
||||||
|
</script> |
||||||
|
</body> |
||||||
|
</html> |
Loading…
Reference in new issue