<?xml version="1.0" encoding="UTF-8"?>

<!-- ***** BEGIN LICENSE BLOCK *****
   - Version: MPL 1.1
   -
   - The contents of this file are subject to the Mozilla Public License Version
   - 1.1 (the "License"); you may not use this file except in compliance with
   - the License. You may obtain a copy of the License at
   - http://www.mozilla.org/MPL/
   -
   - Software distributed under the License is distributed on an "AS IS" basis,
   - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
   - for the specific language governing rights and limitations under the
   - License.
   -
   - The Original Code is the XPath Expressions Editor.
   -
   - The Initial Developer of the Original Code is SHIMODA Hiroshi.
   - Portions created by the Initial Developer are Copyright (C) 2005
   - the Initial Developer. All Rights Reserved.
   -
   - Contributor(s): SHIMODA Hiroshi <piro.outsider.reflex@gmail.com>
   -
   - ***** END LICENSE BLOCK ***** -->

<bindings id="xpath-bindings"
	xmlns="http://www.mozilla.org/xbl"
	xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
	xmlns:xbl="http://www.mozilla.org/xbl">


<binding id="xpath-item-base" extends="xul:vbox">
	<implementation>

		<constructor><![CDATA[
			this.mInit();
		]]></constructor>

		<method name="mInit">
			<body><![CDATA[
			if (this.parentNode.contextType)
				this.contextType = this.parentNode.contextType;

			if (!this.getAttribute('content-type') && this.contentType)
				this.setAttribute('content-type', this.contentType);

			if (!this.getAttribute('id'))
				this.setAttribute('id', this.localName+':'+parseInt(Math.random()*10000000));
			]]></body>
		</method>

		<method name="update">
			<body><![CDATA[
			]]></body>
		</method>


		<property name="ownerList">
			<setter><![CDATA[
				if (val)
					this.mOwnerList = val;
				else
					delete this.mOwnerList;
				return val || null;
			]]></setter>
			<getter><![CDATA[
				if (this.mOwnerList === void(0)) {
					var node = this.parentNode;
					if (node) {
						if (node.internalList)
							node = node.internalList;
						else {
							while (node && !node.containerNode)
							{
								node = node.parentNode;
								if (!node.parentNode) {
									node = null;
									break;
								}
							}
						}
					}

					this.mOwnerList = node || null ;
				}
				return this.mOwnerList;
			]]></getter>
		</property>

		<property name="ownerItem" readonly="true">
			<getter><![CDATA[
				var node = this;
				while (node && !/^(xpath-location-path|xpath-location-step)$/.test(node.localName))
					node = node.parentNode;

				return node;
			]]></getter>
		</property>

		<property name="parentItem" readonly="true">
			<getter><![CDATA[
				return (this.parentNode.localName != 'xpath-operator') ? this.previousSibling : (this.parentNode.parentItem || null) ;
			]]></getter>
		</property>


		<method name="canAcceptNewChild">
			<parameter name="aItem"/>
			<body><![CDATA[
				if (!aItem || this.excludes == 'self::*') return false;

				// Create a clone node to ignore ancestor nodes of the checking node. Why?
				// "excludes" expression is written only for descendant nodes of the item.
				// If we use the expression to the original node, ancestor nodes will affect to the result.
				if (aItem.parentNode) aItem = aItem.cloneNode(true);

				var rejectedNodes = getNodesFromXPath(this.excludes, aItem);
				return (rejectedNodes.snapshotLength) ? false : true ;
			]]></body>
		</method>


		<property name="contextType">
			<getter><![CDATA[
				return this.getAttribute('context-type');
			]]></getter>
			<setter><![CDATA[
				this.setAttribute('context-type', val);

				if (this.hasChildNodes())
					this.firstChild.contextType = val;

				if (this.nextSibling)
					this.nextSibling.contextType = val;

				return val;
			]]></setter>
		</property>

		<property name="focused">
			<getter><![CDATA[
				return this.getAttribute('item-focused') == 'true';
			]]></getter>
			<setter><![CDATA[
				var focused = !(!val);

				if (focused) {
					var nodes = getNodesFromXPath('/descendant::*[@item-focused = "true"][not(*) or not(*[@item-focused])]');
					for (var i = 0; i < nodes.snapshotLength; i++)
						if (nodes.snapshotItem(i) != this)
							nodes.snapshotItem(i).focused = false;

					this.setAttribute('item-focused', true);

					var node = this.parentNode;
					while (node.localName.indexOf('xpath-') > -1 && !node.focused)
					{
						node.setAttribute('item-focused', true);
						node = node.parentNode;
					}
				}
				else {
					this.removeAttribute('item-focused');
					if (this.parentNode.focused)
						this.parentNode.focused = false;
				}

				return focused;
			]]></setter>
		</property>

		<property name="selected">
			<getter><![CDATA[
				return this.getAttribute('item-selected') == 'true';
			]]></getter>
			<setter><![CDATA[
				var selected = !(!val);

				if (!this.ownerList) return false;

				var nodes;
				if (selected) {
					var node = this;
					while (node.parentNode)
					{
						node = node.parentNode;
						if (node.selected)
							return false;
					}

					nodes = this.getElementsByAttribute('item-selected', 'true');
					for (i = nodes.length-1; i > -1; i--)
						nodes[i].selected = false;

					this.setAttribute('item-selected', true);
				}
				else
					this.removeAttribute('item-selected');

				return selected;
			]]></setter>
		</property>

		<property name="removable">
			<getter><![CDATA[
				return this.ownerList && this.getAttribute('removability') != 'false';
			]]></getter>
			<setter><![CDATA[
				if (val)
					this.removeAttribute('removability');
				else
					this.setAttribute('removability', 'false');
				return this.removable;
			]]></setter>
		</property>

		<property name="canCopy" readonly="true">
			<getter><![CDATA[
				return this.ownerList ? true : false ;
			]]></getter>
		</property>

		<property name="canMoveToUpperLevel" readonly="true">
			<getter><![CDATA[
				var node = this.ownerList;
				if (node &&
					node.ownerList &&
					node.ownerList.internalList == node)
					node = node.ownerList;

				if (node)
					node = node.ownerList;


				if (!node)
					return false;
				else
					return node.canAcceptNewChild(this);
			]]></getter>
		</property>


		<property name="dragOver">
			<getter><![CDATA[
				return this.getAttribute('item-drag-over') == 'true';
			]]></getter>
			<setter><![CDATA[
				if (!val)
					this.removeAttribute('item-drag-over');
				else
					this.setAttribute('item-drag-over', true);
				return this.dragOver;
			]]></setter>
		</property>

		<property name="dropPosition">
			<getter><![CDATA[
				return this.getAttribute('item-drop-position');
			]]></getter>
			<setter><![CDATA[
				if (val)
					this.setAttribute('item-drop-position', val);
				else
					this.removeAttribute('item-drop-position');
				return this.dropPosition;
			]]></setter>
		</property>


		<method name="onModified">
			<body><![CDATA[
				if (gExpressionBox.isTyping && !gFocusedItem) return;

				var event = document.createEvent('Events');
				event.initEvent('XPathExpressionModified', false, true);
				this.dispatchEvent(event);
			]]></body>
		</method>

	</implementation>
</binding>







<binding id="xpath-simple-item-base" extends="#xpath-item-base">
</binding>





<binding id="xpath-container-item-base" extends="#xpath-item-base">
	<implementation>

		<field name="mContainerNode">
			null
		</field>
		<property name="containerNode" readonly="true">
			<getter><![CDATA[
				if (!this.mContainerNode) {
					var exp = this.getAttribute('containerNode');
					if (exp)
						eval('this.mContainerNode = ' + exp + ';');
					if (!this.mContainerNode)
						this.mContainerNode = this;
				}
				return this.mContainerNode;
			]]></getter>
		</property>


		<method name="createItem">
			<parameter name="aItemName"/>
			<body><![CDATA[
				aItemName = aItemName || '' ;
				var params = aItemName.split('|');
				if (params.length > 1) {
					aItemName = params[0];
				}
				if (!aItemName) return null;

				var node = document.createElement(aItemName);
				if (params.length > 1) {
					for (var i = 1; i < params.length; i += 2)
						node.setAttribute(params[i], params[i+1]);
				}
				this.appendItem(node);
				if (!gExpressionBox.isTyping) {
					node.selected  = true;
					node.focused   = true;
					gFocusedItem   = node;
				}

				return node;
			]]></body>
		</method>

		<method name="appendItem">
			<parameter name="aItem"/>
			<body><![CDATA[
				if (!aItem) return null;

				if (aItem.ownerList != this && aItem.parentNode != this) {
					clearItemSelection();
					this.containerNode.appendChild(aItem);
					aItem.removable = true;
					aItem.ownerList = this;

					var type = this.childrenContentType || this.getAttribute('content-type-overlay') || this.contentType;
					if (aItem.contentType == type || type == 'any')
						aItem.removeAttribute('content-type-overlay');
					else
						aItem.setAttribute('content-type-overlay', type);

					this.setAttribute('count', this.containerNode.childNodes.length);
					if (this.mAppendItemPostProcess)
						this.mAppendItemPostProcess(aItem);
					this.onModified();
				}

				return aItem;
			]]></body>
		</method>

		<method name="insertItemBefore">
			<parameter name="aItem"/>
			<parameter name="aDistItem"/>
			<body><![CDATA[
				if (!aItem) return null;

				if (aItem.ownerList != this && aItem.parentNode != this)
					this.appendItem(aItem);

				if (aDistItem && 
					aDistItem.parentNode == aItem.parentNode) {
					var nodes = this.containerNode.childNodes;
					var count = nodes.length;
					for (var i = 0; i < count; i++)
						if (nodes[i] == aDistItem) {
							this.moveItemTo(aItem, i);
							return aItem;
						}
				}

				return aItem;
			]]></body>
		</method>

		<method name="removeItem">
			<parameter name="aItem"/>
			<body><![CDATA[
				if (!aItem ||
					aItem.getAttribute('primary') == 'true')
					return;

				if (aItem.focused &&
					aItem.nextSibling &&
					!gExpressionBox.isTyping)
					aItem.nextSibling.focused = true;

				var container = aItem.parentNode;
				container.removeChild(aItem);
				aItem.ownerList = null;

				this.setAttribute('count', container.childNodes.length);
				if (this.mRemoveItemPostProcess)
					this.mRemoveItemPostProcess(aItem);
				this.onModified();

				return aItem;
			]]></body>
		</method>

		<method name="removeAllItems">
			<body><![CDATA[
				var range = document.createRange();
				range.selectNodeContents(this);
				range.deleteContents();
				range.detach();
				this.setAttribute('count', 0);
				this.removeAttribute('item-full');
				this.onModified();
			]]></body>
		</method>


		<method name="unWrapChildren">
			<parameter name="aItem"/>
			<body><![CDATA[
				if (!this.hasChildNodes()) return;

				while (this.hasChildNodes())
					this.moveToUpperLevel(this.firstChild);

				this.ownerList.removeItem(this);
			]]></body>
		</method>

		<method name="moveToUpperLevel">
			<parameter name="aItem"/>
			<body><![CDATA[
				if (!aItem) return null;

				var node = this.removeItem(aItem);
				this.ownerList.insertItemBefore(node, this);

				return node;
			]]></body>
		</method>


		<method name="moveUp">
			<parameter name="aItem"/>
			<body><![CDATA[
				return this.moveItemBy(aItem, -1);
			]]></body>
		</method>

		<method name="moveDown">
			<parameter name="aItem"/>
			<body><![CDATA[
				return this.moveItemBy(aItem, 1);
			]]></body>
		</method>

		<method name="moveItemTo">
			<parameter name="aItem"/>
			<parameter name="aPosition"/>
			<body><![CDATA[
				if (aItem && aItem.nodeType != Node.ELEMENT_NODE)
					aItem = aItem.parentNode;

				if (
					!aItem ||
					aItem.getAttribute('primary') == 'true' ||
					aPosition < 0 ||
					aPosition >= this.containerNode.childNodes.length
					)
					return false;

				var distNode = this.containerNode.childNodes[aPosition];
				if (aItem.compareDocumentPosition(distNode) & Node.DOCUMENT_POSITION_FOLLOWING)
					distNode = distNode.nextSIbling;
				if (distNode == aItem)
					return true;

//				var node = this.containerNode.removeChild(aItem);
//				if (distNode)
					this.containerNode.insertBefore(aItem, distNode);
//				else
//					this.containerNode.appendChild(aItem);

				this.onModified();
				return true;
			]]></body>
		</method>

		<method name="moveItemBy">
			<parameter name="aItem"/>
			<parameter name="aPosition"/>
			<body><![CDATA[
				if (
					!aItem ||
					aItem.getAttribute('primary') == 'true' ||
					aItem.parentNode != this.containerNode
					)
					return false;

				var nodes = this.containerNode.childNodes;
				var count = nodes.length;
				for (var i = 0; i < count; i++)
					if (nodes[i] == aItem)
						return this.moveItemTo(aItem, i+aPosition);

				return false;
			]]></body>
		</method>


		<method name="mGetChildExpressions">
			<parameter name="aStart"/>
			<body><![CDATA[
				var expressions = [];
				var nodes = this.containerNode.childNodes;
				var count = nodes.length;
				for (var i = Math.max((aStart || 0), 0); i < count; i++)
					expressions.push(
						(nodes[i].mHasParen || nodes[i].childNodes.length < 2) ?
							nodes[i].expression :
							'(' + nodes[i].expression + ')'
					);

				return expressions;
			]]></body>
		</method>

		<property name="expression" readonly="true">
			<getter><![CDATA[
				if (!this.containerNode.hasChildNodes()) return '';

				var expressions = this.mGetChildExpressions();
				return expressions.join(this.mExpressionSeparator);
			]]></getter>
		</property>

		<field name="mHasParen">
			false
		</field>

	</implementation>
</binding>



<binding id="xpath-expression" extends="#xpath-container-item-base">
	<content>
		<xul:closebox-bar buttonlabel="この式を削除"/>
		<xul:vbox class="list-container">
			<children/>
		</xul:vbox>
		<xul:edit-bar label="アイテムを追加"
			extraitems="ロケーションパスを追加=xpath-location-path"/>
	</content>

	<implementation>

		<field name="typeLabel">
			'XPath式'
		</field>

		<field name="contentType">
			'any'
		</field>

		<property name="excludes" readonly="true">
			<getter><![CDATA[
				return (this.ownerItem || this.ownerList) ?
						'self::*[contains("xpath-predicate,xpath-location-step,xpath-expression", local-name())]' :
						[
							'self::*[contains("xpath-predicate,xpath-location-step,xpath-expression,xpath-literal", local-name())]',
							'self::xul:xpath-operator[(@type != "addition") or (descendant::xul:xpath-location-step[not(ancestor::xul:xpath-location-path)])]',
							'self::xul:xpath-function[not(contains("id,current,document,key,system-property", @type))]'
						].join('|') ;
			]]></getter>
		</property>

		<property name="mExpressionSeparator" readonly="true">
			<getter><![CDATA[
				var nodes = getNodesFromXPath([
							'child::xul:xpath-location-path',
							'child::xul:xpath-operator[@type = "addition"]',
							'child::xul:xpath-function[contains("id,current,document,key,system-property", @type)]'
						].join('|'), this);
				return (nodes.snapshotLength != this.containerNode.childNodes.length || !nodes.snapshotLength) ?
						' + ' : ' | ' ;
			]]></getter>
		</property>

	</implementation>
</binding>









<binding id="xpath-location-path" extends="#xpath-container-item-base">
	<content>
		<xul:closebox-bar buttonlabel="このロケーションパスを削除"/>
		<xul:vbox class="list-container" content-type="node-set">
			<children/>
		</xul:vbox>
		<xul:edit-bar label="続きを入力"/>
		<xul:value-type type="node-set"/>
	</content>

	<implementation>

		<constructor><![CDATA[
			this.mInit();

			var startingPoint = this.getAttribute('starting-point');
			if (!this.hasChildNodes() && this.getAttribute('relative') != 'true')
				this.createItem('xpath-location-step|primary|true'+(startingPoint ? '|starting-point|'+startingPoint : '' )).removable = false;

			this.removeAttribute('starting-point');
		]]></constructor>

		<field name="typeLabel">
			'ロケーションパス'
		</field>

		<field name="contentType">
			'node-set'
		</field>

		<field name="excludes">
			([
				'self::*[contains("xpath-location-path,xpath-predicate,xpath-literal,xpath-expression", local-name())]',
				'self::xul:xpath-operator[(@type != "addition") or (descendant::xul:xpath-location-path[not(ancestor::xul:xpath-location-step)])]',
				'self::xul:xpath-function[not(contains("id,current,document,key,system-property", @type))]'
			].join('|'))
		</field>

		<property name="expression" readonly="true">
			<getter><![CDATA[
				var steps = [];
				var nodes = this.containerNode.childNodes;
				var count = nodes.length;
				var start = (this.getAttribute('relative') == 'true') ? 0 : 1 ;
				if (count > start) {
					steps = this.mGetChildExpressions(start);
				}
				var starting = (start == 1) ? nodes[0].expression : '' ;
				steps = steps.join('/');
				return [
						starting,
						(starting && starting != '/' && steps ? '/' : '' ),
						steps
					].join('');
			]]></getter>
		</property>

		<field name="mHasParen">
			true
		</field>

	</implementation>
</binding>




<binding id="xpath-location-step-base" extends="#xpath-container-item-base">
	<implementation>

		<!-- for predicates -->
		<field name="contentType">
			'boolean'
		</field>

		<field name="childrenContentType">
			'boolean'
		</field>

		<method name="update">
			<body><![CDATA[
				this.mInitPopup('axis');
				this.mInitPopup('nodetest');
			]]></body>
		</method>

		<property name="nodetest">
			<getter><![CDATA[
				return this.getAttribute('nodetest');
			]]></getter>
			<setter><![CDATA[
				var list = this.mNodetest;

				var items = list.getElementsByAttribute('value', val);
				if (!items.length)
					throw 'Error: xpath-location-step\ninvalid nodetest ['+val+']';

				this.setAttribute('nodetest', val);
				list.selectedItem = items[0];
				this.mUpdateFollowingSteps();

				return this.nodetest;
			]]></setter>
		</property>

		<property name="nodetestValue">
			<getter><![CDATA[
				return this.getAttribute('nodetest-value');
			]]></getter>
			<setter><![CDATA[
				this.setAttribute('nodetest-value', val);
				this.mNodetestValue.setAttribute('value', val);

				return val;
			]]></setter>
		</property>

		<method name="mUpdateFollowingSteps">
			<body><![CDATA[
				var nodes = getNodesFromXPath('(following-sibling::*[contains("xpath-location-step,xpath-operator", local-name())] | following-sibling::*/descendant::*[contains("xpath-location-step,xpath-operator", local-name())])', this);
				var path = this.ownerItem;
				for (var i = 0; i < nodes.snapshotLength; i++)
					if (nodes.snapshotItem(i).ownerItem == path)
						nodes.snapshotItem(i).update();
			]]></body>
		</method>

		<method name="mInitPopup">
			<parameter name="aType"/>
			<parameter name="aPopup"/>
			<body><![CDATA[
				var popup;
				switch (aType)
				{
					case 'axis':
						popup= this.mAxis ? this.mAxis.firstChild : null ;
						if (!popup) return;

						var prev = this.parentItem;
						if (!prev) return;

						var current         = prev.contextType;
						var isRoot          = (current == 'root');
						var isEndAxis       = (prev.axis == 'self');
						var isEnd           = /^(text|comment|processing-instruction)$/.test(current);
						var isSubordination = /^(attribute|namespace)$/.test(current) || /^(attribute|namespace)$/.test(prev.axis);
						var isError         = (prev.axis == 'ERROR');

						this.mShowHideItem(popup, 'value', 'child',
							!isError && !isEndAxis && !isSubordination && !isEnd);
						this.mShowHideItem(popup, 'value', 'descendant',
							!isError && !isEndAxis && !isSubordination && !isEnd);
						this.mShowHideItem(popup, 'value', 'parent',
							!isError && !isRoot && !isEndAxis);
						this.mShowHideItem(popup, 'value', 'ancestor',
							!isError && !isRoot && !isEndAxis);
						this.mShowHideItem(popup, 'value', 'following-sibling',
							!isError && !isRoot && !isEndAxis && !isSubordination);
						this.mShowHideItem(popup, 'value', 'preceding-sibling',
							!isError && !isRoot && !isEndAxis && !isSubordination);
						this.mShowHideItem(popup, 'value', 'following',
							!isError && !isRoot && !isEndAxis && !isSubordination);
						this.mShowHideItem(popup, 'value', 'preceding',
							!isError && !isRoot && !isEndAxis && !isSubordination);
						this.mShowHideItem(popup, 'value', 'descendant-or-self',
							!isError && !isEndAxis && !isSubordination);
						this.mShowHideItem(popup, 'value', 'ancestor-or-self',
							!isError && !isRoot && !isEndAxis && !isSubordination);
						this.mShowHideItem(popup, 'value', 'attribute',
							!isError && !isRoot && !isEnd && !isSubordination);
						this.mShowHideItem(popup, 'value', 'namespace',
							!isError && !isRoot && !isEnd && !isSubordination);
						break;

					case 'nodetest':
						popup = this.mNodetest ? this.mNodetest.firstChild : null ;
						if (!popup)
							return;

						var context         = this.contextType;
						var axis            = this.axis;
						var isAncestor      = /^(parent|ancestor)$/.test(axis);
						var isSubordination = /^(attribute|namespace)$/.test(axis);
						var isSelf          = (axis == 'self');
						var isError         = (axis == 'ERROR');

						var showAll = (
								(isAncestor && !isSubordination) ||
								!/^(comment|text|processing-instruction)$/.test(context)
							) && !isError;

						this.mShowHideItem(popup, 'value', 'all',     showAll);
						this.mShowHideItem(popup, 'value', 'node()',  showAll);
						this.mShowHideItem(popup, 'value', 'name',    showAll);
						this.mShowHideItem(popup, 'value', 'text()',
							(isSelf ?
								/^(root|any|node|all|text)$/.test(context) :
								!(isAncestor || isSubordination)
							) && !isError
						);
						this.mShowHideItem(popup, 'value', 'comment()',
							(isSelf ?
								/^(root|any|node|all|comment)$/.test(context) :
								!(isAncestor || isSubordination)
							) && !isError
						);
						this.mShowHideItem(popup, 'value', 'processing-instruction()',
							(isSelf ?
								/^(root|any|node|all|processing-instruction)$/.test(context) :
								!(isAncestor || isSubordination)
							) && !isError
						);


						var labelType = /^(parent|ancestor)$/.test(axis) ? 'default' :
										/^(attribute|namespace)$/.test(axis) ? axis :
										/^(attribute|namespace)$/.test(context) ? context :
										'default' ;
						var nodes = popup.getElementsByAttribute('label-'+labelType, '*');
						var count = nodes.length;
						for (var i = 0; i < nodes.length; i++)
							nodes[i].setAttribute('label', nodes[i].getAttribute('label-'+labelType));

						break;

					default:
						return;
				}



				var nodes = popup.getElementsByTagNameNS('http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul', 'menuseparator');
				var count = nodes.length;
				for (i = 0; i < count; i++)
					nodes[i].removeAttribute('hidden');

				// Hide needless separators
				nodes = getNodesFromXPath('descendant::xul:menuseparator[not(following-sibling::*[not(@hidden)]) or not(preceding-sibling::*[not(@hidden)]) or local-name(following-sibling::*[not(@hidden)]) = "menuseparator"]', popup);
				for (i = 0; i < nodes.snapshotLength; i++)
					nodes.snapshotItem(i).setAttribute('hidden', true);

				nodes = getNodesFromXPath('descendant::xul:menuitem[not(@hidden) and (not(@anonid) or (@anonid != "error-item"))]', popup);
				var availableItem = (nodes.snapshotLength) ? nodes.snapshotItem(0) : null ;


				var selectItem;
				var errorItem = popup.getElementsByAttribute('anonid', 'error-item')[0];
				var list = popup.parentNode;
				if (!availableItem) {
					errorItem.removeAttribute('hidden');
					selectItem = errorItem;
				}
				else {
					errorItem.setAttribute('hidden', true);
					if (!list.selectedItem ||
						list.selectedItem.getAttribute('hidden') == 'true')
						selectItem = availableItem;
					else if (list.selectedItem.label != list.label)
						selectItem = list.selectedItem;
				}
				if (selectItem) {
					list.selectedItem = selectItem;
					list.setAttribute('value', selectItem.value);
					list.setAttribute('label', selectItem.label);
					switch (aType)
					{
						case 'axis':
							this.axis = selectItem.value;
							break;
						case 'nodetest':
							this.nodetest = selectItem.value;
							break;
					}
				}
			]]></body>
		</method>

		<method name="mShowHideItem">
			<parameter name="aParent"/>
			<parameter name="aAttrName"/>
			<parameter name="aAttrValue"/>
			<parameter name="aShow"/>
			<body><![CDATA[
				var node = aParent.getElementsByAttribute(aAttrName, aAttrValue)[0];
				if (!node) return;

				if (aShow)
					node.removeAttribute('hidden');
				else
					node.setAttribute('hidden', true);
			]]></body>
		</method>

		<method name="mAppendItemPostProcess">
			<body><![CDATA[
				var labelPrimary = this.mLabelColumn.getAttribute('label-primary');
				var label = this.mLabelColumn.getAttribute('label');
				var max = this.childNodes.length;
				var count = this.mLabelColumn.childNodes.length;
				while (count < max)
				{
					this.mLabelColumn.appendChild(document.createElement('hbox'));
					this.mLabelColumn.lastChild.setAttribute('align', 'start');
					this.mLabelColumn.lastChild.appendChild(document.createElement('label'));
					this.mLabelColumn.lastChild.lastChild.setAttribute('value', (count == 0 ? labelPrimary : label ));
					count++;
				}
			]]></body>
		</method>

		<method name="mRemoveItemPostProcess">
			<body><![CDATA[
				var min = this.childNodes.length;
				var count = this.mLabelColumn.childNodes.length;
				while (count > min)
				{
					count--;
					this.mLabelColumn.removeChild(this.mLabelColumn.lastChild);
				}
			]]></body>
		</method>

		<field name="mHasParen">
			true
		</field>

	</implementation>
</binding>

<binding id="xpath-location-step" extends="#xpath-location-step-base">
	<content>
		<xul:closebox-bar buttonlabel="このロケーションパスを削除"/>
		<xul:hbox class="step" align="center">
			<xul:label value="の"/>
			<xul:menulist anonid="axis"
				oncommand="this.parentNode.parentNode.axis = this.value;"
				xbl:inherits="value=axis"
				ondraggesture="event.preventBubble();">
				<xul:menupopup
					onpopupshowing="this.parentNode.parentNode.parentNode.mInitPopup('axis')">
					<xul:menuitem label="子"
						value="child"/>
					<xul:menuitem label="子孫"
						value="descendant"/>
					<xul:menuseparator/>
					<xul:menuitem label="親"
						value="parent"/>
					<xul:menuitem label="祖先"
						value="ancestor"/>
					<xul:menuseparator/>
					<xul:menuitem label="自分より後の兄弟"
						value="following-sibling"/>
					<xul:menuitem label="自分より前の兄弟"
						value="preceding-sibling"/>
					<xul:menuseparator/>
					<xul:menuitem label="子孫を除いた、自分より後"
						value="following"/>
					<xul:menuitem label="祖先を除いた、自分より前"
						value="preceding"/>
					<xul:menuseparator/>
					<xul:menuitem label="自分自身と、子孫"
						value="descendant-or-self"/>
					<xul:menuitem label="自分自身と、祖先"
						value="ancestor-or-self"/>
					<xul:menuseparator/>
					<xul:menuitem label="属性"
						value="attribute"/>
					<xul:menuitem label="名前空間"
						value="namespace"/>
					<xul:menuitem label="（エラー：この文脈ではロケーションステップを指定できません）"
						anonid="error-item"
						value="ERROR"/>
				</xul:menupopup>
			</xul:menulist>
			<xul:label value="にあたる"/>
			<xul:menulist anonid="nodetest"
				oncommand="this.parentNode.parentNode.nodetest = this.value;"
				xbl:inherits="value=nodetest"
				ondraggesture="event.preventBubble();">
				<xul:menupopup
					onpopupshowing="this.parentNode.parentNode.parentNode.mInitPopup('nodetest')">
					<xul:menuitem anonid="nodetest-item-all"
						label-default="あらゆる要素ノード"
						label-attribute="あらゆる属性ノード"
						label-namespace="あらゆる名前空間ノード"
						value="all"/>
					<xul:menuitem anonid="nodetest-item-name"
						label-default="要素ノードで要素名（修飾名）が"
						label-attribute="属性ノードで属性名（修飾名）が"
						label-namespace="名前空間ノードで名前空間接頭辞が"
						value="name"/>
					<xul:menuseparator/>
					<xul:menuitem label="テキストノード"
						value="text()"/>
					<xul:menuitem label="コメントノード"
						value="comment()"/>
					<xul:menuitem label="処理命令ノード"
						value="processing-instruction()"/>
					<xul:menuseparator/>
					<xul:menuitem label="あらゆるノード"
						value="node()"/>
					<xul:menuitem label="（エラー：この文脈で指定可能なノードテストがありません）"
						anonid="error-item"
						value="ERROR"/>
				</xul:menupopup>
			</xul:menulist>
			<xul:hbox class="nodetest-value" align="center">
				<xul:textbox anonid="nodetest-value" flex="1"
					oninput="this.parentNode.parentNode.parentNode.nodetestValue = this.value;"
					xbl:inherits="value=nodetest-value"
					ondraggesture="event.preventBubble();"/>
				<xul:label anonid="nodetest-value-suffix-label"
					value="であるノード"/>
			</xul:hbox>
		</xul:hbox>
		<xul:grid class="predicates">
			<xul:columns>
				<xul:column label="かつ" label-primary="であり"/>
				<xul:column orient="vertical" flex="1" class="list-container"
					content-type="boolean">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:edit-bar label="絞り込み条件を入力"
			extraitems="登場順で絞り込む=xpath-predicate|type|position 属性で絞り込む=xpath-predicate|type|attribute 内容テキストで絞り込む=xpath-predicate|type|text"/>
		<xul:label class="error" value="エラー：この文脈ではロケーションステップを指定できません"/>
	</content>

	<implementation>

		<constructor><![CDATA[
			var axis = this.getAttribute('axis');
			this.axis = axis || 'child';

			var nodetest = this.getAttribute('nodetest');
			this.nodetest = nodetest || 'all';

			var nodetestValue = this.getAttribute('nodetest-value');
			this.nodetestValue = nodetestValue || '';

			this.mInit();

			var prev = (this.parentNode.localName != 'xpath-operator') ? this.previousSibling : this.parentNode ;
			if (prev && prev.contextType)
				this.contextType = prev.contextType;
			else
				this.update();
		]]></constructor>

		<field name="mAxis">
			document.getAnonymousNodes(this)[1].childNodes[1]
		</field>
		<field name="mNodetest">
			document.getAnonymousNodes(this)[1].childNodes[3]
		</field>
		<field name="mNodetestValue">
			document.getAnonymousNodes(this)[1].childNodes[4].childNodes[0]
		</field>
		<field name="mLabelColumn">
			document.getAnonymousNodes(this)[2].childNodes[0].childNodes[0]
		</field>

		<field name="typeLabel">
			'ロケーションステップ'
		</field>

		<field name="excludes">
			([
				'self::*[contains("xpath-location-step,xpath-literal,xpath-expression", local-name())]',
				'self::xul:xpath-operator[(@type = "addition") and descendant::xul:xpath-location-step[not(ancestor::xul:xpath-location-path)]]'
			].join('|'))
		</field>

		<property name="contextType">
			<getter><![CDATA[
				return this.getAttribute('context-type');
			]]></getter>
			<setter><![CDATA[
				var context;

				switch (this.axis)
				{
					case 'attribute':
						context = 'attribute';
						break;
					case 'namespace':
						context = 'namespace';
						break;
					default:
						switch (this.nodetest)
						{
							case 'all':
							case 'name':
								context = /^(attribute|namespace)$/.test(this.parentItem.axis) ? this.parentItem.axis :
										/^(attribute|namespace)$/.test(this.parentItem.contextType) ? this.parentItem.contextType :
										'element'
								break;
							case 'node()':
								context = 'any';
								break;
							case 'text()':
								context = 'text';
								break;
							case 'comment()':
								context = 'comment';
								break;
							case 'processing-instruction()':
								context = 'processing-instruction';
								break;
							default:
								context = 'ERROR';
								break;
						}
						break;
				}

				this.setAttribute('context-type', context);
				this.update();

				if (this.hasChildNodes())
					this.firstChild.contextType = context;

				if (this.nextSibling)
					this.nextSibling.contextType = context;

				return val;
			]]></setter>
		</property>

		<property name="axis">
			<getter><![CDATA[
				return this.getAttribute('axis');
			]]></getter>
			<setter><![CDATA[
				var list = this.mAxis;

				var items = list.getElementsByAttribute('value', val);
				if (!items.length)
					throw 'Error: xpath-location-step\ninvalid axis ['+val+']';

				this.setAttribute('axis', val);
				list.selectedItem = items[0];

				if (items[0].getAttribute('nodeset') == 'true') {
					this.setAttribute('nodeset', 'true');
				}
				else {
					this.removeAttribute('nodeset');
				}

				this.mInitPopup('nodetest');
				this.mUpdateFollowingSteps();

				return this.axis;
			]]></setter>
		</property>

		<property name="expression" readonly="true">
			<getter><![CDATA[
				if (this.axis == 'ERROR' || this.nodetest == 'ERROR')
					return '';

				var nodetest = this.nodetest;
				if (nodetest == 'name')
					nodetest = this.nodetestValue;
				else if (nodetest == 'all')
					nodetest = '*';

				var step = this.axis + '::' + nodetest;

				if (gExpressionType == XPATH_EXPRESSION_SIMPLE)
					step = step
							.replace(/^child::/, '')
							.replace(/^attribute::/, '@')
							.replace(/^descendant-or-self::node\(\)$/, '')
							.replace(/^self::node\(\)$/, '.')
							.replace(/^parent::node\(\)$/, '.');

				var predicates = this.mGetChildExpressions();
				predicates = (predicates.length) ? ['[', predicates.join(']['), ']'].join('') : '' ;

				return [step, predicates].join('');
			]]></getter>
		</property>

	</implementation>
</binding>

<binding id="xpath-location-step-primary" extends="#xpath-location-step-base">
	<content>
		<xul:hbox align="center">
			<xul:menulist anonid="starting-point"
				oncommand="this.parentNode.parentNode.startingPoint = this.value;"
				ondraggesture="event.preventBubble();"
				xbl:inherits="value=starting-point">
				<xul:menupopup>
					<xul:menuitem label="ドキュメントルート"
						value="/"/>
					<xul:menuitem label="このノード"
						value="current"/>
					<xul:menuitem label="このノード自身"
						value="self"/>
				</xul:menupopup>
			</xul:menulist>
			<xul:hbox class="nodetest" align="center">
				<xul:label value="にあたる"/>
				<xul:menulist anonid="nodetest"
					oncommand="this.parentNode.parentNode.parentNode.nodetest = this.value;"
					xbl:inherits="value=nodetest"
					ondraggesture="event.preventBubble();">
					<xul:menupopup
						onpopupshowing="this.parentNode.parentNode.parentNode.parentNode.mInitPopup('nodetest')">
						<xul:menuitem anonid="nodetest-item-all"
							label-default="あらゆる要素ノード"
							label-attribute="あらゆる属性ノード"
							label-namespace="あらゆる名前空間ノード"
							value="all"/>
						<xul:menuitem anonid="nodetest-item-name"
							label-default="要素ノードで要素名（修飾名）が"
							label-attribute="属性ノードで属性名（修飾名）が"
							label-namespace="名前空間ノードで名前空間接頭辞が"
							value="name"/>
						<xul:menuseparator/>
						<xul:menuitem label="テキストノード"
							value="text()"/>
						<xul:menuitem label="コメントノード"
							value="comment()"/>
						<xul:menuitem label="処理命令ノード"
							value="processing-instruction()"/>
						<xul:menuseparator/>
						<xul:menuitem label="あらゆるノード"
							value="node()"/>
						<xul:menuitem label="（エラー：この文脈で指定可能なノードテストがありません）"
							anonid="error-item"
							value="ERROR"/>
					</xul:menupopup>
				</xul:menulist>
			</xul:hbox>
			<xul:hbox class="nodetest-value" align="center">
				<xul:textbox anonid="nodetest-value" flex="1"
					oninput="this.parentNode.parentNode.parentNode.nodetestValue = this.value;"
					xbl:inherits="value=nodetest-value"
					ondraggesture="event.preventBubble();"/>
				<xul:label anonid="nodetest-value-suffix-label"
					value="なノード"/>
			</xul:hbox>
		</xul:hbox>
		<xul:grid class="predicates">
			<xul:columns>
				<xul:column label="かつ" label-primary="であり"/>
				<xul:column orient="vertical" flex="1" class="list-container"
					content-type="boolean">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:edit-bar label="絞り込み条件を入力"
			extraitems="述語を追加=xpath-predicate"/>
	</content>

	<implementation>

		<constructor><![CDATA[
			var starting = this.getAttribute('starting-point');
			this.startingPoint = starting ||
				(
					(!this.ownerList || !this.ownerList.ownerList || !this.ownerList.ownerList.ownerList) ? '/' :
						'current'
				);

			var nodetest = this.getAttribute('nodetest');
			this.nodetest = nodetest || 'node()';

			var nodetestValue = this.getAttribute('nodetest-value');
			this.nodetestValue = nodetestValue || '';

			if (this.hasChildNodes())
				this.mAppendItemPostProcess();

			var event = document.createEvent('Events');
			event.initEvent('XPathExpressionExcludesModified', false, true);
			this.dispatchEvent(event);

			this.mInit();
			this.update();
		]]></constructor>

		<field name="mStartingPoint">
			document.getAnonymousNodes(this)[0].childNodes[0]
		</field>
		<field name="mNodetest">
			document.getAnonymousNodes(this)[0].childNodes[1].childNodes[1]
		</field>
		<field name="mNodetestValue">
			document.getAnonymousNodes(this)[0].childNodes[2].childNodes[0]
		</field>
		<field name="mLabelColumn">
			document.getAnonymousNodes(this)[1].childNodes[0].childNodes[0]
		</field>

		<field name="typeLabel">
			'ロケーションパスの起点'
		</field>

		<property name="excludes" readonly="true">
			<getter><![CDATA[
				return (this.startingPoint == 'self') ?
					[
						'self::*[contains("xpath-location-step,xpath-literal,xpath-expression", local-name())]',
						'self::xul:xpath-operator[(@type = "addition") and descendant::xul:xpath-location-step[not(ancestor::xul:xpath-location-path)]]'
					].join('|') :
					'self::*' ;
			]]></getter>
		</property>

		<property name="contextType">
			<getter><![CDATA[
				return this.getAttribute('context-type');
			]]></getter>
			<setter><![CDATA[
				var context;

				switch(this.startingPoint)
				{
					case 'current':
					case 'self':
						context = this.parentNode.contextType;
						break;
					case '/':
						context = 'root';
						break;
				}

				this.setAttribute('context-type', context);
				this.update();

				if (this.hasChildNodes())
					this.firstChild.contextType = context;

				if (this.nextSibling)
					this.nextSibling.contextType = context;

				return val;
			]]></setter>
		</property>

		<property name="axis" readonly="true"
			onget="return this.startingPoint == 'self' ? 'self' : '' ;"/>

		<property name="startingPoint">
			<getter><![CDATA[
				return this.getAttribute('starting-point');
			]]></getter>
			<setter><![CDATA[
				var list = this.mStartingPoint;

				var items = list.getElementsByAttribute('value', val);
				if (!items.length)
					throw 'Error: xpath-location-step-root\ninvalid starting-point node ['+val+']';

				this.setAttribute('starting-point', val);
				list.selectedItem = items[0];

				this.contextType = true;

				if (!/^(\/|id)$/.test(this.startingPoint) &&
					!this.parentNode.contextType &&
					gCurrentNodeBox.collapsed) {
					gCurrentNodeBox.collapsed = false;
					gRoot.contextType = gCurrentNode.value;
				}

				return val;
			]]></setter>
		</property>

		<property name="expression" readonly="true">
			<getter><![CDATA[
				var expression;
				if (this.startingPoint == 'self') {
					var nodetest = this.nodetest;
					if (nodetest == 'name')
						nodetest = this.nodetestValue;
					else if (nodetest == 'all')
						nodetest = '*';

					var step = this.axis + '::' + nodetest;

					if (gExpressionType == XPATH_EXPRESSION_SIMPLE &&
						step == 'self::node()')
						step = '.';

					var predicates = this.mGetChildExpressions();
					predicates = (predicates.length) ? ['[', predicates.join(']['), ']'].join('') : '' ;

					return [step, predicates].join('');
				}
				else {
					expression = this.startingPoint == 'current' ? '' : this.startingPoint ;
				}
				return expression;
			]]></getter>
		</property>

	</implementation>
</binding>

<binding id="xpath-location-step-id" extends="#xpath-location-step-base">
	<content>
		<xul:label value="IDが"/>
		<xul:radiogroup orient="vertical"
			oncommand="this.parentNode.idType = this.value;">
			<xul:hbox class="id-string">
				<xul:radio value="string" label="文字列"/>
				<xul:textbox anonid="id-string" flex="1"
					oninput="
						this.parentNode.parentNode.parentNode.idType   = 'string';
						this.parentNode.parentNode.parentNode.idString = this.value;
					"
					xbl:inherits="value=id-string"
					ondraggesture="event.preventBubble();"/>
			</xul:hbox>
			<xul:hbox class="id-object">
				<xul:vbox>
					<xul:radio value="object" label="オブジェクト"/>
					<spacer flex="1"/>
				</xul:vbox>
				<xul:vbox flex="1" class="list-container">
					<children/>
				</xul:vbox>
				<xul:label value="の文字列値"/>
			</xul:hbox>
		</xul:radiogroup>
		<xul:label value="である要素ノード"/>
	</content>

	<implementation>

		<constructor><![CDATA[
			var type = this.getAttribute('id-type');
			this.idType = type || 'string' ;

			var string = this.getAttribute('id-string');
			this.idString = string ? string : '';

			if (!this.hasChildNodes()) {
				this.createItem('xpath-expression');
				this.lastChild.removable = false;
				this.lastChild.setAttribute('content-type-overlay', 'string');
				this.setAttribute('item-full', true);

				var event = document.createEvent('Events');
				event.initEvent('XPathExpressionExcludesModified', false, true);
				this.dispatchEvent(event);
			}
			this.mInit();
		]]></constructor>

		<field name="mIdType">
			document.getAnonymousNodes(this)[1]
		</field>
		<field name="mIdString">
			document.getAnonymousNodes(this)[1].childNodes[0].childNodes[1]
		</field>

		<field name="typeLabel">
			'ロケーションパスの起点'
		</field>

		<field name="excludes">
			'self::*'
		</field>

		<property name="contextType">
			<getter><![CDATA[
				return this.getAttribute('context-type');
			]]></getter>
			<setter><![CDATA[
				var context = 'element';

				this.setAttribute('context-type', 'element');
				this.update();

				if (this.hasChildNodes())
					this.firstChild.contextType = context;

				if (this.nextSibling)
					this.nextSibling.contextType = context;

				return val;
			]]></setter>
		</property>

		<property name="idType">
			<getter><![CDATA[
				return this.getAttribute('id-type');
			]]></getter>
			<setter><![CDATA[
				var node = this.mIdType;

				var items = node.getElementsByAttribute('value', val);
				if (!items.length)
					throw 'Error: xpath-location-step-primary\ninvalid id type ['+val+']';

				this.setAttribute('id-type', val);
				node.setAttribute('value', val);
				node.selectedItem = items[0];

				if (!gExpressionBox.isTyping) {
					if (this.idType == 'string') {
						this.mIdString.removeAttribute('disabled');
						this.mIdString.focus();
					}
					else {
						this.firstChild.focused = true;
						this.mIdString.setAttribute('disabled', true);
					}
				}

				return val;
			]]></setter>
		</property>

		<property name="idString">
			<getter><![CDATA[
				return this.getAttribute('id-string');
			]]></getter>
			<setter><![CDATA[
				var node = this.mIdString;

				this.setAttribute('id-string', val);
				node.setAttribute('value', val);

				return val;
			]]></setter>
		</property>

		<method name="update">
			<body><![CDATA[
			]]></body>
		</method>
		<method name="mAppendItemPostProcess">
			<body><![CDATA[
			]]></body>
		</method>
		<method name="mRemoveItemPostProcess">
			<body><![CDATA[
			]]></body>
		</method>

		<property name="expression" readonly="true">
			<getter><![CDATA[
				var args;
				if (this.idType == 'string')
					args = '"'+this.idString+'"';
				else
					args = (this.containerNode.hasChildNodes() ? this.mGetChildExpressions() : [] ).join(', ');
				return ['id(', args, ')'].join('');
			]]></getter>
		</property>


		<field name="mHasParen">
			true
		</field>

	</implementation>
</binding>





<binding id="xpath-predicate-base" extends="#xpath-simple-item-base">
	<implementation>
		<field name="typeLabel">
			'述語（絞り込み条件）'
		</field>
	</implementation>
</binding>

<binding id="xpath-predicate-position" extends="#xpath-predicate-base">
	<content>
		<xul:closebox-bar buttonlabel="この絞り込み条件を削除"/>
		<xul:hbox align="center">
			<xul:label value="登場順が"/>
			<xul:textbox anonid="position" size="5"
				oninput="this.parentNode.parentNode.position = this.value;"
				value="1"
				xbl:inherits="value=position"/>
			<xul:label value="番目である"/>
		</xul:hbox>
	</content>

	<implementation>

		<constructor><![CDATA[
			var position = this.getAttribute('position');
			this.position = position ? position : 1 ;
			this.mInit();
		]]></constructor>

		<field name="mPosition">
			document.getAnonymousNodes(this)[1].childNodes[1]
		</field>

		<property name="position">
			<getter><![CDATA[
				return this.getAttribute('position');
			]]></getter>
			<setter><![CDATA[
				var node = this.mPosition;

				var intVal = parseInt(val);
				if (isNaN(intVal) || intVal <= 0) intVal = 1;
				val = intVal;

				this.setAttribute('position', val);
				node.setAttribute('value', val);

				return val;
			]]></setter>
		</property>

		<property name="expression" readonly="true">
			<getter><![CDATA[
				return ((gExpressionType == XPATH_EXPRESSION_SIMPLE) ? '' : 'position()=') +
					this.position;
			]]></getter>
		</property>

	</implementation>
</binding>

<binding id="xpath-predicate-attribute" extends="#xpath-predicate-base">
	<content>
		<xul:closebox-bar buttonlabel="この絞り込み条件を削除"/>
		<xul:hbox align="start">
			<xul:hbox align="center">
				<xul:textbox anonid="attribute-name" flex="1"
					oninput="this.parentNode.parentNode.parentNode.attributeName = this.value;"
					xbl:inherits="value=attribute-name"/>
				<xul:label value="属性"/>
			</xul:hbox>
			<xul:radiogroup anonid="attribute-type" orient="vertical"
				xbl:inherits="value=attribute-type"
				oncommand="this.parentNode.parentNode.attributeType = this.value;">
				<xul:radio label="を持っている"
					value="has"/>
				<xul:hbox align="center">
					<xul:radio label="の値が"
						value="is"/>
					<xul:textbox anonid="attribute-value" flex="1"
						oninput="
							this.parentNode.parentNode.parentNode.parentNode.attributeType = 'is';
							this.parentNode.parentNode.parentNode.parentNode.attributeValue = this.value;
						"
						xbl:inherits="value=attribute-value"/>
					<xul:label value="である"/>
				</xul:hbox>
			</xul:radiogroup>
		</xul:hbox>
	</content>

	<implementation>

		<constructor><![CDATA[
			var attrName = this.getAttribute('attribute-name');
			this.attributeName = attrName || '' ;

			var attrType = this.getAttribute('attribute-type');
			this.attributeType = attrType || 'has' ;

			var attrValue = this.getAttribute('attribute-value');
			this.attributeValue = attrValue || '';

			this.mInit();
		]]></constructor>

		<field name="mAttributeName">
			document.getAnonymousNodes(this)[1].childNodes[0].childNodes[0]
		</field>
		<field name="mAttributeType">
			document.getAnonymousNodes(this)[1].childNodes[1]
		</field>
		<field name="mAttributeValue">
			document.getAnonymousNodes(this)[1].childNodes[1].childNodes[1].childNodes[1]
		</field>

		<property name="attributeName">
			<getter><![CDATA[
				return this.getAttribute('attribute-name');
			]]></getter>
			<setter><![CDATA[
				var node = this.mAttributeName;

				this.setAttribute('attribute-name', val);
				node.setAttribute('value', val);

				return val;
			]]></setter>
		</property>

		<property name="attributeType">
			<getter><![CDATA[
				return this.getAttribute('attribute-type');
			]]></getter>
			<setter><![CDATA[
				var node = this.mAttributeType;
				if (!node) return val;

				var items = node.getElementsByAttribute('value', val);
				if (!items.length)
					throw 'Error: xpath-predicate\ninvalid attribute type ['+val+']';

				this.setAttribute('attribute-type', val);
				node.setAttribute('value', val);
				node.selectedItem = items[0];

				if (this.attributeType == 'is' && !gExpressionBox.isTyping) {
					this.mAttributeName.removeAttribute('disabled');
					this.mAttributeName.focus();
				}
				else
					this.mAttributeName.setAttribute('disabled', true);

				return val;
			]]></setter>
		</property>

		<property name="attributeValue">
			<getter><![CDATA[
				return this.getAttribute('attribute-value');
			]]></getter>
			<setter><![CDATA[
				var node = this.mAttributeValue;

				this.setAttribute('attribute-value', val);
				node.setAttribute('value', val);

				return val;
			]]></setter>
		</property>

		<property name="expression" readonly="true">
			<getter><![CDATA[
				return ((gExpressionType == XPATH_EXPRESSION_SIMPLE) ? '@' : 'attribute::') +
						this.attributeName +
						(this.attributeType == 'has' ?
							'' :
							(' = "' + this.attributeValue.replace(/"/g, gEscapedQuote) + '"')
						);
			]]></getter>
		</property>

	</implementation>
</binding>

<binding id="xpath-predicate-text" extends="#xpath-predicate-base">
	<content>
		<xul:closebox-bar buttonlabel="この絞り込み条件を削除"/>
		<xul:hbox align="start">
			<xul:label value="内容テキスト"/>
			<xul:radiogroup class="text" anonid="text-type" orient="vertical"
				oncommand="this.parentNode.parentNode.textType = this.value;"
				xbl:inherits="value=text-type">
				<xul:radio label="を持っている"
					value="has"/>
				<xul:hbox align="center">
					<xul:radio label="が"
						value="is"/>
					<xul:textbox anonid="text" flex="1"
						oninput="
							this.parentNode.parentNode.parentNode.parentNode.textType = 'is';
							this.parentNode.parentNode.parentNode.parentNode.text = this.value;
						"
						xbl:inherits="value=text"/>
					<xul:label value="である"/>
				</xul:hbox>
			</xul:radiogroup>
		</xul:hbox>
	</content>

	<implementation>

		<constructor><![CDATA[
			var textType = this.getAttribute('text-type');
			this.textType = textType || 'has' ;

			var text = this.getAttribute('text');
			this.text = text ? text : '';

			this.mInit();
		]]></constructor>

		<field name="mTextType">
			document.getAnonymousNodes(this)[1].childNodes[1]
		</field>
		<field name="mText">
			document.getAnonymousNodes(this)[1].childNodes[1].childNodes[1].childNodes[1]
		</field>

		<property name="textType">
			<getter><![CDATA[
				return this.getAttribute('text-type');
			]]></getter>
			<setter><![CDATA[
				var node = this.mTextType;

				var items = node.getElementsByAttribute('value', val);
				if (!items.length)
					throw 'Error: xpath-predicate\ninvalid text type ['+val+']';

				this.setAttribute('text-type', val);
				node.setAttribute('value', val);
				node.selectedItem = items[0];

				if (this.textType == 'is' && !gExpressionBox.isTyping) {
					this.mText.removeAttribute('disabled');
					this.mText.focus();
				}
				else
					this.mText.setAttribute('disabled', true);

				return val;
			]]></setter>
		</property>

		<property name="text">
			<getter><![CDATA[
				return this.getAttribute('text');
			]]></getter>
			<setter><![CDATA[
				var node = this.mText;

				this.setAttribute('text', val);
				node.setAttribute('value', val);

				return val;
			]]></setter>
		</property>

		<property name="expression" readonly="true">
			<getter><![CDATA[
				return ((gExpressionType == XPATH_EXPRESSION_SIMPLE) ? '' : 'child::') +
						'text()' +
						(this.textType == 'has' ?
							'' :
							(' = "' + this.text.replace(/"/g, gEscapedQuote) + '"')
						);
			]]></getter>
		</property>

	</implementation>
</binding>







<binding id="xpath-operator-base" extends="#xpath-container-item-base">
	<implementation>
		<field name="typeLabel">
			'演算子'
		</field>
	</implementation>
</binding>

<binding id="xpath-operator-addition" extends="#xpath-operator-base">
	<content>
		<xul:closebox-bar buttonlabel="この和集合を削除"/>
		<xul:grid>
			<xul:columns>
				<xul:column
					label-primary-default=""
					label-primary-location-path="このノード"
					label-default="または"
					label-location-path="または、このノード"/>
				<xul:column orient="vertical" flex="1" class="list-container"
					content-type="node-set">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="のすべて（和集合）"/>
		<xul:edit-bar label="アイテムを追加"
			extraitems="XPath式を追加=xpath-expression"/>
		<xul:value-type type="node-set"/>
	</content>

	<implementation>

		<constructor><![CDATA[
			if (this.parentNode.contextType)
				this.contextType = this.parentNode.contextType;

			if (this.hasChildNodes())
				this.mAppendItemPostProcess();
		]]></constructor>

		<field name="mLabelColumn">
			document.getAnonymousNodes(this)[1].childNodes[0].childNodes[0]
		</field>

		<property name="excludes" readonly="true">
			<getter><![CDATA[
				var excludeItem = (!this.ownerItem || this.ownerItem.localName == 'xpath-location-step') ? 'xpath-location-step' : 'xpath-location-path' ;
				var includeItem = (excludeItem == 'xpath-location-path') ? 'xpath-location-step' : 'xpath-location-path' ;


				return [
					'self::*[contains("xpath-predicate,xpath-literal,xpath-expression,'+excludeItem+'", local-name())]',
					'self::xul:xpath-operator[(@type != "addition") or (descendant::xul:'+excludeItem+'[not(ancestor::xul:'+includeItem+')])]',
					'self::xul:xpath-function[not(contains("id,current,document,key,system-property", @type))]'
				].join('|');
			]]></getter>
		</property>

		<method name="update">
			<body><![CDATA[
				var count = this.mLabelColumn.childNodes.length;
				if (count) {
					var owner = this.ownerItem;
					var suffix = (owner && owner.localName == 'xpath-location-path') ? 'location-path' : 'default' ;
					var labelPrimary = this.mLabelColumn.getAttribute('label-primary-' + suffix);
					var label = this.mLabelColumn.getAttribute('label-' + suffix);

					for (var i = 0; i < count; i++)
						this.mLabelColumn.childNodes[i].firstChild.setAttribute('value', (i == 0 ? labelPrimary : label ));
				}
			]]></body>
		</method>

		<method name="mAppendItemPostProcess">
			<body><![CDATA[
				var owner = this.ownerItem;
				var suffix = (owner && owner.localName == 'xpath-location-path') ? 'location-path' : 'default' ;
				var labelPrimary = this.mLabelColumn.getAttribute('label-primary-' + suffix);
				var label = this.mLabelColumn.getAttribute('label-' + suffix);
				var max = this.childNodes.length;
				var count = this.mLabelColumn.childNodes.length;
				while (count < max)
				{
					this.mLabelColumn.appendChild(document.createElement('hbox'));
					this.mLabelColumn.lastChild.setAttribute('align', 'start');
					this.mLabelColumn.lastChild.appendChild(document.createElement('label'));
					this.mLabelColumn.lastChild.lastChild.setAttribute('value', (count == 0 ? labelPrimary : label ));
					count++;
				}
			]]></body>
		</method>

		<method name="mRemoveItemPostProcess">
			<body><![CDATA[
				var min = Math.max(this.childNodes.length, 1);
				var count = this.mLabelColumn.childNodes.length;
				while (count > min)
				{
					count--;
					this.mLabelColumn.removeChild(this.mLabelColumn.lastChild);
				}
			]]></body>
		</method>

		<field name="mExpressionSeparator">
			' | '
		</field>

	</implementation>
</binding>

<binding id="xpath-operator-compare" extends="#xpath-operator-base">
	<content>
		<xul:closebox-bar buttonlabel="この比較グループを削除"/>
		<xul:grid>
			<xul:columns>
				<xul:column>
					<xul:spacer/>
					<xul:label value="と"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:hbox align="center">
			<xul:label value="の値を比べて"/>
			<xul:menulist anonid="type"
				oncommand="this.parentNode.parentNode.type = this.value;"
				ondraggesture="event.preventBubble();">
				<xul:menupopup>
					<xul:menuitem label="値が等しい (=)"
						value="="
						content-type="string"/>
					<xul:menuitem label="値が異なる (!=)"
						value="!="
						content-type="string"/>
					<xul:menuseparator/>
					<xul:menuitem label="下の値が上より大きい (&lt;)"
						value="&lt;"
						content-type="number"/>
					<xul:menuitem label="下の値が上と同じか、上より大きい (≦)"
						value="&lt;="
						content-type="number"/>
					<xul:menuseparator/>
					<xul:menuitem label="下の値が上より小さい (&gt;)"
						value="&gt;"
						content-type="number"/>
					<xul:menuitem label="下の値が上と同じか、上より小さい (≧)"
						value="&gt;="
						content-type="number"/>
				</xul:menupopup>
			</xul:menulist>
			<xul:label value="（※ノードセットを渡した場合、一つでも条件に合えば真）"/>
		</xul:hbox>
		<xul:edit-bar label="アイテムを追加"
			extraitems="XPath式を追加=xpath-expression"/>
		<xul:value-type type="boolean"/>
	</content>


	<implementation>

		<constructor><![CDATA[
			this.mInit();

			this.setAttribute('max-children', 2);

			var type = this.getAttribute('type');
			this.type = type || '=' ;

			if (!this.hasChildNodes()) {
				this.createItem('xpath-expression');
				this.createItem('xpath-expression');
			}
		]]></constructor>

		<field name="mType">
			document.getAnonymousNodes(this)[2].childNodes[1]
		</field>

		<field name="contentType">
			'boolean'
		</field>

		<field name="excludes">
			'self::*[contains("xpath-predicate,xpath-expression", local-name())]'
		</field>

		<property name="type">
			<getter><![CDATA[
				return this.getAttribute('type');
			]]></getter>
			<setter><![CDATA[
				var list = this.mType;
				if (!list) return val;

				var items = list.getElementsByAttribute('value', val);
				if (!items.length)
					throw 'Error: xpath-predicate\ninvalid type ['+val+']';

				this.setAttribute('type', val);
				list.selectedItem = items[0];

				var contentType = items[0].getAttribute('content-type');
				if (contentType)
					this.setAttribute('content-type', contentType);
				else
					this.removeAttribute('contentType');

				return val;
			]]></setter>
		</property>

		<method name="mAppendItemPostProcess">
			<body><![CDATA[
				if (Number(this.getAttribute('max-children')) <= this.childNodes.length)
					this.setAttribute('item-full', true);
				else
					this.removeAttribute('item-full');
			]]></body>
		</method>

		<method name="mRemoveItemPostProcess">
			<body><![CDATA[
				if (Number(this.getAttribute('max-children')) <= this.childNodes.length)
					this.setAttribute('item-full', true);
				else
					this.removeAttribute('item-full');
			]]></body>
		</method>

		<property name="mExpressionSeparator" readonly="true"
			onget="return ' ' + this.type + ' ';"/>

	</implementation>
</binding>

<binding id="xpath-operator-mod" extends="#xpath-operator-base">
	<content>
		<xul:closebox-bar buttonlabel="この計算を削除"/>
		<xul:vbox class="list-container" content-type="number">
			<xul:label ordinal="1" value="÷"/>
			<children/>
		</xul:vbox>
		<xul:label value="の余り"/>
		<xul:edit-bar label="アイテムを追加"
			extraitems="XPath式を追加=xpath-expression"/>
		<xul:value-type type="number"/>
	</content>


	<implementation>

		<constructor><![CDATA[
			this.mInit();

			this.setAttribute('max-children', 2);

			if (!this.hasChildNodes()) {
				this.createItem('xpath-expression');
				this.createItem('xpath-expression');
			}
		]]></constructor>

		<field name="contentType">
			'number'
		</field>

		<field name="excludes">
			'self::*[contains("xpath-predicate,xpath-expression", local-name())]'
		</field>

		<method name="mAppendItemPostProcess">
			<body><![CDATA[
				if (this.childNodes.length > 0) {
					this.childNodes[0].setAttribute('ordinal', '0');
				}
				if (this.childNodes.length > 1) {
					this.childNodes[1].setAttribute('ordinal', '2');
				}

				if (Number(this.getAttribute('max-children')) <= this.childNodes.length)
					this.setAttribute('item-full', true);
				else
					this.removeAttribute('item-full');
			]]></body>
		</method>

		<method name="mRemoveItemPostProcess">
			<body><![CDATA[
				if (Number(this.getAttribute('max-children')) <= this.childNodes.length)
					this.setAttribute('item-full', true);
				else
					this.removeAttribute('item-full');
			]]></body>
		</method>

		<field name="mExpressionSeparator">
			' mod '
		</field>

	</implementation>
</binding>

<binding id="xpath-operator-numeric" extends="#xpath-operator-base">
	<content>
		<xul:closebox-bar buttonlabel="この計算を削除"/>
		<xul:grid>
			<xul:columns>
				<xul:column>
					<xul:spacer/>
					<xul:hbox align="start">
						<xul:menulist anonid="type"
							oncommand="this.parentNode.parentNode.parentNode.parentNode.parentNode.type = this.value;"
							ondraggesture="event.preventBubble();">
							<xul:menupopup>
								<xul:menuitem label="+"
									value="+"/>
								<xul:menuitem label="-"
									value="-"/>
								<xul:menuitem label="×"
									value="x"/>
								<xul:menuitem label="÷"
									value="div"/>
							</xul:menupopup>
						</xul:menulist>
					</xul:hbox>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container"
					content-type="string">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="の計算結果"/>
		<xul:edit-bar label="アイテムを追加"
			extraitems="XPath式を追加=xpath-expression"/>
		<xul:value-type type="number"/>
	</content>


	<implementation>

		<constructor><![CDATA[
			this.mInit();

			var type = this.getAttribute('type');
			this.type = type || '+' ;

			if (!this.hasChildNodes()) {
//				this.createItem('xpath-expression');
//				this.createItem('xpath-expression');
			}
			else
				this.mAppendItemPostProcess();
		]]></constructor>

		<field name="mType">
			document.getAnonymousNodes(this)[1].childNodes[0].childNodes[0].childNodes[1].childNodes[0]
		</field>
		<field name="mTypeColumn">
			document.getAnonymousNodes(this)[1].childNodes[0].childNodes[0]
		</field>

		<field name="contentType">
			'number'
		</field>

		<field name="excludes">
			'self::*[contains("xpath-predicate,xpath-expression", local-name())]'
		</field>

		<property name="type">
			<getter><![CDATA[
				return this.getAttribute('type');
			]]></getter>
			<setter><![CDATA[
				var list = this.mType;
				if (!list) return val;

				var items = list.getElementsByAttribute('value', val);
				if (!items.length)
					throw 'Error: operator\ninvalid type ['+val+']';

				this.setAttribute('type', val);
				list.selectedItem = items[0];

				this.update();

				return val;
			]]></setter>
		</property>

		<method name="update">
			<body><![CDATA[
				var count = this.mTypeColumn.childNodes.length;
				if (count > 2) {
					var label = items[0].getAttribute('label');
					for (var i = 2; i < count; i++)
						this.mTypeColumn.childNodes[i].firstChild.setAttribute('value', label);
				}
			]]></body>
		</method>

		<method name="mAppendItemPostProcess">
			<body><![CDATA[
				var max = this.childNodes.length;
				var count = this.mTypeColumn.childNodes.length;
				while (count < max)
				{
					this.mTypeColumn.appendChild(document.createElement('hbox'));
					this.mTypeColumn.lastChild.setAttribute('align', 'start');
					this.mTypeColumn.lastChild.appendChild(document.createElement('label'));
					this.mTypeColumn.lastChild.lastChild.setAttribute('value', this.mType.selectedItem.getAttribute('label'));
					count++;
				}
			]]></body>
		</method>

		<method name="mRemoveItemPostProcess">
			<body><![CDATA[
				var min = Math.max(this.childNodes.length, 2);
				var count = this.mTypeColumn.childNodes.length;
				while (count > min)
				{
					count--;
					this.mTypeColumn.removeChild(this.mTypeColumn.lastChild);
				}
			]]></body>
		</method>

		<property name="mExpressionSeparator" readonly="true"
			onget="return ' ' + (this.type == 'x' ? '*' : this.type ) + ' ';"/>

	</implementation>
</binding>

<binding id="xpath-operator-logical" extends="#xpath-operator-numeric">
	<content>
		<xul:closebox-bar buttonlabel="この論理演算を削除"/>
		<xul:grid>
			<xul:columns>
				<xul:column>
					<xul:spacer/>
					<xul:hbox align="start">
						<xul:menulist anonid="type"
							oncommand="this.parentNode.parentNode.parentNode.parentNode.parentNode.type = this.value;"
							ondraggesture="event.preventBubble();">
							<xul:menupopup>
								<xul:menuitem label="および"
									value="and"/>
								<xul:menuitem label="または"
									value="or"/>
							</xul:menupopup>
						</xul:menulist>
					</xul:hbox>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container"
					content-type="boolean">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:hbox align="center">
			<xul:label value="の"/>
			<xul:menulist anonid="type"
				oncommand="this.parentNode.parentNode.type = this.value;"
				ondraggesture="event.preventBubble();">
				<xul:menupopup>
					<xul:menuitem label="すべて"
						value="and"/>
					<xul:menuitem label="いずれか"
						value="or"/>
				</xul:menupopup>
			</xul:menulist>
			<xul:label value="が成り立つ場合"/>
		</xul:hbox>
		<xul:edit-bar label="アイテムを追加"
			extraitems="XPath式を追加=xpath-expression"/>
		<xul:value-type type="boolean"/>
	</content>
	<implementation>

		<field name="mType2">
			document.getAnonymousNodes(this)[2].childNodes[1]
		</field>

		<field name="contentType">
			'boolean'
		</field>

		<field name="excludes">
			'self::*[contains("xpath-predicate,xpath-expression", local-name())]'
		</field>

		<property name="type">
			<getter><![CDATA[
				return this.getAttribute('type');
			]]></getter>
			<setter><![CDATA[
				var list = this.mType;
				if (!list) return val;

				var items = list.getElementsByAttribute('value', val);
				if (!items.length)
					throw 'Error: operator\ninvalid type ['+val+']';

				this.setAttribute('type', val);
				list.selectedItem = items[0];

				this.mType2.selectedItem = this.mType2.getElementsByAttribute('value', val)[0];

				var count = this.mTypeColumn.childNodes.length;
				if (count > 2) {
					var label = items[0].getAttribute('label');
					for (var i = 2; i < count; i++)
						this.mTypeColumn.childNodes[i].firstChild.setAttribute('value', label);
				}

				return val;
			]]></setter>
		</property>

	</implementation>
</binding>


<binding id="xpath-literal" extends="#xpath-simple-item-base">
	<content>
		<xul:closebox-bar buttonlabel="この定数を削除"/>
		<xul:hbox align="center">
			<xul:textbox anonid="value" flex="1"
				oninput="this.parentNode.parentNode.value = this.value;"
				xbl:inherits="value"/>
			<xul:menulist anonid="type"
				oncommand="this.parentNode.parentNode.type = this.value;"
				ondraggesture="event.preventBubble();">
				<xul:menupopup>
					<xul:menuitem label="文字列"
						value="string"/>
					<xul:menuitem label="数値"
						value="number"/>
				</xul:menupopup>
			</xul:menulist>
		</xul:hbox>
	</content>


	<implementation>

		<constructor><![CDATA[
			if (this.parentNode.contextType)
				this.contextType = this.parentNode.contextType;

			var type = this.getAttribute('type');
			this.type = type || 'string' ;

			var value = this.getAttribute('value');
			this.value = value ? value : '' ;
		]]></constructor>

		<field name="mType">
			document.getAnonymousNodes(this)[1].childNodes[1]
		</field>
		<field name="mValue">
			document.getAnonymousNodes(this)[1].childNodes[0]
		</field>

		<field name="typeLabel">
			'定数'
		</field>

		<field name="excludes">
			'self::*'
		</field>

		<property name="contentType" readonly="true"
			onget="return this.type;"/>

		<property name="type">
			<getter><![CDATA[
				return this.getAttribute('type');
			]]></getter>
			<setter><![CDATA[
				var list = this.mType;
				if (!list) return val;

				var items = list.getElementsByAttribute('value', val);
				if (!items.length)
					throw 'Error: xpath-predicate\ninvalid type ['+val+']';

				this.setAttribute('type', val);
				list.selectedItem = items[0];

				return val;
			]]></setter>
		</property>

		<property name="value">
			<getter><![CDATA[
				return this.getAttribute('value');
			]]></getter>
			<setter><![CDATA[
				var node = this.mValue;
				if (!node) return val;

				this.setAttribute('value', val);
				node.setAttribute('value', val);

				return val;
			]]></setter>
		</property>

		<property name="expression" readonly="true">
			<getter><![CDATA[
				switch(this.type)
				{
					case 'string':
						return '"' + this.value.replace(/"/g, gEscapedQuote) + '"';

					case 'number':
						return this.value;

					default:
						return '';
				}
			]]></getter>
		</property>

	</implementation>
</binding>





<binding id="xpath-function-base" extends="#xpath-container-item-base">
	<implementation>

		<constructor><![CDATA[
			this.mInit();

			if (this.argumentsDefinition) {
				for (var i = 0; i < this.argumentsDefinition.length; i++)
				{
					if (this.childNodes.length < i+1) {
						this.createItem('xpath-expression');
					}
					this.childNodes[i].removable = false;
					this.childNodes[i].setAttribute('content-type-overlay', this.argumentsDefinition[i]);
				}
			}

			if (this.hasChildNodes() && this.mAppendItemPostProcess)
				this.mAppendItemPostProcess();
		]]></constructor>

		<field name="typeLabel">
			'関数'
		</field>


		<method name="mAppendItemPostProcess">
			<body><![CDATA[
				if (this.argumentsDefinition) {
					for (var i = 0; i < this.argumentsDefinition.length; i++)
					{
						if (this.childNodes.length < i+1) return;

						this.childNodes[i].removable = false;
						this.childNodes[i].setAttribute('content-type-overlay', this.argumentsDefinition[i]);
					}
				}
			]]></body>
		</method>

		<property name="expression" readonly="true">
			<getter><![CDATA[
				var args = this.containerNode.hasChildNodes() ? this.mGetChildExpressions() : [] ;
				return [this.type, '(', args.join(', '), ')'].join('');
			]]></getter>
		</property>

		<field name="mHasParen">
			true
		</field>

	</implementation>
</binding>


<binding id="xpath-function-boolean" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="真偽値への変換：このノードまたは"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="オブジェクト"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
				<xul:column>
					<xul:label value="(省略可)"/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="の値"/>
		<xul:value-type type="boolean"/>
	</content>

	<implementation>
		<field name="type">
			'boolean'
		</field>
		<field name="argumentsDefinition">
			(['boolean'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-ceiling" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="数値"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="の小数点以下を切り上げ"/>
		<xul:value-type type="number"/>
	</content>

	<implementation>
		<field name="type">
			'ceiling'
		</field>
		<field name="argumentsDefinition">
			(['number'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-concat" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="文字列の連結"/>
		<xul:grid>
			<xul:columns>
				<xul:column
					label="+">
					<xul:spacer/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container"
					content-type="string">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:edit-bar label="引数を追加"
			extraitems="XPath式を追加=xpath-expression"/>
		<xul:value-type type="string"/>
	</content>

	<implementation>

		<field name="mLabelColumn">
			document.getAnonymousNodes(this)[2].childNodes[0].childNodes[0]
		</field>

		<field name="type">
			'concat'
		</field>

		<field name="contentType">
			'string'
		</field>

		<method name="mAppendItemPostProcess">
			<body><![CDATA[
				var owner = this.ownerItem;
				var label = this.mLabelColumn.getAttribute('label');
				var max = this.childNodes.length;
				var count = this.mLabelColumn.childNodes.length;
				while (count < max)
				{
					this.mLabelColumn.appendChild(document.createElement('hbox'));
					this.mLabelColumn.lastChild.setAttribute('align', 'start');
					this.mLabelColumn.lastChild.appendChild(document.createElement('label'));
					this.mLabelColumn.lastChild.lastChild.setAttribute('value', label);
					count++;
				}
			]]></body>
		</method>

		<method name="mRemoveItemPostProcess">
			<body><![CDATA[
				var min = Math.max(this.childNodes.length, 1);
				var count = this.mLabelColumn.childNodes.length;
				while (count > min)
				{
					count--;
					this.mLabelColumn.removeChild(this.mLabelColumn.lastChild);
				}
			]]></body>
		</method>

	</implementation>
</binding>

<binding id="xpath-function-contains" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="文字列1"/>
					<xul:label value="文字列2"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
				<xul:column>
					<xul:label value="が"/>
					<xul:label value="を含んでいる"/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:value-type type="boolean"/>
	</content>

	<implementation>
		<field name="type">
			'contains'
		</field>
		<field name="argumentsDefinition">
			(['string', 'string'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-count" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="ノードセット"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="に含まれるノードの数"/>
		<xul:value-type type="number"/>
	</content>

	<implementation>
		<field name="type">
			'count'
		</field>
		<field name="argumentsDefinition">
			(['node-set'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-false" extends="#xpath-simple-item-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="偽 (false)"/>
		<xul:value-type type="boolean"/>
	</content>

	<implementation>
		<field name="type">
			'false'
		</field>
		<field name="excludes">
			'self::*'
		</field>
		<field name="expression">
			'false()'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-floor" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="数値"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="の小数点以下を切り捨て"/>
		<xul:value-type type="number"/>
	</content>

	<implementation>
		<field name="type">
			'floor'
		</field>
		<field name="argumentsDefinition">
			(['number'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-id" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="IDが"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="IDの文字列またはオブジェクト"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="である要素ノード"/>
		<xul:value-type type="node-set"/>
	</content>

	<implementation>
		<field name="type">
			'id'
		</field>
		<field name="argumentsDefinition">
			(['string'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-lang" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="このノードの言語が"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="言語識別子の文字列"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="またはそのサブ言語である"/>
		<xul:value-type type="boolean"/>
	</content>

	<implementation>
		<field name="type">
			'lang'
		</field>
		<field name="argumentsDefinition">
			(['string'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-last" extends="#xpath-simple-item-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="処理対象のノードの数（最後のノードの位置）"/>
		<xul:value-type type="number"/>
	</content>

	<implementation>
		<field name="type">
			'last'
		</field>
		<field name="excludes">
			'self::*'
		</field>
		<field name="expression">
			'last()'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-local-name" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="このノードまたは"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="ノードセット"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
				<xul:column>
					<xul:label value="(省略可)"/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="の最初のノードのローカル名"/>
		<xul:value-type type="string"/>
	</content>

	<implementation>
		<field name="type">
			'local-name'
		</field>
		<field name="argumentsDefinition">
			(['node-set'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-name" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="このノードまたは"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="ノードセット"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
				<xul:column>
					<xul:label value="(省略可)"/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="の最初のノードの修飾名 (名前空間接頭辞:ローカル名)"/>
		<xul:value-type type="string"/>
	</content>

	<implementation>
		<field name="type">
			'name'
		</field>
		<field name="argumentsDefinition">
			(['node-set'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-namespace-uri" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="このノードまたは"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="ノードセット"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
				<xul:column>
					<xul:label value="(省略可)"/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="の最初のノードの名前空間URI"/>
		<xul:value-type type="string"/>
	</content>

	<implementation>
		<field name="type">
			'namespace-uri'
		</field>
		<field name="argumentsDefinition">
			(['node-set'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-normalize-space" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="このノードの文字列値または"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="文字列"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
				<xul:column>
					<xul:label value="(省略可)"/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="の空白記号を正規化"/>
		<xul:value-type type="string"/>
	</content>

	<implementation>
		<field name="type">
			'normalize-space'
		</field>
		<field name="argumentsDefinition">
			(['string'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-not" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="真偽値"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="の値を反転"/>
		<xul:value-type type="boolean"/>
	</content>

	<implementation>
		<field name="type">
			'not'
		</field>
		<field name="argumentsDefinition">
			(['boolean'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-number" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="数値への変換：このノードまたは"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="オブジェクト"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
				<xul:column>
					<xul:label value="(省略可)"/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="の値"/>
		<xul:value-type type="number"/>
	</content>

	<implementation>
		<field name="type">
			'number'
		</field>
		<field name="argumentsDefinition">
			(['number'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-position" extends="#xpath-simple-item-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="このノードの位置（登場順）"/>
		<xul:value-type type="number"/>
	</content>

	<implementation>
		<field name="type">
			'position'
		</field>
		<field name="excludes">
			'self::*'
		</field>
		<field name="expression">
			'position()'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-round" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="数値"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="の小数点以下を四捨五入"/>
		<xul:value-type type="number"/>
	</content>

	<implementation>
		<field name="type">
			'round'
		</field>
		<field name="argumentsDefinition">
			(['number'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-starts-with" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="文字列1"/>
					<xul:label value="文字列2"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
				<xul:column>
					<xul:label value="が"/>
					<xul:label value="で始まる"/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:value-type type="boolean"/>
	</content>

	<implementation>
		<field name="type">
			'starts-with'
		</field>
		<field name="argumentsDefinition">
			(['string', 'string'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-string" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="文字列への変換：このノードまたは"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="オブジェクト"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
				<xul:column>
					<xul:label value="(省略可)"/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="の値"/>
		<xul:value-type type="string"/>
	</content>

	<implementation>
		<field name="type">
			'string'
		</field>
		<field name="argumentsDefinition">
			(['string'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-string-length" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="このノードの文字列値または"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="文字列"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
				<xul:column>
					<xul:label value="(省略可)"/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="の長さ"/>
		<xul:value-type type="number"/>
	</content>

	<implementation>
		<field name="type">
			'string-length'
		</field>
		<field name="argumentsDefinition">
			(['string'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-substring" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
				<xul:row align="center"/>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="文字列"/>
					<xul:label value="数値1"/>
					<xul:label value="数値2"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
				<xul:column>
					<xul:label value="の中で"/>
					<xul:label value="文字目から数えて"/>
					<xul:label value="文字分の部分（省略可）、または最後までの部分"/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:value-type type="string"/>
	</content>

	<implementation>
		<field name="type">
			'substring'
		</field>
		<field name="argumentsDefinition">
			(['string', 'number', 'number'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-substring-after" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="文字列1"/>
					<xul:label value="文字列2"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
				<xul:column>
					<xul:label value="の中で"/>
					<xul:label value="よりも後の部分"/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:value-type type="string"/>
	</content>

	<implementation>
		<field name="type">
			'substring-after'
		</field>
		<field name="argumentsDefinition">
			(['string', 'string'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-substring-before" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="文字列1"/>
					<xul:label value="文字列2"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
				<xul:column>
					<xul:label value="の中で"/>
					<xul:label value="よりも前の部分"/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:value-type type="string"/>
	</content>

	<implementation>
		<field name="type">
			'substring-before'
		</field>
		<field name="argumentsDefinition">
			(['string', 'string'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-sum" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="ノードセット"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="の値の合計"/>
		<xul:value-type type="number"/>
	</content>

	<implementation>
		<field name="type">
			'sum'
		</field>
		<field name="argumentsDefinition">
			(['node-set'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-translate" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
				<xul:row align="center"/>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="文字列1"/>
					<xul:label value="文字列2"/>
					<xul:label value="文字列3"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
				<xul:column>
					<xul:label value="の中の"/>
					<xul:label value="のn番目の文字を"/>
					<xul:label value="のn番目の文字で"/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="置換した文字列"/>
		<xul:value-type type="string"/>
	</content>

	<implementation>
		<field name="type">
			'translate'
		</field>
		<field name="argumentsDefinition">
			(['string', 'string', 'string'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-true" extends="#xpath-simple-item-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="真 (true)"/>
		<xul:value-type type="boolean"/>
	</content>

	<implementation>
		<field name="type">
			'true'
		</field>
		<field name="excludes">
			'self::*'
		</field>
		<field name="expression">
			'true()'
		</field>
	</implementation>
</binding>





<!-- builtin functions of XSLT -->

<binding id="xpath-function-xlst-current" extends="#xpath-simple-item-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="カレントノード"/>
		<xul:value-type type="node-set"/>
	</content>

	<implementation>
		<field name="type">
			'current'
		</field>
		<field name="excludes">
			'self::*'
		</field>
		<field name="expression">
			'current()'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-xslt-document" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="別のドキュメント"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="ドキュメントのURI"/>
					<xul:label value="ベースURI"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
				<xul:column>
					<xul:spacer/>
					<xul:label value="(省略可)"/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="のルートノード"/>
		<xul:value-type type="node-set"/>
	</content>

	<implementation>
		<field name="type">
			'document'
		</field>
		<field name="argumentsDefinition">
			(['string', 'nodeset'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-xslt-element-available" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="以下のXSLT命令"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="要素名"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="を実装している"/>
		<xul:value-type type="boolean"/>
	</content>

	<implementation>
		<field name="type">
			'element-available'
		</field>
		<field name="argumentsDefinition">
			(['string'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-xslt-format-number" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="数値のフォーマットを"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
				<xul:row align="center"/>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="数値"/>
					<xul:label value="フォーマットパターン"/>
					<xul:label value="xsl:decimal-formatによるフォーマットパターン"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
				<xul:column>
					<xul:label value="を"/>
					<xul:label value="で表現"/>
					<xul:label value="(省略可)"/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="以上の指定に従って変換した文字列"/>
		<xul:value-type type="string"/>
	</content>

	<implementation>
		<field name="type">
			'format-number'
		</field>
		<field name="argumentsDefinition">
			(['number', 'string', 'string'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-xslt-element-available" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="以下の関数"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="関数名"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="を実装している"/>
		<xul:value-type type="boolean"/>
	</content>

	<implementation>
		<field name="type">
			'function-available'
		</field>
		<field name="argumentsDefinition">
			(['string'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-xslt-generate-id" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="コンテキストノードまたは"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="ノードセット"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="のための一意なID名"/>
		<xul:value-type type="string"/>
	</content>

	<implementation>
		<field name="type">
			'generate-id'
		</field>
		<field name="argumentsDefinition">
			(['node-set'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-xslt-key" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="以下のキー名と値"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="キーの名前"/>
					<xul:label value="キーの値"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="を持つノード"/>
		<xul:value-type type="node-set"/>
	</content>

	<implementation>
		<field name="type">
			'key'
		</field>
		<field name="argumentsDefinition">
			(['string', 'string'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-xslt-system-property" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="XSLTプロセッサのプロパティ"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="プロパティ名"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="の値"/>
	</content>

	<implementation>
		<field name="type">
			'system-property'
		</field>
		<field name="argumentsDefinition">
			(['string'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>

<binding id="xpath-function-xslt-unparsed-entity-uri" extends="#xpath-function-base">
	<content>
		<xul:closebox-bar buttonlabel="この関数を削除"/>
		<xul:label value="解析対象外エンティティ"/>
		<xul:grid>
			<xul:rows>
				<xul:row align="center"/>
			</xul:rows>
			<xul:columns>
				<xul:column>
					<xul:label value="エンティティ名"/>
				</xul:column>
				<xul:column orient="vertical" flex="1" class="list-container">
					<children/>
				</xul:column>
			</xul:columns>
		</xul:grid>
		<xul:label value="のURI"/>
		<xul:value-type type="string"/>
	</content>

	<implementation>
		<field name="type">
			'unparsed-entity-uri'
		</field>
		<field name="argumentsDefinition">
			(['string'])
		</field>
		<field name="excludes">
			'self::*'
		</field>
	</implementation>
</binding>









<binding id="value-type" extends="xul:hbox">
	<content>
		<xul:label class="node-set-boolean" value="が存在する"/>
		<xul:label class="node-set-string" value="の文字列値"/>
		<xul:label class="node-set-number" value="の文字列値を数値として解釈した値"/>

		<xul:label class="number-boolean" value="が0以外である"/>
		<xul:label class="string-boolean" value="が空でない"/>

		<xul:label class="boolean-number" value="が真であれば1、偽であれば0"/>
		<xul:label class="boolean-string" value="が真であれば&quot;true&quot;、偽であれば&quot;false&quot;"/>

		<xul:spacer flex="1"/>
		<xul:label class="type string" value="文字列"/>
		<xul:label class="type boolean" value="真偽値"/>
		<xul:label class="type number" value="数値"/>
		<xul:label class="type node-set" value="ノードセット"/>
	</content>
</binding>


<binding id="closebox-bar" extends="xul:hbox">
	<content>
		<xul:spacer flex="1"/>
		<xul:toolbarbutton class="closebox"
			xbl:inherits="tooltiptext=buttonlabel"
			oncommand="this.parentNode.parentNode.ownerList.removeItem(this.parentNode.parentNode);"
			onclick="event.preventBubble();"
			ondraggesture="event.preventBubble();"/>
	</content>
</binding>


<binding id="edit-bar" extends="xul:hbox">
	<content>
		<xul:hbox align="center">
			<xul:button popup="add-item-popup"
				xbl:inherits="label,disabled,extraitems"
				ondraggesture="event.preventBubble();"/>
			<children/>
			<xul:spacer flex="1"/>
		</xul:hbox>
	</content>
</binding>







<binding id="xpath-pallet-item" extends="xul:box">
	<content>
		<xul:label xbl:inherits="value=label"/>
	</content>

	<implementation>

		<constructor><![CDATA[
			var i;
			var id;

			if (!this.getAttribute('tooltip')) {
				/*
					Create a new tooltip into the global popupset.
					Why we don't create it into this element as an anonymous
					node? Because, when the pallet is hidden and re-shown, the
					box height of this element is wrongly expanded. So, we have
					to put the tooltip element outside of this element itself.
				*/
				id = 'pallet-item-tooltip-'+this.value;
				var popup = document.getElementById('popupset').appendChild(document.createElement('tooltip'));
				popup.setAttribute('id',             id);
				popup.setAttribute('class',          'pallet-item-tooltip');
				/*
					"noautohide" attribute keeps the tooltip shown, to read the
					long long description.
				*/
				popup.setAttribute('noautohide',     true);
				/*
					When the content of the tooltip is too long, lines will be
					broken. Then, the height of the tooltip is shown too thin,
					so, we have to reset the height manually. It's a bug of
					Gecko...
				*/
				popup.setAttribute('onpopupshowing', 'this.setAttribute("height", this.boxObject.height);');

				/*
					Put lines into a vertical box. When I put lines into the
					tooltip directly, they are shown in wrong order...
				*/
				popup.appendChild(document.createElement('vbox'));
				var content = this.getAttribute('description').split('<br/>');
				if (content[0]) {
					var bar = popup.firstChild.appendChild(document.createElement('hbox'));
					bar.setAttribute('index', '0');

					bar.appendChild(document.createElement('description'));
					bar.lastChild.appendChild(document.createTextNode(content[0]));

					bar.appendChild(document.createElement('spacer'));
					bar.lastChild.setAttribute('flex', '1');

					bar.appendChild(document.createElement('toolbarbutton'));
					bar.lastChild.setAttribute('class',         'closebox');
					bar.lastChild.setAttribute('oncommand',     'this.parentNode.parentNode.hidePopup();');
					bar.lastChild.setAttribute('onclick',       'event.preventBubble();');
					bar.lastChild.setAttribute('ondraggesture', 'event.preventBubble();');
				}
				for (i = 1; i < content.length; i++)
				{
					popup.firstChild.appendChild(document.createElement('description'));
					popup.firstChild.lastChild.appendChild(document.createTextNode(content[i]));
					popup.firstChild.lastChild.setAttribute('index', i);
				}

				this.setAttribute('tooltip', id);
			}


			if (!this.getAttribute('related-template-node')) {
				id = 'item-template-'+this.value;
				var template = document.getElementById('item-templates').appendChild(document.createElement(this.itemName));
				template.setAttribute('id', id);

				var params = this.value.split('|');
				if (params.length > 1) {
					for (i = 1; i < params.length; i += 2)
						template.setAttribute(params[i], params[i+1]);
				}
				this.setAttribute('related-template-node', id);
			}


			/*
				Wrap up this element. I wish to set this element itself with
				the "addEventListener" method, but it doesn't accept the element
				node as it's listener.
			*/
			var handler = {
					node        : this,
					handleEvent : function(aEvent) {
						this.node.handleEvent(aEvent);
					}
				};
			this.handler = handler;
			document.documentElement.addEventListener('XPathExpressionFocused', handler, true);
			document.documentElement.addEventListener('XPathExpressionExcludesModified', handler, true);
			document.documentElement.addEventListener('unload', handler, true);
		]]></constructor>

		<property name="itemName" readonly="true"
			onget="return this.value.split('|')[0];"/>

		<property name="value" readonly="true"
			onget="return this.getAttribute('type');"/>

		<property name="returns" readonly="true"
			onget="return this.getAttribute('returns');"/>

		<property name="disabled"
			onget="return this.getAttribute('disabled') == 'true';"
			onset="if (val) this.setAttribute('disabled', val != false); else this.removeAttribute('disabled'); return val;"/>

		<property name="relatedTemplateNode" readonly="true"
			onget="return document.getElementById(this.getAttribute('related-template-node'));"/>

		<method name="handleEvent">
			<parameter name="aEvent"/>
			<body><![CDATA[
				switch(aEvent.type)
				{
					case 'XPathExpressionFocused':
					case 'XPathExpressionExcludesModified':
						var item = gFocusedItem || gRoot;
						this.disabled = !item.canAcceptNewChild(this.relatedTemplateNode);
						break;

					case 'unload':
						document.documentElement.removeEventListener('XPathExpressionFocused', this.handler, true);
						document.documentElement.removeEventListener('XPathExpressionExcludesModified', handler, true);
						document.documentElement.removeEventListener('unload', this.handler, true);
						break;

					default:
						break;
				}
			]]></body>
		</method>

	</implementation>
</binding>






<binding id="scrollbar"
  extends="chrome://global/content/bindings/scrollbar.xml#scrollbar">
  <implementation>
    <constructor><![CDATA[
      // スクロールバー自身の初期化処理
      if (navigator.platform.indexOf('Mac') != -1)
        this.initScrollbar(); 

      // 親要素の「スクロール可能な要素」に
      // プロパティとして自分自身を登録
      if (this.orient == 'horizontal')
        this.parentNode.mHorizontalScrollbar = this;
      else
        this.parentNode.mVerticalScrollbar = this;
    ]]></constructor>
    <destructor><![CDATA[
      // 非表示になる時には
      // 親要素から自分への参照を削除
      if (this.orient == 'horizontal')
        this.parentNode.mHorizontalScrollbar = null;
      else
        this.parentNode.mVerticalScrollbar = null;
    ]]></destructor>
  </implementation>
</binding>

</bindings>

