From 99ab7da9d19a60bdb95b5ba366793b9559e452ff Mon Sep 17 00:00:00 2001
From: Zacharias Luiten
Date: Tue, 20 Oct 2015 14:37:47 +0200
Subject: [PATCH 01/87] detach correctly when element is collection typed,
fixes #54
---
src/ResizeSensor.js | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/src/ResizeSensor.js b/src/ResizeSensor.js
index 5b9c8b8..e5ce136 100755
--- a/src/ResizeSensor.js
+++ b/src/ResizeSensor.js
@@ -125,14 +125,16 @@
addEvent(expand, 'scroll', onScroll);
addEvent(shrink, 'scroll', onScroll);
}
-
+
var elementType = Object.prototype.toString.call(element);
- if ('[object Array]' === elementType
+ var isCollectionTyped = ('[object Array]' === elementType
|| ('[object NodeList]' === elementType)
|| ('[object HTMLCollection]' === elementType)
|| ('undefined' !== typeof jQuery && element instanceof jQuery) //jquery
|| ('undefined' !== typeof Elements && element instanceof Elements) //mootools
- ) {
+ );
+
+ if (isCollectionTyped) {
var i = 0, j = element.length;
for (; i < j; i++) {
attachResizeEvent(element[i], callback);
@@ -142,7 +144,14 @@
}
this.detach = function() {
- ResizeSensor.detach(element);
+ if (isCollectionTyped) {
+ var i = 0, j = element.length;
+ for (; i < j; i++) {
+ ResizeSensor.detach(element[i]);
+ }
+ } else {
+ ResizeSensor.detach(element);
+ }
};
};
From 50cdad5ed731acea0f0c1aee077c7c8a09486380 Mon Sep 17 00:00:00 2001
From: wickning1
Date: Fri, 11 Dec 2015 21:39:03 -0600
Subject: [PATCH 02/87] dramatically increase the performance of initial page
load when a lot of css rules use element queries
---
src/ElementQueries.js | 34 +++++++++++++++++++++++++---------
1 file changed, 25 insertions(+), 9 deletions(-)
diff --git a/src/ElementQueries.js b/src/ElementQueries.js
index 6e7c357..855f0ab 100755
--- a/src/ElementQueries.js
+++ b/src/ElementQueries.js
@@ -159,7 +159,15 @@
* @param {String} property width|height
* @param {String} value
*/
+ var allQueries = {};
function queueQuery(selector, mode, property, value) {
+ if (typeof(allQueries[mode]) == 'undefined') allQueries[mode] = {};
+ if (typeof(allQueries[mode][property]) == 'undefined') allQueries[mode][property] = {};
+ if (typeof(allQueries[mode][property][value]) == 'undefined') allQueries[mode][property][value] = selector;
+ else allQueries[mode][property][value] += ','+selector;
+ }
+
+ function executeQueries() {
var query;
if (document.querySelectorAll) query = document.querySelectorAll.bind(document);
if (!query && 'undefined' !== typeof $$) query = $$;
@@ -169,14 +177,21 @@
throw 'No document.querySelectorAll, jQuery or Mootools\'s $$ found.';
}
- var elements = query(selector);
- for (var i = 0, j = elements.length; i < j; i++) {
- setupElement(elements[i], {
- mode: mode,
- property: property,
- value: value
- });
+ for (var mode in allQueries) if (allQueries.hasOwnProperty(mode)) {
+ for (var property in allQueries[mode]) if (allQueries[mode].hasOwnProperty(property)) {
+ for (var value in allQueries[mode][property]) if (allQueries[mode][property].hasOwnProperty(value)) {
+ var elements = query(allQueries[mode][property][value]);
+ for (var i = 0, j = elements.length; i < j; i++) {
+ setupElement(elements[i], {
+ mode: mode,
+ property: property,
+ value: value
+ });
+ }
+ }
+ }
}
+
}
var regex = /,?([^,\n]*?)\[[\s\t]*?(min|max)-(width|height)[\s\t]*?[~$\^]?=[\s\t]*?"([^"]*?)"[\s\t]*?]([^\n\s\{]*?)/mgi;
@@ -242,6 +257,7 @@
}
}
}
+ executeQueries();
};
/**
@@ -320,7 +336,7 @@
document.addEventListener('DOMContentLoaded', callback, false);
}
/* Safari, iCab, Konqueror */
- if (/KHTML|WebKit|iCab/i.test(navigator.userAgent)) {
+ else if (/KHTML|WebKit|iCab/i.test(navigator.userAgent)) {
var DOMLoadTimer = setInterval(function () {
if (/loaded|complete/i.test(document.readyState)) {
callback();
@@ -329,7 +345,7 @@
}, 10);
}
/* Other web browsers */
- window.onload = callback;
+ else window.onload = callback;
};
if (window.addEventListener) {
From 833dee08c0cca4156a11e3a2d8176c403c4ea15f Mon Sep 17 00:00:00 2001
From: wickning1
Date: Fri, 11 Dec 2015 21:49:45 -0600
Subject: [PATCH 03/87] fix bug where css parsing fails when attribute portion
of selector comes first
---
src/ElementQueries.js | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/src/ElementQueries.js b/src/ElementQueries.js
index 6e7c357..fccd4b6 100755
--- a/src/ElementQueries.js
+++ b/src/ElementQueries.js
@@ -179,8 +179,8 @@
}
}
- var regex = /,?([^,\n]*?)\[[\s\t]*?(min|max)-(width|height)[\s\t]*?[~$\^]?=[\s\t]*?"([^"]*?)"[\s\t]*?]([^\n\s\{]*?)/mgi;
-
+ var regex = /,?[\s\t]*([^,\n]*?)((?:\[[\s\t]*?(?:min|max)-(?:width|height)[\s\t]*?[~$\^]?=[\s\t]*?"[^"]*?"[\s\t]*?])+)([^,\n\s\{]*)/mgi;
+ var attrRegex = /\[[\s\t]*?(min|max)-(width|height)[\s\t]*?[~$\^]?=[\s\t]*?"([^"]*?)"[\s\t]*?]/mgi;
/**
* @param {String} css
*/
@@ -189,9 +189,11 @@
var smatch;
css = css.replace(/'/g, '"');
while (null !== (match = regex.exec(css))) {
- if (5 < match.length) {
- smatch = match[1] || match[5] || smatch;
- queueQuery(smatch, match[2], match[3], match[4]);
+ smatch = match[1] + match[3];
+ attrs = match[2];
+
+ while (null !== (attrMatch = attrRegex.exec(attrs))) {
+ queueQuery(smatch, attrMatch[1], attrMatch[2], attrMatch[3]);
}
}
}
@@ -235,7 +237,7 @@
this.withTracking = withTracking;
for (var i = 0, j = document.styleSheets.length; i < j; i++) {
try {
- readRules(document.styleSheets[i].cssText || document.styleSheets[i].cssRules || document.styleSheets[i].rules);
+ readRules(document.styleSheets[i].cssRules || document.styleSheets[i].rules || document.styleSheets[i].cssText);
} catch(e) {
if (e.name !== 'SecurityError') {
throw e;
From a062c2b36aeb4ceeb43534e5823e9962e26ec36f Mon Sep 17 00:00:00 2001
From: Casey Foster
Date: Wed, 27 Jan 2016 16:58:04 -0600
Subject: [PATCH 04/87] Fix #63 Use overflow: hidden instead of scroll
---
src/ResizeSensor.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/ResizeSensor.js b/src/ResizeSensor.js
index e5ce136..177e04e 100755
--- a/src/ResizeSensor.js
+++ b/src/ResizeSensor.js
@@ -64,7 +64,7 @@
element.resizeSensor = document.createElement('div');
element.resizeSensor.className = 'resize-sensor';
- var style = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;';
+ var style = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; z-index: -1; visibility: hidden;';
var styleChild = 'position: absolute; left: 0; top: 0;';
element.resizeSensor.style.cssText = style;
@@ -114,7 +114,7 @@
el.addEventListener(name, cb);
}
};
-
+
var onScroll = function() {
if (element.offsetWidth != lastWidth || element.offsetHeight != lastHeight) {
changed();
From a2f12d94ab9516a31d14bae299c4879c435cb8b8 Mon Sep 17 00:00:00 2001
From: Alberto Villa
Date: Thu, 28 Jan 2016 22:12:17 +0100
Subject: [PATCH 05/87] Force 'expand' child to have no transitions
If its size update were animated, the element could become smaller
than its parent, thus making impossible to scroll 'expand' to bottom
on further 'scroll' events and breaking the sensor.
---
src/ResizeSensor.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/ResizeSensor.js b/src/ResizeSensor.js
index 177e04e..204d445 100755
--- a/src/ResizeSensor.js
+++ b/src/ResizeSensor.js
@@ -65,7 +65,7 @@
element.resizeSensor = document.createElement('div');
element.resizeSensor.className = 'resize-sensor';
var style = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; z-index: -1; visibility: hidden;';
- var styleChild = 'position: absolute; left: 0; top: 0;';
+ var styleChild = 'position: absolute; left: 0; top: 0; transition: 0s;';
element.resizeSensor.style.cssText = style;
element.resizeSensor.innerHTML =
From e33b90b34a1941061da299049b562139c168cdb8 Mon Sep 17 00:00:00 2001
From: "Marc J. Schmidt"
Date: Sun, 31 Jan 2016 14:02:19 +0100
Subject: [PATCH 06/87] Made modules loadable via node commonjs
---
README.md | 16 ++++++++++++++++
src/ElementQueries.js | 24 ++++++++++++++++++------
src/ResizeSensor.js | 14 +++++++++++---
3 files changed, 45 insertions(+), 9 deletions(-)
diff --git a/README.md b/README.md
index 8b361f5..49377a5 100644
--- a/README.md
+++ b/README.md
@@ -61,6 +61,22 @@ Include the javascript files at the bottom and you're good to go. No custom java
```
+## Module Loader
+
+If you're using a module loader you need to trigger the event listening or initialization yourself:
+
+```javascript
+var EQ = require('node_modules/css-element-queries/ElementQueries');
+
+ //attaches to DOMLoadContent
+EQ.listen();
+
+//or if you want to trigger it yourself.
+// Parse all available CSS and attach ResizeSensor to those elements which have rules attached
+// (make sure this is called after 'load' event, because CSS files are not ready when domReady is fired.
+EQ.init();
+```
+
Issues
------
diff --git a/src/ElementQueries.js b/src/ElementQueries.js
index 65ecf94..d19b83f 100755
--- a/src/ElementQueries.js
+++ b/src/ElementQueries.js
@@ -5,6 +5,13 @@
*/
;
(function() {
+
+ var ResizeSensor = window.ResizeSensor;
+
+ if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
+ ResizeSensor = require('./ResizeSensor');
+ }
+
/**
*
* @type {Function}
@@ -350,11 +357,16 @@
else window.onload = callback;
};
- if (window.addEventListener) {
- window.addEventListener('load', ElementQueries.init, false);
- } else {
- window.attachEvent('onload', ElementQueries.init);
- }
- domLoaded(ElementQueries.init);
+ ElementQueries.listen = function() {
+ domLoaded(ElementQueries.init);
+ };
+ // make available to common module loader
+ if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
+ module.exports = ElementQueries;
+ }
+ else {
+ window.ElementQueries = ElementQueries;
+ ElementQueries.listen();
+ }
})();
diff --git a/src/ResizeSensor.js b/src/ResizeSensor.js
index 204d445..8fe2db9 100755
--- a/src/ResizeSensor.js
+++ b/src/ResizeSensor.js
@@ -14,7 +14,7 @@
*
* @constructor
*/
- this.ResizeSensor = function(element, callback) {
+ var ResizeSensor = function(element, callback) {
/**
*
* @constructor
@@ -120,7 +120,7 @@
changed();
}
reset();
- }
+ };
addEvent(expand, 'scroll', onScroll);
addEvent(shrink, 'scroll', onScroll);
@@ -155,7 +155,7 @@
};
};
- this.ResizeSensor.detach = function(element) {
+ ResizeSensor.detach = function(element) {
if (element.resizeSensor) {
element.removeChild(element.resizeSensor);
delete element.resizeSensor;
@@ -163,4 +163,12 @@
}
};
+ // make available to common module loader
+ if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
+ module.exports = ResizeSensor;
+ }
+ else {
+ window.ResizeSensor = ResizeSensor;
+ }
+
})();
From 786c776fdbd5ba2bffb24d9ff7b133677580b8cc Mon Sep 17 00:00:00 2001
From: "Marc J. Schmidt"
Date: Sun, 31 Jan 2016 16:15:25 +0100
Subject: [PATCH 07/87] Implemented better responsive image functionality.
Better readme
---
README.md | 70 ++++++++++-------
src/ElementQueries.js | 176 +++++++++++++++++++++++++++++++++++++-----
2 files changed, 198 insertions(+), 48 deletions(-)
diff --git a/README.md b/README.md
index 49377a5..e573631 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-CSS Element Queries
-===================
+# CSS Element Queries
+
[](https://gitter.im/marcj/css-element-queries?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
@@ -15,43 +15,53 @@ Features:
- no interval/timeout detection. Truly event-based through integrated ResizeSensor class.
- no CSS modifications. Valid CSS Syntax
- all CSS selectors available. Uses regular attribute selector. No need to write rules in HTML.
- - supports and tested in webkit, gecko and IE(7/8/9/10/11).
+ - supports and tested in webkit, gecko and IE(7/8/9/10/11)
- `min-width`, `min-height`, `max-width` and `max-height` are supported so far
- works with any layout modifications: HTML (innerHTML etc), inline styles, DOM mutation, CSS3 transitions, fluid layout changes (also percent changes), pseudo classes (:hover etc.), window resizes and more
- no Javascript-Framework dependency (works with jQuery, Mootools, etc.)
+ - Works beautiful for responsive images without FOUC
More demos and information: http://marcj.github.io/css-element-queries/
-Example
--------
+## Examples
+
+### Element Query
```css
-.widget-name {
- padding: 25px;
+.widget-name h2 {
+ font-size: 12px;
}
-.widget-name[max-width="200px"] {
- padding: 0;
+
+.widget-name[min-width~="400px"] h2 {
+ font-size: 18px;
}
-.widget-name[min-width="500px"] {
+
+.widget-name[min-width~="900px"] h2 {
padding: 55px;
+ text-align: center;
+ font-size: 24px;
}
-/* responsive images */
-.responsive-image img {
- width: 100%;
+.widget-name[min-width~="700px"] h2 {
+ font-size: 34px;
+ color: red;
}
+```
-.responsive-image[max-width^='400px'] img {
- content: url(demo/image-400px.jpg);
-}
+```html
+
+
Element responsiveness FTW!
+
+```
-.responsive-image[max-width^='1000px'] img {
- content: url(demo/image-1000px.jpg);
-}
+### Responsive image
-.responsive-image[min-width='1000px'] img {
- content: url(demo/image-full.jpg);
-}
+```html
+
```
Include the javascript files at the bottom and you're good to go. No custom javascript calls needed.
@@ -61,6 +71,13 @@ Include the javascript files at the bottom and you're good to go. No custom java
```
+## See it in action:
+
+Here live http://marcj.github.io/css-element-queries/.
+
+
+
+
## Module Loader
If you're using a module loader you need to trigger the event listening or initialization yourself:
@@ -77,13 +94,12 @@ EQ.listen();
EQ.init();
```
-Issues
-------
+## Issues
- So far does not work on `img` and other elements that can't contain other elements. Wrapping with a `div` works fine though (See demo).
- Adds additional hidden elements into selected target element and forces target element to be relative or absolute.
-License
--------
-MIT license. Copyright [Marc J. Schmidt](http://marcjschmidt.de/).
+## License
+
+MIT license. Copyright [Marc J. Schmidt](https://twitter.com/MarcJSchmidt).
diff --git a/src/ElementQueries.js b/src/ElementQueries.js
index d19b83f..d92b5a4 100755
--- a/src/ElementQueries.js
+++ b/src/ElementQueries.js
@@ -19,7 +19,7 @@
*/
var ElementQueries = this.ElementQueries = function() {
- this.withTracking = false;
+ var trackingActive = false;
var elements = [];
/**
@@ -130,6 +130,8 @@
}
for (var k in attributes) {
+ if(!attributes.hasOwnProperty(k)) continue;
+
if (attrValues[attributes[k]]) {
this.element.setAttribute(attributes[k], attrValues[attributes[k]].substr(1));
} else {
@@ -155,7 +157,7 @@
}
element.elementQueriesSetupInformation.call();
- if (ElementQueries.instance.withTracking && elements.indexOf(element) < 0) {
+ if (trackingActive && elements.indexOf(element) < 0) {
elements.push(element);
}
}
@@ -174,7 +176,7 @@
else allQueries[mode][property][value] += ','+selector;
}
- function executeQueries() {
+ function getQuery() {
var query;
if (document.querySelectorAll) query = document.querySelectorAll.bind(document);
if (!query && 'undefined' !== typeof $$) query = $$;
@@ -184,21 +186,135 @@
throw 'No document.querySelectorAll, jQuery or Mootools\'s $$ found.';
}
+ return query;
+ }
+
+ /**
+ * Start the magic. Go through all collected rules (readRules()) and attach the resize-listener.
+ */
+ function findElementQueriesElements() {
+ var query = getQuery();
+
for (var mode in allQueries) if (allQueries.hasOwnProperty(mode)) {
- for (var property in allQueries[mode]) if (allQueries[mode].hasOwnProperty(property)) {
- for (var value in allQueries[mode][property]) if (allQueries[mode][property].hasOwnProperty(value)) {
- var elements = query(allQueries[mode][property][value]);
- for (var i = 0, j = elements.length; i < j; i++) {
- setupElement(elements[i], {
- mode: mode,
- property: property,
- value: value
- });
- }
+
+ for (var property in allQueries[mode]) if (allQueries[mode].hasOwnProperty(property)) {
+ for (var value in allQueries[mode][property]) if (allQueries[mode][property].hasOwnProperty(value)) {
+ var elements = query(allQueries[mode][property][value]);
+ for (var i = 0, j = elements.length; i < j; i++) {
+ setupElement(elements[i], {
+ mode: mode,
+ property: property,
+ value: value
+ });
+ }
+ }
}
- }
+
}
+ }
+
+ /**
+ *
+ * @param {HTMLElement} element
+ */
+ function attachResponsiveImage(element) {
+ var children = [];
+ var rules = [];
+ var sources = [];
+ var defaultImageId = 0;
+ var lastActiveImage = -1;
+ var loadedImages = [];
+ for (var i in element.children) {
+ if(!element.children.hasOwnProperty(i)) continue;
+
+ if (element.children[i].tagName.toLowerCase() === 'img') {
+ children.push(element.children[i]);
+
+ var minWidth = element.children[i].getAttribute('min-width') || element.children[i].getAttribute('data-min-width');
+ //var minHeight = element.children[i].getAttribute('min-height') || element.children[i].getAttribute('data-min-height');
+ var src = element.children[i].getAttribute('data-src') || element.children[i].getAttribute('url');
+
+ sources.push(src);
+
+ var rule = {
+ minWidth: minWidth
+ };
+
+ rules.push(rule);
+
+ if (!minWidth) {
+ defaultImageId = children.length - 1;
+ element.children[i].style.display = 'block';
+ } else {
+ element.children[i].style.display = 'none';
+ }
+ }
+ }
+
+ lastActiveImage = defaultImageId;
+
+ function check() {
+ var imageToDisplay = false, i;
+
+ for (i in children){
+ if(!children.hasOwnProperty(i)) continue;
+
+ if (rules[i].minWidth) {
+ if (element.offsetWidth > rules[i].minWidth) {
+ imageToDisplay = i;
+ }
+ }
+ }
+
+ if (!imageToDisplay) {
+ //no rule matched, show default
+ imageToDisplay = defaultImageId;
+ }
+
+ if (lastActiveImage != imageToDisplay) {
+ //image change
+
+ if (!loadedImages[imageToDisplay]){
+ //image has not been loaded yet, we need to load the image first in memory to prevent flash of
+ //no content
+
+ var image = new Image();
+ image.onload = function() {
+ children[imageToDisplay].src = sources[imageToDisplay];
+
+ children[lastActiveImage].style.display = 'none';
+ children[imageToDisplay].style.display = 'block';
+
+ loadedImages[imageToDisplay] = true;
+
+ lastActiveImage = imageToDisplay;
+ };
+
+ image.src = sources[imageToDisplay];
+ } else {
+ children[lastActiveImage].style.display = 'none';
+ children[imageToDisplay].style.display = 'block';
+ lastActiveImage = imageToDisplay;
+ }
+ }
+ }
+
+ element.resizeSensor = new ResizeSensor(element, check);
+ check();
+
+ if (trackingActive) {
+ elements.push(element);
+ }
+ }
+
+ function findResponsiveImages(){
+ var query = getQuery();
+
+ var elements = query('[data-responsive-image],[responsive-image]');
+ for (var i = 0, j = elements.length; i < j; i++) {
+ attachResponsiveImage(elements[i]);
+ }
}
var regex = /,?[\s\t]*([^,\n]*?)((?:\[[\s\t]*?(?:min|max)-(?:width|height)[\s\t]*?[~$\^]?=[\s\t]*?"[^"]*?"[\s\t]*?])+)([^,\n\s\{]*)/mgi;
@@ -249,6 +365,8 @@
}
}
+ var defaultCssInjected = false;
+
/**
* Searches all css rules and setups the event listener to all elements with element query rules..
*
@@ -256,7 +374,8 @@
* (no garbage collection possible if you don not call .detach() first)
*/
this.init = function(withTracking) {
- this.withTracking = withTracking;
+ trackingActive = typeof withTracking === 'undefined' ? false : withTracking;
+
for (var i = 0, j = document.styleSheets.length; i < j; i++) {
try {
readRules(document.styleSheets[i].cssRules || document.styleSheets[i].rules || document.styleSheets[i].cssText);
@@ -266,7 +385,17 @@
}
}
}
- executeQueries();
+
+ if (!defaultCssInjected) {
+ var style = document.createElement('style');
+ style.type = 'text/css';
+ style.innerHTML = '[responsive-image] > img, [data-responsive-image] {overflow: hidden; padding: 0; } [responsive-image] > img, [data-responsive-image] > img { width: 100%;}';
+ document.getElementsByTagName('head')[0].appendChild(style);
+ defaultCssInjected = true;
+ }
+
+ findElementQueriesElements();
+ findResponsiveImages();
};
/**
@@ -275,14 +404,13 @@
* (no garbage collection possible if you don not call .detach() first)
*/
this.update = function(withTracking) {
- this.withTracking = withTracking;
- this.init();
+ this.init(withTracking);
};
this.detach = function() {
if (!this.withTracking) {
throw 'withTracking is not enabled. We can not detach elements since we don not store it.' +
- 'Use ElementQueries.withTracking = true; before domready.';
+ 'Use ElementQueries.withTracking = true; before domready or call ElementQueryes.update(true).';
}
var element;
@@ -310,12 +438,18 @@
*/
ElementQueries.detach = function(element) {
if (element.elementQueriesSetupInformation) {
+ //element queries
element.elementQueriesSensor.detach();
delete element.elementQueriesSetupInformation;
delete element.elementQueriesSensor;
- console.log('detached');
+
+ } else if (element.resizeSensor) {
+ //responsive image
+
+ element.resizeSensor.detach();
+ delete element.resizeSensor;
} else {
- console.log('detached already', element);
+ //console.log('detached already', element);
}
};
From 39ed2eddca1690d64fb8ffb8c8f1923654956a2f Mon Sep 17 00:00:00 2001
From: "Marc J. Schmidt"
Date: Sun, 31 Jan 2016 16:16:38 +0100
Subject: [PATCH 08/87] Better demo
---
test/app.js | 119 ++++++
test/images/css-element-queries-demo.gif | Bin 0 -> 594046 bytes
test/index.html | 445 ++---------------------
test/style.css | 323 ++++++++++++++++
4 files changed, 471 insertions(+), 416 deletions(-)
create mode 100644 test/app.js
create mode 100644 test/images/css-element-queries-demo.gif
create mode 100644 test/style.css
diff --git a/test/app.js b/test/app.js
new file mode 100644
index 0000000..21ad158
--- /dev/null
+++ b/test/app.js
@@ -0,0 +1,119 @@
+var EQ = require('../src/ElementQueries');
+var ResizeSensor = require('../src/ResizeSensor');
+
+EQ.listen();
+
+var ResizerDemo = new Class({
+ y: null,
+ initialize: function(container) {
+ this.container = container;
+ this.setupLayout();
+ },
+
+ setupLayout: function(){
+ this.handler = new Element('div', {
+ 'class': 'resizerDemo-handler'
+ }).inject(this.container);
+
+ this.container.makeResizable({
+ snap: 0,
+ handle: this.handler,
+ modifiers: {
+ 'x': 'width',
+ 'y': this.y
+ }
+ });
+ }
+});
+
+var ResizeDemoXY = new Class({
+ Extends: ResizerDemo,
+ y: 'height'
+});
+
+window.addEvent('domready', function(){
+ $$('.examplesResizerDemos').each(function(resizer){
+ new ResizerDemo(resizer);
+ });
+ $$('.examplesResizerDemosXY').each(function(resizer){
+ new ResizeDemoXY(resizer);
+ });
+
+
+ perfTest();
+ example3();
+ example4();
+ example5();
+});
+
+function perfTest(){
+ var container = $('dynamicContainer');
+ var dynamicCount = $('dynamicCount');
+ var dynamicCounter = $('dynamicCounter');
+
+ window.detachDynamic = function() {
+ container.getChildren().each(function(element) {
+ ResizeSensor.detach(element);
+ });
+ };
+
+ window.removeDynamic = function() {
+ container.empty();
+ };
+
+ window.addDynamic = function() {
+ container.empty();
+ var i = 0, to = dynamicCount.value, div, counter = 0;
+ for (; i < to; i++) {
+ div = new Element('div', {
+ 'class': 'dynamicElement',
+ text: '#' + i
+ }).inject(container);
+
+ new ResizeSensor(div, function(){
+ counter++;
+ dynamicCounter.set('text', counter + ' changes.');
+ });
+ }
+ }
+}
+
+function example3(){
+
+ var logger = document.id('example-3-log');
+ var box = document.id('example-3-box');
+ document.id('startStop3').addEvent('click', function(){
+ if (box.hasClass('example-3-box-start')) {
+ box.removeClass('example-3-box-start');
+ } else {
+ box.addClass('example-3-box-start');
+ }
+ });
+ new ResizeSensor(box, function(el){
+ logger.set('html', 'Changed to ' + box.getSize().x+'px width.');
+ });
+
+}
+
+function example4(){
+ var logger = document.id('example-4-log');
+ var box = document.id('example-4-box');
+ document.id('startStop4').addEvent('click', function(){
+ if (box.hasClass('example-4-box-start')) {
+ box.removeClass('example-4-box-start');
+ } else {
+ box.addClass('example-4-box-start');
+ }
+ });
+ new ResizeSensor(box, function(){
+ logger.set('html', 'Changed to ' + box.getSize().y+'px height.');
+ });
+}
+
+function example5(){
+ var box = document.id('example-5');
+ var changed = 0;
+ new ResizeSensor(box.getParent(), function(){
+ box.innerHTML = (++changed) + ' changes. ' + box.getParent().getSize().x+'px/'+box.getParent().getSize().y+'px';
+ });
+}
\ No newline at end of file
diff --git a/test/images/css-element-queries-demo.gif b/test/images/css-element-queries-demo.gif
new file mode 100644
index 0000000000000000000000000000000000000000..5c6965e1ae4df3c6c3ebad7d7c4592ce8ae4c5de
GIT binary patch
literal 594046
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