Browse files

Added CSS styling to Th; started converting Th to use new CSS (sorry …

…about the iml file)
  • Loading branch information...
1 parent 2d7e024 commit 2749cba56a0ef9c4b3632f83ae9135ced3439a1c Ben Galbraith committed Mar 18, 2009
View
27 bespin.iml
@@ -117,6 +117,33 @@
</packaging>
</configuration>
</facet>
+ <facet type="web" name="Web5" implicit="true">
+ <configuration>
+ <descriptors>
+ <deploymentDescriptor name="web.xml" url="file://$MODULE_DIR$/devfiles/bgalbs/bespin/backend/java/web/WEB-INF/web.xml" optional="false" version="2.5" />
+ </descriptors>
+ <webroots>
+ <root url="file://$MODULE_DIR$/devfiles/bgalbs/bespin/backend/java/web" relative="/" />
+ </webroots>
+ <building>
+ <setting name="EXPLODED_URL" value="file://" />
+ <setting name="EXPLODED_ENABLED" value="false" />
+ <setting name="JAR_URL" value="file://" />
+ <setting name="JAR_ENABLED" value="false" />
+ <setting name="BUILD_MODULE_ON_FRAME_DEACTIVATION" value="false" />
+ <setting name="BUILD_EXTERNAL_DEPENDENCIES" value="false" />
+ <setting name="EXCLUDE_EXPLODED_DIRECTORY" value="true" />
+ <setting name="RUN_JASPER_VALIDATION" value="true" />
+ <setting name="BUILD_ONLY_WEB_RESOURCES" value="false" />
+ </building>
+ <packaging>
+ <containerElement type="module" name="bespin">
+ <attribute name="method" value="1" />
+ <attribute name="URI" value="/WEB-INF/classes" />
+ </containerElement>
+ </packaging>
+ </configuration>
+ </facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
View
4 frontend/dashboard.html
@@ -28,6 +28,7 @@
<head>
<title>Bespin &raquo; Dashboard</title>
<link type="text/css" rel="stylesheet" href="css/dashboard.css">
+ <link type="text/css" rel="thstylesheet" href="css/dashboard_th.css">
<link type="text/css" rel="stylesheet" href="css/shared.css">
<!-- begin script tags -->
@@ -67,9 +68,6 @@
<img id="vscroll_track_top" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAGCAYAAADzG6+8AAABkWlDQ1BJQ0MgUHJvZmlsZQAAeAGtkrFLw0AUxr9k0KGiSxctQgYHhSqxLhVdagaVOoQqok6mSUwLMQ1JbHXzTxAFJ0FRcHFxUdfi3IIgiN1chI6CoIKU+C6HdLDo4sHd/d53797du3eAWNVc1xYBbDqBl5udkVZW16TuBkTESKSm6b6bUdUFbnUa3x4gMP1+lMXq5PGL1uPRgYAQJ5+4xXmYcZ7zNONK4AbkozLWC5pBTB1JbymnEO8R91qcTxjnOV8yLusW21sllh2j6BC/EKcN09cBkZ0V6K5HPuIR8RDLn2Zqp5Sz2iR9ua2l34HjZyCRbWuJA6BvHbjabWuvt9GbCPaFvzGRisIJ/Y9ALBOGzRZd6xpoTYXhx2AYfjaALrL3VX3LK0e+dEmhDvxl89x4dF4DYlaLqB4/mecf+cvAeQ1YrADjT8DZCCDdUB6HwBytZe8g1Orfnb9VtG9A0exi3tMC05DYd1FKdsnzXU03o+X/GwJzm2oCKCV3xytahUDK0O8yk9K8o48lpZQsT+ILa8N0t4kBZ8IAAAAJcEhZcwAACxMAAAsTAQCanBgAAAC2SURBVBgZTVDtEsIgDAul8FD+9Hz/N5kf07lNGJgC3gnXawtJGnCX86mCq9baYllWlFJaOOfgg4d6RVCPDjQ0oD0B+/7BY36BWAI9xAs8s+OupSLlY/SdIZbe64ZpukPIiiFAgzYyNZoLc2ACgFDYMis7vN4eCDEgMkQ4zRmgh0gH55xp/4BqbESdn8uYpE1NxJFM/aHcBvFx1EdKiW+lG+WAbdsRaM+A7o/Q+kH+1XZvZOFnfQGn3UWGhj3lNQAAAABJRU5ErkJggg==" width="14" height="6"/>
<img id="vscroll_track_middle" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAABCAYAAADuHp8EAAABkWlDQ1BJQ0MgUHJvZmlsZQAAeAGtkrFLw0AUxr9k0KGiSxctQgYHhSqxLhVdagaVOoQqok6mSUwLMQ1JbHXzTxAFJ0FRcHFxUdfi3IIgiN1chI6CoIKU+C6HdLDo4sHd/d53797du3eAWNVc1xYBbDqBl5udkVZW16TuBkTESKSm6b6bUdUFbnUa3x4gMP1+lMXq5PGL1uPRgYAQJ5+4xXmYcZ7zNONK4AbkozLWC5pBTB1JbymnEO8R91qcTxjnOV8yLusW21sllh2j6BC/EKcN09cBkZ0V6K5HPuIR8RDLn2Zqp5Sz2iR9ua2l34HjZyCRbWuJA6BvHbjabWuvt9GbCPaFvzGRisIJ/Y9ALBOGzRZd6xpoTYXhx2AYfjaALrL3VX3LK0e+dEmhDvxl89x4dF4DYlaLqB4/mecf+cvAeQ1YrADjT8DZCCDdUB6HwBytZe8g1Orfnb9VtG9A0exi3tMC05DYd1FKdsnzXU03o+X/GwJzm2oCKCV3xytahUDK0O8yk9K8o48lpZQsT+ILa8N0t4kBZ8IAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAxSURBVAgdY9RQV/rPxc3JwMzEDMSMDIyMTAxMYJqRAQxA1H8g+v+f4R+QBnH5+PgZAK7lB9Aca2VLAAAAAElFTkSuQmCC" width="14" height="1"/>
<img id="vscroll_track_bottom" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAGCAYAAADzG6+8AAABkWlDQ1BJQ0MgUHJvZmlsZQAAeAGtkrFLw0AUxr9k0KGiSxctQgYHhSqxLhVdagaVOoQqok6mSUwLMQ1JbHXzTxAFJ0FRcHFxUdfi3IIgiN1chI6CoIKU+C6HdLDo4sHd/d53797du3eAWNVc1xYBbDqBl5udkVZW16TuBkTESKSm6b6bUdUFbnUa3x4gMP1+lMXq5PGL1uPRgYAQJ5+4xXmYcZ7zNONK4AbkozLWC5pBTB1JbymnEO8R91qcTxjnOV8yLusW21sllh2j6BC/EKcN09cBkZ0V6K5HPuIR8RDLn2Zqp5Sz2iR9ua2l34HjZyCRbWuJA6BvHbjabWuvt9GbCPaFvzGRisIJ/Y9ALBOGzRZd6xpoTYXhx2AYfjaALrL3VX3LK0e+dEmhDvxl89x4dF4DYlaLqB4/mecf+cvAeQ1YrADjT8DZCCDdUB6HwBytZe8g1Orfnb9VtG9A0exi3tMC05DYd1FKdsnzXU03o+X/GwJzm2oCKCV3xytahUDK0O8yk9K8o48lpZQsT+ILa8N0t4kBZ8IAAAAJcEhZcwAACxMAAAsTAQCanBgAAAC5SURBVBgZbZDbDsIgDIZ/SrfBPCSL+gre6Ps/2OKNg4F/WYy7sEkppfTw1T0f9+q9R98pxAvEUcXBOYcmZipQSkXhRb0ixhESwoCUEmqtqAw2a/d/yninirJmyOl4wMqHJeX2uVXeFdj7yiTPjjknTsfxLtMZaUlYqKWsKLXQ/tS6G86WtDQCtXMcI5wI5vmFN5NVPVnso2+8xr0hk5K8JrIZIAw9btcJMQQuyHGcvLGzs4kV++7L/A+jDXod+ZPecQAAAABJRU5ErkJggg==" width="14" height="6"/>
- <img id="vscroll_top" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAHCAYAAAA4R3wZAAABkWlDQ1BJQ0MgUHJvZmlsZQAAeAGtkrFLw0AUxr9k0KGiSxctQgYHhSqxLhVdagaVOoQqok6mSUwLMQ1JbHXzTxAFJ0FRcHFxUdfi3IIgiN1chI6CoIKU+C6HdLDo4sHd/d53797du3eAWNVc1xYBbDqBl5udkVZW16TuBkTESKSm6b6bUdUFbnUa3x4gMP1+lMXq5PGL1uPRgYAQJ5+4xXmYcZ7zNONK4AbkozLWC5pBTB1JbymnEO8R91qcTxjnOV8yLusW21sllh2j6BC/EKcN09cBkZ0V6K5HPuIR8RDLn2Zqp5Sz2iR9ua2l34HjZyCRbWuJA6BvHbjabWuvt9GbCPaFvzGRisIJ/Y9ALBOGzRZd6xpoTYXhx2AYfjaALrL3VX3LK0e+dEmhDvxl89x4dF4DYlaLqB4/mecf+cvAeQ1YrADjT8DZCCDdUB6HwBytZe8g1Orfnb9VtG9A0exi3tMC05DYd1FKdsnzXU03o+X/GwJzm2oCKCV3xytahUDK0O8yk9K8o48lpZQsT+ILa8N0t4kBZ8IAAAAJcEhZcwAACxMAAAsTAQCanBgAAADnSURBVBgZdZDNS8NAEMV/3SRYY5u0iFuSqgeVfp1aj4qH3kVQ0P9avHnTg9dCTGv9SnazbmMvljgwM8yb997A1Aa9I9No7iBqgnrdY9A/pt0KaNk0xvCaLkiSlKfnF7JcYQpjd21c1hHHHc7PTgnDAK0LtFLkeWbNtujIXQ4PIu4fHpnNklIhVrXfO+Hu9gopJYXWZN9fKJWvLX+b72+XxlG0VwJiBdxcX9orirdFWvY/io1hMh7iug5iOr3AcRwrmm9QqkfP8+jGEjEaDVku5/YRRTWzAg2aPmK/G/H58V6x/h8KwwY/ikpHd6dyKWkAAAAASUVORK5CYII=" width="14" height="7"/>
- <img id="vscroll_middle" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAABCAYAAADuHp8EAAABkWlDQ1BJQ0MgUHJvZmlsZQAAeAGtkrFLw0AUxr9k0KGiSxctQgYHhSqxLhVdagaVOoQqok6mSUwLMQ1JbHXzTxAFJ0FRcHFxUdfi3IIgiN1chI6CoIKU+C6HdLDo4sHd/d53797du3eAWNVc1xYBbDqBl5udkVZW16TuBkTESKSm6b6bUdUFbnUa3x4gMP1+lMXq5PGL1uPRgYAQJ5+4xXmYcZ7zNONK4AbkozLWC5pBTB1JbymnEO8R91qcTxjnOV8yLusW21sllh2j6BC/EKcN09cBkZ0V6K5HPuIR8RDLn2Zqp5Sz2iR9ua2l34HjZyCRbWuJA6BvHbjabWuvt9GbCPaFvzGRisIJ/Y9ALBOGzRZd6xpoTYXhx2AYfjaALrL3VX3LK0e+dEmhDvxl89x4dF4DYlaLqB4/mecf+cvAeQ1YrADjT8DZCCDdUB6HwBytZe8g1Orfnb9VtG9A0exi3tMC05DYd1FKdsnzXU03o+X/GwJzm2oCKCV3xytahUDK0O8yk9K8o48lpZQsT+ILa8N0t4kBZ8IAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAwSURBVAgdY9y7a93/WzcvM/z794/h////DIyMjAx//vwFs0F8EIbJ/YPy///7zwAANqwmfiiYAAYAAAAASUVORK5CYII=" width="14" height="1"/>
- <img id="vscroll_bottom" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAICAYAAADJEc7MAAABkWlDQ1BJQ0MgUHJvZmlsZQAAeAGtkrFLw0AUxr9k0KGiSxctQgYHhSqxLhVdagaVOoQqok6mSUwLMQ1JbHXzTxAFJ0FRcHFxUdfi3IIgiN1chI6CoIKU+C6HdLDo4sHd/d53797du3eAWNVc1xYBbDqBl5udkVZW16TuBkTESKSm6b6bUdUFbnUa3x4gMP1+lMXq5PGL1uPRgYAQJ5+4xXmYcZ7zNONK4AbkozLWC5pBTB1JbymnEO8R91qcTxjnOV8yLusW21sllh2j6BC/EKcN09cBkZ0V6K5HPuIR8RDLn2Zqp5Sz2iR9ua2l34HjZyCRbWuJA6BvHbjabWuvt9GbCPaFvzGRisIJ/Y9ALBOGzRZd6xpoTYXhx2AYfjaALrL3VX3LK0e+dEmhDvxl89x4dF4DYlaLqB4/mecf+cvAeQ1YrADjT8DZCCDdUB6HwBytZe8g1Orfnb9VtG9A0exi3tMC05DYd1FKdsnzXU03o+X/GwJzm2oCKCV3xytahUDK0O8yk9K8o48lpZQsT+ILa8N0t4kBZ8IAAAAJcEhZcwAACxMAAAsTAQCanBgAAAEKSURBVBgZlZAxT8MwEIWfk0jEctwkperSjQHxM/srEBMTO6gDdAAkwogqMiCxAhWFgEBp2sZxqG2cwIyKpZPvdPe9Jz0yOjkyb69TSFnBGANCCNZr1fbN3JTW+uf/naWs4WTZOyhl+M+b5ws4k0kKFnSsk7Mx+zR9gXNxmUApDc7DjcC6/sLD4wzWxmD/4BCu51k4gut6fwqcjq8Qxfau3+sOi2KBNL3DYNBHGIatSEMrpVqRJqA8L3A8OocoK3TjGG5vOx5yzlCWAsn1DYQQNkEFxmgLPc8y3Kb3OBsn8OkWeMDg+xRkb3fHBBZ0bDiEGHx8zrFcriAq2YKU+ujYvTWAPYDRBlEU4xsQKnjf2FzvwQAAAABJRU5ErkJggg==" width="14" height="8"/>
<img id="vscroll_up_arrow" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAMCAYAAABSgIzaAAABkWlDQ1BJQ0MgUHJvZmlsZQAAeAGtkrFLw0AUxr9k0KGiSxctQgYHhSqxLhVdagaVOoQqok6mSUwLMQ1JbHXzTxAFJ0FRcHFxUdfi3IIgiN1chI6CoIKU+C6HdLDo4sHd/d53797du3eAWNVc1xYBbDqBl5udkVZW16TuBkTESKSm6b6bUdUFbnUa3x4gMP1+lMXq5PGL1uPRgYAQJ5+4xXmYcZ7zNONK4AbkozLWC5pBTB1JbymnEO8R91qcTxjnOV8yLusW21sllh2j6BC/EKcN09cBkZ0V6K5HPuIR8RDLn2Zqp5Sz2iR9ua2l34HjZyCRbWuJA6BvHbjabWuvt9GbCPaFvzGRisIJ/Y9ALBOGzRZd6xpoTYXhx2AYfjaALrL3VX3LK0e+dEmhDvxl89x4dF4DYlaLqB4/mecf+cvAeQ1YrADjT8DZCCDdUB6HwBytZe8g1Orfnb9VtG9A0exi3tMC05DYd1FKdsnzXU03o+X/GwJzm2oCKCV3xytahUDK0O8yk9K8o48lpZQsT+ILa8N0t4kBZ8IAAAAJcEhZcwAACxMAAAsTAQCanBgAAAEcSURBVCgVjZLNSsNAFIXPpNH8uFGRaoulf7agCy3SFhFrpXYp6osKbn0NXbkSwSfQJDPKJHGSdC6Z1oUJzD3n3vMNDFw2n52nUF+a5kXV3GUHad0rjWDliaVDyhhxHC91TfsnyIXA9tYm9nZ3zHTJrYBBGCEIIsyuzjC5GJWipjTAJEkQhRyj4TH6/Ta6nQYGJ4cmsXAG+PkVglkM97dzCk8nY7iuQ14LArn4BucCdzfX2PA9PYfnuZhejslrQaCUEr2DpnrXUM+ong6O0Gruk8+ErR1jDL1uC88vr7pVVAYw9dfrVby9f9CMwDXbxsPjE4T4UclURfUCMFQqFnzfRa1WXQUdZx2ddoO2JUvQxixWptitgqU30lX/FL8a0VHUawkSdQAAAABJRU5ErkJggg==" width="14" height="12">
<img id="vscroll_down_arrow" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAMCAYAAABSgIzaAAABkWlDQ1BJQ0MgUHJvZmlsZQAAeAGtkrFLw0AUxr9k0KGiSxctQgYHhSqxLhVdagaVOoQqok6mSUwLMQ1JbHXzTxAFJ0FRcHFxUdfi3IIgiN1chI6CoIKU+C6HdLDo4sHd/d53797du3eAWNVc1xYBbDqBl5udkVZW16TuBkTESKSm6b6bUdUFbnUa3x4gMP1+lMXq5PGL1uPRgYAQJ5+4xXmYcZ7zNONK4AbkozLWC5pBTB1JbymnEO8R91qcTxjnOV8yLusW21sllh2j6BC/EKcN09cBkZ0V6K5HPuIR8RDLn2Zqp5Sz2iR9ua2l34HjZyCRbWuJA6BvHbjabWuvt9GbCPaFvzGRisIJ/Y9ALBOGzRZd6xpoTYXhx2AYfjaALrL3VX3LK0e+dEmhDvxl89x4dF4DYlaLqB4/mecf+cvAeQ1YrADjT8DZCCDdUB6HwBytZe8g1Orfnb9VtG9A0exi3tMC05DYd1FKdsnzXU03o+X/GwJzm2oCKCV3xytahUDK0O8yk9K8o48lpZQsT+ILa8N0t4kBZ8IAAAAJcEhZcwAACxMAAAsTAQCanBgAAAEoSURBVCgVdZLNSsNAFIVPJomtiZHE+iKuFJfiC7gXfDeRUqugKHXlTkFqBWm1ILpVMNUuFFeJzHhn0rkmtU7g/p6PyZ0ZZ3NjXYGWUsaRN5k2HNtaqQXPKMhkWQ4pJRQc+sg6ZCdK13UhhGOlxjOY5znWVldAFARBBU4xAZ5XyK66twwzKKXC6G2Mne0tbpaD9uFZOYWwmf6di8se+oMHW2J/d/+I65sB5zpgMAjqWG4kaLU7FYFOjk/O0ViKK3UGdTUMA3x8fmF374hFzf1TZDT/9KqAtdockmQR3V4fafqOdDTGcPiEYL4+zf1eh+0s0K7ftEProAM9tx5h1uJTtU0hBKIoxPPLK1zhIo6jyX1aReH/gLrs+745KPsAqkiRVWacJfiv9gOl61tN7tS7OAAAAABJRU5ErkJggg==" width="14" height="12">
</div>
View
3 frontend/js/bespin/page/dashboard/init.js
@@ -260,9 +260,6 @@ dojo.provide("bespin.page.dashboard.init");
scrollTopImage: dojo.byId("vscroll_track_top"),
scrollMiddleImage: dojo.byId("vscroll_track_middle"),
scrollBottomImage: dojo.byId("vscroll_track_bottom"),
- scrollHandleTopImage: dojo.byId("vscroll_top"),
- scrollHandleMiddleImage: dojo.byId("vscroll_middle"),
- scrollHandleBottomImage: dojo.byId("vscroll_bottom"),
scrollUpArrow: dojo.byId("vscroll_up_arrow"),
scrollDownArrow: dojo.byId("vscroll_down_arrow")
}});
View
15 frontend/js/th/components.js
@@ -75,13 +75,10 @@ dojo.declare("th.components.Scrollbar", th.Container, {
function loadImg(url) {
var img = new Image();
img.src = url;
- return img;
+ return img;
}
// getting the images for the scrollbar
this.style.scrollUpArrow = loadImg(path + name + '_up_arrow.png');
- this.style.scrollHandleTopImage = loadImg(path + name + '_top.png');
- this.style.scrollHandleMiddleImage = loadImg(path + name + '_middle.png');
- this.style.scrollHandleBottomImage = loadImg(path + name + '_bottom.png');
this.style.scrollDownArrow = loadImg(path + name + '_down_arrow.png');
},
@@ -175,16 +172,16 @@ dojo.declare("th.components.Scrollbar", th.Container, {
if (this.style.scrollBottomImage) ctx.drawImage(this.style.scrollBottomImage, 1, this.down.bounds.y - this.style.scrollBottomImage.height);
// propagate the styles to the children if not already there
- if (this.style.scrollHandleTopImage && !this.bar.style.topImage) {
- this.bar.style.topImage = this.style.scrollHandleTopImage;
- this.bar.style.middleImage = this.style.scrollHandleMiddleImage;
- this.bar.style.bottomImage = this.style.scrollHandleBottomImage;
+ if (this.styles["-th-vscroll-top-image"] && !this.bar.style.topImage) {
+ this.bar.style.topImage = this.styles["-th-vscroll-top-image"];
+ this.bar.style.middleImage = this.styles["-th-vscroll-middle-image"];
+ this.bar.style.bottomImage = this.styles["-th-vscroll-bottom-image"];;
this.up.style.backgroundImage = this.style.scrollUpArrow;
this.down.style.backgroundImage = this.style.scrollDownArrow;
}
this.inherited(arguments);
- }
+ }
});
dojo.declare("th.components.Panel", th.Container, {
View
5 frontend/js/th/default.css
@@ -0,0 +1,5 @@
+Scrollbar {
+ -th-vscroll-top-image: url(/images/dash_vscroll_top.png);
+ -th-vscroll-middle-image: url(/images/dash_vscroll_middle.png);
+ -th-vscroll-bottom-image: url(/images/dash_vscroll_bottom.png);
+}
View
69 frontend/js/th/helpers.js
@@ -101,8 +101,75 @@ dojo.declare("th.helpers.ComponentHelpers", null, {
emptyInsets: function() {
return { left: 0, right: 0, bottom: 0, top: 0 };
+ },
+
+ resolveCss: function() {
+ // right now, all components tie into the global resources bucket; this is fine for now but may need to be loaded from the scene
+ var resources = th.global_resources;
+
+ // build a map of declarations
+ var declarations = {};
+
+ // process the user agent styles first
+ var propertyName;
+ var sheetTypes = [ "userAgentCss", "userCss", "authorCss" ];
+ for (var i = 0; i < sheetTypes.length; i++) {
+ // css splits sheets into user agent, user, and author categories, each of which has different priority
+ // we'll implement this by having the same code take three passes, dynamically grabbing the appropriate CSS array
+ // from the Resources.
+ //
+ // this will have to change if we support !important as the user gets a final crack at overridding author sheets
+ var currentSheet = sheetTypes[i];
+ dojo.forEach(resources[currentSheet], function(css) {
+ for (var selector in css) {
+ // a selector may be compound (e.g., foo, bar, car {}) so we split it out by comma to treat each piece of
+ // the selector independently
+ var selectorPieces = selector.split(",");
+ for (var s = 0; s < selectorPieces.length; s++) {
+ var selectorPiece = dojo.trim(selectorPieces[s]);
+
+ // if this selector selects this component, let's add the rules to the declarations bucket
+ if (this.matchesSelector(selectorPiece)) {
+ var properties = css[selector];
+
+ for (propertyName in properties) {
+ declarations[propertyName] = properties[propertyName];
+ }
+ }
+ }
+ }
+ }, this);
+ }
+
+ this.styles = declarations;
+ },
+
+ // only id and class selectors are supported at the moment
+ matchesSelector: function(selector) {
+ if (selector.indexOf("#") == 0) {
+ if (!this.id) return false;
+ return ("#" + this.id) == selector;
+ }
+
+ var classPieces = this.declaredClass.split(".");
+ var clazz = classPieces[classPieces.length - 1];
+
+ return (clazz.toLowerCase() == selector.toLowerCase());
+ },
+
+ // returns the "specificity" index of the selector. -1 means the first is less specific; 0 means they are equal, 1 means the first
+ // is more specific
+ getSpecificityIndex: function(selector, otherSelector) {
+ if (selector == otherSelector) return 0;
+
+ // if one of them is an id match, they win
+ if (selector.indexOf("#") == 0) return 1;
+ if (otherSelector.indexOf("#") == 0) return -1;
+
+ // for now, we only match on id and type, so 0 is the only option left
+ return 0;
}
-});
+});
dojo.declare("th.helpers.ContainerHelpers", null, {
getScene: function() {
View
221 frontend/js/th/th.js
@@ -32,6 +32,143 @@ dojo.mixin(th, {
HORIZONTAL: "h"
});
+// ** {{{ Resources }}} **
+//
+// Loads those resources that are shared with all Scenes on the same page, like CSS and layout information.
+// Typically there is no need to instantiate this class; a Scene will do it automatically. However, for performance, you may
+// wish to eagerly instantiate an instance to request resources earlier in the page realization process.
+//
+// property cssLoaded
+dojo.declare("th.Resources", null, {
+ constructor: function() {
+ this.loading = false;
+
+ // an array containing objects that correspond to each matching stylesheet in the order specified
+ this.userAgentCss = [];
+ this.authorCss = [];
+ this.userCss = [];
+
+ this.blockUntilImagesLoaded = true;
+
+ // images
+ this.images = {};
+
+ // used during the CSS loading process; due to callbacks, this is pushed top-level so it can be shared across functions
+ this.sheetCount = 0;
+ this.currentSheet = 0;
+
+ // used during image loading process
+ this.imageCount = 0;
+ this.currentImage = 0;
+
+ this.loaded = false; // are all the resources loaded, including CSS and other stuff?
+ this.cssLoaded = false; // are all the CSS sheets loaded?
+ this.imagesLoaded = false; // are all the images references by the CSS loaded?
+
+ this.callbacks = [];
+ },
+
+ load: function() {
+ if (this.loaded) return; // no re-loading
+
+ this.loading = true;
+ this.parseCSS();
+ },
+
+ processImage: function() {
+ this.currentImage++;
+ if (this.imageCount == this.currentImage) {
+ this.imagesLoaded = true;
+ this.onLoaded();
+ }
+ },
+
+ onLoaded: function() {
+ if (this.cssLoaded && ((this.blockUntilImagesLoaded && this.imagesLoaded) || !this.blockUntilImagesLoaded)) {
+ this.loaded = true;
+ this.loading = false;
+ if (this.callbacks) {
+ dojo.forEach(this.callbacks, function(item) {
+ // check if there is context; if so, execute the callback using the context
+ if (item.context) {
+ item.callback.apply(item.context);
+ } else {
+ item.callback();
+ }
+ });
+ }
+ }
+ },
+
+ registerOnLoadCallback: function(callback, context) {
+ this.callbacks.push({ callback: callback, context: context });
+ },
+
+ parseCSS: function() {
+ var links = [];
+
+ // add default stylesheet; cheesy path at the moment, need to come up with a better way to approach this TODO
+ links.push({ url: "js/th/default.css", array: this.userAgentCss, index: 0 });
+
+ var s, l = document.getElementsByTagName('link'), counter = 0;
+ for (var i=0; i < l.length; i++){
+ s = l[i];
+ if (s.rel.toLowerCase().indexOf('thstylesheet') >= 0 && s.href) {
+ links.push({ url: s.href, array: this.authorCss, index: counter++ });
+ }
+ }
+
+ // this shouldn't happen; we should always have at least one userAgentCss otherwise things are going to be mighty sparse
+ if (links.length == 0) {
+ this.cssLoaded = true;
+ return this.onLoaded();
+ }
+
+ this.sheetCount = links.length;
+ dojo.forEach(links, function(link) {
+ dojo.xhrGet({
+ url: link.url,
+ load: dojo.hitch(this, function(response) {
+ this.processCSS(response, link.array, link.index );
+ })
+ });
+ }, this);
+ },
+
+ processCSS: function(stylesheet, array, index) {
+ array[index] = new th.css.CSSParser().parse(stylesheet);
+
+ // load the images
+ for (var rule in array[index]) {
+ for (var property in array[index][rule]) {
+ var value = array[index][rule][property];
+ if (value.indexOf("url(") == 0 && value.indexOf(")") == value.length - 1) {
+ var url = value.substring(4, value.length - 1);
+
+ this.imageCount++;
+ var image = new Image();
+
+ if (this.blockUntilImagesLoaded) {
+ this.imagesLoaded = false;
+ dojo.connect(image, "onload", this, this.processImage);
+ }
+
+ image.src = url;
+ this.images[value] = image;
+
+ // swap out the value in the CSS with an image; not sure this is the right way to go
+ array[index][rule][property] = image;
+ }
+ }
+ }
+
+ if (++this.currentSheet == this.sheetCount) {
+ this.cssLoaded = true;
+ this.onLoaded();
+ }
+ }
+});
+
/*
Event bus; all listeners and events pass through a single global instance of this class.
*/
@@ -42,6 +179,8 @@ dojo.declare("th.Bus", null, {
},
// register a listener with an event
+ // - event: string name of the event
+ // - selector:
bind: function(event, selector, listenerFn, listenerContext) {
var listeners = this.events[event];
if (!listeners) {
@@ -114,18 +253,19 @@ dojo.declare("th.Bus", null, {
// create the global event bus
th.global_event_bus = new th.Bus();
+// create the global resource loader loader
+th.global_resources = new th.Resources();
+
dojo.declare("th.Scene", th.helpers.EventHelpers, {
bus: th.global_event_bus,
- css: {},
+ constructor: function(canvas) {
+ this.resources = th.global_resources;
+ this.resourceCallbackRegistered = false;
- sheetCount: 0,
- currentSheet: 0,
- cssLoaded: false,
- renderRequested: false,
- renderAllowed: true,
+ // if the resource loading process hasn't started, start it!
+ if (!this.resources.loaded && !this.resources.loading) this.resources.load();
- constructor: function(canvas) {
this.canvas = canvas;
dojo.connect(window, "resize", dojo.hitch(this, function() {
@@ -180,18 +320,18 @@ dojo.declare("th.Scene", th.helpers.EventHelpers, {
delete this.mouseDownComponent;
}));
-
- this.parseCSS();
},
- render: function(forceRendering) {
- if (!this.renderAllowed && !forceRendering) {
- return;
- }
- if (!this.cssLoaded) {
- this.renderRequested = true;
+ render: function() {
+ if (!this.resources.loaded) {
+ if (!this.resourceCallbackRegistered) {
+ this.resources.registerOnLoadCallback(this.render, this);
+ this.resourceCallbackRegistered = true;
+ }
+
return;
}
+
this.layout();
this.paint();
},
@@ -204,15 +344,17 @@ dojo.declare("th.Scene", th.helpers.EventHelpers, {
},
paint: function(component) {
- if (!this.cssLoaded) {
- this.renderRequested = true;
+ if (!this.resources.loaded) {
+ if (!this.resourceCallbackRegistered) {
+ this.resources.registerOnLoadCallback(this.render, this);
+ this.resourceCallbackRegistered = true;
+ }
+
return;
}
if (!component) component = this.root;
- //if (component === this.root) console.log("root paint");
-
if (component) {
if (!component.opaque && component.parent) {
return this.paint(component.parent);
@@ -240,42 +382,6 @@ dojo.declare("th.Scene", th.helpers.EventHelpers, {
ctx.restore();
}
- },
-
- parseCSS: function() {
- var links = [];
- var s, l = document.getElementsByTagName('link');
- for (var i=0; i < l.length; i++){
- s = l[i];
- if (s.rel.toLowerCase().indexOf('stylesheet') >= 0&&s.href) {
- links.push(s.href);
- }
- }
- if (links.length == 0) {
- this.cssLoaded = true;
- return;
- }
- this.sheetCount = links.length;
- dojo.forEach(links, function(link) {
- dojo.xhrGet({
- url: link,
- load: dojo.hitch(this, function(response) {
- this.processCSS(response);
- })
- });
- }, this);
- },
-
- processCSS: function(stylesheet) {
- this.css = new th.css.CSSParser().parse(stylesheet, this.css);
-
- if (++this.currentSheet == this.sheetCount) {
- this.cssLoaded = true;
- if (this.renderRequested) {
- this.render();
- this.renderRequested = false;
- }
- }
}
});
@@ -325,6 +431,8 @@ dojo.declare("th.Component", th.helpers.ComponentHelpers, {
},
repaint: function() {
+ if (!this.getScene()) return;
+
this.getScene().paint(this);
}
});
@@ -405,6 +513,7 @@ dojo.declare("th.Container", [th.Component, th.helpers.ContainerHelpers], {
}
ctx.save();
+ this.children[i].resolveCss();
this.children[i].paint(ctx);
ctx.restore();
@@ -439,6 +548,8 @@ dojo.declare("th.Container", [th.Component, th.helpers.ContainerHelpers], {
},
render: function() {
+ if (!th.global_resources.loaded) return;
+
this.layoutTree();
this.repaint();
}

0 comments on commit 2749cba

Please sign in to comment.