Browse Source

#1: IE8 support

modules
RubaXa 10 years ago
parent
commit
f104a49a16
  1. 49
      index.html
  2. 2
      ply.css
  3. 29
      src/Ply.es6
  4. 4
      src/Ply.ui.es6
  5. 15
      tests/Ply.dom.tests.js
  6. 32
      tests/Ply.effects.tests.js
  7. 13
      tests/Ply.stack.tests.js
  8. 73
      tests/Ply.tests.js
  9. 14
      tests/Ply.ui.tests.js
  10. 16
      tests/index.html

49
index.html

@ -97,6 +97,10 @@
<div style="height: 100px"></div>
<script>
// Polyfills
![].forEach && document.writeln('<script src="//cdnjs.cloudflare.com/ajax/libs/es5-shim/3.4.0/es5-shim.min.js"><' + '/script>')
</script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.0/highlight.min.js"></script>
@ -119,17 +123,24 @@
var $el = $(this);
var $code = $el.closest('.row').find('code');
var code = $code.text().split('\n');
var offset = code[1].match(/^\s+/)[0].length;
var offset = ((code[1] || code[0]).match(/^[\s\t]+/) || [''])[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);
code = code.slice(+(code.length > 1)).join('\n');
hljs.highlightBlock($code.wrap('<pre/>').parent().addClass('javascript')[0])
$el.data('code', code);
var $codeEl = $('<pre class="javascript"/>')
.insertBefore($code)
.append('<code>' + code + '</code>')
;
$code.remove();
try {
hljs.highlightBlock($codeEl[0]);
} catch (err) {}
})
.on('click', function () {
Function($(this).data('code'))();
@ -243,21 +254,23 @@
(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);
if (canvas.getContext) {
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") + ")";
el.style.backgroundColor = color;
el.style.backgroundImage = "url(" + canvas.toDataURL("image/png") + ")";
}
}
// Usage

2
ply.css

@ -123,6 +123,7 @@
border-radius: 3px;
font-size: 18px;
}
.ply-ok {
width: 100px;
}
@ -133,6 +134,7 @@
.ply-ok:focus,
.ply-cancel:focus {
box-shadow: 0 0 1px 2px rgba(255, 180, 0, .6);
border: 2px solid rgb(255, 210, 102)\9;
}
.ply-ok::-moz-focus-inner,

29
src/Ply.es6

@ -403,7 +403,9 @@
_css(el, spec.css);
}
else if (name === 'text') {
(value != null) && _appendChild(el, document.createTextNode(value));
try {
(value != null) && _appendChild(el, document.createTextNode(value));
} catch (e) {}
}
else if (name === 'html') {
(value != null) && (el.innerHTML = value);
@ -413,7 +415,11 @@
el.setAttribute(_plyAttr, value);
}
else if (name in el) {
el[name] = value;
try {
el[name] = value;
} catch (e) {
el.setAttribute(name, value);
}
}
else if (/^data-/.test(name)) {
el.setAttribute(name, value);
@ -629,7 +635,10 @@
*/
function _createPly(target, options, onlyLayer) {
// Корневой слой
target.wrapEl = _buildDOM({ css: { whiteSpace: 'nowrap', zIndex: options.zIndex } });
target.wrapEl = _buildDOM({
tag: 'form',
css: { whiteSpace: 'nowrap', zIndex: options.zIndex }
});
// Затемнение
@ -679,7 +688,6 @@
outline: 0
});
return target;
}
@ -793,7 +801,7 @@
// Подписываемся кнопку «отмена» и «крестик»
_this.on('click', ':close', (evt, el) => {
evt.preventDefault();
_this.closeBy(el.nodeName === 'BUTTON' ? 'cancel' : 'x');
_this.closeBy(el.type === 'reset' ? 'cancel' : 'x');
});
@ -885,6 +893,8 @@
* @returns {Promise}
*/
applyEffect: function (el, name, effects) {
el = this[el] || el;
if (!el.nodeType) {
effects = name;
name = el;
@ -892,7 +902,7 @@
}
effects = Ply.effects.get(effects || this.effects);
return Ply.effects.apply.call(effects, this[el] || el, name);
return Ply.effects.apply.call(effects, el, name);
},
@ -1172,8 +1182,10 @@
destroy: function () {
_removeElement(this.wrapEl);
this.visible = false;
this._deactivate();
Ply.stack.remove(this);
this.visible = false;
this.options.destroy(this);
}
};
@ -1236,7 +1248,7 @@
var idx = this._idx[layer.cid];
if (idx >= 0) {
array_splice.call(this, idx);
array_splice.call(this, idx, 1);
delete this._idx[layer.cid];
this.last = this[this.length-1];
@ -1652,6 +1664,7 @@
Ply.each = _each;
Ply.extend = _extend;
Ply.promise = _promise;
Ply.support = support;
Ply.defaults = _defaults;
Ply.attrName = _plyAttr;
Ply.Context = Context;

4
src/Ply.ui.es6

@ -70,7 +70,7 @@
* @param {Boolean} [simpleMode]
*/
ui.factory = function (name, renderer, simpleMode) {
ui[name.trim().replace(/\s+/g, ' ')] = function (data, path) {
ui[name.replace(/^\s+|\s+$/g, '').replace(/\s+/g, ' ')] = function (data, path) {
var fragment = document.createDocumentFragment();
if ((data != null) || name === ':root') {
@ -112,7 +112,7 @@
// Ply-слой - корневой элемент
ui.factory(':root', function (data) {
return {
tag: 'form.ply-form',
tag: '.ply-form',
className: data.mod,
children: [
ui(':header', data.header),

15
tests/Ply.dom.tests.js

@ -7,13 +7,18 @@
expected.tagName = (expected.tagName || 'div').toUpperCase();
Ply.each(expected, function (value, attr) {
equal(actual[attr] || actual.getAttribute(attr), value, msg + '.' + attr);
var attrVal = actual[attr] || actual.getAttribute(attr);
if (attr === 'innerHTML') {
attrVal = attrVal.toLowerCase();
}
equal(attrVal, value, msg + '.' + attr);
});
}
test('build()', function () {
elementEqual(Ply.dom.build(), { });
ok(!Ply.dom.build().parentNode, 'parent');
});
@ -69,7 +74,7 @@
},
'hr': true,
'br': false,
'button': 'Enter'
'button': 'enter'
}
});
@ -78,7 +83,7 @@
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' });
elementEqual(el.childNodes[2], { tagName: 'button', innerHTML: 'enter' });
});
@ -93,7 +98,7 @@
},
{ tag: 'hr', skip: true },
false && { tag: bar },
{ tag: 'button', text: "Enter" }
{ tag: 'button', text: "enter" }
]
});
@ -101,7 +106,7 @@
elementEqual(el, { tagName: 'form' });
elementEqual(el.childNodes[0], { tagName: 'input', type: 'checkbox', disabled: true });
elementEqual(el.childNodes[1], { tagName: 'button', innerHTML: 'Enter' });
elementEqual(el.childNodes[1], { tagName: 'button', innerHTML: 'enter' });
});

32
tests/Ply.effects.tests.js

@ -186,7 +186,7 @@
var log = { open: [], close: [] },
type = 'open',
pid, i,
layer = new Ply({ effect: 'fade' })
layer = new Ply('fade', { effect: 'fade' })
;
pid = setInterval(function () {
@ -195,22 +195,26 @@
return layer.open().then(function () {
type = 'close';
ok(layer.layerEl.offsetHeight > 0, '> 0');
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;
ok(layer.layerEl.offsetHeight == 0, '== 0');
if (Ply.support.transition) {
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;
for (i = 1; i < log.close.length; i++) {
if (log.close[i] > log.close[i-1]) {
equal(log.close, null, 'close: ' + i);
break;
}
}
}
@ -226,7 +230,7 @@
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 new Ply(name, { effect: name + ':50' }).open().then(function (layer) {
return layer.close();
});
});

13
tests/Ply.stack.tests.js

@ -1,15 +1,20 @@
(function (Ply) {
module('Ply.stack');
function hasParent(el) {
return !!(el && el.parentNode && el.parentNode.nodeType !== 11);
}
asyncTest('2x', function () {
new Ply('foo', { effect: 'slide' }).open().then(function (foo) {
new Ply('bar', { effect: 'fall' }).open().then(function (bar) {
ok(!foo.layerEl.parentNode, 'foo.parent == null');
ok(!bar.overlayBoxEl.parentNode, 'bar.parent == null');
ok(!hasParent(foo.layerEl), 'foo.parent == null');
ok(!hasParent(bar.overlayBoxEl), 'bar.parent == null');
Ply.stack.last.close().then(function () {
ok(!!foo.layerEl.parentNode, 'foo.parent != null');
ok(!!bar.overlayBoxEl.parentNode, 'bar.parent != null');
ok(hasParent(foo.layerEl), 'foo.parent != null');
ok(hasParent(bar.overlayBoxEl), 'bar.parent != null');
Ply.stack.last.close().then(function () {
start();

73
tests/Ply.tests.js

@ -3,6 +3,12 @@
var layer;
function hasParent(el) {
return !!(el && el.parentNode && el.parentNode.nodeType !== 11);
}
test('core', function () {
equal(typeof Ply, 'function');
ok(new Ply instanceof Ply);
@ -21,7 +27,7 @@
function checkVisiblity(layer, state, msg) {
equal(!!layer.visible, state, '[' + msg + '] visible: ' + state);
equal(!!layer.wrapEl.parentNode, state, msg + ' -> parentNode is ' + (state ? '' : 'not') + 'exists');
equal(hasParent(layer.wrapEl.parentNode), state, msg + ' -> parentNode is ' + (state ? '' : 'not ') + 'exists');
}
@ -29,7 +35,9 @@
layer = new Ply();
for (var key in Ply.defaults.overlay) {
equal(layer.overlayBoxEl.style[key], Ply.defaults.overlay[key], key);
var val = layer.overlayBoxEl.style[key] + '';
val = val.replace(/,\s*/g, ', ');
equal(val, Ply.defaults.overlay[key], key);
}
equal(layer.bodyEl, document.body, 'body');
@ -45,7 +53,7 @@
// Overlay 2
layer = new Ply({ overlay: { opacity: 1, backgroundColor: 'rgb(255, 0, 0)' } });
equal(layer.overlayBoxEl.style.opacity, 1, 'opacity: 1');
equal(layer.overlayBoxEl.style.backgroundColor, 'rgb(255, 0, 0)', 'backgroundColor: red');
equal(layer.overlayBoxEl.style.backgroundColor.replace(/,\s*/g, ', '), 'rgb(255, 0, 0)', 'backgroundColor: red');
// Overlay 3
layer = new Ply({ overlay: null });
@ -75,31 +83,32 @@
var content = document.createElement('b');
content.innerHTML = '<b>!</b>';
equal(new Ply('').contentEl.innerHTML, '', 'conentEl');
equal(new Ply('Wow!').contentEl.innerHTML, 'Wow!', 'contentEl');
equal(new Ply(content).contentEl.innerHTML, '<b>!</b>');
equalHtml(new Ply('').contentEl.innerHTML, '', 'conentEl');
equalHtml(new Ply('Wow!').contentEl.innerHTML, 'Wow!', 'contentEl');
equalHtml(new Ply(content).contentEl.innerHTML, '<b>!</b>');
equal(new Ply({ el: 'Wow!' }).contentEl.innerHTML, 'Wow!', 'contentEl');
equal(new Ply({ el: content }).contentEl.innerHTML, '<b>!</b>');
equalHtml(new Ply({ el: 'Wow!' }).contentEl.innerHTML, 'Wow!', 'contentEl');
equalHtml(new Ply({ el: content }).contentEl.innerHTML, '<b>!</b>');
});
promiseTest('open/close', function () {
promiseTest('open-close', function () {
layer = new Ply({ el: 'Wow!' });
ok(!layer.wrapEl.parentNode, '!parent - open');
ok(!hasParent(layer.wrapEl), '!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(hasParent(layer.wrapEl), 'parent - open');
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');
ok(!hasParent(layer.wrapEl), '!parent - close');
});
});
});
@ -107,7 +116,7 @@
promiseTest('closeByEsc', function () {
function open(msg, esc) {
var layer = new Ply({ flags: { closeByEsc: esc }, effect: { duration: 1 } });
var layer = new Ply({ el: msg, flags: { closeByEsc: esc }, effect: { duration: 1 } });
checkVisiblity(layer, false, msg);
@ -142,23 +151,23 @@
promiseTest('closeByOverlay', function () {
function test(msg, state, callback) {
var layer = new Ply({ flags: { closeByOverlay: state }, effect: { duration: 1 } });
function testMe(msg, state, callback) {
var layer = new Ply({ el: msg, 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 sleep($.noop, 50).then(function () {
return callback(layer, msg);
});
});
}
return test('closeByOverlay: true', true, function (layer, msg) {
return testMe('closeByOverlay: true', true, function (layer, msg) {
checkVisiblity(layer, false, msg);
return test('closeByOverlay: false', false, function (layer, msg) {
return testMe('closeByOverlay: false', false, function (layer, msg) {
checkVisiblity(layer, true, msg);
return layer.close();
});
@ -181,7 +190,7 @@
});
promiseTest('destory', function () {
promiseTest('destroy', function () {
return new Ply({ effect: 'none:1' }).open().then(function (layer) {
checkVisiblity(layer, true, '#1');
@ -192,18 +201,20 @@
});
promiseTest('on/off', function () {
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) {
return new Ply('<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);
});
@ -225,13 +236,27 @@
simulateEvent(layer.contentEl.getElementsByTagName('em')[1], 'click');
equal(log.join('\n'), [
var tmp, expected = [
'layer:DIV.click->:layer',
'foo:I.click->foo',
'bar:B.click->bar',
'bar:B.click->bar',
'layer:DIV.click->:layer'
].join('\n'));
];
tmp = expected.slice();
$.each(log, function (i, entry) {
i = $.inArray(entry, tmp);
ok(i > -1, 'log.'+entry);
tmp.splice(i, 1);
});
tmp = log.slice();
$.each(expected, function (i, entry) {
i = $.inArray(entry, tmp);
ok(i > -1, 'expected.'+entry);
tmp.splice(i, 1);
});
return layer.close();
});

14
tests/Ply.ui.tests.js

@ -17,7 +17,7 @@
promiseTest('dialog("alert")', function () {
setTimeout(function () {
var el = Ply.stack.last.wrapEl;
simulateEvent(el.getElementsByTagName('button')[0], 'click');
el.getElementsByTagName('button')[0].click();
}, 50);
return Ply.dialog('alert', { effect: 'none:1' }, 'msg').then(function (ui) {
@ -30,7 +30,7 @@
promiseTest('dialog("confirm")', function () {
setTimeout(function () {
var el = Ply.stack.last.wrapEl;
simulateEvent(el.getElementsByTagName('button')[1], 'click');
el.getElementsByTagName('button')[1].click();
}, 50);
return Ply.dialog('confirm', { effect: 'none:1' }, {
@ -47,7 +47,7 @@
setTimeout(function () {
var el = Ply.stack.last.wrapEl;
Ply.stack.last.context.val('email', 'xx@yy.zz');
simulateEvent(el.getElementsByTagName('button')[0], 'click');
el.getElementsByTagName('button')[0].click();
}, 50);
return Ply.dialog('prompt', { effect: 'none:1' }, {
@ -64,7 +64,7 @@
promiseTest('dialog("confirm") with YES/NO', function () {
setTimeout(function () {
var el = Ply.stack.last.wrapEl;
simulateEvent(el.getElementsByTagName('button')[0], 'click');
el.getElementsByTagName('button')[0].click();
}, 50);
return Ply.dialog("confirm", { effect: 'none:1' }, { ok: 'YES', cancel: 'NO' }).then(function (ui) {
@ -99,10 +99,8 @@
log.push(ui.name + ':' + ui.state);
setTimeout(function () {
simulateEvent(
ui.layer.layerEl.getElementsByTagName('button')[1]
|| ui.layer.layerEl.getElementsByTagName('button')[0],
'click');
var el = ui.layer.layerEl;
(el.getElementsByTagName('button')[1] || el.getElementsByTagName('button')[0]).click();
}, 10);
}
}).then(function () {

16
tests/index.html

@ -77,8 +77,7 @@
else {
options.clientX = options.x;
options.clientY = options.y;
var evt = document.createEventObject();
oEvent = $.extend(evt, options);
oEvent = $.extend(document.createEventObject(), options);
element.fireEvent('on' + eventName, oEvent);
}
return element;
@ -95,6 +94,19 @@
});
});
};
function _htmlNormalize(html) {
if (typeof html === 'string') {
html = html.replace(/<\/?\w+/g, function (match) {
return match.toLowerCase();
});
}
return html;
}
window.equalHtml = function (actual, expected, message) {
equal(_htmlNormalize(actual), _htmlNormalize(expected), message);
};
})();
</script>

Loading…
Cancel
Save