Permalink
Browse files

Module refactors

  • Loading branch information...
kriszyp committed Apr 2, 2013
1 parent b000a5c commit 8f16c75e19263dd84eba6f5e7a414709c00844bb
Showing with 1,192 additions and 1,408 deletions.
  1. +3 −2 build.js
  2. +1 −1 build/build-xstyle.cmd
  3. +175 −0 core/elemental.js
  4. 0 { → core}/load-css.js
  5. +18 −13 { → core}/load-imports.js
  6. +324 −0 core/parser.js
  7. +635 −0 core/ruleModel.js
  8. +1 −1 css.js
  9. +0 −13 ext.css
  10. +3 −3 ext/widget.js
  11. +13 −1,351 main.js
  12. +2 −2 test/converter.js
  13. +3 −3 test/testCore.html
  14. +12 −17 test/testDijit.css
  15. +2 −2 test/testDijit.html
View
@@ -33,12 +33,13 @@ if(typeof define == 'undefined'){
var fs = require('fs'),
pathModule = require('path'),
xstyle;
- define = pseudoDefine;
- require('./main');
+ define = pseudoDefine;
+ require('./core/parser');
}else{
define(['build/fs', './build/base64'], function(fsModule, base64){
fs = fsModule;
base64Module = base64;
+ // must create our own path module for Rhino :/
pathModule = {
resolve: function(base, target){
return (base.replace(/[^\/]+$/, '') + target)
View
@@ -1 +1 @@
-uglifyjs ../core/amdLoader.js ../../put-selector/put.js ../main.js -o ..\xstyle.min.js --source-map ..\xstyle.min.js.map -p 2 -c -m
+uglifyjs ../core/amdLoader.js ../../put-selector/put.js ../core/elemental.js ../core/ruleModel.js ../core/parser.js ../main.js -o ..\xstyle.min.js --source-map ..\xstyle.min.js.map -p 2 -c -m
View
@@ -0,0 +1,175 @@
+define("xstyle/core/elemental", ["put-selector/put"], function(put){
+ // using delegation, listen for any input changes in the document and "put" the value
+ // TODO: add a hook so one could add support for IE8, or maybe this event delegation isn't really that useful
+ var doc = document;
+ doc.addEventListener('change', function(event){
+ var element = event.target;
+ // get the variable computation so we can put the value
+ var variable = element['-x-variable'];
+ if(variable.put){ // if it can be put, we do so
+ variable.put(element.value);
+ }
+ });
+
+
+ // elemental section, this code is for property handlers that need to mutate the DOM for elements
+ // that match it's rule
+ var testDiv = doc.createElement("div");
+ var features = {
+ "dom-qsa2.1": !!testDiv.querySelectorAll
+ };
+ function has(feature){
+ return features[feature];
+ }
+ // get the matches function, whatever it is called in this browser
+ var matchesSelector = testDiv.matches || testDiv.matchesSelector || testDiv.webkitMatchesSelector || testDiv.mozMatchesSelector || testDiv.msMatchesSelector || testDiv.oMatchesSelector;
+ var selectorRenderers = [];
+ var classHash = {}, propertyHash = {};
+ var renderQueue = [];
+ var documentQueried;
+ // probably want to inline our own DOM readiness code
+ function domReady(callback){
+ // TODO: support IE7-8
+ if(/e/.test(doc.readyState||'')){
+ // TODO: fix the issues with sync so this can be run immediately
+ setTimeout(callback, 200);
+ }else{
+ doc.addEventListener("DOMContentLoaded", callback);
+ }
+ }
+ domReady(function(){
+ if(!documentQueried){
+ documentQueried = true;
+ if(has("dom-qsa2.1")){
+ // if we have a query engine, it is fastest to use that
+ for(var i = 0, l = selectorRenderers.length; i < l; i++){
+ // find the matches and register the renderers
+ findMatches(selectorRenderers[i]);
+ }
+ // render all the elements that are queued up
+ renderWaiting();
+ }else{
+ //else rely on css expressions (or maybe we should use document.all and just scan everything)
+ var all = doc.all;
+ for(var i = 0, l = all.length; i < l; i++){
+ update(all[i]);
+ }
+ }
+ }
+ });
+ function findMatches(renderer){
+ // find the elements for a given selector and apply the renderers to it
+ var toRender = [];
+ var results = doc.querySelectorAll(renderer.selector);
+ var name = renderer.name;
+ for(var i = 0, l = results.length; i < l; i++){
+ var element = results[i];
+ var currentStyle = element.elementalStyle;
+ var currentSpecificities = element.elementalSpecificities;
+ if(!currentStyle){
+ currentStyle = element.elementalStyle = {};
+ currentSpecificities = element.elementalSpecificities = {};
+ }
+ // TODO: only override if the selector is equal or higher specificity
+ // var specificity = renderer.selector.match(/ /).length;
+ if(true || currentSpecificities[name] <= renderer.specificity){ // only process changes
+ var elementRenderings = element.renderings;
+ if(!elementRenderings){
+ // put it in the queue
+ elementRenderings = element.renderings = [];
+ renderQueue.push(element);
+ }
+
+ elementRenderings.push({
+ name: name,
+ rendered: currentStyle[name] == renderer.propertyValue,
+ renderer: renderer
+ });
+ currentStyle[name] = renderer.propertyValue;
+ }
+ }
+
+ }
+ var isCurrent;
+ function renderWaiting(){
+ // render all the elements in the queue to be rendered
+ for(var i = 0; i < renderQueue.length; i++){
+ var element = renderQueue[i];
+ var renderings = element.renderings, currentStyle = element.elementalStyle;
+ delete element.renderings;
+ for(var j = 0; j < renderings.length; j++){
+ var rendering = renderings[j];
+ var renderer = rendering.renderer;
+ var rendered = renderer.rendered;
+ isCurrent = currentStyle[rendering.name] == renderer.propertyValue; // determine if this renderer matches the current computed style
+ if(!rendered && isCurrent){
+ try{
+ renderer.render(element);
+ }catch(e){
+ console.error(e, e.stack);
+ put(element, "div.error", e.toString());
+ }
+ }
+ if(rendered && !isCurrent && renderer.unrender){
+ renderer.unrender(element);
+ renderings.splice(j--, 1); // TODO: need to remove duplicate rendered items as well
+ }
+ }
+ }
+ renderQueue = [];
+ }
+ function apply(element, renderers){
+ // an element was found that matches a selector, so we apply the renderers
+ for(var i = 0, l = renderers.length; i < l; i++){
+ renderers[i](element);
+ }
+ }
+ function update(element, selector){
+ /* At some point, might want to use getMatchedCSSRules for faster access to matching rules
+ if(typeof getMatchedCSSRules != "undefined"){
+ // webkit gives us fast access to which rules apply
+ getMatchedCSSRules(element);
+ }else{*/
+ for(var i = 0, l = selectorRenderers.length; i < l; i++){
+ var renderer = selectorRenderers[i];
+ if((!selector || (selector == renderer.selector)) &&
+ (matchesSelector ?
+ // use matchesSelector if available
+ matchesSelector.call(element, renderer.selector) : // TODO: determine if it is higher specificity that other same name properties
+ // else use IE's custom css property inheritance mechanism
+ element.currentStyle[renderer.name] == renderer.propertyValue)){
+ renderer.render(element);
+ }
+ }
+ }
+ return {
+ ready: domReady,
+ addRenderer: function(propertyName, propertyValue, rule, handler){
+ var renderer = {
+ selector: rule.selector,
+ propertyValue: propertyValue,
+ name: propertyName,
+ render: handler
+ };
+ // the main entry point for adding elemental handlers for a selector. The handler
+ // will be called for each element that is created that matches a given selector
+ selectorRenderers.push(renderer);
+ if(documentQueried){
+ findMatches(renderer);
+ }
+ renderWaiting();
+ /*if(!matchesSelector){
+ // create a custom property to identify this rule in created elements
+ return (renderers.triggerProperty = 'selector_' + encodeURIComponent(selector).replace(/%/g, '/')) + ': 1;' +
+ (document.querySelectorAll ? '' :
+ // we use css expressions for IE6-7 to find new elements that match the selector, since qSA is not available, wonder if it is better to just use document.all...
+ 'zoom: expression(cssxRegister(this,"' + selector +'"));');
+ }*/
+ },
+ update: update, // this should be called for newly created dynamic elements to ensure the proper rules are applied
+ clearRenderers: function(){
+ // clears all the renderers in use
+ selectorRenderers = [];
+ }
+ };
+});
File renamed without changes.
@@ -3,7 +3,7 @@
// and provides loading of the text of any sheets. This is intended to only be loaded as needed
// for development, ideally stylesheets should be flattened and inlined for finished/production
// applications, and this module won't be loaded.
-define('xstyle/load-imports', [], function(){
+define('xstyle/core/load-imports', [], function(){
var insertedSheets = {},
features = {
"dom-deep-import": !document.createStyleSheet // essentially test to see if it is IE, inaccurate marker, maybe should use dom-addeventlistener?
@@ -178,18 +178,23 @@ define('xstyle/load-imports', [], function(){
}
if(sheetToDelete != sheet){
if(href){
- // record the stylesheet in our hash
- insertedSheets[href] = sheet;
- sheet.ownerElement = link;
- var sourceSheet = sheet;
- loadingCount++;
- fetchText(href, function(text){
- sourceSheet.localSource = text;
- finishedModule();
- }, function(){
- sourceSheet.localSource = '';
- finishedModule();
- });
+ if(/no-xstyle$/.test(href)){
+ sheet.localSource = '';
+ return;
+ }else{
+ // record the stylesheet in our hash
+ insertedSheets[href] = sheet;
+ sheet.ownerElement = link;
+ var sourceSheet = sheet;
+ loadingCount++;
+ fetchText(href, function(text){
+ sourceSheet.localSource = text;
+ finishedModule();
+ }, function(){
+ sourceSheet.localSource = '';
+ finishedModule();
+ });
+ }
}else{
sheet.localSource = link.innerHTML;
}
Oops, something went wrong.

0 comments on commit 8f16c75

Please sign in to comment.