Skip to content
Browse files

Add several XBL-related files I had sitting around in my working copy…

…. Not sure exactly the state of these files, whether they work at all, etc.
  • Loading branch information...
1 parent 8426488 commit 4c0bbd7b796bf771ccfe08e99b4227b45fc09f6d Jason Johnston committed Apr 15, 2005
Showing with 1,381 additions and 1 deletion.
  1. +21 −0 Ellipses-test.html
  2. +26 −0 Ellipses.xml
  3. +357 −0 SortableTableColumn-test.html
  4. +114 −0 SortableTableColumn.xml
  5. +39 −0 TitleTip.xml
  6. +88 −0 XBL-DOMOverrides.js
  7. +1 −1 XBL-doc.html
  8. +139 −0 XBL.htc
  9. +497 −0 test/many-elements.html
  10. +35 −0 test/test-innerhtml.html
  11. +48 −0 test/test-xul.xml
  12. +16 −0 test/testpage-emptyelement.html
View
21 Ellipses-test.html
@@ -0,0 +1,21 @@
+<html>
+<head>
+ <title>Ellipses</title>
+
+ <script type="text/javascript" src="../XBL.js"></script>
+
+ <style type="text/css">
+ .ellipses {white-space:nowrap; -moz-binding:url(Ellipses.xml#element); border:1px solid red;}
+ </style>
+
+</head>
+
+<body>
+
+ <h1>Test Ellipses:</h1>
+
+ <p class="ellipses">This is a long line of text set to never wrap so you can test the ellipses XBL binding by horizontally resizing your browser window.</p>
+
+
+</body>
+</html>
View
26 Ellipses.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+
+<bindings xmlns="http://www.mozilla.org/xbl" xmlns:h="http://www.w3.org/1999/xhtml">
+ <binding id="element">
+
+ <implementation>
+ <field name="timer" />
+ <field name="actualValue" />
+
+ <method name="update">
+ <body>
+ var eltWidth = document.defaultView.getComputedStyle(this, null).getPropertyValue("width");
+ var txtWidth = this.offsetWidth;
+ if(txtWidth > parseFloat(eltWidth)) {
+ //BLAHBLAHBLAH
+ }
+ </body>
+ </method>
+
+ <constructor><![CDATA[
+ this.actualValue = this.firstChild.nodeValue;
+ this.timer = setInterval(this., 500);
+ ]]></constructor>
+ </implementation>
+ </binding>
+</bindings>
View
357 SortableTableColumn-test.html
@@ -0,0 +1,357 @@
+<html>
+<head>
+<title>Sort columns by clicking on column headers</title>
+<style type="text/css">
+
+* {font-family:sans-serif;font-size:12px;}
+
+table {border-spacing: 0px; empty-cells:show;}
+td, th {padding:2px; border:0px; border-right:1px solid black; text-align:left;}
+thead th {background:#CCC; border:1px outset #CCC; cursor:default;}
+thead th:active {border-style:inset;}
+
+th.sortable {background:#CCC no-repeat 100% 50%; -moz-binding:url(SortableTableColumn.xml#column-header);}
+th.sortable-table-column-sorted-up {background-image:url(assets/sort_arrow_up.gif);}
+th.sortable-table-column-sorted-down {background-image:url(assets/sort_arrow_down.gif);}
+
+</style>
+
+<script type="text/javascript" src="XBL.js"></script>
+
+</head>
+<body>
+
+<h1>Test Sortable Table Columns</h1>
+
+<table cellspacing="0">
+<thead>
+ <tr>
+ <th class="sortable">Column 1</th>
+ <th class="sortable">Column 2</th>
+ <th class="sortable">Column 3</th>
+ <th class="sortable">Column 4</th>
+ <th class="sortable numeric-sort">Column 5 (numeric)</th>
+ <th class="sortable date-sort">Column 6 (dates)</th>
+ </tr>
+</thead>
+<tbody>
+ <tr>
+ <td>AAA</td>
+ <td>AAB</td>
+ <td>AAC</td>
+ <td>AAD</td>
+ <td>12345</td>
+ <td>02/04/1978</td>
+ </tr>
+ <tr>
+ <td>AAD</td>
+ <td>BBE</td>
+ <td>DFE</td>
+ <td>QQQ</td>
+ <td>23456</td>
+ <td>02/05/1978</td>
+ </tr>
+ <tr>
+ <td>123</td>
+ <td>asdf</td>
+ <td>ERER</td>
+ <td>LKJ</td>
+ <td>646</td>
+ <td>02/06/1978</td>
+ </tr>
+ <tr>
+ <td>CCC</td>
+ <td>EEE</td>
+ <td>YYY</td>
+ <td>GGG</td>
+ <td>84572987/td>
+ <td>02/01/1978</td>
+ </tr>
+ <tr>
+ <td>ayaaayy</td>
+ <td>werrrrr</td>
+ <td>fghjk6</td>
+ <td>876</td>
+ <td>474687.22</td>
+ <td>03/05/1978</td>
+ </tr>
+ <tr>
+ <td>234</td>
+ <td>345</td>
+ <td>456</td>
+ <td>567</td>
+ <td>987874.2223476</td>
+ <td>03/19/1978</td>
+ </tr>
+ <tr>
+ <td>GEG</td>
+ <td>RTR</td>
+ <td>ERER</td>
+ <td>GFGF</td>
+ <td>16.2</td>
+ <td>12/04/1978</td>
+ </tr>
+ <tr>
+ <td>VB</td>
+ <td>sdf</td>
+ <td>hhh</td>
+ <td>rtry</td>
+ <td>1455578</td>
+ <td>12/24/1978</td>
+ </tr>
+ <tr>
+ <td>qer</td>
+ <td>a</td>
+ <td>jjtj</td>
+ <td>lllil</td>
+ <td>98763</td>
+ <td>02/04/1988</td>
+ </tr>
+ <tr>
+ <td>tyu</td>
+ <td>uuuuu</td>
+ <td>kkk</td>
+ <td>yui</td>
+ <td>24973586</td>
+ <td>02/04/2002</td>
+ </tr>
+ <tr>
+ <td>tyutyu</td>
+ <td>uuuu</td>
+ <td>uuu</td>
+ <td>uuu</td>
+ <td>1</td>
+ <td>06/14/1978</td>
+ </tr>
+ <tr>
+ <td>rty</td>
+ <td>rty</td>
+ <td>yui</td>
+ <td>wer</td>
+ <td>-9833</td>
+ <td>06/16/1978</td>
+ </tr>
+ <tr>
+ <td>oihui</td>
+ <td>654sty</td>
+ <td>34srg</td>
+ <td>67dyj</td>
+ <td>-8476</td>
+ <td>06/14/1932</td>
+ </tr>
+ <tr>
+ <td>sert</td>
+ <td>____</td>
+ <td>uiol</td>
+ <td>---</td>
+ <td>-9.9973</td>
+ <td>06/14/2000</td>
+ </tr>
+ <tr>
+ <td>dfg</td>
+ <td>ert</td>
+ <td>kmym</td>
+ <td>werrr</td>
+ <td>-29384</td>
+ <td>06/15/2000</td>
+ </tr>
+ <tr>
+ <td>we</td>
+ <td>we</td>
+ <td>er</td>
+ <td>rt</td>
+ <td>347775</td>
+ <td>10/10/2002</td>
+ </tr>
+ <tr>
+ <td>Jason Johnston</td>
+ <td>dfdfsfdfddfs</td>
+ <td>3442424</td>
+ <td>34534534</td>
+ <td>-29</td>
+ <td>10/11/2002</td>
+ </tr>
+ <tr>
+ <td> Jason Johnston</td>
+ <td>345345</td>
+ <td>345345</td>
+ <td>65456545</td>
+ <td>1526</td>
+ <td>10/04/2002</td>
+ </tr>
+ <tr>
+ <td>Jason Johnston </td>
+ <td>hrtae</td>
+ <td>dtykj dyhj </td>
+ <td> ergh ,yfu y</td>
+ <td>44</td>
+ <td>10/10/1999</td>
+ </tr>
+ <tr>
+ <td> Jason Johnston </td>
+ <td>44t afg h shsthst h</td>
+ <td>tyjj </td>
+ <td>j dj</td>
+ <td>9835</td>
+ <td>10/10/1854</td>
+ </tr>
+ <tr>
+ <td>
+ Jason Johnston</td>
+ <td>arg awerg aeg aerg aerg aegergaergergegaerg</td>
+ <td> grgerttjuyturj</td>
+ <td>ertert</td>
+ <td>35677</td>
+ <td>12/31/1987</td>
+ </tr>
+ <tr>
+ <td>adf</td>
+ <td>l,gkil</td>
+ <td>oi;;</td>
+ <td>hjkfguky</td>
+ <td>234</td>
+ <td>10/10/2222</td>
+ </tr>
+ <tr>
+ <td>67fuykfyuk</td>
+ <td>fyumm</td>
+ <td>srgsergse</td>
+ <td>btndtnyu</td>
+ <td>92746</td>
+ <td>10/11/2000</td>
+ </tr>
+ <tr>
+ <td>kyukd5</td>
+ <td> s5h h </td>
+ <td>fgj tyj</td>
+ <td> dyj dyj </td>
+ <td>.836764</td>
+ <td>01/01/2001</td>
+ </tr>
+ <tr>
+ <td>474wn </td>
+ <td>ASDFASDF</td>
+ <td>WRT HJ</td>
+ <td>DTYJDTYJDTNN</td>
+ <td>0.3746</td>
+ <td>01/01/2000</td>
+ </tr>
+ <tr>
+ <td>45YH</td>
+ <td>TDYN</td>
+ <td></td>
+ <td>BGN.K.</td>
+ <td>82.384</td>
+ <td>01/31/2001</td>
+ </tr>
+ <tr>
+ <td>tyjtjy</td>
+ <td>tjyjj</td>
+ <td>4444</td>
+ <td>avavfa</td>
+ <td>23555</td>
+ <td>01/01/2002</td>
+ </tr>
+ <tr>
+ <td>65u4hstb</td>
+ <td>srth45</td>
+ <td>srng,fyu</td>
+ <td>ey45y</td>
+ <td>0</td>
+ <td>01/01/1955</td>
+ </tr>
+ <tr>
+ <td>rtnsrn</td>
+ <td>o87t8k</td>
+ <td>s6srth</td>
+ <td>45yswg</td>
+ <td>2444</td>
+ <td>01/01/1956</td>
+ </tr>
+ <tr>
+ <td>kjhgjk ghjk </td>
+ <td>y5rsth </td>
+ <td>rgggg</td>
+ <td>zsdff</td>
+ <td>4647</td>
+ <td>01/01/1954</td>
+ </tr>
+ <tr>
+ <td>89845151</td>
+ <td>-----</td>
+ <td>_____</td>
+ <td>+=====</td>
+ <td>2345</td>
+ <td>12/16/2002</td>
+ </tr>
+ <tr>
+ <td>====</td>
+ <td>()</td>
+ <td>2;oi4nfo</td>
+ <td>28y9oianf</td>
+ <td>49876</td>
+ <td>12/17/2001</td>
+ </tr>
+ <tr>
+ <td>adsflkj</td>
+ <td>nowinv</td>
+ <td>wer </td>
+ <td>34tq34g </td>
+ <td>2242</td>
+ <td>12/18/1999</td>
+ </tr>
+ <tr>
+ <td> reter</td>
+ <td>dasf</td>
+ <td> gfdg</td>
+ <td>e4tagr</td>
+ <td>2345</td>
+ <td>11/16/1958</td>
+ </tr>
+ <tr>
+ <td>456</td>
+ <td> adfg</td>
+ <td>gsdfg</td>
+ <td>sdfg</td>
+ <td>3456</td>
+ <td>05/04/2010</td>
+ </tr>
+ <tr>
+ <td>iho;j,</td>
+ <td>sesg</td>
+ <td> sdfdfg</td>
+ <td>545 </td>
+ <td>4567</td>
+ <td>05/16/2010</td>
+ </tr>
+ <tr>
+ <td>shgsw5</td>
+ <td> sdfg</td>
+ <td>sdfgwer5t</td>
+ <td>sdfgshykjtyk</td>
+ <td>5678</td>
+ <td>11/16/1957</td>
+ </tr>
+ <tr>
+ <td>457</td>
+ <td>4w57457</td>
+ <td>w4574w57</td>
+ <td>jkv,vnbm</td>
+ <td>6789</td>
+ <td>05/20/2010</td>
+ </tr>
+ <tr>
+ <td>.,mn</td>
+ <td>sretgbbb</td>
+ <td>xdfg</td>
+ <td>retrg</td>
+ <td>5959595959</td>
+ <td>12/31/2002</td>
+ </tr>
+
+</tbody>
+</table>
+
+
+</body>
+</html>
View
114 SortableTableColumn.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0"?>
+<!-- XXX - this doesn't work in Mozilla. Why? Maybe can't attach bindings to a <th>? -->
+
+<bindings xmlns="http://www.mozilla.org/xbl">
+ <binding id="column-header">
+ <implementation>
+ <field name="column">
+ var i=0, elt=this;
+ while(elt.previousSibling) {
+ elt=elt.previousSibling;
+ if(elt.nodeType==1) {
+ if(elt.getAttribute("colspan")) i=i + parseFloat(elt.getAttribute("colspan"));
+ else i++;
+ }
+ } i;
+ </field>
+
+ <field name="lastSorted">1</field>
+
+ <field name="_sorted">0</field>
+ <property name="sorted" onget="return this._sorted;">
+ <setter><![CDATA[
+ if(val==this._sorted) return; //do nothing if already sorted that way
+ this._sorted = val;
+ this.className = this.className.replace(/\s*sortable-table-column-sorted-(up|down)\s*/g, " ");
+ if(val==0) return; //do nothing else if no sort
+
+ var i;
+ var beginSort=new Date(); //for testing total time
+
+ function stripWhitespaceNodes(parent) { //strips non-element nodes from between elements
+ var elts=parent.childNodes;
+ for(var i=0;i<elts.length;i++) {
+ if(elts[i].nodeType!=1) {
+ parent.removeChild(elts[i]);
+ i--; //child is gone, so length is one less
+ }
+ }
+ parent._textNodesStripped=true;
+ }
+
+ //get following tbody:
+ var tbody=this.parentNode.parentNode;
+ while((!tbody.localName || tbody.localName.toLowerCase()!="tbody") && tbody.nextSibling) tbody=tbody.nextSibling;
+ var table=tbody.parentNode;
+
+ //don't allow clicking to build up:
+ //window.addEventListener("click",SortableTableColumn._cancelEvent,true);
+
+ //remove sort from other column headers:
+ var hdrs = this.parentNode.childNodes;
+ for(i=0; i<hdrs.length; i++) {
+ if(hdrs[i] != this && hdrs[i].sorted) hdrs[i].sorted = 0;
+ }
+
+ //set sort direction:
+ this.className += " sortable-table-column-sorted-" + (val>0 ? "up" : "down");
+
+ //remove whitespace between rows:
+ if(!tbody._textNodesStripped) stripWhitespaceNodes(tbody);
+
+ //sort rows within array:
+ var allRows=tbody.childNodes;
+ var sortCells=[];
+ for(i=0;i<allRows.length;i++) {
+ //remove whitespace between cells:
+ if(!allRows[i]._textNodesStripped) stripWhitespaceNodes(allRows[i]);
+
+ var thisCell=allRows[i].childNodes[this.column];
+ if (!thisCell.row) thisCell.row=allRows[i]; //cache row as prop of text node (perf)
+ if (!thisCell.val) {
+ var txtNode=thisCell;
+ while(txtNode.firstChild) txtNode=txtNode.firstChild; //get deepest firstChild node
+ thisCell.val = (txtNode.nodeValue) ? txtNode.nodeValue.replace(/^\\s*/,"").toUpperCase() : ""; //cache text value (perf)
+ if(this.className.match(/numeric-sort/)) {
+ thisCell.val = parseFloat(thisCell.val);
+ if(isNaN(thisCell.val)) thisCell.val = -999999999;
+ }
+ if(this.className.match(/date-sort/)) {
+ var parts = thisCell.val.split("/");
+ if(parts.length == 3) thisCell.val = parts[2] + parts[0] + parts[1];
+ else thisCell.val = "99/99/9999";
+ }
+ }
+ sortCells[sortCells.length]=thisCell;
+ }
+
+ function byValProp(a,b) { //sorts elements by .val property
+ return (a.val>b.val) ? 1 : (a.val<b.val) ? -1 : 0;
+ }
+ sortCells.sort(byValProp); //Sort it!
+
+ //write sorted rows:
+ for(var i=0;i<sortCells.length;i++) {
+ if(val==-1) tbody.insertBefore(sortCells[i].row,tbody.firstChild);
+ else tbody.appendChild(sortCells[i].row);
+ }
+
+ var endSort=new Date();
+ window.status="Sorting completed on " + allRows.length + " rows. (" + (endSort - beginSort)/1000 + " sec.)";
+
+ //wait a bit before allowing clicks:
+ //setTimeout('window.removeEventListener("click",SortableTableColumn._cancelEvent,true)',1);
+
+ this.lastSorted = val; //remember last sort direction
+ ]]></setter>
+ </property>
+ </implementation>
+
+ <handlers>
+ <handler event="click" action="this.sorted == 0 ? this.sorted = this.lastSorted : this.sorted *= -1" />
+ </handlers>
+ </binding>
+</bindings>
View
39 TitleTip.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<bindings xmlns="http://www.mozilla.org/xbl">
+ <binding id="PopupBase">
+ <implementation>
+ <constructor>
+ </constructor>
+ </implementation>
+ <handlers>
+ <handler event="mousedown" action="event.stopPropagation();" />
+ </handlers>
+ </binding>
+
+ <binding id="TitleTip" extends="#PopupBase">
+ <implementation>
+ <field name="type">"title-tip"</field>
+
+ <constructor>
+ </constructor>
+ </implementation>
+ </binding>
+
+ <binding id="TitledElement">
+ <implementation>
+ <field name="titleTipPopup" />
+ </implementation>
+ <handlers>
+ <handler event="mouseover">
+ var pop = this.titleTipPopup = document.createElement("div");
+ pop.className = "title-tip";
+ document.body.appendChild(pop);
+ </handler>
+ <handler event="mouseout">
+ var pop = this.titleTipPopup;
+ if(pop) document.body.removeChild(pop);
+ this.titleTipPopup = null;
+ </handler>
+ </handlers>
+ </binding>
+</bindings>
View
88 XBL-DOMOverrides.js
@@ -0,0 +1,88 @@
+ElementXBL = {
+ // Override standard DOM methods to be aware of anonymous content:
+ getElementsByTagName : function(name) {
+ return this._xblRealGetElementsByTagName(name);
+ },
+ appendChild : function(newChild) {
+ var p = this; //XXX - need way to get to the insertion point
+ XBL.insertBeforeHelper(p, newChild, null);
+ return p._xblRealAppendChild(newChild);
+ },
+ insertBefore : function(newChild, refChild) {
+ XBL.insertBeforeHelper(this, newChild, refChild);
+ return this._xblRealInsertBefore(newChild, refChild);
+ },
+ replaceChild : function(newChild, oldChild) {
+ return this._xblRealReplaceChild(newChild, oldChild);
+ },
+ removeChild : function(oldChild) {
+ XBL.removeChildHelper(oldChild);
+ return this._xblRealRemoveChild(oldChild);
+ },
+ hasChildNodes : function() {
+ return this._xblRealHasChildNodes();
+ },
+ cloneNode : function(deep) {
+ return this._xblRealCloneNode(deep);
+ },
+
+ _xblGetExplicitChildren : function() {
+ if(!this._xblExplicitChildren) {
+ this._xblExplicitChildren = [];
+ var i, kid, kids=this.childNodes;
+ for(i=0; (kid=kids[i]); i++) {
+ element._xblExplicitChildren[i] = kid;
+ // Handle any child text nodes:
+ if(kid.nodeType==3) {
+ kid._xblRealParentNode = element;
+ kid._xblRealPrevSibling = kids[i-1];
+ kid._xblRealNextSibling = kids[i+1];
+ }
+ }
+ }
+ return this._xblExplicitChildren;
+ }
+};
+
+
+
+// Common routines used in override DOM methods:
+removeChildHelper : function(child) { //updates DOM properties when child removed
+ var i, x, y, p;
+ if(!(p=child._xblRealParentNode)) return; //exit if parentless
+ for(i=0; (x=p._xblRealChildNodes[i]); i++) {
+ if(x==child) {
+ var prev = p._xblRealChildNodes[i-1] || null;
+ var next = p._xblRealChildNodes[i+1] || null;
+ prev._xblRealNextSibling = next;
+ next._xblRealPrevSibling = prev;
+ for(i=i; i<p._xblRealChildNodes.length; i++) p._xblRealChildNodes[i] = p._xblRealChildNodes[i+1];
+ p._xblRealChildNodes.length--;
+ break;
+ }
+ }
+ child._xblRealPrevSibling = child._xblRealNextSibling = child._xblRealParentNode = null;
+},
+insertBeforeHelper : function(parent, newChild, refChild) {
+ var i, j, x, y, prev, next, kids=parent._xblRealChildNodes, refPos=null;
+ XBL.removeChildHelper(newChild);
+
+ if(refChild) for(i=0; (x=kids[i]); i++) if(x==refChild) {refPos = i; break;} //find index of refChild
+ var len = kids.length; //keep orig length
+ if(refPos) { // refChild is actual child; insert before.
+ prev = kids[refPos-1];
+ next = refChild;
+ for(i=refPos; i<len; i++) kids[i+1] = kids[i]; //shift all up one slot
+ kids[refPos] = newChild; //insert new child
+ } else { // refChild is not actual child; insert at end.
+ prev = kids[len-1] || null;
+ next = null;
+ kids[len] = newChild;
+ }
+ if(prev) prev._xblRealNextSibling = newChild;
+ if(next) next._xblRealPrevSibling = newChild;
+ newChild._xblRealPrevSibling = prev;
+ newChild._xblRealNextSibling = next;
+ newChild._xblRealParentNode = parent;
+},
+
View
2 XBL-doc.html
@@ -218,7 +218,7 @@
if(kid.bindingOwner == this) {
// insert code to find real firstChild in IE
}</code></pre>
- <p>What's going on above: The .bindingOwner property only exists on anonymous XBL content nodes, and points to the bound element. Therefore if the bound element's firstChild has a .bindingOwner pointing back to the bound element, you know that the anonymous content model is not supported and you can create a conditional statement to find the correct node. In this way a binding can function in both models.</p>
+ <p>What's going on above: The <code>.bindingOwner</code> property only exists on anonymous XBL content nodes, and points to the bound element. Therefore if the bound element's <code>firstChild</code> has a <code>.bindingOwner</code> pointing back to the bound element, you know that the anonymous content model is not supported and you can create a conditional statement to find the correct node. In this way a binding can function in both models.</p>
<h3>Time of Binding Attachment:</h3>
<p>Unlike Mozilla's XBL implementation which attached bindings to elements as soon as those elements are loaded, this library has to wait until the entire document is loaded. In some ways this makes things easier (you can be sure that everything is already there) but it is different nonetheless and must be taken into account.</p>
View
139 XBL.htc
@@ -0,0 +1,139 @@
+<PUBLIC:COMPONENT lightWeight="true" xmlns:xbl="http://www.mozilla.org/xbl">
+
+ <PUBLIC:PROPERTY NAME="xblChildNodes" GET="getXBLChildNodes" />
+ <!--<PUBLIC:PROPERTY NAME="bindingOwner" GET="getBindingOwner" />-->
+ <PUBLIC:PROPERTY NAME="anonymousParent" GET="getAnonymousParent" />
+
+ <!--
+ <PUBLIC:PROPERTY NAME="childNodes" GET="getChildNodes" />
+ <PUBLIC:PROPERTY NAME="firstChild" GET="getFirstChild" /
+ <PUBLIC:PROPERTY NAME="parentNode" GET="getParentNode" />
+ <PUBLIC:PROPERTY NAME="previousSibling" GET="getPreviousSibling" />
+ <PUBLIC:PROPERTY NAME="nextSibling" GET="getNextSibling" />
+ -->
+
+ <PUBLIC:EVENT ID="bindingAttachedEvent" NAME="onbindingattached" />
+ <PUBLIC:EVENT ID="bindingDetachedEvent" NAME="onbindingdetached" />
+
+ <PUBLIC:METHOD NAME="_xblFireBindingAttachedEvent" /><!-- used to fire custom event from outside HTC -->
+
+ <!--
+ <PUBLIC:ATTACH EVENT="oncontentready" HANDLER="onContentReady" />
+ <PUBLIC:ATTACH EVENT="onreadystatechange" HANDLER="onElementReady" />
+ -->
+ <PUBLIC:ATTACH EVENT="ondocumentready" HANDLER="onHTCAttached" />
+ <!--<PUBLIC:ATTACH EVENT="ondetach" HANDLER="onHTCDetached" />-->
+
+ <SCRIPT LANGUAGE="JScript">
+
+ function onContentReady() {
+ alert('content ready: ' + element.nodeName);
+ }
+
+ function onElementReady() {
+ if(element.readyState=="complete") alert('element ready: ' + element.nodeName);
+ }
+
+ //=== Store initial values of DOM properties: ===//
+ // This should happen before the <PROPERTY> tags above override the initial values,
+ // so we have a way to get to them later. We have to update these when calling our
+ // custom DOM manipulation methods so they will return correct values.
+
+ // At this point the element's contents may not be fully created, so we only know
+ // the parentNode and the previousSibling for sure.
+ /*
+ element._xblRealChildNodes = element.childNodes;
+ var i, kid
+ alert(element.childNodes.length);
+ for(i=0; (kid=element.childNodes[i]); i++) {
+ element._xblRealChildNodes[i] = kid;
+ }
+
+ //element._xblRealFirstChild = element.firstChild;
+ //element._xblRealLastChild = element.lastChild;
+ var parent = element._xblRealParentNode = element.parentElement; //parentElement works here, parentNode doesn't.
+ element._xblRealChildNodes = [];
+
+ if(!parent._xblRealChildNodes) parent._xblRealChildNodes = [];
+ parent._xblRealChildNodes[parent._xblRealChildNodes.length];
+
+ var prev = element._xblRealPrevSibling = element.previousSibling;
+ //alert(prev);
+ if(prev) prev._xblRealNextSibling = element;
+ if(prev && prev.nodeType==3) { //text prev-siblings need to be done manually:
+ prev._xblRealParentNode = parent;
+ var prev2 = prev._xblRealPrevSibling = prev.previousSibling;
+ if(prev2) prev2._xblRealNextSibling = prev;
+ }
+ */
+
+
+ function onHTCAttached() {
+// alert('document ready');
+ var elt = element;
+
+ // Add ElementXBL methods:
+ for(var x in XBL.ElementXBL) {
+ if(elt[x]) elt["_xblReal"+x.charAt(0).toUpperCase()+x.substring(1)] = elt[x]; //make backup if already exists, such as for overridden DOM methods.
+ elt[x] = XBL.ElementXBL[x];
+ }
+
+ // See if there's a binding set in the CSS, and if so attach it:
+ if(!elt.currentStyle) return;
+ var binding = elt.currentStyle.getAttribute("moz-binding"); //IE strangely drops the "-" prefix on -moz-binding
+ if(!binding) return;
+ var m = binding.match(/\s*url\s*\(\s*([^\)]+)\)\s*/); //extract the binding URL
+ if(!m) return; //illegal binding value; exit.
+
+ elt.addBinding(m[1]);
+
+ }
+
+ function onHTCDetached() {
+ }
+
+/*
+ //=== Redefined DOM property getters: ===//
+ function getChildNodes() {
+ var x;
+ return (x=element._xblGetExplicitChildren) ? x() : [];
+ }
+ function getFirstChild() {
+ return element.childNodes[0];
+ }
+ function getParentNode() {
+ return element._xblRealParentNode;
+ }
+ function getPreviousSibling() {
+ return element._xblRealPrevSibling;
+ }
+ function getNextSibling() {
+ return element._xblRealNextSibling;
+ }
+*/
+
+ //=== ElementXBL property getters: ===//
+ function getXBLChildNodes() {
+ return element.document.getAnonymousNodes(element);
+ }
+ function getBindingOwner() {
+ return element._xblBindingOwner || null;
+ }
+ function getAnonymousParent() {
+ return element._xblRealParentNode;
+ }
+
+ //=== Custom Event Triggers: ===//
+ function _xblFireBindingAttachedEvent() {
+ var attEvt = createEventObject();
+ attEvt.cancelBubble=true;
+ bindingAttachedEvent.fire(attEvt);
+ }
+ function _xblFireBindingDetachedEvent() {
+ var detEvt = createEventObject();
+ detEvt.cancelBubble=true;
+ bindingDetachedEvent.fire(detEvt);
+ }
+
+ </SCRIPT>
+</PUBLIC:COMPONENT>
View
497 test/many-elements.html
@@ -0,0 +1,497 @@
+<html>
+<head>
+ <title>Test XBL Bindings</title>
+ <style type="text/css">
+ p {-moz-binding:url(bindings.xml#content-before);}
+ </style>
+
+ <script type="text/javascript" src="../XBL.js"></script>
+
+</head>
+<body>
+
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+ <p>Paragraph</p>
+
+</body>
View
35 test/test-innerhtml.html
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Test XBL Bindings</title>
+
+ <script type="text/javascript">
+
+ function propChanged() {
+ if(window.event.propertyName == "innerHTML") alert('innerHTML changed!');
+ if(window.event.propertyName == "madeUpProperty") alert('madeUpProperty is now ' + event.srcElement.madeUpProperty);
+ }
+
+
+
+ function clicked() {
+ document.getElementById("target").innerHTML = "<h1>Hellooooo!</h1>";
+ }
+
+ function loaded() {
+ document.getElementById("target").attachEvent("onpropertychange", propChanged);
+ }
+
+ window.onload = loaded;
+
+ </script>
+
+</head>
+<body>
+
+ <div id="target">This element's innerHTML will change. If the onpropertychange event is fired, you should see an alert.</div>
+ <button onclick="clicked()">Click Me!</button>
+ <button onclick="document.getElementById('target').madeUpProperty = 'bleh'">Click Me!</button>
+
+
+</body>
View
48 test/test-xul.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Test XBL Bindings</title>
+
+ <script type="text/javascript"><![CDATA[
+
+ function propChanged() {
+ if(window.event.propertyName == "innerHTML") alert('innerHTML changed!');
+ if(window.event.propertyName == "madeUpProperty") alert('madeUpProperty is now ' + event.srcElement.madeUpProperty);
+ }
+
+
+
+ function clicked() {
+ document.getElementById("target").innerHTML = "<h1>Hellooooo!</h1>";
+ }
+
+ function loaded() {
+ document.getElementById("target").attachEvent("onpropertychange", propChanged);
+ }
+
+// window.onload = loaded;
+
+
+
+ function makeXULPopup(btn) {
+ var p = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul","popup");
+ p.appendChild(document.createTextNode("blah"));
+ document.documentElement.appendChild(p);
+ p.showPopup(btn,-1,-1,"popup","bottomright","topleft");
+ }
+
+ ]]></script>
+
+</head>
+<body>
+
+ <div id="target">This element's innerHTML will change. If the onpropertychange event is fired, you should see an alert.</div>
+ <button onclick="clicked()">Click Me!</button>
+ <button onclick="document.getElementById('target').madeUpProperty = 'bleh'">Click Me!</button>
+
+ <hr />
+
+ <xul:button onclick="makeXULPopup(this);" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">Create XUL Popup</xul:button>
+
+</body>
+</html>
View
16 test/testpage-emptyelement.html
@@ -0,0 +1,16 @@
+<html>
+<head>
+ <style type="text/css">
+ div, p {border:1px dotted blue; padding:3px;}
+ #target {border-color:red; -moz-binding:url(bindings.xml#theBindingWithoutKids);}
+ </style>
+
+ <script type="text/javascript" src="http://nucleus/script-library/IEtoW3C.js"></script>
+ <script type="text/javascript" src="../XBL.js"></script>
+
+</head>
+<body>
+
+ <div id="target"></div>
+
+</body>

0 comments on commit 4c0bbd7

Please sign in to comment.
Something went wrong with that request. Please try again.