From: Subject: Current Meeting Agenda | University Academic Senate | Marquette University Date: Tue, 22 Feb 2011 17:35:31 -0600 MIME-Version: 1.0 Content-Type: multipart/related; type="text/html"; boundary="----=_NextPart_000_0000_01CBD2B6.E7122D00" X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5994 This is a multi-part message in MIME format. ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Location: http://www.marquette.edu/academicsenate/restricted/current_meeting-agenda.shtml Current = Meeting Agenda | University Academic Senate | Marquette = University
=

Find a form or document

=20
  • {N= AME}

3D"Marquette

University Academic Senate Agenda
February 21, = 2011
3:00 p.m.=20 to 5:00 p.m.
AMU Ballroom E

I. Call to Order and Reflection by Dr. Sid Syam=20             = (3:00-3:05)

II. Approval of  January 24, 2011 Minutes=20             &= nbsp;      =20 (3:05-3:10)          &n= bsp;      =20 (Attachment=20 II )

III. Provost Report- Dr. John Pauly=20             &= nbsp;    =20             = (3:10-3:30)=20

    • Update on retirement policy
    • Raise pool
    • 9 month pay schedule

IV. Chair=92s report =96 Dr. Christine Krueger=20         =20            =20 (3:30-3:40)

    • Update on CAPI work on confidentiality and transparency = policy
    • Report on Fr. Wild=92s state of the university address
    • Discussion of UAS statement on collegiality
V. = Vice Chairs=20 Report =96 Dr. Marilyn Frenn=20            =20          (3:45-4:10)=20             &= nbsp;   =20 (Attachment=20 V)
    • Faculty Council motion on meetings with deans=92 = council   =20 =             &= nbsp;           &n= bsp;=20
    • Faculty Council motion on UAS participation in leadership=20 bodies  =20            =

VI. Other business

    • Report on Health Clinic, Dr. Margaret Callahan, Dean, College of = Nursing=20 (4:10-4:15)
    • Committee on Faculty Welfare =96 Prof Judith McMullen/Mr. Matt = Blessing=20 MOTION: Legal Domiciled Adults=20 benefits       (4:15-4.45)   = (Attachment=20 VIb1 and VIb2)
    • First reading of Motion to change UAS statutes on chair of = University=20 Assessment Committee, Dr. Gary Meyer, Vice Provost for Undergraduate = Programs and Teaching (4:45-4:50)=20 =             &= nbsp;   =20 (Attachment=20 VIc)
    • Request for UAS recommendations for faculty representation on = search=20 committees for CTL Director and Assessment Director    = (4:50-5:00)=20

VII. Motion to Adjourn

 

The next meeting will be Monday, March 21 at 3 p.m. in AMU = Ballroom=20 E

 

 

UPCOMING EVENTS


  • The=20 next meeting of UAS is Monday February 21, 2011 in AMU Ballroom E at 3 = p.m.=20 The agenda has been approved by the Executive Committee.
  • University=20 Academic Senate agenda for February 21, 2011

 

3D"Marquette
=A9 2011 Marquette = University


------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/_globalimages/blue_navbar/logo_onwhite.gif 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 evWrRQgCADs= ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/_globalimages/blue_navbar/rss_onwhite.gif R0lGODlhDgAOAOZqANtXHPWRNel9Me6BLfKpXPrq1u+FKv6cPfaTOONsJfiXNeJsLPOMMuByLPSQ LO+EMvfp2veRN/fu3vbexvK9hOh4MOyxfO19MumNRPLJo95hJe2DMdtdIvft2+16LuJ9Ned0LfGR MvWNK/SPMveSMfqWOvSybf+fNfGKMPKzdvCPNvLiy/n17fbixPTy6/bx5vOJNveWN/CCNPCSPPGR N/iVLPGkWfDQufPYuO+2jPf39fKdPO+VNPOKIu/XxOGCR/fv6eyXRtdiM+eENN1uOPCHOt1+Q99u LNlvMOyqePPPnfOUMfjy5PXTr/TXr/CQOvPbsep0Jt9tJuOYX/2aOfuYO/yZPfPVqvnqz/aLNe7g z+2iXNyEUvv58OWxkumnZ+abYPv8+eKlhNZ1ReSgfeyHM/aaN/mcOf3///v//////wAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5 BAEAAGoALAAAAAAOAA4AAAfKgGoNUR4yMBEIJVYHByqCIFNgGAMGIwgKZmcnDB4fEGEuKykBJJln CjEyAhkFLGloLQQ1Z2YBDEUDZWUzFB1pTCYONCgPMGVNOBYOO1BpLFsGGxdZKhJpaQUES05oK0MC FREjNhRYaV0ETxBpFgkgJQEiPTxXaBIbSWhaRwtVJCkTTIRogSbHhxc6uGigYsZXARFf0EyQcgMN GQAHFCh5kcEABhc+kHgBIgZAiBMIgpQZIOCHkQVExgjhoIZBDGIXKiRIsEADAJqBAAA7 ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/_globalimages/blue_navbar/01.gif R0lGODlhggAXAMQAAEBmjH+Zsu/y9RBAcM/Z4iBNeY+lvGCAoN/l7DBZg5+yxVBzlq+/z3CNqb/M 2f///wAzZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAA AAAALAAAAACCABcAAAX/ICSOZGmeaKqubOu+cCzPdG3feK7vfO//wKBwSCwaj8ikMnZwOA0Do8Pw GigeiIDL4FiWAg+F4cEYHhKQwOF1PTAeAEihoXI8WgMtEBwn3EcFEAMAUSIJhCRxIwCBi418K4wl dgMJDmsPXSeEdiKDhZ5oEJ1ykjuQCAKjDwJqmQ9rCgKpBWACmRAJs2G5AgQCDAAPwxCZC7ADDwa6 CLwjYA6Ndg8BnbhjDs0QB1iwq7cBYJncfgunDwR+VHYNBQgEEAQIxQS1AGALYwVXA2NWD/0e1IJT zEGyAMIW8PM34h81EbisdfEV7867ePAoRbxDSc05BR5XQezS6YoDNHz4+tjJBoeUCEi4CDgAs4ql ohELbmEieQfXxmICHNwS+ZMbAnMunGhCAWkEqZ/bBAgYeK8lHACc7hQgBLNLAAEKytjBikgEFwjC FBQk2uUnOrJsRaIt5yKcHqYEnf5Jh3GUAW4L8OkbLNDfmARd0WKhQ7gRhDeHlK2VCIHiUHnx5lHu xKWAZB1NRZA6ZsecrHd50AXtlUptAV/AcvlZW/kBGmZgSeQchiCQgVZgmnUZw+oOOW+UDyC4pFpU kU8jEojicxOtY+swTJUA4JxEAlBowUNfsdXLidDm0wdp0l29+/fw48ufT7++jWH48+vfz7+///8A BijggAQCGAIAOw== ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/_globalimages/blue_navbar/02.gif R0lGODlhcQAXAMQAABBAcEBmjM/Z4n+ZsmCAoO/y9d/l7CBNeTBZg4+lvFBzlp+yxa+/z3CNqb/M 2f///wAzZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAA AAAALAAAAABxABcAAAX/ICSOZGmeaKqubOu+cCzPdG3feK7vfO//wKBwSCwajzqF4MFABAGLh2Hg SjiQrcNDoChcdQDqKEpgPAKQQ0PleLTCRsKDAGmrDiM8IAAgAZx1biNtfw50D18mfHYQe30jfyKM BwF4QANnJHaIgQUDbZ5yBnOdDwOYnCKYDpZtpptXCYijEKKkoKaohlsPCpeZg26cbQ0HxAcGAhAC yoTDgiJQD6YizxCcBcpLEMnLzQ8A1oQDdD+YaMHXV4yMD14FbrCBJl2k1pz37/HC626ivi4cCHzR oNc8eewEbQnAcJ61EVYgBHiwQJ3DK/cEMESDUFCAJQBZnBLTAgETANkucc5bKcDAMpcdSZhBMDGB RXkp4b3cGdOKFptAZLnzhWlUP0mC5CyhI4+AgUT1pOBJ4KkoJ6E6ld7iV+up0gKAgOwhgeCRCkcw AoQla1ZiW7QrKGGZS7eu3bt48+rdy7fvjmmAAwseTLiw4cOIEytebDgEADs= ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/_globalimages/blue_navbar/03.gif R0lGODlhQQAXAMQAAH+ZskBmjO/y9RBAcDBZg4+lvCBNec/Z4mCAoK+/z1BzlnCNqd/l7J+yxb/M 2f///wAzZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAA AAAALAAAAABBABcAAAXDICSOZGmeaKqubOu+cCzPdG3feK7vfO+XCUdBRHAgasXjz/B4CESBB6Bm AAR+kMXD8SBAolPUwAAZeEeEAZaUECAei68UwoVs7QLBtml1OgdgWAIOTA5yU3V3DwcDi40OYAUP AYE+UQ0Beod0D3aGip+QUgCTlSwFDg5nK5JNTQqBiaGenmCklHMtCAAAZCwHTxAKDwWxnaC0W7al uTyNCSKNB4GkDMigy7hhayhp3N/g4eLj5OXmNa7p6uvs7e7v8E0hADs= ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/_globalimages/blue_navbar/04.gif R0lGODlhRAAXAMQAAH+Zsr/M2TBZg+/y9RBAcCBNeY+lvJ+yxc/Z4mCAoN/l7FBzlq+/z3CNqUBm jP///wAzZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAA AAAALAAAAABEABcAAAXcICSOZGmeaKqubOu+cCzPdG3feK7vfO/jgoDwIPj9HI8AYDDAJYrGERIA MTwckIIDOiqIHF4SFgK4Qghb4xRyeAgWD8TDQH4MAoKB4nGoD5JID24DcnQ+SAoBcRAJVIp1RG0E VgRlDnJ1DmULjUdJAA0EWQyCD5kQigF7mlePlnkDVC4GQlwqayOSrmaKDr6VraaWo3MujQBhK7gi igR7p1YF0Za7Dgl4CgiesiJwD6SneQoDfdSmAnJ5cglRJgWiKGAsaPDt9vf4+fr7/P0vpQADChxI sKDBgwFDAAA7 ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/_globalimages/blue_navbar/05.gif R0lGODlhaQAXAMQAAL/M2d/l7O/y9RBAcCBNeVBzlmCAoDBZg8/Z4o+lvJ+yxXCNqa+/z0BmjH+Z sv///wAzZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAA AAAALAAAAABpABcAAAX/ICSOZGmeaKqubOu+cCzPdG3feK7vfO//wKBwSCwaVQaAEiA7AAysQSLw YAxKzgeisCo8Bwpm0PFQOByyxgNNWKQWD4Ph4SYFAoWA4Nrgmu4Ec2hjDw0jAw2GIwcHKGpoD2In BWsJhSVaEEkHjyKJVxCREGSKQKQiBAJ6CBADCHcBiGukjwAPawFMDAEktmUmtgmgt4UIqgIEvr4P QmS3AA0OBKRzBZQGj7RroUwKAhACCYsCtwVqJAQIDwJcj9OJ26KnhAsNjd630Zees4WdonPU+IFg q4AAAd5MOCPQaQGVeEzmrXACQByMedVIkULEsB88SEwGlHkAihsENVV6jIkjg20NgQcJ/kXct2Ka AygX95EpoKAQJWt0svmDKEIdqxHGCBCgIglcrJ2P1CQQZFLij3mpqlx6dWfAAHJUPkJIIACNpUEi DjxESGeEM1EDGBTTCnIUzSIDCGBpJGIA3xRWUek9wfHE3yNBAHxDzLjGzcaQI0ueTLmy5RPEMmve zLmz58+gQ4seTSwEADs= ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/_globalimages/blue_navbar/06.gif R0lGODlhNQAXAMQAAL/M2e/y9SBNeRBAcK+/zzBZg5+yxWCAoI+lvN/l7FBzls/Z4nCNqX+ZskBm jP///wAzZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAA AAAALAAAAAA1ABcAAAW8ICSOZGmeaKqubOu+cCzPdG3feK7v5gEAB5Hhp/IVjLzG40GADJYPldLh aAiSj0ACoshGRY6rqCCYkgZUnJLwECACgGhB+zBwH4vFo7oXaAMLN0pKBwsEcRAGDwMIi2yMe1NV ZXs2U3UPDIhxAAl7iFNmBgFLDpafSwWbe1QDoJF7Bw8KZjWhWRCIjW5tj2x8fAqKprasTLlyf3Zd XsB+TJU8JWEjZCcDYtLa29zd3t/gL1Dj5OXm5+jpDyEAOw== ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/_globalimages/blue_navbar/07.gif R0lGODlhVAAXAMQAAL/M2RBAcM/Z4iBNee/y9TBZg4+lvJ+yxd/l7FBzlmCAoK+/z3CNqX+ZskBm jP///wAzZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAA AAAALAAAAABUABcAAAX/ICSOZGmeaKqubOu+cCzPdG3feK7vPN4AABPAkCoAFCsjshdDPB6F0iOI GjQcKyuW+SpMHwxRADsdDQKQwcDk2EIKDnRp4BapR20m45F4LEQCBAtTDg9OXw9tDw0BAggEAhAH BI90i5KQBFEPBE9xjpA9gxBObw8GAYSnfQZ9V4uFBg4NAw8CWoW0p6kHEFOusbNrO7YOAIm5vgC5 zLCLjQ8HaAdTUc0Nysq50NIxQFQmfU9Pspeqr+jJAQ22IgoEBJbo2ecQ6+0wDfooBlD2tl4MeFnm LN0iJdQCDFHAZ9uuU9oOHkm4I9AIAQ+gdSJoEF2jR70mIRAw5pKBTGvOMX0k0IsLiTExHAx7E8UE HRUyXercybOnz59AgwodSrSo0aM4xildyrSp06dQo0p9GgIAOw== ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/_globalimages/blue_navbar/08.gif R0lGODlhgwAXAMQAAEBmjH+ZsjBZgxBAcM/Z4u/y9Y+lvCBNeVBzlt/l7GCAoK+/z3CNqZ+yxb/M 2f///wAzZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAA AAAALAAAAACDABcAAAX/ICSOZGmeaKqubOu+cCzPdG3feK7vfO//wKBwSDQZHA4BZIA0nI40BuFB UJKOSEZxO3I8HlrE13FSBGaCR+PwWJS8gQWYu/UWGhBD4UGGCAAHJwJWI4EDAIRLfGJnJF6KfUsD EAcAJJYlA5MAAJOFkweBS4h1bQkQBHJkBlQPCBCPAwQJCQSHD3sCBVNOIwFftm8PlG0QuA8ADbsF SlNTZMcABAUJBZUPCWNfiLsPvUNwD2kMfBABCsZkjwquYgoAVAC/CGYjsl9OyF182a+4CGkMDFAT MA20AgADcHqg0JsYA4zm1SPiBV4DceWkjYE17NfChmd0FWgk4pcUb+L25wVQKCIjw3TwzpQrB4FB NoYxczIUSdKFgCYxHn0pkA5CraKPPOpsdEDOt1h7iO4r4VKmg5hFy7ExsHQpJacwDqxEB+ORFzcz CbBRN0wMArdYFSQ5KoIVggFyCnjiSJXMQIHeAsKDRgaeAXYgl8oVQBdcxznlWNViK2LWUay6ppBd 4uWLMjciHpGgqWdaIC+sCFdug7M1yMwPNtMpkUi0n0T2OpkYgNtFJV8KBoIm0fvEob2zUxyglbyE smmvmgMRK0q6iD/IrWvfzr279+/gw4sfT758kC/o06tfz769+/fw48ufTz9+CAA7 ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/_globalimages/blue_navbar/09.gif R0lGODlhdgAXAMQAAEBmjM/Z4hBAcN/l7H+ZsjBZg4+lvO/y9WCAoJ+yxXCNqSBNeVBzlq+/z7/M 2f///wAzZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAA AAAALAAAAAB2ABcAAAX/ICSOZGmeaKqubOu+cCzPdG3feK7vfO//wKCwxXA4CiKDw6Y8QgRGw3CK SjweCpHjARMQSFsshHFd8rwiBJJqOmwb2odg/QQIUFvw45CAGA4PZgUACyWFdioCiBB5BA8AIguQ bAVYAwdxW18IgQ8IjFyBjoEjbwMQAQ2kBg8BDwygBwSsBwNceaSctgijV1cQVpd0QgqPVpBbAgGn AwGop7hLeaUPjpXFSwSfpFsKCwfOtqAQpM2ozo2PCw8GAuxUWwCsX3nR4/bTcQAPVpVLAK64cSEn 7VaoJXscABrnCMC+AVvMuCgQpYuvK+gMErx3cBw1cns2mhMogqS9Vg6RlXFpuC+Bw2EsFhDQBoNM FlRykg04FcBZz3EkP77Z2GpdQRHgIIizt+wZw0fuEkSdwmoNqyJ7qo3pBMuRrSUIIH50lGXVg2ZH /QQS5zVXK08Qwh5xBazVAZhsRszRuwhCgTsz8I6wM+0vCUWAUUjKy9hFvsaQfSiJTLmy5cuYM2ve zLmz584XQ4seTbq06dOoU6tefTEEADs= ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/_globalimages/blue_navbar/10.gif R0lGODlhlwAXAMQAAEBmjM/Z4n+ZshBAcDBZg9/l7O/y9SBNeY+lvGCAoJ+yxVBzlnCNqa+/z7/M 2f///wAzZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAA AAAALAAAAACXABcAAAX/ICSOZGmeaKqubOu+cCzPdG3feK7vfO//wKBwSCwaeQiHkjFMnhiBR4Bg EhgMisHJmeK6CI7ECCw+Oh6CKEB4NhEeisOjUUo8EAL0qZ3iuwB6IgcCa2YPEIACgoUiAIwDAFoi BAAHJZaQkmcDVCMDDw4LgSN5CxAOCCKZIpudEKunhxAHAK6Cs5WIaASSJZxDbQwPpgoPBQa8AccB EHYFD2IIUsOxBgJ2Z0xnUYqkD1K9jcaM2A/a04rlYm2iUal5BmHTC4DHBpB6ZwajP2ffCrPufEIA iKCAAwWYBWB2DQKoWAwQKiwQy6EDT1HuOGQEQdgcLQkhKKv4MOTINgkU/7XJowDMgwHXEuVxlO/l yCBnABSjWeCMgwFRsjiMtw9Rxot8Ho5ooxRCHih3HtiCQCCoRRJMLz5s0+ZAg2+HZjYzZkrmA5oq D/lxoeRiizaJAClwRAWmFIcBHK0JuVXWQ0ok3VYcsM8AiQQOeBmg+HdN1qtcDxUbsPJsoyj00MxM VHFtCwGg2R5K9CkLHDKTR46UIgeprIUiDT8WIW3BgK/3RghjQFihQtmHHsKGHXnAM6eWk8ghqPks 5003gXTVWCwAMqDHANqJEs1YANciRGUL7MkfHAN0BD17YMCUeHPk35ti9+0r8jXbkZlFG+tMtyO4 kJCLKpGMkQIsKvyCAkRgnhSIAoIjHBAOCbSw0AqAGGaIg2cadughC158KOKIJJZo4okopqjiiiy2 6CKAYMUo44w01mjjjTjmqOOOPPbo4wMhAAA7 ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/_globalimages/blue_navbar/11.gif R0lGODlhUAAXAMQAAGCAoL/M2TBZgxBAcM/Z4t/l7O/y9VBzlq+/z4+lvCBNeXCNqZ+yxUBmjH+Z sv///wAzZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAA AAAALAAAAABQABcAAAX/ICSOZGmeaKqubOu+cCzPdG3feK7vPKsEAUBJEBwRhSlAQNCjAR4PxAgg aDwcIyvWNMA2HIrmDGEgGESOR0MrGEC0okHDDQk8TAJmvKEXmwwIDA9VUGoPBQYGclcQTwUPAGkP AWlzBAWYAwJlDwl+Q1dPWJVapIwFBBAEqXYQlU8HB5BpB5GfJGkLTwGuaqW+jA8GAQZ3rZWVRolb MEC8MASFUF3ADqZYDwRrDXV3yGpyYQoInTHWzC0DUSIJDwfX16oF8t29DbKxD7pLqLcisgv+dRIQ 7dcaRk+iCQFQgJIaeZk2KfR3Qw4dFHlGWKTIsaPHjyBDihxJsqTJk/6kDKlcybKly5cwY7YMAQA7 ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/_globalimages/blue_navbar/12.gif R0lGODlhSgAXAMQAAEBmjH+Zss/Z4u/y9RBAcDBZg1BzliBNeWCAoL/M2d/l7HCNqZ+yxY+lvK+/ z////wAzZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAA AAAALAAAAABKABcAAAXtICSOZGmeaKqubOu+cCzPdG3feK7vaqAMDAJvuEI8GItHgMg8MR4HyCMB IQAApSikUCBxs1VAt1lKPEiHwU8AATwGD4JgMBAQ5HS7G16oPxpkJGYkAAEHAQ9XDwIARgYGDwaO kAZujIiSS4EigyQMcIluS4gCAkqkpgGiW3SaLwUJCYAwDnFSCY6IiqMPC1eHvb+rEAe1sy6HAQgx Sb5/mE+7EJAI1NYPCKsICQUKbJtVZg8KB2kPtdJ43ndz66t9psvgIgdjVVonXyP6JVZC8wADChxI sKDBgwgTKuTxoKHDhxAjSpxIsaLFiSEAADs= ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/_globalimages/blue_navbar/13.gif R0lGODlhegAXAMQAAO/y9RBAcM/Z4jBZg4+lvCBNed/l7GCAoJ+yxa+/z1BzlnCNqX+ZskBmjL/M 2f///wAzZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAA AAAALAAAAAB6ABcAAAX/ICSOZGmeaKqubOu+cCzPdG3feK7vfO//wKAQGEAADIQA5OAYmBwEnmMq akwPQyDjsSA8GJAGo2BiYF+FherBdnq/vbTo4PwJBKKHA9YYFcgleiMNgCMPAA9YAohgYQ1KIwGS fSoFlBCCW5QDdTqCJJoCBhBeAZmHggpsAg+UDmwMAwCLCCR6AAimCXCLBgBkqA2srHt6DXAID74D r3psDwGLs5A4mWYQml4QDninwg8QuwG7l4LJAV6Feg4GqgtfBQwNx2CHCscEBYLG8A9J/pj2aDrw QIEqBZ72vBLYShW9gNhavdoGTpMhhRVbXdxi5OECA7AgPtzngN4xAwshz2racgdODgB7VGr098CJ t4kTLebBGLFcSTYJ6OkjMHJP0YAmHyCYZ5OhGC7zCt3YNUCf022+dvacKO6VT1LQSl3EBPULPoL1 9gzwZxXpF1O5lMpsoOpAXR0DQLK5+i6BVk0TFRwhN4IAgDGzAEQZ+2rAQ1a70opYtAsjSDDJFrk5 PIBVtCMCqOVwLJrPGC+dShCCkZpEgD6fLomwtIJTlhiyFsW8/em279eth0DxTby48ePIkytfzry5 8+fQazybTr269evYs2vfzr27d+ohAAA7 ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/jpeg Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/provost/images/discover_research.jpg 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 ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/jpeg Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/academicsenate/images/siteheader_2col.jpg /9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAABkAAD/4QNvaHR0cDov L25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENl aGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4 OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjAtYzA2MCA2MS4xMzQ3NzcsIDIwMTAvMDIvMTItMTc6 MzI6MDAgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5 OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHht bG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0i aHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6eG1w PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9 InhtcC5kaWQ6MDE4MDExNzQwNzIwNjgxMTk1RkVDMzkzMUY5QUJGNDIiIHhtcE1NOkRvY3VtZW50 SUQ9InhtcC5kaWQ6OUQyMjBEMTQ5NDMwMTFERjgyNjRBNjM0MUUzNTRCOEQiIHhtcE1NOkluc3Rh bmNlSUQ9InhtcC5paWQ6OUQyMjBEMTM5NDMwMTFERjgyNjRBNjM0MUUzNTRCOEQiIHhtcDpDcmVh dG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giPiA8eG1wTU06RGVyaXZlZEZy b20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpGODdGMTE3NDA3MjA2ODExOTQ1N0E5ODQ1NzQ5 NTM1RCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowMTgwMTE3NDA3MjA2ODExOTVGRUMzOTMx RjlBQkY0MiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94 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 h/O9+th80hqlLTxlzwnwiGdXSXp8Z/xhh7d6r+Kpt/T875yu6m+nT8/1BLbzK+bl1/S/Hq5Z0/TJ 1zyEvt/hFcvT1DLT1JDL1cIdOb6b5hyH6l8sfO/zg36j0707qfTvTjbOR0/HoPDm7eG6ldZd6mGn V0sJenp4YxGGiYnLqY+qI4Z35vyXjTmbeT6vedKVrztzH4t3l8PCvs8OGn6LMynqlx9cKe4Tlrl/ OIyB8H3lN+0nLrt3/Fx3V4eHh9n26svNPCIwz4+yPZPjP+lyx+Hd409teFfH8WkCfHODj5Jyj6G2 huZu27fZWtKB+On81PDjXRAJSxgPy+WFNlPJStd1acKV4bfHx+32aUNU8Pl9PT9kZwnxi/Q6fYH7 bmcfHl7K+2tONfCn26aVORy0+n2Rk9OR1TlHslNxuX1O7YfmbfDl08+7Z5tlPirw8a6R5tPm0y4f CUvshSZY6dUpcOUKSI6vr0ubz+r5DXpOdt5nK5pORs3cOX7q8afZqM9o+mXpl054/wAYZT9PLycz lKU+PthSI8zonvS8mnUMtnO5fqPUcg3L6SnmrX9pTy1+LVe7LSOv8ksZfLLx8OXwhbvR0jq6p6RK Xt9nP7Iu7Q2fO1t+nbuq9Za/tPj6vmBt31+75+/9Hhu0ky6CvqtPQl7NP7pS9kQlZf5efV+9KXh9 sY27Om+arh67p+p9Veb923mdVzzbtnTfm8zw9lfHjqX+J0k9GfSlhLLT7fCJKeHV+fjLLLGcsJTi gnWg+j8zpunJu37N2+iv+Pr99s6qvJ3ebdT2ajL6en/NadU8Ph8vCcs/DxjCNMjOcp+E/T0zjLrd d6Tb/U+q8rlj63s5lOmqp0nTbfL1u2vh+PUVv6b6l/pdHqf93OWfGf3ZygTo82menGWWXpzxhZSH pPysnz/mP5a2tqV67p/mPaPSczd/y7r/AE7dy+Xx5O6nHVdber9a71uh+ZY6ZSn05jVljLVnPjE1 f130X43U+kmmU56Z8JekoX/bN/FH1l9/CT5p+evT5Dn+hcvZ8n7CfMXrvN8vonU8rnV82/ZTjrZB 9T9Yj6TT1pj+3wnn4RVOacOrp0TwnKc/3xOZL/1Gv4a5M+Seu/hL8l//AG7+V/Qvl35H5Dj/AKn6 v+89Z6l1XOp+8dTu28aa0veX+nPqGv8AU31OrqIlLqaJ6xon08Ja5S1YT8I3/bX5h0F/lP0XU6a/ 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 ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/jpeg Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/academicsenate/images/lnk_toggletab2.jpg /9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAZAAA/+4ADkFkb2JlAGTAAAAAAf/b AIQAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAgICAgICAgIC AwMDAwMDAwMDAwEBAQEBAQECAQECAgIBAgIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD AwMDAwMDAwMDAwMDAwMDAwMD/8AAEQgAOAB2AwERAAIRAQMRAf/EALAAAAEEAwEBAAAAAAAAAAAA AAgEBQYHAQIDCQoBAAAHAQEBAAAAAAAAAAAAAAIDBAUGBwkBAAgQAAAGAQIDBAYIBQIHAAAAAAEC AwQFBgcAESESCDETFAlBUWGBkSJxobHB0UJSFfDhMmIW8SOSotLiM0MYEQACAQMDAQcBBgQEBQUA AAABAgMRBAUAEgYhMUFhIhMUB1FxgbEyIwjwkaEVwUJystFSYpIWcyQ0NRf/2gAMAwEAAhEDEQA/ APlzeNdnbsOXscrhuIepUxe31a0q9vXr3az+9anl0n8KHs/4dc9v9uueufqNY8L/AG/8ofjr3t/t 171z9RrbwfsD4aF7enaNe9wPrrPg/YHw132/hrnuB9dZ8KPq+sfw132w/iuve58dbeCN6h+I/wDT oXtfDQDdDW4Mx/SHv3+82hC08NBN0PqddPAD6S7+4fx0MWZ7RoHvPE/z10LGjxHl3+r7DaGbNj9N Ba96duuhY4Q9Aj7ub79Gexr36LN4O/XQIwfVv7hD7NDFifpXQWvh9ddAigHsKPw/nowY+vd00D3/ AI6dIiJE0rGFEo/NIMw4hw4rphtoQx1KMO46Cb4EUrr6UoLrRWlKLdrcIAIVmQiWwCJxEALIXKHg dij+XhID9O+sq/Xuh8qe+aSQk5ksCXYkL7sNtBrUClRtHShIpTprRD2tr/4F7FY0C/23aQFFC3ty KkU6mvWvbUA6+bKQZbSD8OXseOQ9fYscOHHWq6WxKA+A/DWdT3FHIr3nSPwYfp/j46GLU9mg+5H1 1nwhf0D8f5a77Xx1z3HjrPgy/o+38NdFr4a57jxP9NbeB/s+3QhbH6a57nxOuwMd/wAgfAfx0MWm izdU1uDEP0/V/ro4Wbd+gG78ddyx/D+nb6A20ctj3EaKa88dKSRoD+T6eH4Bto5bCp8dEten66UE jAHsKPt+XcfdxDShccD1A0S17Tv0qLFB6Cj9IgH37aUJjq9duiDf+NRpUSIA3/rH4D7uPHSgY6or QaIbIU6g6UEhwHjyD7BHj9vYOlC4wDoBol8ifrp+gITmm4YBTD5pWPDsEdt3aIdmw6MfGbY2YDsU /hotMjWQLXtI/HRC0zJsI1xnmGoLxliLIyV9q0azcFhlzxKiyOX6ysoc8gUwopJA3anUATbblLw4 8NZFf2R25/7xZ7bauT3FN49ShuB2J2k1oDTv1pz7yMcF9Pa+443t2mn/AMc9/ZoVJVoJZSSDYflk Hgf0hx2cKBw9XZrVaC3UwoTT8g/DWcE036zj/qP4nV64Y6SOoPqIj5yTwpjiQvzSrkQcWhaNfwzV KtR7l+1i0pmfXlZCPbREGV89TIq9XORs3LzKKnIkQ5yxjPct49xqdbbLTiGZx5QVY7jQnatAdzUB IUdT2AEkDUjwvGc5n4WnxcJliT8xDKNoqBVqkUWpHmPQdpIAJ1YuTfLp62cL0+4X7K/TvdKLUMey 0LE3mbmloAjerGssghE1yYlW7WYcviVKwSbgjVlNppKRDx0PcouTqgJAa8b8jcMytzHZ4+8jluZl Zo1UPV9o3Mq1UAuoFWjqHA6lQOunG/4JyvGQSXV7aSR28TKHZivk3GilutdjE0V/yE9AxPTTTdeg nq+x5GUeZt2CrXExmRLPS6XWVTKwzp1/l+RmpH9BrNjiGMm6mqTNXaPUK4im802j1JBuPeoAcm5t GWvyDxO+kmjtLpGeCN3cUYeSI0kdSQFdUPRyhbaehodFXPB+T2aRSXNs6pM6IpqD55BWNWAJKM46 oHC7h1FRqRNfLj6317m9x8p015DirhF0FDKEpEWJtHVkI6ivbVNUiKnnshYZCMjGreetleeMYwh1 wWlVkRBmRcDEE3m+SOELZrfLfQtbtOYgVq9ZAiyFQFBJ2oys3SiA+anXXV4By9rprM2cq3CxCUhq LRCzIGJYgDcylV61Yjy16ara89IvUrjIcvFvmGrbVD4CksYxOZkZls3ar45e5nYIyeMErKgZwKzM bmxXKo0ACmEQHY4EEBDTjZ8143kDamxuI5RepK0G2p9UQGk2w9/pkeb/AB0gu+JZ+x9yL2B4zaNE s1enpmYVi3dem8Hp/XVh1by/Osa35MyJhyDwJbFsj4nXg2OQ64+cQUMNXk7Qi1cVaFkJealo6ECf tKbxP9rYFcmeSJhErdJQxDgX0vyBw61xlvl57yMWF0GMTgM29UJDsFVS21KHe1NqdrEAjXouEcpn yE+MgtZDfWxUSKSq7S9CiksQu56jYtdzdignVv07yserW2dO5uo6Ox+qaDNmhLBhKM8VUi8iBZiP 5+vysqrCShGTJhDwF2gDQLsjt03fklVik8KKJVFy9PyLwy25ION3l1tufYG79QDdD6dEdV3LUlni f1lKqyGMV37iFPP/AATllxgP7/bW263977b0ydsu+rozbTQBVkX0m3MGDmm2gLBRmfyr+r/DfUCH TkNAb3q5HpEfkJGaqkq0SpY1VWu16bnZmQstnPXmVdiKlJWFOIfPJTwLX9yTEiSihFETqAxXynwz I8dHJkmaKwM7Q7XU+r6gd1VQibyzSKhkRU3HYakAhgB5H435Zj86ePyQrJeiFZdyMPT2FEZmLvtC hGf02L7RvFASCCQ3vWJcj4ryFY8R5HpE9Tsn1WXSgpylSzISTjOVdJtlmLcrZAVyuwkWz1FZqqgZ VJ0ismoiY6ahDDPcNl8XncUmZxkscuOkQssgPl2itTU0pQghq0KkEGhGoTl8ZksPk2xWQieO/Rwr RkeYMaECg7aggilQQQRUEavi39BnWJjt/jyJt+Ab9HS2WLKlSaFGN49rMyUteViMlSUdywg3km7r 92TRkEVVIeSI0kkkVAUOgUnzaZcdz3h+SiuprPI27QWcXqysSVVYuo9UFgoeKoIEqbkJFA1dO2R4 XymwltobqwuFlupRHEoAYtIafpEKSVkoQTG+1wOpFNE/dfKpz/SMW9OkgWt2qa6gM/ZWzLjVthBm zrz4zEmKImHl/wBwhLPE2GTjLEu/au3niU0zkKyVj1kTGFYihCMWE+WOO3uXykbywpxvHWVtO10S 4r7hmWjoyBkAIWhIO4OpAoQS85j4zzllise6RStyG/u7iEWwCk/oKrVV1cq5ILVAPlKMD1BACyfw bkqoUWi5Ms1TfRVCyY9tbDH9oVM1VjLY5ozxjH29OJURXUOqEA9k26S4mKQAOsXbcB31cuIvMdlM ldYe2lV8nZLE08XUPEJwzRbwQKb1VivXsU6qnJWeQx2Pt8rdRsuNu2kWGTptkMRVZNpB67Cyg+JG mCswwGsMCXl7ZmLDiBduL1APSA7jx0/3GNAtZDTqI2/A6Y4MhW4jFe11/EahlYfsgDJcQiFgOU2R q8u7WTjHasIk5TyBCdwi4edwKLUBcLcpT84AYxgD06xt/td1/wDoHu5TYgjInYpkQTspuFclU3bm IUEkU6AFu7Wsnv7deEegry72xtD5SUqISoBalB18evZqHzKIBMSobAIhJPd+30ulfb7dalWkINrG T/yL+A1m7cSE3D/62/E6Mvp+6p6/hjpv6tcHyVJmZyW6i6BUqjC2JhMM20fAL17J1Vvqy8rHrszO FUFm1eOgQyKhjd4qAiUClHeu+UcAus7yXG56C4RIbKV2ZCpJbdC8flYNTtcGhA6Dt66nXHea22G4 9f4WWF3lu41VXDAAbZUkNQRXsQioJ6ns6aLDLPmYUXJf/wBhkTxRbGaPUx0ydMWBoUjuww6v+MyG CC43/eZmSBJqIOI+dPSFjNSJf7iZnBROHA28Pxnw/krH+11u4S2Pv7u4aiN5xcertUde1fUG6vQ0 ND2ak+R+U8def3IC1lpfWVrAtWXymD0txPTsbYaU7Kio1fWRvNh6aHtQj6ViDpzutDrAZ16O84hV Um2HoCLqR+nJ+k6tNKjJ2oVdjcsjjYlmni21itT99KLLvFElE2yaIHcNGO+E+UR3TXeUyFvNcezv rff+uxf3QokhV3KRba7TFCqoAoILE0V0v/lzjjWy22OsZ4oPd2c+39FQntzV0DIoeTdSoklZnJJB CgVIpNuujFl8uPmXQObKZldfEXmGZTisoIS1IslcVyhjF9j7MVnyfi6uLGtLZ1XpmsJR9iCIkkgU TBog1RVapnFBJMJPP8ZZjH2fHp8NLanK4O2MJWRH9GYSQJDM42EMr1XehoakkMRUnUeh+Q8Te3Wd hy0VwMbmLgSgoy+rEY5mliU7wVZaNsbr0ABUGgGjN6xutzpce9R/mS42m2VtyzgjqzhOhGdrGRcF XmpSMjF2vpgwzRFGcAeRnoxeDloiVsD59FSr9MAcx7hkJyNFzcyJYrw/405c3G+PZSAxWmcxr5JJ IbqKRQY7u4lBfap3KwQK6KfKwYedeh1JeVfIXFxn87j5fUusRkFx7JLbyISHtYIztqw2lSxZHYdV K/lPZrSH83vG9szV1a2i547yPTaL1J5mwfnKuL0thhu53aoWDDtERp0rV5ZPK9SsVUUi7c3J3jOY ZpFkoNZIqqKSwqqk0sHwpnLPFYq2t5raa6x1nc2zeobiOKRbiT1Fce3kSTdGfzRsdkoJDEUB0jPy 7h7rI5K4uIriG1v7qC4X0xA8iNBHsKH1kdKOPyuBujIBANSNChkXrWx1mXpv6o8QZDr2TErtlfrU e9ZOOLNHStVmWZJmQqVno40/Jjt1HVty6TZQtkMspIRrBNR87IAii3LuBrTw/wAfZXB8oxGcxslo bCzwIxk8bLIp2iSOX1YAGcAlkoEdyEU/mY9lbZTnONzHHMpiMhHci+u80chC6sjDcY3i9OYlUJor 1LooLN/lXropH3miYUfdR+ec1NMe5ch691V9OuM8SZbQ/bcM26dx3fcWwuMIevz+N4G9R83UrzU3 TbG3K8aTqDQ6x33fE7o7ZIowqT4Y5K/Fsdx03FlJPiMlcT25rcxpNDcPO7pO0ZWSKQGbytEWACUN QxOpgnyzx9eR32dEF3HBlcfBBOKW8jQywJCitCsgZJIyIfMJApJaooVA0M+QOs/E956gb91MK4sv 9iyjEZG6ZLJ09y1+uFTcoQFVwOavpT8TkqKqVMrcNKubk1qTRNqhGt27WLRcqoB3xUEjnnXHfifO 4/j8HGWvreHCzWd/FepDE9Xe7VxG0DSSOy+iZGJLsTIVB6biBDc78m4a9zk3IVs55ctFc2Ulo8si URLUoXWZY0RW9URgAIAEDEddoJ9L7752OHDZDxjkXGWCskunMb1Ft+ou/Vm7zOLq/WY6cfVqwVGx RdPToFLSk7fNOIa3Pxa2CxORdprgidRuflL3cAw37YeQHG3uLzWUslR8W1lBJDHcPIyiRJY2lM0u 2JQ8aboYF2su4BxU7pxlv3E4IZC0yOIx12WTIi7mSV4ERWKPHIsQij3SMUkfbLM1Q1CVPSlfMPNL 6Y8STnSDH9OvTvlBrQelvPWUssCTI15r6llskNl6rzMDZYxp+1s5ZvGyDNayrKNgVdOEzFYIAooJ l1DIyO1/bxzHLWWfPK8vYnKZrFW9qDbwP6cb20qSRsdxQspEShqKprI5A8oDR64+dOKYu7wg4zi7 wY7EZKe4InmTfIlxG8bqNoYKQZCVqzDyKCfMSoMdUXUThnJmCumrp7wnUclxFU6crH1ASbSz5Rla u7sNtZ5rsNLszdR3HVRolGw7yHdV9dA6aai6Zku6OCgmMcpLx4BwbkmF5Vm+X8onsZL/ADMOPUxW qSiOFrKOaM0aUlnDiRWBIUg7hSgBNPc25jx/K8axHFuOw3kdniZr5hJcNGXlF3JDIKrGAqFCjKQC QRQ1qSAGtTYANmrgbB807EBtw7RkG4cdWne2i+ynbu9J/wDadVva3J95F/6q/wC4aremqrEY5fbL yMos0WsVYVZFTVUUZtnJbXV1VY9yjuCTdPZM4pn2Hn74SjxApgwTurWN/lm1kgtrRbxMq5kJFJHj MjFZUftLAkBkJAG2o6Eg7PxzOnx1Ihkcwvj1oOlAwT8pHj2g9v46bMoYhyVjiwTKF1p8vXzFknxh M8SKBDEM6W5VCCRQ4mS48DBwD161GwfPuG5a0X2GStJAiKGpItAVoKFq0r3UFdZ5ZjhvKMXOTfWN zHvY7QVPUV6dAKj7xqq1UlUO7BdJRATkKcgKpnREyZw3KcAOBTCQwdg9ghqXW91bXSCa2kSSI9hU gg/eNRaa3uLeQxzo6SDtDAg/yOtNKdJdbk7fdoa6C3ZpQn+b3ffoYFTTRL92lKfYP0/hpQdFv2aW p9hff9+lkY610lk7NOCQe3jt9vHSyPu0lY9/dpxS7R9v4iP36cIRpA/ZpzTDs+nf+PhpyiHTSKQ9 dPCJdgD3B8OI/HTjD49um+Q6dUg4AHq4/V/3acUH003ue06d2SKzpQUmiKztYhFFTotUlHKpU0SC ZU/dIAooBUiFExh22KUBEeAaHc5LH423a7v54obZB5nd1VV8SSQB9+g29hf5CdbayhlmuHNFVFLM x8AASfu0ysst44rM9XXcpb4MxQnmXM2jnzaXkSeCcNnTgFYmLUdyqJSoG3KY6JSG47CIlMAVVyP9 wfw5ho2sLnPWU13NBJtW3LXXYKEM1sJQhqRQSFa9oqAaWNgfhb5PybLexYe6htYpkDNcBbbtIPT1 zGW6A/lBPd2kamcPKxjPEFseQUec9cmLHGyF2tyDN13SEfHSManGJyBRRB94de0qMCogCYhylNw2 46xQvVnT5fssnOZBgnuJDFJQ+mV9FywNB0IAboaGvZrVe1fHng11Z7gcoIkT06+dayA1p9NvSo7y Ne5PVD0rROeZFWXBXw74necizRksgYhjHMIiVRN2JydvoEB1T1nnJ7CT1QxVq9vUGp8Qa6tCewW4 URlVKkdnaKd3drywv/l23lgB1Ye1P1TIr9+zM4K7cOG5kjG5fDuV1Fl25REwhypmKBt+IDvqd2fy fyO2jEaZC7VAwIHqOaEdQRUmnXrUU1GbvhWCuiwnsrclgQ3kUVr21IArXQX2vpE6i6sEmlFOo94y WVIsms/gHr6Vbdzzj3KL9dyoHcqif5w7vc5QDiAgA6s/AfuN+RsS7yQ5i4mDdNs+2YL/AKBIrbfw 8Og1W+W+COB5ABfYLEq9f02KV+2nU/ZXVTydbyvXnvNYcfpgwTbkIonBLSrR0ZdMuyjgDy7eWTAi p/m5fyhwAfTq5ML+8Dk8KJHlbOyuiCNzLujY/WgG5RX7On2dNVxkv2x4CbfJYXdzE9PKh2sgPifz 9e/TKnaYpIzdtKt5uEerc3fi/iDGimhg3ESqSbVys6UMG3DZmBR9Yaufj/7seE5FzHlre4sa9Aai UH71Ap9poNVdl/21cws4w2PnguWr1HVAB4VJLfco0+N52suHDlu0tlXd+EEhFFTzDeITUMpvsDRO wjCunm3ZukmfYeHbq28P83/GOYdIYMpAlw/+RyVI+8VQf92qyy3xJz7FI0s+PlMCdrLSn3V6n+Wp KVm7KzbSR2jsjB2Ai0kDtnBWLj0j4d4YgN1xAP0mHs1aWPzOJyJK4+5gnZR12SK1Pt2k01X19isp j1DX1tPCGNBvRlr9lQK6XsGjp+p3TBs6fqhsIps26ztUA35QMKbcihwDmEA3223HTjPkrDHRe4v5 4YYKgbndVWp8WIGm6Cxvr6T0bOGSWWhO1FLH+QFdKllo6NYqycpOVqJaIAXvQkLJBoSIAJhDmTr5 X6lkebCHYgzVPtxAo8N4LlfnD4u4/IYchmLUyhKgRkyg/QBkDJXuoW6d+pfi/iT5CzkYlscZP6RN KuAhHiVch6fYvXu1HVMlUZqo1Ig+sFkFyn3hv8Pqrt94Q+yogg8G3P6ITvBMAAAtxcp7G35g22Gn M9+9HguNiVsBj72+nr1WQpbqB/r/AFST4baePdqzsT+1XmV65/ut1a2sVOhTdIa+KkR0FO8E/ZpM tky2ODkTpOD7TNrFVIIO7dPM20c6TFMQUSVr9YSSkyAc4iJTJzRTE7Nx7RpvkP73+b3DunG7DHWc B7DMJLiRR07CJIkJ6HqY+/s79Wphf2jcSiWN85e3txOv5hGUjjc/YUZ1Hhv++nTUjcMupG1TFMYt 6pWcesbvIuoxWu1yufuwIlbx6jgi7afvbq62yOdnBPmUFrIpE5uwoapHkP7lfl/kkOy/5BewpGK/ +1YWZ6/V7YROe3sLHu+g1bWH+A/izBq0lrhbeUswBNwGuP5CYuo+4DV5TnRflqVqE1LX2yWeQj4+ KVVUCZmZSRSap7lRIJUXjhVJJuh3gCIFAClIA7Btw1VmKz2W5TyWGyluppr69uBueWR3LuRSrsxJ ZiAFBNe4dmrMbE4rA4xpba2ihtLeLoscartUHsUACgFSxA8TTVo4s8vKDVorjJT6x0aQnGrdSNpV YpruWlX9glVwOzdeLGVr8M0ORNdEuyrZV0gHEpjgbYNSm2tMHxXJzPe31xNfKrB7eZNksO8hlO2r UWgrQ7WPcOuopn0zOY9vjrK1WPH+osjXCMrxOEqCoYEEMa9KqB46g0VN2FCkWSMZM3DXFUhBpSsv ZzSEOdOSNH3Su15GFI0SSO1ScIWt62370SKbp92BROYo67bXMsuHubcf/WxqsxXbUgmaMih/MBVu 4/lqOzprl/bYu15LZI0Vc3c3DWwatNu22mc+Wvmqqba9xIbtA19QjKRayrBKQinKL5kulzIrtVAV RcJpiIgZNQogYQAR2MU2xiiAgIAICGvmWUE9TX/j3dPDV1UCLQmn003vWZFygmq2QA+wGH5SqE5i jzc+w7mEwlEeAcOGiTSlPMAD/H3aEDpvCrRL8yhHkezOCu4DuiHKKew8xgAxfmLvx+nR8EzCpQ/m 7tAdUIqfy6iE/gXHljKn39eaHOsQQVILcgjvxADAIFD5TFDiG2lwuLhQrVO3rokRxsCAAVHZoabl 0MYnsRjl/wAcbNlD94UTFRTDlESf7ZeXYDl5x7O3jpQmYu0JoaU7u/RRtonWp6LoO7v5WVCllXIR 6ZG5ymEu4EACAJttthAPmEd9hH0Dw06W/IpQQHPd+Gk8mNUjy9pGhMtnla3mnvmkzRZqdiHfjiN0 3sHJSMYts5Kql3YuWDhAxyGEQ3KIiA8B23ANpLjuc5GzFbSaSMU7jT+Oz/DTHecVxt+a3dvFI69R uUH8ft1Xavl7Z2nlG0fYbPapZk0O5O3SkJeUegAujnO5ETLLHMoZUxhAwnER24dnDTld8+yl6iG5 u5n2LRfMRT+RFf66S2fEcVZPutraJH+u2p+4tUj7tXxRfKpOYUFZYDAf+tceQR47huHOJd+Ydw7d RKbkVGonTT/HjSAB3eGjVo3lxUOBTQF6xTXBMAKc4pkOPOX1gIF4mHs9A7aa5s/M4oOz+ulqWCDR Ej0l42rbVJyyiGfOmQA5kmqahuYAESnOHKIlNy7+zSA5K4ZupJJ/iulMVrEvh/jqH3isVSo2jpld tolsBXOQ5WJdAKQACca6gZNsmv8A+PYSlfEIAmKGwCYA0hv8jHFEVuX2RlSwJNAdhFetfv8At0el q7wTSxAFlkQGnU9T/Lr2eOiPzO0rRMQZFZOl42OTfUqwINVD8hRB54BbwRSF5TGOYFyk4AA7gOvY bkkGL5BjsnE5PpX0D+U9aeou7rUU8te/STIWRmx91bSUUNbyL1HeUYDofHw15IUPNuMkI5o7r1uu NItddx2agQFbma9GStQh5cHScg6sUM6ScNyoyDx0mY6ni0yqFAwcxxKUA19J8ox2ZvOdvh/T4/yK O45CmXuJsZkUGTaBAVS1u4GLARxrRaRyUO0+QEk6q/D3dnJxc3VnNc2ESY4WqRXds6QpKfzTI46P vIrUgEA9dRSDaYPa1+5U1fIB2tCkMgtsgR9eLHCZ/I2BTKNUyI9oiwcpm5cdEnYMi6bvnBYrRA6Q hzKAbTxHwv5ZtreREs0N9cIJWm/T2CNSJhGY91BcB0CBalCWrpBc3XErjN288k8JtYJGVas4dXML wbg3aVZJGq3cQPDX/9k= ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/jpeg Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/academicsenate/images/campus5_180.jpg /9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAABkAAD/4QMraHR0cDov L25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENl aGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4 OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjAtYzA2MCA2MS4xMzQ3NzcsIDIwMTAvMDIvMTItMTc6 MzI6MDAgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5 OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHht bG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6 Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUu Y29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBo b3Rvc2hvcCBDUzUgTWFjaW50b3NoIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjlEMjIwRDE3 OTQzMDExREY4MjY0QTYzNDFFMzU0QjhEIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjlEMjIw RDE4OTQzMDExREY4MjY0QTYzNDFFMzU0QjhEIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmlu c3RhbmNlSUQ9InhtcC5paWQ6OUQyMjBEMTU5NDMwMTFERjgyNjRBNjM0MUUzNTRCOEQiIHN0UmVm OmRvY3VtZW50SUQ9InhtcC5kaWQ6OUQyMjBEMTY5NDMwMTFERjgyNjRBNjM0MUUzNTRCOEQiLz4g PC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9 InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB 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 adE8te2mF/Np/wAWP//Z ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/_globalimages/footer_bethedifference.gif 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 fAmXOngDgjCHZ5gHAS5hTVYQCAA7 ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.marquette.edu/_globalimages/go.gif R0lGODlhFgAQAOYAAP7+/ufn535+fq6urvj4+IODg/n5+ejo6PPz89LS0vz8/KysrFlZWYWFhcfH x2VlZZCQkKioqJWVlampqfLy8nR0dGRkZKurq93d3aGhoWpqar+/v1hYWP39/enp6bKysnh4eO7u 7np6emFhYdDQ0Nzc3KWlpX19fcHBwbe3t4+Pj5eXl9PT046Ojp+fn7a2tvHx8XNzc6+vr5KSkoCA gOvr62NjY9XV1cDAwMjIyOLi4rq6umtra/Dw8OTk5JOTk8zMzGZmZv///wAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5 BAAAAAAALAAAAAAWABAAAAeZgAE+g4SFhoYpQEKLjI2OjkEOj5OTHIqOCh0AjAqbkJeLGCoCDTtC MCukOJ+NNBAGFDpCESAGGzwhjUGgHjYJjTELQgQPKLqgN0ElQC4mQiMvi0EDx4wBFiwHEgxCIsII D5KMu4wAJy01A0FCFxUBMhoI1YwHGQU/H8MTBTMkrJQApeUIGJABKIKPyCGcFKTHj4cQI0qUmCAQ ADs= ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: text/css; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Location: http://www.marquette.edu/_globalcss/headerstyles2.css #eduMainNav { PADDING-BOTTOM: 0px; MARGIN: 0px auto; PADDING-LEFT: 0px; WIDTH: 760px; = PADDING-RIGHT: 0px; HEIGHT: 121px; PADDING-TOP: 0px } #eduMainNav .logo { FLOAT: left } .edunavbar { PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: = 0px; HEIGHT: 23px; CLEAR: both; PADDING-TOP: 0px } #eduMainNav .utilities { TEXT-ALIGN: right; PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; = PADDING-RIGHT: 10px; FLOAT: right; PADDING-TOP: 13px } .onwhite { BACKGROUND: url(/_globalimages/blue_navbar/onwhitebg.gif) #fff repeat-x = 50% top } .onwhite .news { COLOR: #036 } #eduMainNav A { FONT: 8.5pt Verdana, Arial, Helvetica, sans-serif; TEXT-DECORATION: = none } #eduMainNav A:hover { BORDER-BOTTOM: 1px dotted } #eduMainNav .edunavbar A:hover { BORDER-BOTTOM: medium none } .onwhite A { COLOR: #06c } .onblue A { COLOR: #ffff99 } .ongold A { COLOR: #06c } .onblue { BACKGROUND: url(/_globalimages/white_navbar/onbluebg.gif) #036 repeat-x = 50% top } .onblue .news { COLOR: #fff } .ongold { BACKGROUND: url(/_globalimages/white_navbar/ongoldbg.gif) #fdb827 = repeat-x 50% top } .ongold .news { COLOR: #036 } #eduMainNav .headerlink_onwhite { MARGIN: 0px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; COLOR: = #003366; FONT-SIZE: 9px; FONT-WEIGHT: bold; TEXT-DECORATION: none } #eduMainNav .headerlink_onwhite:hover { BORDER-BOTTOM: #0033ff 1px dotted; COLOR: #0033ff; TEXT-DECORATION: = none } #eduMainNav .headerlink_onblue { MARGIN: 0px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; COLOR: = #fff; FONT-SIZE: 9px; FONT-WEIGHT: bold; TEXT-DECORATION: none } #eduMainNav .headerlink_onblue:hover { BORDER-BOTTOM: #fdb827 1px dotted; COLOR: #fdb827; TEXT-DECORATION: = none } .edunavbar FORM { PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: = 0px; DISPLAY: inline; PADDING-TOP: 0px } #eduMainNav .searchbox { BORDER-BOTTOM: #999999 1px solid; BORDER-LEFT: #999999 1px solid; = MARGIN: 3px 0px 3px 8px; WIDTH: 179px; FONT-FAMILY: Verdana, Arial, = Helvetica, sans-serif; HEIGHT: 12px; COLOR: #666; FONT-SIZE: 9px; = VERTICAL-ALIGN: top; BORDER-TOP: #999999 1px solid; BORDER-RIGHT: = #999999 1px solid } .mainNav #eduMainNav .searchbox { BORDER-BOTTOM: #999999 1px solid; BORDER-LEFT: #999999 1px solid; = MARGIN: 3px 0px 3px 8px; WIDTH: 179px; FONT-FAMILY: Verdana, Arial, = Helvetica, sans-serif; HEIGHT: 12px; COLOR: #666; FONT-SIZE: 9px; = VERTICAL-ALIGN: top; BORDER-TOP: #999999 1px solid; BORDER-RIGHT: = #999999 1px solid } #eduMainNav .searchbox:hover { BORDER-BOTTOM: #ea0 1px solid; BORDER-LEFT: #ea0 1px solid; BORDER-TOP: = #ea0 1px solid; BORDER-RIGHT: #ea0 1px solid } #eduMainNav .gobutton { MARGIN: 3px 5px 0px; VERTICAL-ALIGN: top } #eduMainNav .REmail { COLOR: #666 } #eduMainNav .BEmail { COLOR: #000 } ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: text/css; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Location: http://www.marquette.edu/_globalcss/footerstyles2.css #footer { BACKGROUND: #fff; HEIGHT: 100px; COLOR: #000000; BORDER-TOP: #003366 = 1px solid } .footer_left { MARGIN: 5px 0px 0px 4px; BACKGROUND: #ffffff; FLOAT: left } .footer_right { MARGIN: 5px 4px 0px 0px; BACKGROUND: #ffffff; FLOAT: right; COLOR: = #000000 } ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: text/css; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Location: http://www.marquette.edu/academicsenate/_css/_level2_B.css BODY { TEXT-ALIGN: left; MARGIN: 0px; FONT-FAMILY: Verdana, Arial, Helvetica, = sans-serif; BACKGROUND: url(images/level2_aquarium.jpg) #eee repeat-y = center 50%; FONT-SIZE: 11px } A { COLOR: #0066cc; TEXT-DECORATION: none } A:hover { BORDER-BOTTOM: 1px dotted; COLOR: #0033ff } .mainNav A:hover { BORDER-BOTTOM: 0px; TEXT-DECORATION: none } #container { TEXT-ALIGN: left; WIDTH: 955px; BACKGROUND: #ffffff 0px 0px; = MARGIN-LEFT: auto; MARGIN-RIGHT: auto } #siteheader { WIDTH: 960px } #siteheader .siteheader_left { BORDER-BOTTOM: #ffffff 3px solid; FLOAT: left } #siteheader .siteheader_left A { BORDER-BOTTOM: #ffffff 3px solid; FLOAT: left } #siteheader .siteheader_left A:hover { BORDER-BOTTOM: #fc0 3px solid; FLOAT: left } #siteheader .siteheader_right { FLOAT: right } #banner_main { WIDTH: 955px; BACKGROUND: #ffffff 0px 0px; FLOAT: left; HEIGHT: 88px } #eduMainNav { PADDING-BOTTOM: 0px; MARGIN: 0px auto; PADDING-LEFT: 0px; WIDTH: 760px; = PADDING-RIGHT: 0px; FLOAT: left; HEIGHT: 121px; COLOR: #003366; = PADDING-TOP: 0px } DIV.topimage { BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: = 0px; MARGIN: 1px 0px 0px; PADDING-LEFT: 0px; WIDTH: 194px; = PADDING-RIGHT: 0px; FLOAT: right; HEIGHT: 119px; BORDER-TOP: medium = none; BORDER-RIGHT: medium none; TEXT-DECORATION: none; PADDING-TOP: 0px } * HTML DIV.topimage { PADDING-TOP: 3px } #banner { POSITION: relative; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: = 0px; PADDING-RIGHT: 0px; BACKGROUND: #fff; COLOR: #fff; PADDING-TOP: 0px } #banner H1 { PADDING-BOTTOM: 0px; MARGIN: 15px 0px 0px 8px; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; = COLOR: #036; FONT-SIZE: 18px; PADDING-TOP: 0px } .banner_left { MARGIN: 0px 2px 0px 0px; WIDTH: 575px; DISPLAY: block; FLOAT: left } #banner_right { MARGIN: 0px 20px 0px 0px; WIDTH: 320px; DISPLAY: block; FLOAT: right; = HEIGHT: 45px } #banner_right H1 { FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; COLOR: #036; = FONT-SIZE: 14px; FONT-WEIGHT: bold } #banner_lower { PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 10px; WIDTH: 226px; = PADDING-RIGHT: 0px; FLOAT: left; HEIGHT: 212px; PADDING-TOP: 0px } .body_bold { FONT-WEIGHT: bold } .body_italic { FONT-STYLE: italic } .body_red { COLOR: #cc0000 } .breadcrumb { PADDING-BOTTOM: 0px; MARGIN: 0px 0px 0px 9px; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; = COLOR: #fc0; FONT-SIZE: 10px; FONT-WEIGHT: bold; PADDING-TOP: 0px } .breadcrumb:hover { COLOR: #03f } .breadcrumb_urhere { PADDING-BOTTOM: 0px; MARGIN: 0px 0px 0px 9px; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; = COLOR: #036; FONT-SIZE: 10px; FONT-WEIGHT: bold; PADDING-TOP: 0px } .breadcrumb_urhere:hover { PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: = #03f; PADDING-TOP: 0px } #social { MARGIN: 2px auto 2px 260px; WIDTH: 500px } .logo { FLOAT: left } .mainedu_topnav { PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: = 0px; DISPLAY: none; PADDING-TOP: 0px } .show { DISPLAY: block } .selected { FONT-WEIGHT: bold } #toggleId { BORDER-BOTTOM: medium none; DISPLAY: block; FLOAT: right; MARGIN-RIGHT: = 10px } #mu_nav { Z-INDEX: 100; POSITION: absolute; TOP: 1px; LEFT: 777px } #midcontent { PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: = 0px; HEIGHT: 212px; PADDING-TOP: 0px } #profiles { BORDER-LEFT: #036 1px solid; PADDING-BOTTOM: 0px; MARGIN: 10px 0px 0px = 5px; PADDING-LEFT: 5px; WIDTH: 220px; PADDING-RIGHT: 0px; FLOAT: right; = COLOR: #666; PADDING-TOP: 0px } #profiles IMG { PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 4px; = PADDING-TOP: 0px } #profiles H1 { FONT-STYLE: normal; MARGIN: 10px 0px 0px; FONT-FAMILY: Verdana, Arial, = Helvetica, sans-serif; COLOR: #ea0; FONT-SIZE: 10px; FONT-WEIGHT: bold } #profiles H2 { PADDING-BOTTOM: 0px; FONT-STYLE: italic; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; FONT-FAMILY: Georgia, Times New Roman, Times, serif; = COLOR: #036; FONT-SIZE: 10pt; FONT-WEIGHT: normal; PADDING-TOP: 0px } #profiles H2 A { COLOR: #036 } #profiles H2 A:hover { COLOR: #03f } #profiles H3 { PADDING-BOTTOM: 0px; FONT-STYLE: italic; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; = COLOR: #036; FONT-SIZE: 9pt; FONT-WEIGHT: normal; PADDING-TOP: 0px } #profiles H3 A { COLOR: #036 } #profiles H3 A:hover { COLOR: #03f } #callout_leftcol { PADDING-BOTTOM: 5px; FONT-STYLE: italic; MARGIN: 0px 0px 20px; = PADDING-LEFT: 0px; WIDTH: 185px; PADDING-RIGHT: 5px; FONT-FAMILY: = Georgia, Times New Roman, Times, serif; FLOAT: left; COLOR: #036; = FONT-SIZE: 14pt; FONT-WEIGHT: normal; PADDING-TOP: 5px } #callout_leftcol H2 { PADDING-BOTTOM: 5px; FONT-STYLE: normal; PADDING-LEFT: 0px; = PADDING-RIGHT: 5px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; = COLOR: #666; FONT-SIZE: 10px; FONT-WEIGHT: bold; PADDING-TOP: 5px } #callout_leftcol H2 A { COLOR: #666 } #callout_leftcol H2 A:hover { COLOR: #03f } #callout_rightcol { PADDING-BOTTOM: 5px; FONT-STYLE: italic; MARGIN: 7px 4px 5px 7px; = PADDING-LEFT: 10px; WIDTH: 225px; PADDING-RIGHT: 0px; FONT-FAMILY: = Georgia, Times New Roman, Times, serif; FLOAT: left; COLOR: #036; = FONT-SIZE: 14pt; FONT-WEIGHT: normal; PADDING-TOP: 5px } #callout_rightcol H2 { PADDING-BOTTOM: 5px; FONT-STYLE: normal; PADDING-LEFT: 0px; = PADDING-RIGHT: 5px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; = COLOR: #666; FONT-SIZE: 10px; FONT-WEIGHT: bold; PADDING-TOP: 5px } #callout_rightcol H2 A { COLOR: #666 } #callout_rightcol H2 A:hover { COLOR: #03f } #row1_left_column { BORDER-LEFT: #fff 1px solid; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 20px; = PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FLOAT: right; PADDING-TOP: 0px } #row1_left_column H2 { PADDING-BOTTOM: 0px; PADDING-LEFT: 10px; PADDING-RIGHT: 0px; = FONT-FAMILY: Georgia, Times New Roman, Times, serif; COLOR: #666; = FONT-SIZE: 9pt; PADDING-TOP: 0px } #row1_left_column H1 { PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; = FONT-FAMILY: Verdana, Geneva, sans-serif; COLOR: #036; FONT-SIZE: 14px; = FONT-WEIGHT: bold; PADDING-TOP: 0px } #row1_left_column H1 A { COLOR: #000000; TEXT-DECORATION: none } #row1_left_column H1 A:visited { COLOR: #000000; TEXT-DECORATION: none } #row1_left_column H1 A:hover { BORDER-BOTTOM: 1px dotted; PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; COLOR: #0033ff; TEXT-DECORATION: none; PADDING-TOP: = 0px } #row1_left_column H3 { PADDING-BOTTOM: 0px; PADDING-LEFT: 10px; PADDING-RIGHT: 0px; = FONT-FAMILY: Verdana, Geneva, sans-serif; COLOR: #036; FONT-SIZE: 10px; = FONT-WEIGHT: bold; PADDING-TOP: 0px } #row1_left_column H3 A { TEXT-DECORATION: none } #row1_left_column H3 A:visited { COLOR: #03f; TEXT-DECORATION: none } #row1_left_column H3 A:hover { BORDER-BOTTOM: 1px dotted; PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; COLOR: #03f; TEXT-DECORATION: none; PADDING-TOP: 0px } #row1_left_column IMG { PADDING-BOTTOM: 3px; PADDING-LEFT: 3px; PADDING-RIGHT: 5px; = PADDING-TOP: 10px } #left_column { PADDING-BOTTOM: 15px; MARGIN: 7px 0px 5px 4px; PADDING-LEFT: 5px; = WIDTH: 185px; PADDING-RIGHT: 5px; FLOAT: left; PADDING-TOP: 10px } #left_column H1 { PADDING-BOTTOM: 4px; MARGIN: 0px 0px 3px; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; = COLOR: #036; FONT-SIZE: 8pt; PADDING-TOP: 0px } #left_column H1 A { FONT-SIZE: 8pt; TEXT-DECORATION: none } #left_column H1 A:hover { COLOR: #0033ff; TEXT-DECORATION: none } #left_column UL { PADDING-BOTTOM: 0px; LIST-STYLE-TYPE: square; MARGIN: 0px 0px 5px 2px; = PADDING-LEFT: 15px; PADDING-RIGHT: 0px; COLOR: #fff; LIST-STYLE-IMAGE: = url(../images/arrow_yellow.gif); PADDING-TOP: 0px } #left_column LI { PADDING-BOTTOM: 5px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: = #000; TEXT-DECORATION: none; PADDING-TOP: 0px } #left_column LI A { PADDING-BOTTOM: 1px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: = #03f; TEXT-DECORATION: none; PADDING-TOP: 0px } #left_column LI A:hover { BORDER-BOTTOM: 1px dotted; PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; COLOR: #03f; PADDING-TOP: 0px } #left_column IMG { PADDING-BOTTOM: 15px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FLOAT: = left; PADDING-TOP: 0px } #mid_column { PADDING-BOTTOM: 15px; MARGIN: 7px 0px 5px 4px; PADDING-LEFT: 5px; = WIDTH: 488px; PADDING-RIGHT: 5px; FLOAT: left; PADDING-TOP: 10px } #mid_column H1 { PADDING-BOTTOM: 0px; MARGIN: 0px 0px 8px; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; = COLOR: #036; FONT-SIZE: 8pt; PADDING-TOP: 0px } #mid_column H1 A { FONT-SIZE: 8pt; TEXT-DECORATION: none } #mid_column H1 A:hover { COLOR: #0033ff; TEXT-DECORATION: none } #mid_column UL { PADDING-BOTTOM: 0px; LIST-STYLE-TYPE: square; MARGIN: 0px 0px 5px; = PADDING-LEFT: 1.25em; PADDING-RIGHT: 0px; COLOR: #fff; LIST-STYLE-IMAGE: = url(../images/arrow_yellow.gif); PADDING-TOP: 0px } #mid_column LI { PADDING-BOTTOM: 5px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: = #000; TEXT-DECORATION: none; PADDING-TOP: 0px } #mid_column LI A { PADDING-BOTTOM: 1px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: = #03f; TEXT-DECORATION: none; PADDING-TOP: 0px } #mid_column LI A:hover { BORDER-BOTTOM: 1px dotted; PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; COLOR: #03f; PADDING-TOP: 0px } #fright_topbanner { BORDER-BOTTOM: #ea0 1px solid; BORDER-LEFT: #ea0 1px solid; = PADDING-BOTTOM: 5px; MARGIN: 10px 14px 5px 0px; PADDING-LEFT: 5px; = WIDTH: 220px; PADDING-RIGHT: 5px; BACKGROUND: #fffae6; FLOAT: right; = BORDER-TOP: #ea0 1px solid; BORDER-RIGHT: #ea0 1px solid; PADDING-TOP: = 5px } #fright_topbanner H1 { PADDING-BOTTOM: 0px; MARGIN: 0px 0px 3px; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; = COLOR: #036; FONT-SIZE: 8pt; PADDING-TOP: 0px } #fright_topbanner H1 A { COLOR: #036; FONT-SIZE: 8pt; TEXT-DECORATION: none } #fright_topbanner H1 A:hover { COLOR: #0033ff; TEXT-DECORATION: none } #fright_topbanner H2 { PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; = FONT-FAMILY: Georgia, Times New Roman, Times, serif; COLOR: #036; = FONT-SIZE: 13pt; FONT-WEIGHT: normal; PADDING-TOP: 0px } #fright_topbanner H2 A { PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; = FONT-FAMILY: Georgia, Times New Roman, Times, serif; COLOR: #036; = FONT-SIZE: 13pt; PADDING-TOP: 0px } #fright_topbanner H2 A:hover { COLOR: #03f } #fright_topbanner UL { PADDING-BOTTOM: 5px; LIST-STYLE-TYPE: square; MARGIN: 0px 0px 5px; = PADDING-LEFT: 1.25em; PADDING-RIGHT: 0px; COLOR: #036; PADDING-TOP: 0px } #fright_topbanner LI { PADDING-BOTTOM: 5px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: = #666666; FONT-WEIGHT: bold; TEXT-DECORATION: none; PADDING-TOP: 0px } #fright_topbanner LI A { PADDING-BOTTOM: 1px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: = #666; TEXT-DECORATION: none; PADDING-TOP: 0px } #fright_topbanner LI A:hover { BORDER-BOTTOM: 1px dotted; PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; COLOR: #03f; PADDING-TOP: 0px } .fright_banner_image { PADDING-BOTTOM: 4px; PADDING-LEFT: 0px; PADDING-RIGHT: 4px; = PADDING-TOP: 4px } #fright_column { PADDING-BOTTOM: 0px; BACKGROUND-COLOR: #fff6dd; MARGIN: 7px 4px 0px = 0px; PADDING-LEFT: 5px; WIDTH: 230px; PADDING-RIGHT: 5px; FLOAT: right; = PADDING-TOP: 5px } #fright_column H1 { PADDING-BOTTOM: 0px; MARGIN: 0px 0px 3px; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; = COLOR: #036; FONT-SIZE: 8pt; PADDING-TOP: 0px } #fright_column H1 A { FONT-SIZE: 8pt; TEXT-DECORATION: none } #fright_column H1 A:hover { COLOR: #0033ff; TEXT-DECORATION: none } #fright_column UL { PADDING-BOTTOM: 0px; LIST-STYLE-TYPE: square; MARGIN: 0px 0px 5px; = PADDING-LEFT: 2.25em; PADDING-RIGHT: 0px; COLOR: #fff; PADDING-TOP: 0px } #fright_column LI { PADDING-BOTTOM: 5px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: = #000; TEXT-DECORATION: none; PADDING-TOP: 0px } #fright_column LI A { PADDING-BOTTOM: 1px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: = #03f; TEXT-DECORATION: none; PADDING-TOP: 0px } #fright_column LI A:hover { BORDER-BOTTOM: 1px dotted; PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; COLOR: #03f; PADDING-TOP: 0px } #r2_left_column { PADDING-BOTTOM: 5px; MARGIN: 7px 0px 5px 6px; PADDING-LEFT: 5px; WIDTH: = 340px; PADDING-RIGHT: 5px; FLOAT: left; PADDING-TOP: 5px } #r2_left_column IMG { PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 8px; = PADDING-TOP: 0px } #r2_left_column H1 { PADDING-BOTTOM: 0px; MARGIN: 0px 0px 3px; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; = COLOR: #036; FONT-SIZE: 8pt; PADDING-TOP: 0px } #r2_left_column UL { PADDING-BOTTOM: 0px; LIST-STYLE-TYPE: square; MARGIN: 0px 0px 5px 2px; = PADDING-LEFT: 1.25em; PADDING-RIGHT: 0px; COLOR: #fff; LIST-STYLE-IMAGE: = url(../images/arrow_yellow.gif); PADDING-TOP: 0px } #r2_left_column LI { PADDING-BOTTOM: 5px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: = #000; TEXT-DECORATION: none; PADDING-TOP: 0px } #r2_left_column LI A { PADDING-BOTTOM: 1px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: = #03f; TEXT-DECORATION: none; PADDING-TOP: 0px } #r2_left_column LI A:hover { BORDER-BOTTOM: 1px dotted; PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; COLOR: #03f; PADDING-TOP: 0px } #r2_right_column { PADDING-BOTTOM: 5px; MARGIN: 7px 5px 5px 6px; PADDING-LEFT: 5px; WIDTH: = 340px; PADDING-RIGHT: 5px; FLOAT: right; PADDING-TOP: 5px } #r2_right_column IMG { PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 8px; = PADDING-TOP: 0px } #r2_right_column H1 { PADDING-BOTTOM: 0px; MARGIN: 0px 0px 3px; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; = COLOR: #036; FONT-SIZE: 8pt; PADDING-TOP: 0px } #r2_right_column UL { PADDING-BOTTOM: 0px; LIST-STYLE-TYPE: square; MARGIN: 0px 0px 5px 2px; = PADDING-LEFT: 1.25em; PADDING-RIGHT: 0px; COLOR: #fff; LIST-STYLE-IMAGE: = url(../images/arrow_yellow.gif); PADDING-TOP: 0px } #r2_right_column LI { PADDING-BOTTOM: 5px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: = #000; TEXT-DECORATION: none; PADDING-TOP: 0px } #r2_right_column LI A { PADDING-BOTTOM: 1px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: = #03f; TEXT-DECORATION: none; PADDING-TOP: 0px } #r2_right_column LI A:hover { BORDER-BOTTOM: 1px dotted; PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; COLOR: #03f; PADDING-TOP: 0px } #bleft_menu { BORDER-BOTTOM: #eeaa00 1px solid; BORDER-LEFT: #eeaa00 1px solid; = PADDING-BOTTOM: 5px; MARGIN: 7px 0px 15px 6px; PADDING-LEFT: 5px; WIDTH: = 180px; PADDING-RIGHT: 5px; FLOAT: left; BORDER-TOP: #eeaa00 1px solid; = BORDER-RIGHT: #eeaa00 1px solid; PADDING-TOP: 5px } #bleft_menu H1 { PADDING-BOTTOM: 0px; MARGIN: 0px 0px 3px; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; = COLOR: #ea0; FONT-SIZE: 8pt; PADDING-TOP: 0px } #bleft_menu H1 A { FONT-SIZE: 8pt; TEXT-DECORATION: none } #bleft_menu H1 A:hover { COLOR: #0033ff; TEXT-DECORATION: none } #bleft_menu UL { PADDING-BOTTOM: 0px; LIST-STYLE-TYPE: square; MARGIN: 0px 0px 5px 2px; = PADDING-LEFT: 1.25em; PADDING-RIGHT: 0px; COLOR: #003366; PADDING-TOP: = 0px } #bleft_menu LI { PADDING-BOTTOM: 1px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: = #666666; FONT-WEIGHT: bold; TEXT-DECORATION: none; PADDING-TOP: 0px } #bleft_menu LI A { PADDING-BOTTOM: 1px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: = #666666; FONT-WEIGHT: bold; TEXT-DECORATION: none; PADDING-TOP: 0px } #bleft_menu LI A:hover { BORDER-BOTTOM: 1px dotted; PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; = PADDING-RIGHT: 0px; COLOR: #0033ff; PADDING-TOP: 0px } #bsidebar { PADDING-BOTTOM: 0px; MARGIN: 7px 4px 15px 0px; PADDING-LEFT: 0px; = WIDTH: 546px; PADDING-RIGHT: 0px; BACKGROUND: #036; FLOAT: right; COLOR: = #fff; PADDING-TOP: 0px } #bsidebar IMG { PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 8px; = PADDING-TOP: 0px } #bsidebar A { COLOR: #fff; TEXT-DECORATION: underline } #bsidebar H1 { TEXT-ALIGN: center; PADDING-BOTTOM: 4px; MARGIN: 0px 0px 3px; = PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-FAMILY: Verdana, Arial, = Helvetica, sans-serif; COLOR: #ea0; FONT-SIZE: 10pt; PADDING-TOP: 7px } #bsidebar H1 A { COLOR: #fff; FONT-SIZE: 9pt; TEXT-DECORATION: none } #bsidebar H1 A:hover { COLOR: #0033ff; TEXT-DECORATION: none } .bsidebar_copy { PADDING-BOTTOM: 0px; LINE-HEIGHT: 8pt; PADDING-LEFT: 0px; = PADDING-RIGHT: 10px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; = COLOR: #fff; FONT-SIZE: 8pt; PADDING-TOP: 0px } .bsidebar_text { PADDING-BOTTOM: 0px; PADDING-LEFT: 4px; PADDING-RIGHT: 4px; = FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; FONT-SIZE: 8pt; = PADDING-TOP: 0px } .bsidebar_submit { BORDER-BOTTOM: #ccc 1px; BORDER-LEFT: #ccc 1px; PADDING-BOTTOM: 3px; = PADDING-LEFT: 0px; WIDTH: 80px; PADDING-RIGHT: 0px; FONT-FAMILY: = Verdana, Arial, Helvetica, sans-serif; HEIGHT: 14px; FONT-SIZE: 8pt; = BORDER-TOP: #ccc 1px; BORDER-RIGHT: #ccc 1px; PADDING-TOP: 0px } .bsidebar_label { TEXT-ALIGN: right; PADDING-BOTTOM: 0px; LINE-HEIGHT: 8pt; PADDING-LEFT: = 0px; PADDING-RIGHT: 10px; FONT-FAMILY: Verdana, Arial, Helvetica, = sans-serif; COLOR: #fff; FONT-SIZE: 8pt; FONT-WEIGHT: bold; PADDING-TOP: = 3px } .sub_title { PADDING-BOTTOM: 1px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; = FONT-FAMILY: Georgia, Times New Roman, Times, serif; FONT-SIZE: 10pt; = FONT-WEIGHT: 500; PADDING-TOP: 0px } .nameplate { FONT-FAMILY: Georgia, Times New Roman, Times, serif; COLOR: #036; = FONT-SIZE: 10pt; FONT-WEIGHT: bold } .left_50 { WIDTH: 250px } .right_50 { MARGIN: 0px 0px 0px 260px; WIDTH: 250px; FLOAT: right } .float_clear { PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: = 0px; CLEAR: both; PADDING-TOP: 0px } .float_left { FLOAT: left } .float_right { FLOAT: right } .dotted { BORDER-BOTTOM: #cccccc 1px dotted; MARGIN-BOTTOM: 1px } ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: text/css; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Location: http://www.marquette.edu/academicsenate/_css/_tables.css TABLE.muedu { BORDER-BOTTOM: #ccc 1px solid; BORDER-SPACING: 0px; WIDTH: 488px; = BORDER-COLLAPSE: collapse; BORDER-TOP: #ccc 4px solid } TABLE.muedu TH { TEXT-ALIGN: left; PADDING-BOTTOM: 0.2em; PADDING-LEFT: 0.5em; = PADDING-RIGHT: 0.5em; BORDER-TOP: #ccc 1px dotted; FONT-WEIGHT: normal; = PADDING-TOP: 0.2em } TABLE.muedu TD { TEXT-ALIGN: left; PADDING-BOTTOM: 0.2em; PADDING-LEFT: 0.5em; = PADDING-RIGHT: 0.5em; BORDER-TOP: #ccc 1px dotted; PADDING-TOP: 0.2em } TABLE.muedu THEAD TH { BORDER-BOTTOM: #ccc 1px solid; TEXT-ALIGN: left } TABLE.muedu TH.Corner { TEXT-ALIGN: left } .body_bold { FONT-WEIGHT: bold } .body_italic { FONT-STYLE: italic } .body_red { COLOR: #cc0000 } TABLE.muedu_minutes { BORDER-BOTTOM: #ccc 1px solid; BORDER-SPACING: 0px; WIDTH: 688px; = BORDER-COLLAPSE: collapse; BORDER-TOP: #ccc 4px solid } TABLE.muedu_minutes TH { TEXT-ALIGN: left; PADDING-BOTTOM: 0.2em; PADDING-LEFT: 0.5em; = PADDING-RIGHT: 0.5em; BORDER-TOP: #ccc 1px dotted; FONT-WEIGHT: normal; = PADDING-TOP: 0.2em } TABLE.muedu_minutes TD { TEXT-ALIGN: left; PADDING-BOTTOM: 0.2em; PADDING-LEFT: 0.5em; = PADDING-RIGHT: 0.5em; BORDER-TOP: #ccc 1px dotted; PADDING-TOP: 0.2em } TABLE.muedu_minutes THEAD TH { BORDER-BOTTOM: #ccc 1px solid; TEXT-ALIGN: left } TABLE.muedu_minutes TH.Corner { TEXT-ALIGN: left } .body_bold { FONT-WEIGHT: bold } .body_italic { FONT-STYLE: italic } ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: text/css; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Location: http://www.marquette.edu/academicsenate/_css/SpryAutoSuggest.css .hideSuggestClass { Z-INDEX: 1011; BORDER-BOTTOM: #ccc 1px solid; POSITION: absolute; = BORDER-LEFT: #ccc 1px solid; MARGIN: 0px; WIDTH: 320px; DISPLAY: none; = BACKGROUND: #ffffff; HEIGHT: 140px; OVERFLOW: auto; BORDER-TOP: #ccc 1px = solid; CURSOR: pointer; BORDER-RIGHT: #ccc 1px solid } .showSuggestClass UL { PADDING-BOTTOM: 10px; LIST-STYLE-TYPE: none; MARGIN: 0px; PADDING-LEFT: = 0px; PADDING-RIGHT: 0px; LIST-STYLE-IMAGE: none; PADDING-TOP: 0px } .showSuggestClass LI { PADDING-BOTTOM: 0px; LINE-HEIGHT: 17px; LIST-STYLE-TYPE: none; MARGIN: = 7px 0px; PADDING-LEFT: 5px; PADDING-RIGHT: 0px; LIST-STYLE-IMAGE: none; = PADDING-TOP: 0px } .showSuggestClass A { PADDING-BOTTOM: 1px; PADDING-LEFT: 0px; WIDTH: 200px; PADDING-RIGHT: = 0px; DISPLAY: block; COLOR: #000; TEXT-DECORATION: none; PADDING-TOP: = 0px } .showSuggestClass A:hover { BORDER-BOTTOM: 1px dotted; PADDING-BOTTOM: 0px; BACKGROUND-COLOR: #fff = !important; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; COLOR: #03f; = PADDING-TOP: 0px } .showSuggestClass .hideSuggestClass { DISPLAY: block !important; CURSOR: pointer } .showSuggestClass .hoverSuggestClass { BACKGROUND-COLOR: #fff !important; COLOR: #000 } .iframeSuggest { Z-INDEX: 900; POSITION: absolute } #quick_find { Z-INDEX: 1011; WIDTH: 290px; FLOAT: left; MARGIN-LEFT: 0px } #quick_find H1 { FONT-FAMILY: Verdana, Geneva, sans-serif; COLOR: #036; FONT-SIZE: 14px; = FONT-WEIGHT: bold } * HTML #productSampleUl { POSITION: absolute; WIDTH: 190px } ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: application/octet-stream Content-Transfer-Encoding: quoted-printable Content-Location: http://www.marquette.edu/omc/newscenter/random.php =0A= ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: application/octet-stream Content-Transfer-Encoding: quoted-printable Content-Location: http://www.marquette.edu/academicsenate/_js/yahoo-dom-event.js /* Copyright (c) 2007, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.net/yui/license.txt version: 2.2.2 */ if(typeof YAHOO=3D=3D"undefined"){var YAHOO=3D{};} YAHOO.namespace=3Dfunction(){var = a=3Darguments,o=3Dnull,i,j,d;for(i=3D0;i-1){retu= rn true;}else{return = YAHOO.lang.isObject(obj)&&obj.constructor=3D=3DArray;}},isBoolean:functio= n(obj){return typeof = obj=3D=3D'boolean';},isFunction:function(obj){return typeof = obj=3D=3D'function';},isNull:function(obj){return = obj=3D=3D=3Dnull;},isNumber:function(obj){return typeof = obj=3D=3D'number'&&isFinite(obj);},isObject:function(obj){return = obj&&(typeof = obj=3D=3D'object'||YAHOO.lang.isFunction(obj));},isString:function(obj){r= eturn typeof obj=3D=3D'string';},isUndefined:function(obj){return typeof = obj=3D=3D'undefined';},hasOwnProperty:function(obj,prop){if(Object.protot= ype.hasOwnProperty){return obj.hasOwnProperty(prop);} return!YAHOO.lang.isUndefined(obj[prop])&&obj.constructor.prototype[prop]= !=3D=3Dobj[prop];},extend:function(subc,superc,overrides){if(!superc||!su= bc){throw new Error("YAHOO.lang.extend failed, please check that "+"all = dependencies are included.");} var F=3Dfunction(){};F.prototype=3Dsuperc.prototype;subc.prototype=3Dnew = F();subc.prototype.constructor=3Dsubc;subc.superclass=3Dsuperc.prototype;= if(superc.prototype.constructor=3D=3DObject.prototype.constructor){superc= .prototype.constructor=3Dsuperc;} if(overrides){for(var i in = overrides){subc.prototype[i]=3Doverrides[i];}}},augment:function(r,s){if(= !s||!r){throw new Error("YAHOO.lang.augment failed, please check that = "+"all dependencies are included.");} var = rp=3Dr.prototype,sp=3Ds.prototype,a=3Darguments,i,p;if(a[2]){for(i=3D2;i<= a.length;i=3Di+1){rp[a[i]]=3Dsp[a[i]];}}else{for(p in = sp){if(!rp[p]){rp[p]=3Dsp[p];}}}}};YAHOO.init();YAHOO.util.Lang=3DYAHOO.l= ang;YAHOO.augment=3DYAHOO.lang.augment;YAHOO.extend=3DYAHOO.lang.extend;Y= AHOO.register("yahoo",YAHOO,{version:"2.2.2",build:"204"}); (function(){var = Y=3DYAHOO.util,getStyle,setStyle,id_counter=3D0,propertyCache=3D{};var = ua=3Dnavigator.userAgent.toLowerCase(),isOpera=3D(ua.indexOf('opera')>-1)= ,isSafari=3D(ua.indexOf('safari')>-1),isGecko=3D(!isOpera&&!isSafari&&ua.= indexOf('gecko')>-1),isIE=3D(!isOpera&&ua.indexOf('msie')>-1);var = patterns=3D{HYPHEN:/(-[a-z])/i,ROOT_TAG:/body|html/i};var = toCamel=3Dfunction(property){if(!patterns.HYPHEN.test(property)){return = property;} if(propertyCache[property]){return propertyCache[property];} var = converted=3Dproperty;while(patterns.HYPHEN.exec(converted)){converted=3Dc= onverted.replace(RegExp.$1,RegExp.$1.substr(1).toUpperCase());} propertyCache[property]=3Dconverted;return = converted;};if(document.defaultView&&document.defaultView.getComputedStyl= e){getStyle=3Dfunction(el,property){var = value=3Dnull;if(property=3D=3D'float'){property=3D'cssFloat';} var = computed=3Ddocument.defaultView.getComputedStyle(el,'');if(computed){valu= e=3Dcomputed[toCamel(property)];} return el.style[property]||value;};}else = if(document.documentElement.currentStyle&&isIE){getStyle=3Dfunction(el,pr= operty){switch(toCamel(property)){case'opacity':var = val=3D100;try{val=3Del.filters['DXImageTransform.Microsoft.Alpha'].opacit= y;}catch(e){try{val=3Del.filters('alpha').opacity;}catch(e){}} return val/100;break;case'float':property=3D'styleFloat';default:var = value=3Del.currentStyle?el.currentStyle[property]:null;return(el.style[pr= operty]||value);}};}else{getStyle=3Dfunction(el,property){return = el.style[property];};} if(isIE){setStyle=3Dfunction(el,property,val){switch(property){case'opaci= ty':if(YAHOO.lang.isString(el.style.filter)){el.style.filter=3D'alpha(opa= city=3D'+val*100+')';if(!el.currentStyle||!el.currentStyle.hasLayout){el.= style.zoom=3D1;}} break;case'float':property=3D'styleFloat';default:el.style[property]=3Dva= l;}};}else{setStyle=3Dfunction(el,property,val){if(property=3D=3D'float')= {property=3D'cssFloat';} el.style[property]=3Dval;};} YAHOO.util.Dom=3D{get:function(el){if(YAHOO.lang.isString(el)){return = document.getElementById(el);} if(YAHOO.lang.isArray(el)){var c=3D[];for(var = i=3D0,len=3Del.length;i=3Dthis.le= ft&®ion.right<=3Dthis.right&®ion.top>=3Dthis.top&®ion.bottom<=3D= this.bottom);};YAHOO.util.Region.prototype.getArea=3Dfunction(){return((t= his.bottom-this.top)*(this.right-this.left));};YAHOO.util.Region.prototyp= e.intersect=3Dfunction(region){var t=3DMath.max(this.top,region.top);var = r=3DMath.min(this.right,region.right);var = b=3DMath.min(this.bottom,region.bottom);var = l=3DMath.max(this.left,region.left);if(b>=3Dt&&r>=3Dl){return new = YAHOO.util.Region(t,r,b,l);}else{return = null;}};YAHOO.util.Region.prototype.union=3Dfunction(region){var = t=3DMath.min(this.top,region.top);var = r=3DMath.max(this.right,region.right);var = b=3DMath.max(this.bottom,region.bottom);var = l=3DMath.min(this.left,region.left);return new = YAHOO.util.Region(t,r,b,l);};YAHOO.util.Region.prototype.toString=3Dfunct= ion(){return("Region {"+"top: "+this.top+", right: "+this.right+", = bottom: "+this.bottom+", left: = "+this.left+"}");};YAHOO.util.Region.getRegion=3Dfunction(el){var = p=3DYAHOO.util.Dom.getXY(el);var t=3Dp[1];var = r=3Dp[0]+el.offsetWidth;var b=3Dp[1]+el.offsetHeight;var l=3Dp[0];return = new YAHOO.util.Region(t,r,b,l);};YAHOO.util.Point=3Dfunction(x,y){if(x = instanceof Array){y=3Dx[1];x=3Dx[0];} this.x=3Dthis.right=3Dthis.left=3Dthis[0]=3Dx;this.y=3Dthis.top=3Dthis.bo= ttom=3Dthis[1]=3Dy;};YAHOO.util.Point.prototype=3Dnew = YAHOO.util.Region();YAHOO.register("dom",YAHOO.util.Dom,{version:"2.2.2",= build:"204"}); YAHOO.util.CustomEvent=3Dfunction(type,oScope,silent,signature){this.type= =3Dtype;this.scope=3DoScope||window;this.silent=3Dsilent;this.signature=3D= signature||YAHOO.util.CustomEvent.LIST;this.subscribers=3D[];if(!this.sil= ent){} var = onsubscribeType=3D"_YUICEOnSubscribe";if(type!=3D=3DonsubscribeType){this= .subscribeEvent=3Dnew = YAHOO.util.CustomEvent(onsubscribeType,this,true);}};YAHOO.util.CustomEve= nt.LIST=3D0;YAHOO.util.CustomEvent.FLAT=3D1;YAHOO.util.CustomEvent.protot= ype=3D{subscribe:function(fn,obj,override){if(!fn){throw new = Error("Invalid callback for subscriber to '"+this.type+"'");} if(this.subscribeEvent){this.subscribeEvent.fire(fn,obj,override);} this.subscribers.push(new = YAHOO.util.Subscriber(fn,obj,override));},unsubscribe:function(fn,obj){if= (!fn){return this.unsubscribeAll();} var found=3Dfalse;for(var = i=3D0,len=3Dthis.subscribers.length;i0){param=3Dargs[0];} ret=3Ds.fn.call(scope,param,s.obj);}else{ret=3Ds.fn.call(scope,this.type,= args,s.obj);} if(false=3D=3D=3Dret){if(!this.silent){} return false;}}} return true;},unsubscribeAll:function(){for(var = i=3D0,len=3Dthis.subscribers.length;i=3D0){cacheItem=3Dlisteners[index];} if(!el||!cacheItem){return false;} if(this.useLegacyEvent(el,sType)){var = legacyIndex=3Dthis.getLegacyIndex(el,sType);var = llist=3DlegacyHandlers[legacyIndex];if(llist){for(i=3D0,len=3Dllist.lengt= h;i0);} var notAvail=3D[];var executeItem=3Dfunction(el,item){var = scope=3Del;if(item.override){if(item.override=3D=3D=3Dtrue){scope=3Ditem.= obj;}else{scope=3Ditem.override;}} item.fn.call(scope,item.obj);};var = i,len,item,el;for(i=3D0,len=3DonAvailStack.length;i0){for(var = i=3D0,len=3DsearchList.length;i0){j=3Dlisteners.le= ngth;while(j){index=3Dj-1;l=3Dlisteners[index];if(l){EU.removeListener(l[= EU.EL],l[EU.TYPE],l[EU.FN],index);} j=3Dj-1;} l=3Dnull;EU.clearCache();} for(i=3D0,len=3DlegacyEvents.length;i');var = el=3Ddocument.getElementById("_yui_eu_dr");el.onreadystatechange=3Dfuncti= on(){if("complete"=3D=3Dthis.readyState){this.parentNode.removeChild(this= );YAHOO.util.Event._ready();}};el=3Dnull;YAHOO.util.Event.onDOMReady(YAHO= O.util.Event._tryPreloadAttach,YAHOO.util.Event,true);}else = if(EU.webkit){EU._drwatch=3DsetInterval(function(){var = rs=3Ddocument.readyState;if("loaded"=3D=3Drs||"complete"=3D=3Drs){clearIn= terval(EU._drwatch);EU._drwatch=3Dnull;EU._ready();}},EU.POLL_INTERVAL);}= else{EU._simpleAdd(document,"DOMContentLoaded",EU._ready);} EU._simpleAdd(window,"load",EU._load);EU._simpleAdd(window,"unload",EU._u= nload);EU._tryPreloadAttach();})();} YAHOO.util.EventProvider=3Dfunction(){};YAHOO.util.EventProvider.prototyp= e=3D{__yui_events:null,__yui_subscribers:null,subscribe:function(p_type,p= _fn,p_obj,p_override){this.__yui_events=3Dthis.__yui_events||{};var = ce=3Dthis.__yui_events[p_type];if(ce){ce.subscribe(p_fn,p_obj,p_override)= ;}else{this.__yui_subscribers=3Dthis.__yui_subscribers||{};var = subs=3Dthis.__yui_subscribers;if(!subs[p_type]){subs[p_type]=3D[];} subs[p_type].push({fn:p_fn,obj:p_obj,override:p_override});}},unsubscribe= :function(p_type,p_fn,p_obj){this.__yui_events=3Dthis.__yui_events||{};va= r ce=3Dthis.__yui_events[p_type];if(ce){return = ce.unsubscribe(p_fn,p_obj);}else{return = false;}},unsubscribeAll:function(p_type){return = this.unsubscribe(p_type);},createEvent:function(p_type,p_config){this.__y= ui_events=3Dthis.__yui_events||{};var opts=3Dp_config||{};var = events=3Dthis.__yui_events;if(events[p_type]){}else{var = scope=3Dopts.scope||this;var silent=3Dopts.silent||null;var ce=3Dnew = YAHOO.util.CustomEvent(p_type,scope,silent,YAHOO.util.CustomEvent.FLAT);e= vents[p_type]=3Dce;if(opts.onSubscribeCallback){ce.subscribeEvent.subscri= be(opts.onSubscribeCallback);} this.__yui_subscribers=3Dthis.__yui_subscribers||{};var = qs=3Dthis.__yui_subscribers[p_type];if(qs){for(var = i=3D0;i0)?val:0;} YAHOO.util.Dom.setStyle(this.getEl(),attr,val+unit);},getAttribute:functi= on(attr){var el=3Dthis.getEl();var = val=3DYAHOO.util.Dom.getStyle(el,attr);if(val!=3D=3D'auto'&&!this.pattern= s.offsetUnit.test(val)){return parseFloat(val);} var a=3Dthis.patterns.offsetAttribute.exec(attr)||[];var = pos=3D!!(a[3]);var = box=3D!!(a[2]);if(box||(YAHOO.util.Dom.getStyle(el,'position')=3D=3D'abso= lute'&&pos)){val=3Del['offset'+a[0].charAt(0).toUpperCase()+a[0].substr(1= )];}else{val=3D0;} return = val;},getDefaultUnit:function(attr){if(this.patterns.defaultUnit.test(att= r)){return'px';} return'';},setRuntimeAttribute:function(attr){var start;var end;var = attributes=3Dthis.attributes;this.runtimeAttributes[attr]=3D{};var = isset=3Dfunction(prop){return(typeof = prop!=3D=3D'undefined');};if(!isset(attributes[attr]['to'])&&!isset(attri= butes[attr]['by'])){return false;} start=3D(isset(attributes[attr]['from']))?attributes[attr]['from']:this.g= etAttribute(attr);if(isset(attributes[attr]['to'])){end=3Dattributes[attr= ]['to'];}else = if(isset(attributes[attr]['by'])){if(start.constructor=3D=3DArray){end=3D= [];for(var = i=3D0,len=3Dstart.length;i0&&isFinite(tweak)){if(tween.currentFrame+tweak>=3Dframes){tweak= =3Dframes-(frame+1);} tween.currentFrame+=3Dtweak;}};};YAHOO.util.Bezier=3Dnew = function(){this.getPosition=3Dfunction(points,t){var = n=3Dpoints.length;var tmp=3D[];for(var = i=3D0;i0&&!(control[0]instanceof = Array)){control=3D[control];}else{var = tmp=3D[];for(i=3D0,len=3Dcontrol.length;i0){this.runtimeA= ttributes[attr]=3Dthis.runtimeAttributes[attr].concat(control);} this.runtimeAttributes[attr][this.runtimeAttributes[attr].length]=3Dend;}= else{superclass.setRuntimeAttribute.call(this,attr);}};var = translateValues=3Dfunction(val,start){var = pageXY=3DY.Dom.getXY(this.getEl());val=3D[val[0]-pageXY[0]+start[0],val[1= ]-pageXY[1]+start[1]];return val;};var = isset=3Dfunction(prop){return(typeof = prop!=3D=3D'undefined');};})();(function(){YAHOO.util.Scroll=3Dfunction(e= l,attributes,duration,method){if(el){YAHOO.util.Scroll.superclass.constru= ctor.call(this,el,attributes,duration,method);}};YAHOO.extend(YAHOO.util.= Scroll,YAHOO.util.ColorAnim);var Y=3DYAHOO.util;var = superclass=3DY.Scroll.superclass;var = proto=3DY.Scroll.prototype;proto.toString=3Dfunction(){var = el=3Dthis.getEl();var id=3Del.id||el.tagName;return("Scroll = "+id);};proto.doMethod=3Dfunction(attr,start,end){var = val=3Dnull;if(attr=3D=3D'scroll'){val=3D[this.method(this.currentFrame,st= art[0],end[0]-start[0],this.totalFrames),this.method(this.currentFrame,st= art[1],end[1]-start[1],this.totalFrames)];}else{val=3Dsuperclass.doMethod= .call(this,attr,start,end);} return val;};proto.getAttribute=3Dfunction(attr){var val=3Dnull;var = el=3Dthis.getEl();if(attr=3D=3D'scroll'){val=3D[el.scrollLeft,el.scrollTo= p];}else{val=3Dsuperclass.getAttribute.call(this,attr);} return val;};proto.setAttribute=3Dfunction(attr,val,unit){var = el=3Dthis.getEl();if(attr=3D=3D'scroll'){el.scrollLeft=3Dval[0];el.scroll= Top=3Dval[1];}else{superclass.setAttribute.call(this,attr,val,unit);}};})= ();YAHOO.register("animation",YAHOO.util.Anim,{version:"2.2.2",build:"204= "}); ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: application/octet-stream Content-Transfer-Encoding: quoted-printable Content-Location: http://www.marquette.edu/academicsenate/_js/toggle.js // JavaScript Document var Dom =3D YAHOO.util.Dom; var Event =3D YAHOO.util.Event; var $ =3D function(id) { return document.getElementById(id); }=20 //++++++++++++++++++++++++++++++++++++ // YUI TOGGLE // 12/21/2007 - Edwart Visser & Arjen Weeber // // toggle the visibility // // REQUIRES: yahoo-dom-event.js // OPTIONAL: animation-min.js // //++++++++++++++++++++++++++++++++++++ YAHOO.namespace("lutsr"); YAHOO.lutsr.doToggle =3D { init : function() { this.toggleLinks =3D Dom.getElementsByClassName("toggle"); for(var i=3D0; i, // and // for the = specifications. // // Author: Junji Takagi // Detect whether RegExp supports Unicode characters or not. var REGEXP_UNICODE =3D function() { var tests =3D [' ', '\u0120', -1, // Konquerer 3.4.0 fails here. '!', '\u0120', -1, '\u0120', '\u0120', 0, '\u0121', '\u0120', -1, '\u0121', '\u0120|\u0121', 0, '\u0122', '\u0120|\u0121', -1, '\u0120', '[\u0120]', 0, // Safari 2.0.3 fails here. '\u0121', '[\u0120]', -1, '\u0121', '[\u0120\u0121]', 0, // Safari 2.0.3 fails = here. '\u0122', '[\u0120\u0121]', -1, '\u0121', '[\u0120-\u0121]', 0, // Safari 2.0.3 fails = here. '\u0122', '[\u0120-\u0121]', -1]; for (var i =3D 0; i < tests.length; i +=3D 3) { if (tests[i].search(new RegExp(tests[i + 1])) !=3D tests[i + 2]) { return false; } } return true; }(); // Common tokens in XML 1.0 and XML 1.1. var XML_S =3D '[ \t\r\n]+'; var XML_EQ =3D '(' + XML_S + ')?=3D(' + XML_S + ')?'; var XML_CHAR_REF =3D '&#[0-9]+;|&#x[0-9a-fA-F]+;'; // XML 1.0 tokens. var XML10_VERSION_INFO =3D XML_S + 'version' + XML_EQ + '("1\\.0"|' + = "'1\\.0')"; var XML10_BASE_CHAR =3D (REGEXP_UNICODE) ? '\u0041-\u005a\u0061-\u007a\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u00ff' + '\u0100-\u0131\u0134-\u013e\u0141-\u0148\u014a-\u017e\u0180-\u01c3' + = '\u01cd-\u01f0\u01f4-\u01f5\u01fa-\u0217\u0250-\u02a8\u02bb-\u02c1\u0386'= + = '\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03ce\u03d0-\u03d6\u03da\u03dc' = + '\u03de\u03e0\u03e2-\u03f3\u0401-\u040c\u040e-\u044f\u0451-\u045c' + '\u045e-\u0481\u0490-\u04c4\u04c7-\u04c8\u04cb-\u04cc\u04d0-\u04eb' + = '\u04ee-\u04f5\u04f8-\u04f9\u0531-\u0556\u0559\u0561-\u0586\u05d0-\u05ea'= + '\u05f0-\u05f2\u0621-\u063a\u0641-\u064a\u0671-\u06b7\u06ba-\u06be' + '\u06c0-\u06ce\u06d0-\u06d3\u06d5\u06e5-\u06e6\u0905-\u0939\u093d' + = '\u0958-\u0961\u0985-\u098c\u098f-\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2'= + '\u09b6-\u09b9\u09dc-\u09dd\u09df-\u09e1\u09f0-\u09f1\u0a05-\u0a0a' + '\u0a0f-\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32-\u0a33\u0a35-\u0a36' + '\u0a38-\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8b\u0a8d' + '\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2-\u0ab3\u0ab5-\u0ab9' + '\u0abd\u0ae0\u0b05-\u0b0c\u0b0f-\u0b10\u0b13-\u0b28\u0b2a-\u0b30' + = '\u0b32-\u0b33\u0b36-\u0b39\u0b3d\u0b5c-\u0b5d\u0b5f-\u0b61\u0b85-\u0b8a'= + = '\u0b8e-\u0b90\u0b92-\u0b95\u0b99-\u0b9a\u0b9c\u0b9e-\u0b9f\u0ba3-\u0ba4'= + '\u0ba8-\u0baa\u0bae-\u0bb5\u0bb7-\u0bb9\u0c05-\u0c0c\u0c0e-\u0c10' + '\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c60-\u0c61\u0c85-\u0c8c' + = '\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cde\u0ce0-\u0ce1'= + '\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d28\u0d2a-\u0d39\u0d60-\u0d61' + '\u0e01-\u0e2e\u0e30\u0e32-\u0e33\u0e40-\u0e45\u0e81-\u0e82\u0e84' + = '\u0e87-\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5' = + = '\u0ea7\u0eaa-\u0eab\u0ead-\u0eae\u0eb0\u0eb2-\u0eb3\u0ebd\u0ec0-\u0ec4' = + = '\u0f40-\u0f47\u0f49-\u0f69\u10a0-\u10c5\u10d0-\u10f6\u1100\u1102-\u1103'= + = '\u1105-\u1107\u1109\u110b-\u110c\u110e-\u1112\u113c\u113e\u1140\u114c' = + '\u114e\u1150\u1154-\u1155\u1159\u115f-\u1161\u1163\u1165\u1167\u1169' = + '\u116d-\u116e\u1172-\u1173\u1175\u119e\u11a8\u11ab\u11ae-\u11af' + '\u11b7-\u11b8\u11ba\u11bc-\u11c2\u11eb\u11f0\u11f9\u1e00-\u1e9b' + '\u1ea0-\u1ef9\u1f00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d' + = '\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc' = + = '\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec'= + '\u1ff2-\u1ff4\u1ff6-\u1ffc\u2126\u212a-\u212b\u212e\u2180-\u2182' + '\u3041-\u3094\u30a1-\u30fa\u3105-\u312c\uac00-\ud7a3' : 'A-Za-z'; var XML10_IDEOGRAPHIC =3D (REGEXP_UNICODE) ? '\u4e00-\u9fa5\u3007\u3021-\u3029' : ''; var XML10_COMBINING_CHAR =3D (REGEXP_UNICODE) ? '\u0300-\u0345\u0360-\u0361\u0483-\u0486\u0591-\u05a1\u05a3-\u05b9' + = '\u05bb-\u05bd\u05bf\u05c1-\u05c2\u05c4\u064b-\u0652\u0670\u06d6-\u06dc' = + = '\u06dd-\u06df\u06e0-\u06e4\u06e7-\u06e8\u06ea-\u06ed\u0901-\u0903\u093c'= + = '\u093e-\u094c\u094d\u0951-\u0954\u0962-\u0963\u0981-\u0983\u09bc\u09be' = + = '\u09bf\u09c0-\u09c4\u09c7-\u09c8\u09cb-\u09cd\u09d7\u09e2-\u09e3\u0a02' = + = '\u0a3c\u0a3e\u0a3f\u0a40-\u0a42\u0a47-\u0a48\u0a4b-\u0a4d\u0a70-\u0a71' = + = '\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0b01-\u0b03'= + = '\u0b3c\u0b3e-\u0b43\u0b47-\u0b48\u0b4b-\u0b4d\u0b56-\u0b57\u0b82-\u0b83'= + = '\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0c01-\u0c03\u0c3e-\u0c44'= + '\u0c46-\u0c48\u0c4a-\u0c4d\u0c55-\u0c56\u0c82-\u0c83\u0cbe-\u0cc4' + '\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5-\u0cd6\u0d02-\u0d03\u0d3e-\u0d43' + = '\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1' = + = '\u0eb4-\u0eb9\u0ebb-\u0ebc\u0ec8-\u0ecd\u0f18-\u0f19\u0f35\u0f37\u0f39' = + = '\u0f3e\u0f3f\u0f71-\u0f84\u0f86-\u0f8b\u0f90-\u0f95\u0f97\u0f99-\u0fad' = + '\u0fb1-\u0fb7\u0fb9\u20d0-\u20dc\u20e1\u302a-\u302f\u3099\u309a' : ''; var XML10_DIGIT =3D (REGEXP_UNICODE) ? '\u0030-\u0039\u0660-\u0669\u06f0-\u06f9\u0966-\u096f\u09e6-\u09ef' + '\u0a66-\u0a6f\u0ae6-\u0aef\u0b66-\u0b6f\u0be7-\u0bef\u0c66-\u0c6f' + '\u0ce6-\u0cef\u0d66-\u0d6f\u0e50-\u0e59\u0ed0-\u0ed9\u0f20-\u0f29' : '0-9'; var XML10_EXTENDER =3D (REGEXP_UNICODE) ? '\u00b7\u02d0\u02d1\u0387\u0640\u0e46\u0ec6\u3005\u3031-\u3035' + '\u309d-\u309e\u30fc-\u30fe' : ''; var XML10_LETTER =3D XML10_BASE_CHAR + XML10_IDEOGRAPHIC; var XML10_NAME_CHAR =3D XML10_LETTER + XML10_DIGIT + '\\._:' + XML10_COMBINING_CHAR + XML10_EXTENDER + '-'; var XML10_NAME =3D '[' + XML10_LETTER + '_:][' + XML10_NAME_CHAR + ']*'; var XML10_ENTITY_REF =3D '&' + XML10_NAME + ';'; var XML10_REFERENCE =3D XML10_ENTITY_REF + '|' + XML_CHAR_REF; var XML10_ATT_VALUE =3D '"(([^<&"]|' + XML10_REFERENCE + ')*)"|' + "'(([^<&']|" + XML10_REFERENCE + ")*)'"; var XML10_ATTRIBUTE =3D '(' + XML10_NAME + ')' + XML_EQ + '(' + XML10_ATT_VALUE + ')'; // XML 1.1 tokens. // TODO(jtakagi): NameStartChar also includes \u10000-\ueffff. // ECMAScript Language Specifiction defines UnicodeEscapeSequence as // "\u HexDigit HexDigit HexDigit HexDigit" and we may need to use // surrogate pairs, but any browser doesn't support surrogate paris in // character classes of regular expression, so avoid including them for = now. var XML11_VERSION_INFO =3D XML_S + 'version' + XML_EQ + '("1\\.1"|' + = "'1\\.1')"; var XML11_NAME_START_CHAR =3D (REGEXP_UNICODE) ? ':A-Z_a-z\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02ff\u0370-\u037d' + '\u037f-\u1fff\u200c-\u200d\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff' + '\uf900-\ufdcf\ufdf0-\ufffd' : ':A-Z_a-z'; var XML11_NAME_CHAR =3D XML11_NAME_START_CHAR + ((REGEXP_UNICODE) ? '\\.0-9\u00b7\u0300-\u036f\u203f-\u2040-' : = '\\.0-9-'); var XML11_NAME =3D '[' + XML11_NAME_START_CHAR + '][' + XML11_NAME_CHAR = + ']*'; var XML11_ENTITY_REF =3D '&' + XML11_NAME + ';'; var XML11_REFERENCE =3D XML11_ENTITY_REF + '|' + XML_CHAR_REF; var XML11_ATT_VALUE =3D '"(([^<&"]|' + XML11_REFERENCE + ')*)"|' + "'(([^<&']|" + XML11_REFERENCE + ")*)'"; var XML11_ATTRIBUTE =3D '(' + XML11_NAME + ')' + XML_EQ + '(' + XML11_ATT_VALUE + ')'; // XML Namespace tokens. // Used in XML parser and XPath parser. var XML_NC_NAME_CHAR =3D XML10_LETTER + XML10_DIGIT + '\\._' + XML10_COMBINING_CHAR + XML10_EXTENDER + '-'; var XML_NC_NAME =3D '[' + XML10_LETTER + '_][' + XML_NC_NAME_CHAR + = ']*'; // Code from dom.js. // // Based on var DOM_ELEMENT_NODE =3D 1; var DOM_ATTRIBUTE_NODE =3D 2; var DOM_TEXT_NODE =3D 3; var DOM_CDATA_SECTION_NODE =3D 4; var DOM_ENTITY_REFERENCE_NODE =3D 5; var DOM_ENTITY_NODE =3D 6; var DOM_PROCESSING_INSTRUCTION_NODE =3D 7; var DOM_COMMENT_NODE =3D 8; var DOM_DOCUMENT_NODE =3D 9; var DOM_DOCUMENT_TYPE_NODE =3D 10; var DOM_DOCUMENT_FRAGMENT_NODE =3D 11; var DOM_NOTATION_NODE =3D 12; // Code from util.js. // // Copyright 2005 Google // // Author: Steffen Meschkat // // Miscellaneous utility and placeholder functions. // Dummy implmentation for the logging functions. Replace by something // useful when you want to debug. function xpathLog(msg) {}; function xsltLog(msg) {}; function xsltLogXml(msg) {}; // Throws an exception if false. function assert(b) { if (!b) { throw "Assertion failed"; } } // Splits a string s at all occurrences of character c. This is like // the split() method of the string object, but IE omits empty // strings, which violates the invariant (s.split(x).join(x) =3D=3D s). function stringSplit(s, c) { var a =3D s.indexOf(c); if (a =3D=3D -1) { return [ s ]; } var parts =3D []; parts.push(s.substr(0,a)); while (a !=3D -1) { var a1 =3D s.indexOf(c, a + 1); if (a1 !=3D -1) { parts.push(s.substr(a + 1, a1 - a - 1)); } else { parts.push(s.substr(a + 1)); } a =3D a1; } return parts; } // Applies the given function to each element of the array, preserving // this, and passing the index. function mapExec(array, func) { for (var i =3D 0; i < array.length; ++i) { func.call(this, array[i], i); } } // Returns an array that contains the return value of the given // function applied to every element of the input array. function mapExpr(array, func) { var ret =3D []; for (var i =3D 0; i < array.length; ++i) { ret.push(func(array[i])); } return ret; }; // Reverses the given array in place. function reverseInplace(array) { for (var i =3D 0; i < array.length / 2; ++i) { var h =3D array[i]; var ii =3D array.length - i - 1; array[i] =3D array[ii]; array[ii] =3D h; } } // Removes value from array. Returns the number of instances of value // that were removed from array. function removeFromArray(array, value, opt_notype) { var shift =3D 0; for (var i =3D 0; i < array.length; ++i) { if (array[i] =3D=3D=3D value || (opt_notype && array[i] =3D=3D = value)) { array.splice(i--, 1); shift++; } } return shift; } // Shallow-copies an array. function copyArray(dst, src) { for (var i =3D 0; i < src.length; ++i) { dst.push(src[i]); } } // Returns the text value of a node; for nodes without children this // is the nodeValue, for nodes with children this is the concatenation // of the value of all children. function xmlValue(node) { if (!node) { return ''; } var ret =3D ''; if (node.nodeType =3D=3D DOM_TEXT_NODE || node.nodeType =3D=3D DOM_CDATA_SECTION_NODE || node.nodeType =3D=3D DOM_ATTRIBUTE_NODE) { ret +=3D node.nodeValue; } else if (node.nodeType =3D=3D DOM_ELEMENT_NODE || node.nodeType =3D=3D DOM_DOCUMENT_NODE || node.nodeType =3D=3D DOM_DOCUMENT_FRAGMENT_NODE) { for (var i =3D 0; i < node.childNodes.length; ++i) { ret +=3D arguments.callee(node.childNodes[i]); } } return ret; } // Code from xpath.js. // // Copyright 2005 Google Inc. // All Rights Reserved // // An XPath parser and evaluator written in JavaScript. The // implementation is complete except for functions handling // namespaces. // // Reference: [XPATH] XPath Specification // . // // // The API of the parser has several parts: // // 1. The parser function xpathParse() that takes a string and returns // an expession object. // // 2. The expression object that has an evaluate() method to evaluate = the // XPath expression it represents. (It is actually a hierarchy of // objects that resembles the parse tree, but an application will call // evaluate() only on the top node of this hierarchy.) // // 3. The context object that is passed as an argument to the evaluate() // method, which represents the DOM context in which the expression is // evaluated. // // 4. The value object that is returned from evaluate() and represents // values of the different types that are defined by XPath (number, // string, boolean, and node-set), and allows to convert between them. // // These parts are near the top of the file, the functions and data // that are used internally follow after them. // // // Author: Steffen Meschkat // The entry point for the parser. // // @param expr a string that contains an XPath expression. // @return an expression object that can be evaluated with an // expression context. function xpathParse(expr) { xpathLog('parse ' + expr); xpathParseInit(); var cached =3D xpathCacheLookup(expr); if (cached) { xpathLog(' ... cached'); return cached; } // Optimize for a few common cases: simple attribute node tests // (@id), simple element node tests (page), variable references // ($address), numbers (4), multi-step path expressions where each // step is a plain element node test // (page/overlay/locations/location). if (expr.match(/^(\$|@)?\w+$/i)) { var ret =3D makeSimpleExpr(expr); xpathParseCache[expr] =3D ret; xpathLog(' ... simple'); return ret; } if (expr.match(/^\w+(\/\w+)*$/i)) { var ret =3D makeSimpleExpr2(expr); xpathParseCache[expr] =3D ret; xpathLog(' ... simple 2'); return ret; } var cachekey =3D expr; // expr is modified during parse var stack =3D []; var ahead =3D null; var previous =3D null; var done =3D false; var parse_count =3D 0; var lexer_count =3D 0; var reduce_count =3D 0; while (!done) { parse_count++; expr =3D expr.replace(/^\s*/, ''); previous =3D ahead; ahead =3D null; var rule =3D null; var match =3D ''; for (var i =3D 0; i < xpathTokenRules.length; ++i) { var result =3D xpathTokenRules[i].re.exec(expr); lexer_count++; if (result && result.length > 0 && result[0].length > = match.length) { rule =3D xpathTokenRules[i]; match =3D result[0]; break; } } // Special case: allow operator keywords to be element and // variable names. // NOTE(mesch): The parser resolves conflicts by looking ahead, // and this is the only case where we look back to // disambiguate. So this is indeed something different, and // looking back is usually done in the lexer (via states in the // general case, called "start conditions" in flex(1)). Also,the // conflict resolution in the parser is not as robust as it could // be, so I'd like to keep as much off the parser as possible (all // these precedence values should be computed from the grammar // rules and possibly associativity declarations, as in bison(1), // and not explicitly set. if (rule && (rule =3D=3D TOK_DIV || rule =3D=3D TOK_MOD || rule =3D=3D TOK_AND || rule =3D=3D TOK_OR) && (!previous || previous.tag =3D=3D TOK_AT || previous.tag =3D=3D TOK_DSLASH || previous.tag =3D=3D TOK_SLASH || previous.tag =3D=3D TOK_AXIS || previous.tag =3D=3D TOK_DOLLAR)) { rule =3D TOK_QNAME; } if (rule) { expr =3D expr.substr(match.length); xpathLog('token: ' + match + ' -- ' + rule.label); ahead =3D { tag: rule, match: match, prec: rule.prec ? rule.prec : 0, // || 0 is removed by the = compiler expr: makeTokenExpr(match) }; } else { xpathLog('DONE'); done =3D true; } while (xpathReduce(stack, ahead)) { reduce_count++; xpathLog('stack: ' + stackToString(stack)); } } xpathLog('stack: ' + stackToString(stack)); if (stack.length !=3D 1) { throw 'XPath parse error ' + cachekey + ':\n' + = stackToString(stack); } var result =3D stack[0].expr; xpathParseCache[cachekey] =3D result; xpathLog('XPath parse: ' + parse_count + ' / ' + lexer_count + ' / ' + reduce_count); return result; } var xpathParseCache =3D {}; function xpathCacheLookup(expr) { return xpathParseCache[expr]; } function xpathReduce(stack, ahead) { var cand =3D null; if (stack.length > 0) { var top =3D stack[stack.length-1]; var ruleset =3D xpathRules[top.tag.key]; if (ruleset) { for (var i =3D 0; i < ruleset.length; ++i) { var rule =3D ruleset[i]; var match =3D xpathMatchStack(stack, rule[1]); if (match.length) { cand =3D { tag: rule[0], rule: rule, match: match }; cand.prec =3D xpathGrammarPrecedence(cand); break; } } } } var ret; if (cand && (!ahead || cand.prec > ahead.prec || (ahead.tag.left && cand.prec >=3D ahead.prec))) { for (var i =3D 0; i < cand.match.matchlength; ++i) { stack.pop(); } xpathLog('reduce ' + cand.tag.label + ' ' + cand.prec + ' ahead ' + (ahead ? ahead.tag.label + ' ' + ahead.prec + (ahead.tag.left ? ' left' : '') : ' none ')); var matchexpr =3D mapExpr(cand.match, function(m) { return m.expr; = }); cand.expr =3D cand.rule[3].apply(null, matchexpr); stack.push(cand); ret =3D true; } else { if (ahead) { xpathLog('shift ' + ahead.tag.label + ' ' + ahead.prec + (ahead.tag.left ? ' left' : '') + ' over ' + (cand ? cand.tag.label + ' ' + cand.prec : ' none')); stack.push(ahead); } ret =3D false; } return ret; } function xpathMatchStack(stack, pattern) { // NOTE(mesch): The stack matches for variable cardinality are // greedy but don't do backtracking. This would be an issue only // with rules of the form A* A, i.e. with an element with variable // cardinality followed by the same element. Since that doesn't // occur in the grammar at hand, all matches on the stack are // unambiguous. var S =3D stack.length; var P =3D pattern.length; var p, s; var match =3D []; match.matchlength =3D 0; var ds =3D 0; for (p =3D P - 1, s =3D S - 1; p >=3D 0 && s >=3D 0; --p, s -=3D ds) { ds =3D 0; var qmatch =3D []; if (pattern[p] =3D=3D Q_MM) { p -=3D 1; match.push(qmatch); while (s - ds >=3D 0 && stack[s - ds].tag =3D=3D pattern[p]) { qmatch.push(stack[s - ds]); ds +=3D 1; match.matchlength +=3D 1; } } else if (pattern[p] =3D=3D Q_01) { p -=3D 1; match.push(qmatch); while (s - ds >=3D 0 && ds < 2 && stack[s - ds].tag =3D=3D = pattern[p]) { qmatch.push(stack[s - ds]); ds +=3D 1; match.matchlength +=3D 1; } } else if (pattern[p] =3D=3D Q_1M) { p -=3D 1; match.push(qmatch); if (stack[s].tag =3D=3D pattern[p]) { while (s - ds >=3D 0 && stack[s - ds].tag =3D=3D pattern[p]) { qmatch.push(stack[s - ds]); ds +=3D 1; match.matchlength +=3D 1; } } else { return []; } } else if (stack[s].tag =3D=3D pattern[p]) { match.push(stack[s]); ds +=3D 1; match.matchlength +=3D 1; } else { return []; } reverseInplace(qmatch); qmatch.expr =3D mapExpr(qmatch, function(m) { return m.expr; }); } reverseInplace(match); if (p =3D=3D -1) { return match; } else { return []; } } function xpathTokenPrecedence(tag) { return tag.prec || 2; } function xpathGrammarPrecedence(frame) { var ret =3D 0; if (frame.rule) { /* normal reduce */ if (frame.rule.length >=3D 3 && frame.rule[2] >=3D 0) { ret =3D frame.rule[2]; } else { for (var i =3D 0; i < frame.rule[1].length; ++i) { var p =3D xpathTokenPrecedence(frame.rule[1][i]); ret =3D Math.max(ret, p); } } } else if (frame.tag) { /* TOKEN match */ ret =3D xpathTokenPrecedence(frame.tag); } else if (frame.length) { /* Q_ match */ for (var j =3D 0; j < frame.length; ++j) { var p =3D xpathGrammarPrecedence(frame[j]); ret =3D Math.max(ret, p); } } return ret; } function stackToString(stack) { var ret =3D ''; for (var i =3D 0; i < stack.length; ++i) { if (ret) { ret +=3D '\n'; } ret +=3D stack[i].tag.label; } return ret; } // XPath expression evaluation context. An XPath context consists of a // DOM node, a list of DOM nodes that contains this node, a number // that represents the position of the single node in the list, and a // current set of variable bindings. (See XPath spec.) // // The interface of the expression context: // // Constructor -- gets the node, its position, the node set it // belongs to, and a parent context as arguments. The parent context // is used to implement scoping rules for variables: if a variable // is not found in the current context, it is looked for in the // parent context, recursively. Except for node, all arguments have // default values: default position is 0, default node set is the // set that contains only the node, and the default parent is null. // // Notice that position starts at 0 at the outside interface; // inside XPath expressions this shows up as position()=3D1. // // clone() -- creates a new context with the current context as // parent. If passed as argument to clone(), the new context has a // different node, position, or node set. What is not passed is // inherited from the cloned context. // // setVariable(name, expr) -- binds given XPath expression to the // name. // // getVariable(name) -- what the name says. // // setNode(position) -- sets the context to the node at the given // position. Needed to implement scoping rules for variables in // XPath. (A variable is visible to all subsequent siblings, not // only to its children.) function ExprContext(node, opt_position, opt_nodelist, opt_parent) { this.node =3D node; this.position =3D opt_position || 0; this.nodelist =3D opt_nodelist || [ node ]; this.variables =3D {}; this.parent =3D opt_parent || null; if (opt_parent) { this.root =3D opt_parent.root; } else if (this.node.nodeType =3D=3D DOM_DOCUMENT_NODE) { // NOTE(mesch): DOM Spec stipulates that the ownerDocument of a // document is null. Our root, however is the document that we are // processing, so the initial context is created from its document // node, which case we must handle here explcitly. this.root =3D node; } else { this.root =3D node.ownerDocument; } } ExprContext.prototype.clone =3D function(opt_node, opt_position, = opt_nodelist) { return new ExprContext( opt_node || this.node, typeof opt_position !=3D 'undefined' ? opt_position : = this.position, opt_nodelist || this.nodelist, this); }; ExprContext.prototype.setVariable =3D function(name, value) { this.variables[name] =3D value; }; ExprContext.prototype.getVariable =3D function(name) { if (typeof this.variables[name] !=3D 'undefined') { return this.variables[name]; } else if (this.parent) { return this.parent.getVariable(name); } else { return null; } }; ExprContext.prototype.setNode =3D function(position) { this.node =3D this.nodelist[position]; this.position =3D position; }; ExprContext.prototype.contextSize =3D function() { return this.nodelist.length; }; // XPath expression values. They are what XPath expressions evaluate // to. Strangely, the different value types are not specified in the // XPath syntax, but only in the semantics, so they don't show up as // nonterminals in the grammar. Yet, some expressions are required to // evaluate to particular types, and not every type can be coerced // into every other type. Although the types of XPath values are // similar to the types present in JavaScript, the type coercion rules // are a bit peculiar, so we explicitly model XPath types instead of // mapping them onto JavaScript types. (See XPath spec.) // // The four types are: // // StringValue // // NumberValue // // BooleanValue // // NodeSetValue // // The common interface of the value classes consists of methods that // implement the XPath type coercion rules: // // stringValue() -- returns the value as a JavaScript String, // // numberValue() -- returns the value as a JavaScript Number, // // booleanValue() -- returns the value as a JavaScript Boolean, // // nodeSetValue() -- returns the value as a JavaScript Array of DOM // Node objects. // function StringValue(value) { this.value =3D value; this.type =3D 'string'; } StringValue.prototype.stringValue =3D function() { return this.value; }; StringValue.prototype.booleanValue =3D function() { return this.value.length > 0; }; StringValue.prototype.numberValue =3D function() { return this.value - 0; }; StringValue.prototype.nodeSetValue =3D function() { throw this; }; function BooleanValue(value) { this.value =3D value; this.type =3D 'boolean'; } BooleanValue.prototype.stringValue =3D function() { return '' + this.value; }; BooleanValue.prototype.booleanValue =3D function() { return this.value; }; BooleanValue.prototype.numberValue =3D function() { return this.value ? 1 : 0; }; BooleanValue.prototype.nodeSetValue =3D function() { throw this; }; function NumberValue(value) { this.value =3D value; this.type =3D 'number'; } NumberValue.prototype.stringValue =3D function() { return '' + this.value; }; NumberValue.prototype.booleanValue =3D function() { return !!this.value; }; NumberValue.prototype.numberValue =3D function() { return this.value - 0; }; NumberValue.prototype.nodeSetValue =3D function() { throw this; }; function NodeSetValue(value) { this.value =3D value; this.type =3D 'node-set'; } NodeSetValue.prototype.stringValue =3D function() { if (this.value.length =3D=3D 0) { return ''; } else { return xmlValue(this.value[0]); } }; NodeSetValue.prototype.booleanValue =3D function() { return this.value.length > 0; }; NodeSetValue.prototype.numberValue =3D function() { return this.stringValue() - 0; }; NodeSetValue.prototype.nodeSetValue =3D function() { return this.value; }; // XPath expressions. They are used as nodes in the parse tree and // possess an evaluate() method to compute an XPath value given an XPath // context. Expressions are returned from the parser. Teh set of // expression classes closely mirrors the set of non terminal symbols // in the grammar. Every non trivial nonterminal symbol has a // corresponding expression class. // // The common expression interface consists of the following methods: // // evaluate(context) -- evaluates the expression, returns a value. // // toString() -- returns the XPath text representation of the // expression (defined in xsltdebug.js). // // parseTree(indent) -- returns a parse tree representation of the // expression (defined in xsltdebug.js). function TokenExpr(m) { this.value =3D m; } TokenExpr.prototype.evaluate =3D function() { return new StringValue(this.value); }; function LocationExpr() { this.absolute =3D false; this.steps =3D []; } LocationExpr.prototype.appendStep =3D function(s) { this.steps.push(s); }; LocationExpr.prototype.prependStep =3D function(s) { var steps0 =3D this.steps; this.steps =3D [ s ]; for (var i =3D 0; i < steps0.length; ++i) { this.steps.push(steps0[i]); } }; LocationExpr.prototype.evaluate =3D function(ctx) { var start; if (this.absolute) { start =3D ctx.root; } else { start =3D ctx.node; } var nodes =3D []; xPathStep(nodes, this.steps, 0, start, ctx); return new NodeSetValue(nodes); }; function xPathStep(nodes, steps, step, input, ctx) { var s =3D steps[step]; var ctx2 =3D ctx.clone(input); var nodelist =3D s.evaluate(ctx2).nodeSetValue(); for (var i =3D 0; i < nodelist.length; ++i) { if (step =3D=3D steps.length - 1) { nodes.push(nodelist[i]); } else { xPathStep(nodes, steps, step + 1, nodelist[i], ctx); } } } function StepExpr(axis, nodetest, opt_predicate) { this.axis =3D axis; this.nodetest =3D nodetest; this.predicate =3D opt_predicate || []; } StepExpr.prototype.appendPredicate =3D function(p) { this.predicate.push(p); }; StepExpr.prototype.evaluate =3D function(ctx) { var input =3D ctx.node; var nodelist =3D []; // NOTE(mesch): When this was a switch() statement, it didn't work // in Safari/2.0. Not sure why though; it resulted in the JavaScript // console output "undefined" (without any line number or so). if (this.axis =3D=3D xpathAxis.ANCESTOR_OR_SELF) { nodelist.push(input); for (var n =3D input.parentNode; n; n =3D n.parentNode) { nodelist.push(n); } } else if (this.axis =3D=3D xpathAxis.ANCESTOR) { for (var n =3D input.parentNode; n; n =3D n.parentNode) { nodelist.push(n); } } else if (this.axis =3D=3D xpathAxis.ATTRIBUTE) { copyArray(nodelist, input.attributes); } else if (this.axis =3D=3D xpathAxis.CHILD) { copyArray(nodelist, input.childNodes); } else if (this.axis =3D=3D xpathAxis.DESCENDANT_OR_SELF) { nodelist.push(input); xpathCollectDescendants(nodelist, input); } else if (this.axis =3D=3D xpathAxis.DESCENDANT) { xpathCollectDescendants(nodelist, input); } else if (this.axis =3D=3D xpathAxis.FOLLOWING) { for (var n =3D input; n; n =3D n.parentNode) { for (var nn =3D n.nextSibling; nn; nn =3D nn.nextSibling) { nodelist.push(nn); xpathCollectDescendants(nodelist, nn); } } } else if (this.axis =3D=3D xpathAxis.FOLLOWING_SIBLING) { for (var n =3D input.nextSibling; n; n =3D n.nextSibling) { nodelist.push(n); } } else if (this.axis =3D=3D xpathAxis.NAMESPACE) { alert('not implemented: axis namespace'); } else if (this.axis =3D=3D xpathAxis.PARENT) { if (input.parentNode) { nodelist.push(input.parentNode); } } else if (this.axis =3D=3D xpathAxis.PRECEDING) { for (var n =3D input; n; n =3D n.parentNode) { for (var nn =3D n.previousSibling; nn; nn =3D nn.previousSibling) = { nodelist.push(nn); xpathCollectDescendantsReverse(nodelist, nn); } } } else if (this.axis =3D=3D xpathAxis.PRECEDING_SIBLING) { for (var n =3D input.previousSibling; n; n =3D n.previousSibling) { nodelist.push(n); } } else if (this.axis =3D=3D xpathAxis.SELF) { nodelist.push(input); } else { throw 'ERROR -- NO SUCH AXIS: ' + this.axis; } // process node test var nodelist0 =3D nodelist; nodelist =3D []; for (var i =3D 0; i < nodelist0.length; ++i) { var n =3D nodelist0[i]; if (this.nodetest.evaluate(ctx.clone(n, i, = nodelist0)).booleanValue()) { nodelist.push(n); } } // process predicates for (var i =3D 0; i < this.predicate.length; ++i) { var nodelist0 =3D nodelist; nodelist =3D []; for (var ii =3D 0; ii < nodelist0.length; ++ii) { var n =3D nodelist0[ii]; if (this.predicate[i].evaluate(ctx.clone(n, ii, = nodelist0)).booleanValue()) { nodelist.push(n); } } } return new NodeSetValue(nodelist); }; function NodeTestAny() { this.value =3D new BooleanValue(true); } NodeTestAny.prototype.evaluate =3D function(ctx) { return this.value; }; function NodeTestElementOrAttribute() {} NodeTestElementOrAttribute.prototype.evaluate =3D function(ctx) { return new BooleanValue( ctx.node.nodeType =3D=3D DOM_ELEMENT_NODE || ctx.node.nodeType =3D=3D DOM_ATTRIBUTE_NODE); }; function NodeTestText() {} NodeTestText.prototype.evaluate =3D function(ctx) { return new BooleanValue(ctx.node.nodeType =3D=3D DOM_TEXT_NODE); }; function NodeTestComment() {} NodeTestComment.prototype.evaluate =3D function(ctx) { return new BooleanValue(ctx.node.nodeType =3D=3D DOM_COMMENT_NODE); }; function NodeTestPI(target) { this.target =3D target; } NodeTestPI.prototype.evaluate =3D function(ctx) { return new BooleanValue(ctx.node.nodeType =3D=3D DOM_PROCESSING_INSTRUCTION_NODE = && (!this.target || ctx.node.nodeName =3D=3D this.target)); }; function NodeTestNC(nsprefix) { this.regex =3D new RegExp("^" + nsprefix + ":"); this.nsprefix =3D nsprefix; } NodeTestNC.prototype.evaluate =3D function(ctx) { var n =3D ctx.node; return new BooleanValue(this.regex.match(n.nodeName)); }; function NodeTestName(name) { this.name =3D name; } NodeTestName.prototype.evaluate =3D function(ctx) { var n =3D ctx.node; return new BooleanValue(n.nodeName =3D=3D this.name); }; function PredicateExpr(expr) { this.expr =3D expr; } PredicateExpr.prototype.evaluate =3D function(ctx) { var v =3D this.expr.evaluate(ctx); if (v.type =3D=3D 'number') { // NOTE(mesch): Internally, position is represented starting with // 0, however in XPath position starts with 1. See functions // position() and last(). return new BooleanValue(ctx.position =3D=3D v.numberValue() - 1); } else { return new BooleanValue(v.booleanValue()); } }; function FunctionCallExpr(name) { this.name =3D name; this.args =3D []; } FunctionCallExpr.prototype.appendArg =3D function(arg) { this.args.push(arg); }; FunctionCallExpr.prototype.evaluate =3D function(ctx) { var fn =3D '' + this.name.value; var f =3D this.xpathfunctions[fn]; if (f) { return f.call(this, ctx); } else { xpathLog('XPath NO SUCH FUNCTION ' + fn); return new BooleanValue(false); } }; FunctionCallExpr.prototype.xpathfunctions =3D { 'last': function(ctx) { assert(this.args.length =3D=3D 0); // NOTE(mesch): XPath position starts at 1. return new NumberValue(ctx.contextSize()); }, 'position': function(ctx) { assert(this.args.length =3D=3D 0); // NOTE(mesch): XPath position starts at 1. return new NumberValue(ctx.position + 1); }, 'count': function(ctx) { assert(this.args.length =3D=3D 1); var v =3D this.args[0].evaluate(ctx); return new NumberValue(v.nodeSetValue().length); }, 'id': function(ctx) { assert(this.args.length =3D=3D 1); var e =3D this.args[0].evaluate(ctx); var ret =3D []; var ids; if (e.type =3D=3D 'node-set') { ids =3D []; var en =3D e.nodeSetValue(); for (var i =3D 0; i < en.length; ++i) { var v =3D xmlValue(en[i]).split(/\s+/); for (var ii =3D 0; ii < v.length; ++ii) { ids.push(v[ii]); } } } else { ids =3D e.stringValue().split(/\s+/); } var d =3D ctx.node.ownerDocument; for (var i =3D 0; i < ids.length; ++i) { var n =3D d.getElementById(ids[i]); if (n) { ret.push(n); } } return new NodeSetValue(ret); }, 'local-name': function(ctx) { alert('not implmented yet: XPath function local-name()'); }, 'namespace-uri': function(ctx) { alert('not implmented yet: XPath function namespace-uri()'); }, 'name': function(ctx) { assert(this.args.length =3D=3D 1 || this.args.length =3D=3D 0); var n; if (this.args.length =3D=3D 0) { n =3D [ ctx.node ]; } else { n =3D this.args[0].evaluate(ctx).nodeSetValue(); } if (n.length =3D=3D 0) { return new StringValue(''); } else { return new StringValue(n[0].nodeName); } }, 'string': function(ctx) { assert(this.args.length =3D=3D 1 || this.args.length =3D=3D 0); if (this.args.length =3D=3D 0) { return new StringValue(new NodeSetValue([ ctx.node = ]).stringValue()); } else { return new StringValue(this.args[0].evaluate(ctx).stringValue()); } }, 'concat': function(ctx) { var ret =3D ''; for (var i =3D 0; i < this.args.length; ++i) { ret +=3D this.args[i].evaluate(ctx).stringValue(); } return new StringValue(ret); }, 'starts-with': function(ctx) { assert(this.args.length =3D=3D 2); var s0 =3D this.args[0].evaluate(ctx).stringValue(); var s1 =3D this.args[1].evaluate(ctx).stringValue(); return new BooleanValue(s0.indexOf(s1) =3D=3D 0); }, 'contains': function(ctx) { assert(this.args.length =3D=3D 2); var s0 =3D this.args[0].evaluate(ctx).stringValue(); var s1 =3D this.args[1].evaluate(ctx).stringValue(); return new BooleanValue(s0.indexOf(s1) !=3D -1); }, 'substring-before': function(ctx) { assert(this.args.length =3D=3D 2); var s0 =3D this.args[0].evaluate(ctx).stringValue(); var s1 =3D this.args[1].evaluate(ctx).stringValue(); var i =3D s0.indexOf(s1); var ret; if (i =3D=3D -1) { ret =3D ''; } else { ret =3D s0.substr(0,i); } return new StringValue(ret); }, 'substring-after': function(ctx) { assert(this.args.length =3D=3D 2); var s0 =3D this.args[0].evaluate(ctx).stringValue(); var s1 =3D this.args[1].evaluate(ctx).stringValue(); var i =3D s0.indexOf(s1); var ret; if (i =3D=3D -1) { ret =3D ''; } else { ret =3D s0.substr(i + s1.length); } return new StringValue(ret); }, 'substring': function(ctx) { // NOTE: XPath defines the position of the first character in a // string to be 1, in JavaScript this is 0 ([XPATH] Section 4.2). assert(this.args.length =3D=3D 2 || this.args.length =3D=3D 3); var s0 =3D this.args[0].evaluate(ctx).stringValue(); var s1 =3D this.args[1].evaluate(ctx).numberValue(); var ret; if (this.args.length =3D=3D 2) { var i1 =3D Math.max(0, Math.round(s1) - 1); ret =3D s0.substr(i1); } else { var s2 =3D this.args[2].evaluate(ctx).numberValue(); var i0 =3D Math.round(s1) - 1; var i1 =3D Math.max(0, i0); var i2 =3D Math.round(s2) - Math.max(0, -i0); ret =3D s0.substr(i1, i2); } return new StringValue(ret); }, 'string-length': function(ctx) { var s; if (this.args.length > 0) { s =3D this.args[0].evaluate(ctx).stringValue(); } else { s =3D new NodeSetValue([ ctx.node ]).stringValue(); } return new NumberValue(s.length); }, 'normalize-space': function(ctx) { var s; if (this.args.length > 0) { s =3D this.args[0].evaluate(ctx).stringValue(); } else { s =3D new NodeSetValue([ ctx.node ]).stringValue(); } s =3D s.replace(/^\s*/,'').replace(/\s*$/,'').replace(/\s+/g, ' '); return new StringValue(s); }, 'translate': function(ctx) { assert(this.args.length =3D=3D 3); var s0 =3D this.args[0].evaluate(ctx).stringValue(); var s1 =3D this.args[1].evaluate(ctx).stringValue(); var s2 =3D this.args[2].evaluate(ctx).stringValue(); for (var i =3D 0; i < s1.length; ++i) { s0 =3D s0.replace(new RegExp(s1.charAt(i), 'g'), s2.charAt(i)); } return new StringValue(s0); }, 'boolean': function(ctx) { assert(this.args.length =3D=3D 1); return new BooleanValue(this.args[0].evaluate(ctx).booleanValue()); }, 'not': function(ctx) { assert(this.args.length =3D=3D 1); var ret =3D !this.args[0].evaluate(ctx).booleanValue(); return new BooleanValue(ret); }, 'true': function(ctx) { assert(this.args.length =3D=3D 0); return new BooleanValue(true); }, 'false': function(ctx) { assert(this.args.length =3D=3D 0); return new BooleanValue(false); }, 'lang': function(ctx) { assert(this.args.length =3D=3D 1); var lang =3D this.args[0].evaluate(ctx).stringValue(); var xmllang; var n =3D ctx.node; while (n && n !=3D n.parentNode /* just in case ... */) { xmllang =3D n.getAttribute('xml:lang'); if (xmllang) { break; } n =3D n.parentNode; } if (!xmllang) { return new BooleanValue(false); } else { var re =3D new RegExp('^' + lang + '$', 'i'); return new BooleanValue(xmllang.match(re) || xmllang.replace(/_.*$/,'').match(re)); } }, 'number': function(ctx) { assert(this.args.length =3D=3D 1 || this.args.length =3D=3D 0); if (this.args.length =3D=3D 1) { return new NumberValue(this.args[0].evaluate(ctx).numberValue()); } else { return new NumberValue(new NodeSetValue([ ctx.node = ]).numberValue()); } }, 'sum': function(ctx) { assert(this.args.length =3D=3D 1); var n =3D this.args[0].evaluate(ctx).nodeSetValue(); var sum =3D 0; for (var i =3D 0; i < n.length; ++i) { sum +=3D xmlValue(n[i]) - 0; } return new NumberValue(sum); }, 'floor': function(ctx) { assert(this.args.length =3D=3D 1); var num =3D this.args[0].evaluate(ctx).numberValue(); return new NumberValue(Math.floor(num)); }, 'ceiling': function(ctx) { assert(this.args.length =3D=3D 1); var num =3D this.args[0].evaluate(ctx).numberValue(); return new NumberValue(Math.ceil(num)); }, 'round': function(ctx) { assert(this.args.length =3D=3D 1); var num =3D this.args[0].evaluate(ctx).numberValue(); return new NumberValue(Math.round(num)); }, // TODO(mesch): The following functions are custom. There is a // standard that defines how to add functions, which should be // applied here. 'ext-join': function(ctx) { assert(this.args.length =3D=3D 2); var nodes =3D this.args[0].evaluate(ctx).nodeSetValue(); var delim =3D this.args[1].evaluate(ctx).stringValue(); var ret =3D ''; for (var i =3D 0; i < nodes.length; ++i) { if (ret) { ret +=3D delim; } ret +=3D xmlValue(nodes[i]); } return new StringValue(ret); }, // ext-if() evaluates and returns its second argument, if the // boolean value of its first argument is true, otherwise it // evaluates and returns its third argument. 'ext-if': function(ctx) { assert(this.args.length =3D=3D 3); if (this.args[0].evaluate(ctx).booleanValue()) { return this.args[1].evaluate(ctx); } else { return this.args[2].evaluate(ctx); } }, // ext-cardinal() evaluates its single argument as a number, and // returns the current node that many times. It can be used in the // select attribute to iterate over an integer range. 'ext-cardinal': function(ctx) { assert(this.args.length >=3D 1); var c =3D this.args[0].evaluate(ctx).numberValue(); var ret =3D []; for (var i =3D 0; i < c; ++i) { ret.push(ctx.node); } return new NodeSetValue(ret); } }; function UnionExpr(expr1, expr2) { this.expr1 =3D expr1; this.expr2 =3D expr2; } UnionExpr.prototype.evaluate =3D function(ctx) { var nodes1 =3D this.expr1.evaluate(ctx).nodeSetValue(); var nodes2 =3D this.expr2.evaluate(ctx).nodeSetValue(); var I1 =3D nodes1.length; for (var i2 =3D 0; i2 < nodes2.length; ++i2) { var n =3D nodes2[i2]; var inBoth =3D false; for (var i1 =3D 0; i1 < I1; ++i1) { if (nodes1[i1] =3D=3D n) { inBoth =3D true; i1 =3D I1; // break inner loop } } if (!inBoth) { nodes1.push(n); } } return new NodeSetValue(nodes1); }; function PathExpr(filter, rel) { this.filter =3D filter; this.rel =3D rel; } PathExpr.prototype.evaluate =3D function(ctx) { var nodes =3D this.filter.evaluate(ctx).nodeSetValue(); var nodes1 =3D []; for (var i =3D 0; i < nodes.length; ++i) { var nodes0 =3D this.rel.evaluate(ctx.clone(nodes[i], i, = nodes)).nodeSetValue(); for (var ii =3D 0; ii < nodes0.length; ++ii) { nodes1.push(nodes0[ii]); } } return new NodeSetValue(nodes1); }; function FilterExpr(expr, predicate) { this.expr =3D expr; this.predicate =3D predicate; } FilterExpr.prototype.evaluate =3D function(ctx) { var nodes =3D this.expr.evaluate(ctx).nodeSetValue(); for (var i =3D 0; i < this.predicate.length; ++i) { var nodes0 =3D nodes; nodes =3D []; for (var j =3D 0; j < nodes0.length; ++j) { var n =3D nodes0[j]; if (this.predicate[i].evaluate(ctx.clone(n, j, = nodes0)).booleanValue()) { nodes.push(n); } } } return new NodeSetValue(nodes); }; function UnaryMinusExpr(expr) { this.expr =3D expr; } UnaryMinusExpr.prototype.evaluate =3D function(ctx) { return new NumberValue(-this.expr.evaluate(ctx).numberValue()); }; function BinaryExpr(expr1, op, expr2) { this.expr1 =3D expr1; this.expr2 =3D expr2; this.op =3D op; } BinaryExpr.prototype.evaluate =3D function(ctx) { var ret; switch (this.op.value) { case 'or': ret =3D new BooleanValue(this.expr1.evaluate(ctx).booleanValue() = || this.expr2.evaluate(ctx).booleanValue()); break; case 'and': ret =3D new BooleanValue(this.expr1.evaluate(ctx).booleanValue() = && this.expr2.evaluate(ctx).booleanValue()); break; case '+': ret =3D new NumberValue(this.expr1.evaluate(ctx).numberValue() + this.expr2.evaluate(ctx).numberValue()); break; case '-': ret =3D new NumberValue(this.expr1.evaluate(ctx).numberValue() - this.expr2.evaluate(ctx).numberValue()); break; case '*': ret =3D new NumberValue(this.expr1.evaluate(ctx).numberValue() * this.expr2.evaluate(ctx).numberValue()); break; case 'mod': ret =3D new NumberValue(this.expr1.evaluate(ctx).numberValue() % this.expr2.evaluate(ctx).numberValue()); break; case 'div': ret =3D new NumberValue(this.expr1.evaluate(ctx).numberValue() / this.expr2.evaluate(ctx).numberValue()); break; case '=3D': ret =3D this.compare(ctx, function(x1, x2) { return x1 =3D=3D x2; = }); break; case '!=3D': ret =3D this.compare(ctx, function(x1, x2) { return x1 !=3D x2; = }); break; case '<': ret =3D this.compare(ctx, function(x1, x2) { return x1 < x2; }); break; case '<=3D': ret =3D this.compare(ctx, function(x1, x2) { return x1 <=3D x2; = }); break; case '>': ret =3D this.compare(ctx, function(x1, x2) { return x1 > x2; }); break; case '>=3D': ret =3D this.compare(ctx, function(x1, x2) { return x1 >=3D x2; = }); break; default: alert('BinaryExpr.evaluate: ' + this.op.value); } return ret; }; BinaryExpr.prototype.compare =3D function(ctx, cmp) { var v1 =3D this.expr1.evaluate(ctx); var v2 =3D this.expr2.evaluate(ctx); var ret; if (v1.type =3D=3D 'node-set' && v2.type =3D=3D 'node-set') { var n1 =3D v1.nodeSetValue(); var n2 =3D v2.nodeSetValue(); ret =3D false; for (var i1 =3D 0; i1 < n1.length; ++i1) { for (var i2 =3D 0; i2 < n2.length; ++i2) { if (cmp(xmlValue(n1[i1]), xmlValue(n2[i2]))) { ret =3D true; // Break outer loop. Labels confuse the jscompiler and we // don't use them. i2 =3D n2.length; i1 =3D n1.length; } } } } else if (v1.type =3D=3D 'node-set' || v2.type =3D=3D 'node-set') { if (v1.type =3D=3D 'number') { var s =3D v1.numberValue(); var n =3D v2.nodeSetValue(); ret =3D false; for (var i =3D 0; i < n.length; ++i) { var nn =3D xmlValue(n[i]) - 0; if (cmp(s, nn)) { ret =3D true; break; } } } else if (v2.type =3D=3D 'number') { var n =3D v1.nodeSetValue(); var s =3D v2.numberValue(); ret =3D false; for (var i =3D 0; i < n.length; ++i) { var nn =3D xmlValue(n[i]) - 0; if (cmp(nn, s)) { ret =3D true; break; } } } else if (v1.type =3D=3D 'string') { var s =3D v1.stringValue(); var n =3D v2.nodeSetValue(); ret =3D false; for (var i =3D 0; i < n.length; ++i) { var nn =3D xmlValue(n[i]); if (cmp(s, nn)) { ret =3D true; break; } } } else if (v2.type =3D=3D 'string') { var n =3D v1.nodeSetValue(); var s =3D v2.stringValue(); ret =3D false; for (var i =3D 0; i < n.length; ++i) { var nn =3D xmlValue(n[i]); if (cmp(nn, s)) { ret =3D true; break; } } } else { ret =3D cmp(v1.booleanValue(), v2.booleanValue()); } } else if (v1.type =3D=3D 'boolean' || v2.type =3D=3D 'boolean') { ret =3D cmp(v1.booleanValue(), v2.booleanValue()); } else if (v1.type =3D=3D 'number' || v2.type =3D=3D 'number') { ret =3D cmp(v1.numberValue(), v2.numberValue()); } else { ret =3D cmp(v1.stringValue(), v2.stringValue()); } return new BooleanValue(ret); }; function LiteralExpr(value) { this.value =3D value; } LiteralExpr.prototype.evaluate =3D function(ctx) { return new StringValue(this.value); }; function NumberExpr(value) { this.value =3D value; } NumberExpr.prototype.evaluate =3D function(ctx) { return new NumberValue(this.value); }; function VariableExpr(name) { this.name =3D name; } VariableExpr.prototype.evaluate =3D function(ctx) { return ctx.getVariable(this.name); }; // Factory functions for semantic values (i.e. Expressions) of the // productions in the grammar. When a production is matched to reduce // the current parse state stack, the function is called with the // semantic values of the matched elements as arguments, and returns // another semantic value. The semantic value is a node of the parse // tree, an expression object with an evaluate() method that evaluates = the // expression in an actual context. These factory functions are used // in the specification of the grammar rules, below. function makeTokenExpr(m) { return new TokenExpr(m); } function passExpr(e) { return e; } function makeLocationExpr1(slash, rel) { rel.absolute =3D true; return rel; } function makeLocationExpr2(dslash, rel) { rel.absolute =3D true; rel.prependStep(makeAbbrevStep(dslash.value)); return rel; } function makeLocationExpr3(slash) { var ret =3D new LocationExpr(); ret.appendStep(makeAbbrevStep('.')); ret.absolute =3D true; return ret; } function makeLocationExpr4(dslash) { var ret =3D new LocationExpr(); ret.absolute =3D true; ret.appendStep(makeAbbrevStep(dslash.value)); return ret; } function makeLocationExpr5(step) { var ret =3D new LocationExpr(); ret.appendStep(step); return ret; } function makeLocationExpr6(rel, slash, step) { rel.appendStep(step); return rel; } function makeLocationExpr7(rel, dslash, step) { rel.appendStep(makeAbbrevStep(dslash.value)); return rel; } function makeStepExpr1(dot) { return makeAbbrevStep(dot.value); } function makeStepExpr2(ddot) { return makeAbbrevStep(ddot.value); } function makeStepExpr3(axisname, axis, nodetest) { return new StepExpr(axisname.value, nodetest); } function makeStepExpr4(at, nodetest) { return new StepExpr('attribute', nodetest); } function makeStepExpr5(nodetest) { return new StepExpr('child', nodetest); } function makeStepExpr6(step, predicate) { step.appendPredicate(predicate); return step; } function makeAbbrevStep(abbrev) { switch (abbrev) { case '//': return new StepExpr('descendant-or-self', new NodeTestAny); case '.': return new StepExpr('self', new NodeTestAny); case '..': return new StepExpr('parent', new NodeTestAny); } } function makeNodeTestExpr1(asterisk) { return new NodeTestElementOrAttribute; } function makeNodeTestExpr2(ncname, colon, asterisk) { return new NodeTestNC(ncname.value); } function makeNodeTestExpr3(qname) { return new NodeTestName(qname.value); } function makeNodeTestExpr4(typeo, parenc) { var type =3D typeo.value.replace(/\s*\($/, ''); switch(type) { case 'node': return new NodeTestAny; case 'text': return new NodeTestText; case 'comment': return new NodeTestComment; case 'processing-instruction': return new NodeTestPI(''); } } function makeNodeTestExpr5(typeo, target, parenc) { var type =3D typeo.replace(/\s*\($/, ''); if (type !=3D 'processing-instruction') { throw type; } return new NodeTestPI(target.value); } function makePredicateExpr(pareno, expr, parenc) { return new PredicateExpr(expr); } function makePrimaryExpr(pareno, expr, parenc) { return expr; } function makeFunctionCallExpr1(name, pareno, parenc) { return new FunctionCallExpr(name); } function makeFunctionCallExpr2(name, pareno, arg1, args, parenc) { var ret =3D new FunctionCallExpr(name); ret.appendArg(arg1); for (var i =3D 0; i < args.length; ++i) { ret.appendArg(args[i]); } return ret; } function makeArgumentExpr(comma, expr) { return expr; } function makeUnionExpr(expr1, pipe, expr2) { return new UnionExpr(expr1, expr2); } function makePathExpr1(filter, slash, rel) { return new PathExpr(filter, rel); } function makePathExpr2(filter, dslash, rel) { rel.prependStep(makeAbbrevStep(dslash.value)); return new PathExpr(filter, rel); } function makeFilterExpr(expr, predicates) { if (predicates.length > 0) { return new FilterExpr(expr, predicates); } else { return expr; } } function makeUnaryMinusExpr(minus, expr) { return new UnaryMinusExpr(expr); } function makeBinaryExpr(expr1, op, expr2) { return new BinaryExpr(expr1, op, expr2); } function makeLiteralExpr(token) { // remove quotes from the parsed value: var value =3D token.value.substring(1, token.value.length - 1); return new LiteralExpr(value); } function makeNumberExpr(token) { return new NumberExpr(token.value); } function makeVariableReference(dollar, name) { return new VariableExpr(name.value); } // Used before parsing for optimization of common simple cases. See // the begin of xpathParse() for which they are. function makeSimpleExpr(expr) { if (expr.charAt(0) =3D=3D '$') { return new VariableExpr(expr.substr(1)); } else if (expr.charAt(0) =3D=3D '@') { var a =3D new NodeTestName(expr.substr(1)); var b =3D new StepExpr('attribute', a); var c =3D new LocationExpr(); c.appendStep(b); return c; } else if (expr.match(/^[0-9]+$/)) { return new NumberExpr(expr); } else { var a =3D new NodeTestName(expr); var b =3D new StepExpr('child', a); var c =3D new LocationExpr(); c.appendStep(b); return c; } } function makeSimpleExpr2(expr) { var steps =3D stringSplit(expr, '/'); var c =3D new LocationExpr(); for (var i =3D 0; i < steps.length; ++i) { var a =3D new NodeTestName(steps[i]); var b =3D new StepExpr('child', a); c.appendStep(b); } return c; } // The axes of XPath expressions. var xpathAxis =3D { ANCESTOR_OR_SELF: 'ancestor-or-self', ANCESTOR: 'ancestor', ATTRIBUTE: 'attribute', CHILD: 'child', DESCENDANT_OR_SELF: 'descendant-or-self', DESCENDANT: 'descendant', FOLLOWING_SIBLING: 'following-sibling', FOLLOWING: 'following', NAMESPACE: 'namespace', PARENT: 'parent', PRECEDING_SIBLING: 'preceding-sibling', PRECEDING: 'preceding', SELF: 'self' }; var xpathAxesRe =3D [ xpathAxis.ANCESTOR_OR_SELF, xpathAxis.ANCESTOR, xpathAxis.ATTRIBUTE, xpathAxis.CHILD, xpathAxis.DESCENDANT_OR_SELF, xpathAxis.DESCENDANT, xpathAxis.FOLLOWING_SIBLING, xpathAxis.FOLLOWING, xpathAxis.NAMESPACE, xpathAxis.PARENT, xpathAxis.PRECEDING_SIBLING, xpathAxis.PRECEDING, xpathAxis.SELF ].join('|'); // The tokens of the language. The label property is just used for // generating debug output. The prec property is the precedence used // for shift/reduce resolution. Default precedence is 0 as a lookahead // token and 2 on the stack. TODO(mesch): this is certainly not // necessary and too complicated. Simplify this! // NOTE: tabular formatting is the big exception, but here it should // be OK. var TOK_PIPE =3D { label: "|", prec: 17, re: new RegExp("^\\|") }; var TOK_DSLASH =3D { label: "//", prec: 19, re: new RegExp("^//") }; var TOK_SLASH =3D { label: "/", prec: 30, re: new RegExp("^/") }; var TOK_AXIS =3D { label: "::", prec: 20, re: new RegExp("^::") }; var TOK_COLON =3D { label: ":", prec: 1000, re: new RegExp("^:") }; var TOK_AXISNAME =3D { label: "[axis]", re: new RegExp('^(' + = xpathAxesRe + ')') }; var TOK_PARENO =3D { label: "(", prec: 34, re: new RegExp("^\\(") }; var TOK_PARENC =3D { label: ")", re: new RegExp("^\\)") }; var TOK_DDOT =3D { label: "..", prec: 34, re: new RegExp("^\\.\\.") = }; var TOK_DOT =3D { label: ".", prec: 34, re: new RegExp("^\\.") }; var TOK_AT =3D { label: "@", prec: 34, re: new RegExp("^@") }; var TOK_COMMA =3D { label: ",", re: new RegExp("^,") }; var TOK_OR =3D { label: "or", prec: 10, re: new RegExp("^or\\b") = }; var TOK_AND =3D { label: "and", prec: 11, re: new RegExp("^and\\b") = }; var TOK_EQ =3D { label: "=3D", prec: 12, re: new RegExp("^=3D") = }; var TOK_NEQ =3D { label: "!=3D", prec: 12, re: new RegExp("^!=3D") = }; var TOK_GE =3D { label: ">=3D", prec: 13, re: new RegExp("^>=3D") = }; var TOK_GT =3D { label: ">", prec: 13, re: new RegExp("^>") }; var TOK_LE =3D { label: "<=3D", prec: 13, re: new RegExp("^<=3D") = }; var TOK_LT =3D { label: "<", prec: 13, re: new RegExp("^<") }; var TOK_PLUS =3D { label: "+", prec: 14, re: new RegExp("^\\+"), = left: true }; var TOK_MINUS =3D { label: "-", prec: 14, re: new RegExp("^\\-"), = left: true }; var TOK_DIV =3D { label: "div", prec: 15, re: new = RegExp("^div\\b"), left: true }; var TOK_MOD =3D { label: "mod", prec: 15, re: new = RegExp("^mod\\b"), left: true }; var TOK_BRACKO =3D { label: "[", prec: 32, re: new RegExp("^\\[") }; var TOK_BRACKC =3D { label: "]", re: new RegExp("^\\]") }; var TOK_DOLLAR =3D { label: "$", re: new RegExp("^\\$") }; var TOK_NCNAME =3D { label: "[ncname]", re: new RegExp('^' + = XML_NC_NAME) }; var TOK_ASTERISK =3D { label: "*", prec: 15, re: new RegExp("^\\*"), = left: true }; var TOK_LITERALQ =3D { label: "[litq]", prec: 20, re: new = RegExp("^'[^\\']*'") }; var TOK_LITERALQQ =3D { label: "[litqq]", prec: 20, re: new RegExp('^"[^\\"]*"') }; var TOK_NUMBER =3D { label: "[number]", prec: 35, re: new RegExp('^\\d+(\\.\\d*)?') }; var TOK_QNAME =3D { label: "[qname]", re: new RegExp('^(' + XML_NC_NAME + ':)?' + XML_NC_NAME) }; var TOK_NODEO =3D { label: "[nodetest-start]", re: new RegExp('^(processing-instruction|comment|text|node)\\(') }; // The table of the tokens of our grammar, used by the lexer: first // column the tag, second column a regexp to recognize it in the // input, third column the precedence of the token, fourth column a // factory function for the semantic value of the token. // // NOTE: order of this list is important, because the first match // counts. Cf. DDOT and DOT, and AXIS and COLON. var xpathTokenRules =3D [ TOK_DSLASH, TOK_SLASH, TOK_DDOT, TOK_DOT, TOK_AXIS, TOK_COLON, TOK_AXISNAME, TOK_NODEO, TOK_PARENO, TOK_PARENC, TOK_BRACKO, TOK_BRACKC, TOK_AT, TOK_COMMA, TOK_OR, TOK_AND, TOK_NEQ, TOK_EQ, TOK_GE, TOK_GT, TOK_LE, TOK_LT, TOK_PLUS, TOK_MINUS, TOK_ASTERISK, TOK_PIPE, TOK_MOD, TOK_DIV, TOK_LITERALQ, TOK_LITERALQQ, TOK_NUMBER, TOK_QNAME, TOK_NCNAME, TOK_DOLLAR ]; // All the nonterminals of the grammar. The nonterminal objects are // identified by object identity; the labels are used in the debug // output only. var XPathLocationPath =3D { label: "LocationPath" }; var XPathRelativeLocationPath =3D { label: "RelativeLocationPath" }; var XPathAbsoluteLocationPath =3D { label: "AbsoluteLocationPath" }; var XPathStep =3D { label: "Step" }; var XPathNodeTest =3D { label: "NodeTest" }; var XPathPredicate =3D { label: "Predicate" }; var XPathLiteral =3D { label: "Literal" }; var XPathExpr =3D { label: "Expr" }; var XPathPrimaryExpr =3D { label: "PrimaryExpr" }; var XPathVariableReference =3D { label: "Variablereference" }; var XPathNumber =3D { label: "Number" }; var XPathFunctionCall =3D { label: "FunctionCall" }; var XPathArgumentRemainder =3D { label: "ArgumentRemainder" }; var XPathPathExpr =3D { label: "PathExpr" }; var XPathUnionExpr =3D { label: "UnionExpr" }; var XPathFilterExpr =3D { label: "FilterExpr" }; var XPathDigits =3D { label: "Digits" }; var xpathNonTerminals =3D [ XPathLocationPath, XPathRelativeLocationPath, XPathAbsoluteLocationPath, XPathStep, XPathNodeTest, XPathPredicate, XPathLiteral, XPathExpr, XPathPrimaryExpr, XPathVariableReference, XPathNumber, XPathFunctionCall, XPathArgumentRemainder, XPathPathExpr, XPathUnionExpr, XPathFilterExpr, XPathDigits ]; // Quantifiers that are used in the productions of the grammar. var Q_01 =3D { label: "?" }; var Q_MM =3D { label: "*" }; var Q_1M =3D { label: "+" }; // Tag for left associativity (right assoc is implied by undefined). var ASSOC_LEFT =3D true; // The productions of the grammar. Columns of the table: // // - target nonterminal, // - pattern, // - precedence, // - semantic value factory // // The semantic value factory is a function that receives parse tree // nodes from the stack frames of the matched symbols as arguments and // returns an a node of the parse tree. The node is stored in the top // stack frame along with the target object of the rule. The node in // the parse tree is an expression object that has an evaluate() method // and thus evaluates XPath expressions. // // The precedence is used to decide between reducing and shifting by // comparing the precendence of the rule that is candidate for // reducing with the precedence of the look ahead token. Precedence of // -1 means that the precedence of the tokens in the pattern is used // instead. TODO: It shouldn't be necessary to explicitly assign // precedences to rules. var xpathGrammarRules =3D [ [ XPathLocationPath, [ XPathRelativeLocationPath ], 18, passExpr ], [ XPathLocationPath, [ XPathAbsoluteLocationPath ], 18, passExpr ], [ XPathAbsoluteLocationPath, [ TOK_SLASH, XPathRelativeLocationPath = ], 18, makeLocationExpr1 ], [ XPathAbsoluteLocationPath, [ TOK_DSLASH, XPathRelativeLocationPath = ], 18, makeLocationExpr2 ], [ XPathAbsoluteLocationPath, [ TOK_SLASH ], 0, makeLocationExpr3 ], [ XPathAbsoluteLocationPath, [ TOK_DSLASH ], 0, makeLocationExpr4 ], [ XPathRelativeLocationPath, [ XPathStep ], 31, makeLocationExpr5 ], [ XPathRelativeLocationPath, [ XPathRelativeLocationPath, TOK_SLASH, XPathStep ], 31, makeLocationExpr6 ], [ XPathRelativeLocationPath, [ XPathRelativeLocationPath, TOK_DSLASH, XPathStep ], 31, makeLocationExpr7 ], [ XPathStep, [ TOK_DOT ], 33, makeStepExpr1 ], [ XPathStep, [ TOK_DDOT ], 33, makeStepExpr2 ], [ XPathStep, [ TOK_AXISNAME, TOK_AXIS, XPathNodeTest ], 33, makeStepExpr3 ], [ XPathStep, [ TOK_AT, XPathNodeTest ], 33, makeStepExpr4 ], [ XPathStep, [ XPathNodeTest ], 33, makeStepExpr5 ], [ XPathStep, [ XPathStep, XPathPredicate ], 33, makeStepExpr6 ], [ XPathNodeTest, [ TOK_ASTERISK ], 33, makeNodeTestExpr1 ], [ XPathNodeTest, [ TOK_NCNAME, TOK_COLON, TOK_ASTERISK ], 33, makeNodeTestExpr2 ], [ XPathNodeTest, [ TOK_QNAME ], 33, makeNodeTestExpr3 ], [ XPathNodeTest, [ TOK_NODEO, TOK_PARENC ], 33, makeNodeTestExpr4 ], [ XPathNodeTest, [ TOK_NODEO, XPathLiteral, TOK_PARENC ], 33, makeNodeTestExpr5 ], [ XPathPredicate, [ TOK_BRACKO, XPathExpr, TOK_BRACKC ], 33, makePredicateExpr ], [ XPathPrimaryExpr, [ XPathVariableReference ], 33, passExpr ], [ XPathPrimaryExpr, [ TOK_PARENO, XPathExpr, TOK_PARENC ], 33, makePrimaryExpr ], [ XPathPrimaryExpr, [ XPathLiteral ], 30, passExpr ], [ XPathPrimaryExpr, [ XPathNumber ], 30, passExpr ], [ XPathPrimaryExpr, [ XPathFunctionCall ], 30, passExpr ], [ XPathFunctionCall, [ TOK_QNAME, TOK_PARENO, TOK_PARENC ], -1, makeFunctionCallExpr1 ], [ XPathFunctionCall, [ TOK_QNAME, TOK_PARENO, XPathExpr, XPathArgumentRemainder, Q_MM, TOK_PARENC ], -1, makeFunctionCallExpr2 ], [ XPathArgumentRemainder, [ TOK_COMMA, XPathExpr ], -1, makeArgumentExpr ], [ XPathUnionExpr, [ XPathPathExpr ], 20, passExpr ], [ XPathUnionExpr, [ XPathUnionExpr, TOK_PIPE, XPathPathExpr ], 20, makeUnionExpr ], [ XPathPathExpr, [ XPathLocationPath ], 20, passExpr ], [ XPathPathExpr, [ XPathFilterExpr ], 19, passExpr ], [ XPathPathExpr, [ XPathFilterExpr, TOK_SLASH, XPathRelativeLocationPath ], 20, makePathExpr1 ], [ XPathPathExpr, [ XPathFilterExpr, TOK_DSLASH, XPathRelativeLocationPath ], 20, makePathExpr2 ], [ XPathFilterExpr, [ XPathPrimaryExpr, XPathPredicate, Q_MM ], 20, makeFilterExpr ], [ XPathExpr, [ XPathPrimaryExpr ], 16, passExpr ], [ XPathExpr, [ XPathUnionExpr ], 16, passExpr ], [ XPathExpr, [ TOK_MINUS, XPathExpr ], -1, makeUnaryMinusExpr ], [ XPathExpr, [ XPathExpr, TOK_OR, XPathExpr ], -1, makeBinaryExpr ], [ XPathExpr, [ XPathExpr, TOK_AND, XPathExpr ], -1, makeBinaryExpr ], [ XPathExpr, [ XPathExpr, TOK_EQ, XPathExpr ], -1, makeBinaryExpr ], [ XPathExpr, [ XPathExpr, TOK_NEQ, XPathExpr ], -1, makeBinaryExpr ], [ XPathExpr, [ XPathExpr, TOK_LT, XPathExpr ], -1, makeBinaryExpr ], [ XPathExpr, [ XPathExpr, TOK_LE, XPathExpr ], -1, makeBinaryExpr ], [ XPathExpr, [ XPathExpr, TOK_GT, XPathExpr ], -1, makeBinaryExpr ], [ XPathExpr, [ XPathExpr, TOK_GE, XPathExpr ], -1, makeBinaryExpr ], [ XPathExpr, [ XPathExpr, TOK_PLUS, XPathExpr ], -1, makeBinaryExpr, ASSOC_LEFT ], [ XPathExpr, [ XPathExpr, TOK_MINUS, XPathExpr ], -1, makeBinaryExpr, ASSOC_LEFT ], [ XPathExpr, [ XPathExpr, TOK_ASTERISK, XPathExpr ], -1, makeBinaryExpr, ASSOC_LEFT ], [ XPathExpr, [ XPathExpr, TOK_DIV, XPathExpr ], -1, makeBinaryExpr, ASSOC_LEFT ], [ XPathExpr, [ XPathExpr, TOK_MOD, XPathExpr ], -1, makeBinaryExpr, ASSOC_LEFT ], [ XPathLiteral, [ TOK_LITERALQ ], -1, makeLiteralExpr ], [ XPathLiteral, [ TOK_LITERALQQ ], -1, makeLiteralExpr ], [ XPathNumber, [ TOK_NUMBER ], -1, makeNumberExpr ], [ XPathVariableReference, [ TOK_DOLLAR, TOK_QNAME ], 200, makeVariableReference ] ]; // That function computes some optimizations of the above data // structures and will be called right here. It merely takes the // counter variables out of the global scope. var xpathRules =3D []; function xpathParseInit() { if (xpathRules.length) { return; } // Some simple optimizations for the xpath expression parser: sort // grammar rules descending by length, so that the longest match is // first found. xpathGrammarRules.sort(function(a,b) { var la =3D a[1].length; var lb =3D b[1].length; if (la < lb) { return 1; } else if (la > lb) { return -1; } else { return 0; } }); var k =3D 1; for (var i =3D 0; i < xpathNonTerminals.length; ++i) { xpathNonTerminals[i].key =3D k++; } for (i =3D 0; i < xpathTokenRules.length; ++i) { xpathTokenRules[i].key =3D k++; } xpathLog('XPath parse INIT: ' + k + ' rules'); // Another slight optimization: sort the rules into bins according // to the last element (observing quantifiers), so we can restrict // the match against the stack to the subest of rules that match the // top of the stack. // // TODO(mesch): What we actually want is to compute states as in // bison, so that we don't have to do any explicit and iterated // match against the stack. function push_(array, position, element) { if (!array[position]) { array[position] =3D []; } array[position].push(element); } for (i =3D 0; i < xpathGrammarRules.length; ++i) { var rule =3D xpathGrammarRules[i]; var pattern =3D rule[1]; for (var j =3D pattern.length - 1; j >=3D 0; --j) { if (pattern[j] =3D=3D Q_1M) { push_(xpathRules, pattern[j-1].key, rule); break; } else if (pattern[j] =3D=3D Q_MM || pattern[j] =3D=3D Q_01) { push_(xpathRules, pattern[j-1].key, rule); --j; } else { push_(xpathRules, pattern[j].key, rule); break; } } } xpathLog('XPath parse INIT: ' + xpathRules.length + ' rule bins'); var sum =3D 0; mapExec(xpathRules, function(i) { if (i) { sum +=3D i.length; } }); xpathLog('XPath parse INIT: ' + (sum / xpathRules.length) + ' average bin size'); } // Local utility functions that are used by the lexer or parser. function xpathCollectDescendants(nodelist, node) { for (var n =3D node.firstChild; n; n =3D n.nextSibling) { nodelist.push(n); arguments.callee(nodelist, n); } } function xpathCollectDescendantsReverse(nodelist, node) { for (var n =3D node.lastChild; n; n =3D n.previousSibling) { nodelist.push(n); arguments.callee(nodelist, n); } } // The entry point for the library: match an expression against a DOM // node. Returns an XPath value. function xpathDomEval(expr, node) { var expr1 =3D xpathParse(expr); var ret =3D expr1.evaluate(new ExprContext(node)); return ret; } // Utility function to sort a list of nodes. Used by xsltSort() and // nxslSelect(). function xpathSort(input, sort) { if (sort.length =3D=3D 0) { return; } var sortlist =3D []; for (var i =3D 0; i < input.contextSize(); ++i) { var node =3D input.nodelist[i]; var sortitem =3D { node: node, key: [] }; var context =3D input.clone(node, 0, [ node ]); for (var j =3D 0; j < sort.length; ++j) { var s =3D sort[j]; var value =3D s.expr.evaluate(context); var evalue; if (s.type =3D=3D 'text') { evalue =3D value.stringValue(); } else if (s.type =3D=3D 'number') { evalue =3D value.numberValue(); } sortitem.key.push({ value: evalue, order: s.order }); } // Make the sort stable by adding a lowest priority sort by // id. This is very convenient and furthermore required by the // spec ([XSLT] - Section 10 Sorting). sortitem.key.push({ value: i, order: 'ascending' }); sortlist.push(sortitem); } sortlist.sort(xpathSortByKey); var nodes =3D []; for (var i =3D 0; i < sortlist.length; ++i) { nodes.push(sortlist[i].node); } input.nodelist =3D nodes; input.setNode(0); } // Sorts by all order criteria defined. According to the JavaScript // spec ([ECMA] Section 11.8.5), the compare operators compare strings // as strings and numbers as numbers. // // NOTE: In browsers which do not follow the spec, this breaks only in // the case that numbers should be sorted as strings, which is very // uncommon. function xpathSortByKey(v1, v2) { // NOTE: Sort key vectors of different length never occur in // xsltSort. for (var i =3D 0; i < v1.key.length; ++i) { var o =3D v1.key[i].order =3D=3D 'descending' ? -1 : 1; if (v1.key[i].value > v2.key[i].value) { return +1 * o; } else if (v1.key[i].value < v2.key[i].value) { return -1 * o; } } return 0; } // Parses and then evaluates the given XPath expression in the given // input context. Notice that parsed xpath expressions are cached. function xpathEval(select, context) { var expr =3D xpathParse(select); var ret =3D expr.evaluate(context); return ret; } ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: application/octet-stream Content-Transfer-Encoding: quoted-printable Content-Location: http://www.marquette.edu/academicsenate/_js/SpryData.js // SpryData.js - version 0.46 - Spry Pre-Release 1.6.1 // // Copyright (c) 2006. Adobe Systems Incorporated. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions = are met: // // * Redistributions of source code must retain the above copyright = notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright = notice, // this list of conditions and the following disclaimer in the = documentation // and/or other materials provided with the distribution. // * Neither the name of Adobe Systems Incorporated nor the names of = its // contributors may be used to endorse or promote products derived = from this // software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS = "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, = THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR = PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS = BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR = BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER = IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR = OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED = OF THE // POSSIBILITY OF SUCH DAMAGE. var Spry; if (!Spry) Spry =3D {}; ////////////////////////////////////////////////////////////////////// // // Spry.Utils // ////////////////////////////////////////////////////////////////////// if (!Spry.Utils) Spry.Utils =3D {}; Spry.Utils.msProgIDs =3D ["MSXML2.XMLHTTP.6.0", "MSXML2.XMLHTTP.3.0"]; Spry.Utils.createXMLHttpRequest =3D function() { var req =3D null; try { // Try to use the ActiveX version of XMLHttpRequest. This will // allow developers to load file URLs in IE7 when running in the // local zone. if (window.ActiveXObject) { while (!req && Spry.Utils.msProgIDs.length) { try { req =3D new ActiveXObject(Spry.Utils.msProgIDs[0]); } catch = (e) { req =3D null; } if (!req) Spry.Utils.msProgIDs.splice(0, 1); } } // We're either running in a non-IE browser, or we failed to // create the ActiveX version of the XMLHttpRequest object. // Try to use the native version of XMLHttpRequest if it exists. if (!req && window.XMLHttpRequest) req =3D new XMLHttpRequest(); } catch (e) { req =3D null; } if (!req) Spry.Debug.reportError("Failed to create an XMLHttpRequest object!" ); return req; }; Spry.Utils.loadURL =3D function(method, url, async, callback, opts) { var req =3D new Spry.Utils.loadURL.Request(); req.method =3D method; req.url =3D url; req.async =3D async; req.successCallback =3D callback; Spry.Utils.setOptions(req, opts); try { req.xhRequest =3D Spry.Utils.createXMLHttpRequest(); if (!req.xhRequest) return null; if (req.async) req.xhRequest.onreadystatechange =3D function() { = Spry.Utils.loadURL.callback(req); }; req.xhRequest.open(req.method, req.url, req.async, req.username, = req.password); if (req.headers) { for (var name in req.headers) req.xhRequest.setRequestHeader(name, req.headers[name]); } req.xhRequest.send(req.postData); if (!req.async) Spry.Utils.loadURL.callback(req); } catch(e) { if (req.errorCallback) req.errorCallback(req); else Spry.Debug.reportError("Exception caught while loading " + url + ": " = + e); req =3D null; } return req; }; Spry.Utils.loadURL.callback =3D function(req) { if (!req || req.xhRequest.readyState !=3D 4) return; if (req.successCallback && (req.xhRequest.status =3D=3D 200 || = req.xhRequest.status =3D=3D 0)) req.successCallback(req); else if (req.errorCallback) req.errorCallback(req); }; Spry.Utils.loadURL.Request =3D function() { var props =3D Spry.Utils.loadURL.Request.props; var numProps =3D props.length; for (var i =3D 0; i < numProps; i++) this[props[i]] =3D null; this.method =3D "GET"; this.async =3D true; this.headers =3D {}; }; Spry.Utils.loadURL.Request.props =3D [ "method", "url", "async", = "username", "password", "postData", "successCallback", "errorCallback", = "headers", "userData", "xhRequest" ]; Spry.Utils.loadURL.Request.prototype.extractRequestOptions =3D = function(opts, undefineRequestProps) { if (!opts) return; var props =3D Spry.Utils.loadURL.Request.props; var numProps =3D props.length; for (var i =3D 0; i < numProps; i++) { var prop =3D props[i]; if (opts[prop] !=3D undefined) { this[prop] =3D opts[prop]; if (undefineRequestProps) opts[prop] =3D undefined; } } }; Spry.Utils.loadURL.Request.prototype.clone =3D function() { var props =3D Spry.Utils.loadURL.Request.props; var numProps =3D props.length; var req =3D new Spry.Utils.loadURL.Request; for (var i =3D 0; i < numProps; i++) req[props[i]] =3D this[props[i]]; if (this.headers) { req.headers =3D {}; Spry.Utils.setOptions(req.headers, this.headers); } return req; }; Spry.Utils.setInnerHTML =3D function(ele, str, preventScripts) { if (!ele) return; ele =3D Spry.$(ele); var scriptExpr =3D "]*>(.|\s|\n|\r)*?"; ele.innerHTML =3D str.replace(new RegExp(scriptExpr, "img"), ""); if (preventScripts) return; var matches =3D str.match(new RegExp(scriptExpr, "img")); if (matches) { var numMatches =3D matches.length; for (var i =3D 0; i < numMatches; i++) { var s =3D = matches[i].replace(/]*>[\s\r\n]*(<\!--)?|(-->)?[\s\r\n]*<\/scri= pt>/img, ""); Spry.Utils.eval(s); } } }; Spry.Utils.updateContent =3D function (ele, url, finishFunc, opts) { Spry.Utils.loadURL("GET", url, true, function(req) { Spry.Utils.setInnerHTML(ele, req.xhRequest.responseText); if (finishFunc) finishFunc(ele, url); }, opts); }; ////////////////////////////////////////////////////////////////////// // // Functions from SpryDOMUtils.js // - These have been left in for backwards compatibility, but they // should only be defined if Spry.$$ (SpryDOMUtils.js) is not // already included. // - If SpryDOMUtils.js is included *after* SpryData.js, these // functions will be replaced with the latest versions in // SpryDOMUtils.js. // ////////////////////////////////////////////////////////////////////// if (!Spry.$$) { Spry.Utils.addEventListener =3D function(element, eventType, handler, = capture) { try { element =3D Spry.$(element); if (element.addEventListener) element.addEventListener(eventType, handler, capture); else if (element.attachEvent) element.attachEvent("on" + eventType, handler); } catch (e) {} }; Spry.Utils.removeEventListener =3D function(element, eventType, handler, = capture) { try { element =3D Spry.$(element); if (element.removeEventListener) element.removeEventListener(eventType, handler, capture); else if (element.detachEvent) element.detachEvent("on" + eventType, handler); } catch (e) {} }; Spry.Utils.addLoadListener =3D function(handler) { if (typeof window.addEventListener !=3D 'undefined') window.addEventListener('load', handler, false); else if (typeof document.addEventListener !=3D 'undefined') document.addEventListener('load', handler, false); else if (typeof window.attachEvent !=3D 'undefined') window.attachEvent('onload', handler); }; Spry.Utils.addClassName =3D function(ele, className) { ele =3D Spry.$(ele); if (!ele || !className || (ele.className && ele.className.search(new = RegExp("\\b" + className + "\\b")) !=3D -1)) return; ele.className +=3D (ele.className ? " " : "") + className; }; Spry.Utils.removeClassName =3D function(ele, className) { ele =3D Spry.$(ele); if (!ele || !className || (ele.className && ele.className.search(new = RegExp("\\b" + className + "\\b")) =3D=3D -1)) return; ele.className =3D ele.className.replace(new RegExp("\\s*\\b" + = className + "\\b", "g"), ""); }; ////////////////////////////////////////////////////////////////////// // // Define Prototype's $() convenience function, but make sure it is // namespaced under Spry so that we avoid collisions with other // toolkits. // ////////////////////////////////////////////////////////////////////// Spry.$ =3D function(element) { if (arguments.length > 1) { for (var i =3D 0, elements =3D [], length =3D arguments.length; i < = length; i++) elements.push(Spry.$(arguments[i])); return elements; } if (typeof element =3D=3D 'string') element =3D document.getElementById(element); return element; }; } // if (!Spry.$$) ////////////////////////////////////////////////////////////////////// Spry.Utils.getObjectByName =3D function(name) { var result =3D null; if (name) { var lu =3D window; var objPath =3D name.split("."); for (var i =3D 0; lu && i < objPath.length; i++) { result =3D lu[objPath[i]]; lu =3D result; } } return result; }; Spry.Utils.eval =3D function(str) { // Call this method from your JS function when // you don't want the JS expression to access or // interfere with any local variables in your JS // function. return eval(str); }; Spry.Utils.escapeQuotesAndLineBreaks =3D function(str) { if (str) { str =3D str.replace(/\\/g, "\\\\"); str =3D str.replace(/["']/g, "\\$&"); str =3D str.replace(/\n/g, "\\n"); str =3D str.replace(/\r/g, "\\r"); } return str; }; Spry.Utils.encodeEntities =3D function(str) { if (str && str.search(/[&<>"]/) !=3D -1) { str =3D str.replace(/&/g, "&"); str =3D str.replace(//g, ">"); str =3D str.replace(/"/g, """); } return str }; Spry.Utils.decodeEntities =3D function(str) { var d =3D Spry.Utils.decodeEntities.div; if (!d) { d =3D document.createElement('div'); Spry.Utils.decodeEntities.div =3D d; if (!d) return str; } d.innerHTML =3D str; if (d.childNodes.length =3D=3D 1 && d.firstChild.nodeType =3D=3D 3 /* = Node.TEXT_NODE */ && d.firstChild.nextSibling =3D=3D null) str =3D d.firstChild.data; else { // Hmmm, innerHTML processing of str produced content // we weren't expecting, so just replace entities we // expect folks will use in node attributes that contain // JavaScript. str =3D str.replace(/</gi, "<"); str =3D str.replace(/>/gi, ">"); str =3D str.replace(/"/gi, "\""); str =3D str.replace(/&/gi, "&"); } return str; }; Spry.Utils.fixupIETagAttributes =3D function(inStr) { var outStr =3D ""; // Break the tag string into 3 pieces. var tagStart =3D inStr.match(/^<[^\s>]+\s*/)[0]; var tagEnd =3D inStr.match(/\s*\/?>$/)[0]; var tagAttrs =3D inStr.replace(/^<[^\s>]+\s*|\s*\/?>/g, ""); // Write out the start of the tag. outStr +=3D tagStart; // If the tag has attributes, parse it out manually to avoid = accidentally fixing up // attributes that contain JavaScript expressions. if (tagAttrs) { var startIndex =3D 0; var endIndex =3D 0; while (startIndex < tagAttrs.length) { // Find the '=3D' char of the attribute. while (tagAttrs.charAt(endIndex) !=3D '=3D' && endIndex < = tagAttrs.length) ++endIndex; // If we are at the end of the string, just write out what we've // collected. if (endIndex >=3D tagAttrs.length) { outStr +=3D tagAttrs.substring(startIndex, endIndex); break; } // Step past the '=3D' character and write out what we've // collected so far. ++endIndex; outStr +=3D tagAttrs.substring(startIndex, endIndex); startIndex =3D endIndex; if (tagAttrs.charAt(endIndex) =3D=3D '"' || tagAttrs.charAt(endIndex) = =3D=3D "'") { // Attribute is quoted. Advance us past the quoted value! var savedIndex =3D endIndex++; while (endIndex < tagAttrs.length) { if (tagAttrs.charAt(endIndex) =3D=3D tagAttrs.charAt(savedIndex)) { endIndex++; break; } else if (tagAttrs.charAt(endIndex) =3D=3D "\\") endIndex++; endIndex++; } outStr +=3D tagAttrs.substring(startIndex, endIndex); startIndex =3D endIndex; } else { // This attribute value wasn't quoted! Wrap it with quotes and // write out everything till we hit a space, or the end of the // string. outStr +=3D "\""; var sIndex =3D tagAttrs.slice(endIndex).search(/\s/); endIndex =3D (sIndex !=3D -1) ? (endIndex + sIndex) : = tagAttrs.length; outStr +=3D tagAttrs.slice(startIndex, endIndex); outStr +=3D "\""; startIndex =3D endIndex; } } } outStr +=3D tagEnd; // Write out the end of the tag. return outStr; }; Spry.Utils.fixUpIEInnerHTML =3D function(inStr) { var outStr =3D ""; // Create a regular expression that will match: // // ]]> // ]]> // Yet another workaround for an IE innerHTML bug. // // The idea here is that we only want to fix up attribute values on = tags that // are not in any comments or CDATA. var regexp =3D new = RegExp("<\\!--|<\\!\\[CDATA\\[|<\\w+[^<>]*>|-->|\\]\\](>|\>)", "g"); var searchStartIndex =3D 0; var skipFixUp =3D 0; while (inStr.length) { var results =3D regexp.exec(inStr); if (!results || !results[0]) { outStr +=3D inStr.substr(searchStartIndex, inStr.length - = searchStartIndex); break; } if (results.index !=3D searchStartIndex) { // We found a match but it's not at the start of the inStr. // Create a string token for everything that precedes the match. outStr +=3D inStr.substr(searchStartIndex, results.index - = searchStartIndex); } if (results[0] =3D=3D "" || results[0] =3D=3D "]]>" || = (skipFixUp && results[0] =3D=3D "]]>")) { --skipFixUp; outStr +=3D results[0]; } else if (!skipFixUp && results[0].charAt(0) =3D=3D '<') outStr +=3D Spry.Utils.fixupIETagAttributes(results[0]); else outStr +=3D results[0]; searchStartIndex =3D regexp.lastIndex; } return outStr; }; Spry.Utils.stringToXMLDoc =3D function(str) { var xmlDoc =3D null; try { // Attempt to parse the string using the IE method. var xmlDOMObj =3D new ActiveXObject("Microsoft.XMLDOM"); xmlDOMObj.async =3D false; xmlDOMObj.loadXML(str); xmlDoc =3D xmlDOMObj; } catch (e) { // The IE method didn't work. Try the Mozilla way. try { var domParser =3D new DOMParser; xmlDoc =3D domParser.parseFromString(str, 'text/xml'); } catch (e) { Spry.Debug.reportError("Caught exception in = Spry.Utils.stringToXMLDoc(): " + e + "\n"); xmlDoc =3D null; } } return xmlDoc; }; Spry.Utils.serializeObject =3D function(obj) { // Create a JSON representation of a given object. var str =3D ""; var firstItem =3D true; if (obj =3D=3D null || obj =3D=3D undefined) return str + obj; var objType =3D typeof obj; if (objType =3D=3D "number" || objType =3D=3D "boolean") str +=3D obj; else if (objType =3D=3D "string") str +=3D "\"" + Spry.Utils.escapeQuotesAndLineBreaks(obj) + "\""; else if (obj.constructor =3D=3D Array) { str +=3D "["; for (var i =3D 0; i < obj.length; i++) { if (!firstItem) str +=3D ", "; str +=3D Spry.Utils.serializeObject(obj[i]); firstItem =3D false; } str +=3D "]"; } else if (objType =3D=3D "object") { str +=3D "{"; for (var p in obj) { if (!firstItem) str +=3D ", "; str +=3D "\"" + p + "\": " + Spry.Utils.serializeObject(obj[p]); firstItem =3D false; } str +=3D "}"; } return str; }; Spry.Utils.getNodesByFunc =3D function(root, func) { var nodeStack =3D new Array; var resultArr =3D new Array; var node =3D root; while (node) { if (func(node)) resultArr.push(node); if (node.hasChildNodes()) { nodeStack.push(node); node =3D node.firstChild; } else { if (node =3D=3D root) node =3D null; else try { node =3D node.nextSibling; } catch (e) { node =3D null; }; } while (!node && nodeStack.length > 0) { node =3D nodeStack.pop(); if (node =3D=3D root) node =3D null; else try { node =3D node.nextSibling; } catch (e) { node =3D null; } } } if (nodeStack && nodeStack.length > 0) Spry.Debug.trace("-- WARNING: Spry.Utils.getNodesByFunc() failed to = traverse all nodes!\n"); return resultArr; }; // XXX: UNUSED FUNCTION Spry.Utils.getFirstChildWithNodeName =3D function(node, nodeName) { var child =3D node.firstChild; while (child) { if (child.nodeName =3D=3D nodeName) return child; child =3D child.nextSibling; } return null; }; Spry.Utils.setOptions =3D function(obj, optionsObj, = ignoreUndefinedProps) { if (!optionsObj) return; for (var optionName in optionsObj) { if (ignoreUndefinedProps && optionsObj[optionName] =3D=3D undefined) continue; obj[optionName] =3D optionsObj[optionName]; } }; Spry.Utils.SelectionManager =3D {}; Spry.Utils.SelectionManager.selectionGroups =3D new Object; Spry.Utils.SelectionManager.SelectionGroup =3D function() { this.selectedElements =3D new Array; }; Spry.Utils.SelectionManager.SelectionGroup.prototype.select =3D = function(element, className, multiSelect) { var selObj =3D null; if (!multiSelect) { // Multiple selection is not enabled, so clear any // selected elements from our list. this.clearSelection(); } else { // Multiple selection is enabled, so check to see if element // is already in the array. If it is, make sure the className // is the className that was passed in. for (var i =3D 0; i < this.selectedElements.length; i++) { selObj =3D this.selectedElements[i].element; if (selObj.element =3D=3D element) { if (selObj.className !=3D className) { Spry.Utils.removeClassName(element, selObj.className); Spry.Utils.addClassName(element, className); } return; } } } // Add the element to our list of selected elements. selObj =3D new Object; selObj.element =3D element; selObj.className =3D className; this.selectedElements.push(selObj); Spry.Utils.addClassName(element, className); }; Spry.Utils.SelectionManager.SelectionGroup.prototype.unSelect =3D = function(element) { for (var i =3D 0; i < this.selectedElements.length; i++) { var selObj =3D this.selectedElements[i].element; if (selObj.element =3D=3D element) { Spry.Utils.removeClassName(selObj.element, selObj.className); return; } } }; Spry.Utils.SelectionManager.SelectionGroup.prototype.clearSelection =3D = function() { var selObj =3D null; do { selObj =3D this.selectedElements.shift(); if (selObj) Spry.Utils.removeClassName(selObj.element, selObj.className); } while (selObj); }; Spry.Utils.SelectionManager.getSelectionGroup =3D = function(selectionGroupName) { if (!selectionGroupName) return null; var groupObj =3D = Spry.Utils.SelectionManager.selectionGroups[selectionGroupName]; if (!groupObj) { groupObj =3D new Spry.Utils.SelectionManager.SelectionGroup(); Spry.Utils.SelectionManager.selectionGroups[selectionGroupName] =3D = groupObj; } return groupObj; }; Spry.Utils.SelectionManager.select =3D function(selectionGroupName, = element, className, multiSelect) { var groupObj =3D = Spry.Utils.SelectionManager.getSelectionGroup(selectionGroupName); if (!groupObj) return; groupObj.select(element, className, multiSelect); }; Spry.Utils.SelectionManager.unSelect =3D function(selectionGroupName, = element) { var groupObj =3D = Spry.Utils.SelectionManager.getSelectionGroup(selectionGroupName); if (!groupObj) return; groupObj.unSelect(element, className); }; Spry.Utils.SelectionManager.clearSelection =3D = function(selectionGroupName) { var groupObj =3D = Spry.Utils.SelectionManager.getSelectionGroup(selectionGroupName); if (!groupObj) return; groupObj.clearSelection(); }; Spry.Utils.Notifier =3D function() { this.observers =3D []; this.suppressNotifications =3D 0; }; Spry.Utils.Notifier.prototype.addObserver =3D function(observer) { if (!observer) return; // Make sure the observer isn't already on the list. var len =3D this.observers.length; for (var i =3D 0; i < len; i++) { if (this.observers[i] =3D=3D observer) return; } this.observers[len] =3D observer; }; Spry.Utils.Notifier.prototype.removeObserver =3D function(observer) { if (!observer) return; for (var i =3D 0; i < this.observers.length; i++) { if (this.observers[i] =3D=3D observer) { this.observers.splice(i, 1); break; } } }; Spry.Utils.Notifier.prototype.notifyObservers =3D function(methodName, = data) { if (!methodName) return; if (!this.suppressNotifications) { var len =3D this.observers.length; for (var i =3D 0; i < len; i++) { var obs =3D this.observers[i]; if (obs) { if (typeof obs =3D=3D "function") obs(methodName, this, data); else if (obs[methodName]) obs[methodName](this, data); } } } }; Spry.Utils.Notifier.prototype.enableNotifications =3D function() { if (--this.suppressNotifications < 0) { this.suppressNotifications =3D 0; Spry.Debug.reportError("Unbalanced enableNotifications() call!\n"); } }; Spry.Utils.Notifier.prototype.disableNotifications =3D function() { ++this.suppressNotifications; }; ////////////////////////////////////////////////////////////////////// // // Spry.Debug // ////////////////////////////////////////////////////////////////////// Spry.Debug =3D {}; Spry.Debug.enableTrace =3D true; Spry.Debug.debugWindow =3D null; Spry.Debug.onloadDidFire =3D false; Spry.Utils.addLoadListener(function() { Spry.Debug.onloadDidFire =3D = true; Spry.Debug.flushQueuedMessages(); }); Spry.Debug.flushQueuedMessages =3D function() { if (Spry.Debug.flushQueuedMessages.msgs) { var msgs =3D Spry.Debug.flushQueuedMessages.msgs; for (var i =3D 0; i < msgs.length; i++) Spry.Debug.debugOut(msgs[i].msg, msgs[i].color); Spry.Debug.flushQueuedMessages.msgs =3D null; } }; Spry.Debug.createDebugWindow =3D function() { if (!Spry.Debug.enableTrace || Spry.Debug.debugWindow || = !Spry.Debug.onloadDidFire) return; try { Spry.Debug.debugWindow =3D document.createElement("div"); var div =3D Spry.Debug.debugWindow; div.style.fontSize =3D "12px"; div.style.fontFamily =3D "console"; div.style.position =3D "absolute"; div.style.width =3D "400px"; div.style.height =3D "300px"; div.style.overflow =3D "auto"; div.style.border =3D "solid 1px black"; div.style.backgroundColor =3D "white"; div.style.color =3D "black"; div.style.bottom =3D "0px"; div.style.right =3D "0px"; // div.style.opacity =3D "0.5"; // div.style.filter =3D "alpha(opacity=3D50)"; div.setAttribute("id", "SpryDebugWindow"); document.body.appendChild(Spry.Debug.debugWindow); } catch (e) {} }; Spry.Debug.debugOut =3D function(str, bgColor) { if (!Spry.Debug.debugWindow) { Spry.Debug.createDebugWindow(); if (!Spry.Debug.debugWindow) { if (!Spry.Debug.flushQueuedMessages.msgs) Spry.Debug.flushQueuedMessages.msgs =3D new Array; Spry.Debug.flushQueuedMessages.msgs.push({msg: str, color: bgColor}); return; } } var d =3D document.createElement("div"); if (bgColor) d.style.backgroundColor =3D bgColor; d.innerHTML =3D str; Spry.Debug.debugWindow.appendChild(d); }; Spry.Debug.trace =3D function(str) { Spry.Debug.debugOut(str); }; Spry.Debug.reportError =3D function(str) { Spry.Debug.debugOut(str, "red"); }; ////////////////////////////////////////////////////////////////////// // // Spry.Data // ////////////////////////////////////////////////////////////////////// Spry.Data =3D {}; Spry.Data.regionsArray =3D {}; Spry.Data.initRegionsOnLoad =3D true; Spry.Data.initRegions =3D function(rootNode) { rootNode =3D rootNode ? Spry.$(rootNode) : document.body; var lastRegionFound =3D null; var regions =3D Spry.Utils.getNodesByFunc(rootNode, function(node) { try { if (node.nodeType !=3D 1 /* Node.ELEMENT_NODE */) return false; // Region elements must have an spryregion attribute with a // non-empty value. An id attribute is also required so we can // reference the region by name if necessary. var attrName =3D "spry:region"; var attr =3D node.attributes.getNamedItem(attrName); if (!attr) { attrName =3D "spry:detailregion"; attr =3D node.attributes.getNamedItem(attrName); } if (attr) { if (lastRegionFound) { var parent =3D node.parentNode; while (parent) { if (parent =3D=3D lastRegionFound) { Spry.Debug.reportError("Found a nested " + attrName + " in the = following markup. Nested regions are currently not supported.
" =
+ Spry.Utils.encodeEntities(parent.innerHTML) + "
"); return false; } parent =3D parent.parentNode; } } if (attr.value) { attr =3D node.attributes.getNamedItem("id"); if (!attr || !attr.value) { // The node is missing an id attribute so add one. node.setAttribute("id", "spryregion" + = (++Spry.Data.initRegions.nextUniqueRegionID)); } lastRegionFound =3D node; return true; } else Spry.Debug.reportError(attrName + " attributes require one or more = data set names as values!"); } } catch(e) {} return false; }); var name, dataSets, i; var newRegions =3D []; for (i =3D 0; i < regions.length; i++) { var rgn =3D regions[i]; var isDetailRegion =3D false; // Get the region name. name =3D rgn.attributes.getNamedItem("id").value; attr =3D rgn.attributes.getNamedItem("spry:region"); if (!attr) { attr =3D rgn.attributes.getNamedItem("spry:detailregion"); isDetailRegion =3D true; } if (!attr.value) { Spry.Debug.reportError("spry:region and spry:detailregion attributes = require one or more data set names as values!"); continue; } // Remove the spry:region or spry:detailregion attribute so it doesn't = appear in // the output generated by our processing of the dynamic region. rgn.attributes.removeNamedItem(attr.nodeName); // Remove the hiddenRegionCSS class from the rgn. Spry.Utils.removeClassName(rgn, = Spry.Data.Region.hiddenRegionClassName); // Get the DataSets that should be bound to the region. dataSets =3D Spry.Data.Region.strToDataSetsArray(attr.value); if (!dataSets.length) { Spry.Debug.reportError("spry:region or spry:detailregion attribute = has no data set!"); continue; } var hasBehaviorAttributes =3D false; var hasSpryContent =3D false; var dataStr =3D ""; var parent =3D null; var regionStates =3D {}; var regionStateMap =3D {}; // Check if there are any attributes on the region node that remap // the default states. attr =3D rgn.attributes.getNamedItem("spry:readystate"); if (attr && attr.value) regionStateMap["ready"] =3D attr.value; attr =3D rgn.attributes.getNamedItem("spry:errorstate"); if (attr && attr.value) regionStateMap["error"] =3D attr.value; attr =3D rgn.attributes.getNamedItem("spry:loadingstate"); if (attr && attr.value) regionStateMap["loading"] =3D attr.value; attr =3D rgn.attributes.getNamedItem("spry:expiredstate"); if (attr && attr.value) regionStateMap["expired"] =3D attr.value; // Find all of the processing instruction regions in the region. // Insert comments around the regions we find so we can identify them // easily when tokenizing the region html string. var piRegions =3D Spry.Utils.getNodesByFunc(rgn, function(node) { try { if (node.nodeType =3D=3D 1 /* ELEMENT_NODE */) { var attributes =3D node.attributes; var numPI =3D Spry.Data.Region.PI.orderedInstructions.length; var lastStartComment =3D null; var lastEndComment =3D null; for (var i =3D 0; i < numPI; i++) { var piName =3D Spry.Data.Region.PI.orderedInstructions[i]; var attr =3D attributes.getNamedItem(piName); if (!attr) continue; var piDesc =3D Spry.Data.Region.PI.instructions[piName]; var childrenOnly =3D (node =3D=3D rgn) ? true : = piDesc.childrenOnly; var openTag =3D piDesc.getOpenTag(node, piName); var closeTag =3D piDesc.getCloseTag(node, piName); if (childrenOnly) { var oComment =3D document.createComment(openTag); var cComment =3D document.createComment(closeTag); if (!lastStartComment) node.insertBefore(oComment, node.firstChild); else node.insertBefore(oComment, lastStartComment.nextSibling); lastStartComment =3D oComment; if (!lastEndComment) node.appendChild(cComment); else node.insertBefore(cComment, lastEndComment); lastEndComment =3D cComment; } else { var parent =3D node.parentNode; parent.insertBefore(document.createComment(openTag), node); parent.insertBefore(document.createComment(closeTag), = node.nextSibling); } // If this is a spry:state processing instruction, record the = state name // so we know that we should re-generate the region if we ever see = that state. if (piName =3D=3D "spry:state") regionStates[attr.value] =3D true; node.removeAttribute(piName); } if (Spry.Data.Region.enableBehaviorAttributes) { var bAttrs =3D Spry.Data.Region.behaviorAttrs; for (var behaviorAttrName in bAttrs) { var bAttr =3D attributes.getNamedItem(behaviorAttrName); if (bAttr) { hasBehaviorAttributes =3D true; if (bAttrs[behaviorAttrName].setup) bAttrs[behaviorAttrName].setup(node, bAttr.value); } } } } } catch(e) {} return false; }); // Get the data in the region. dataStr =3D rgn.innerHTML; // Argh! IE has an innerHTML bug where it will remove the quotes = around any // attribute value that it thinks is a single word. This includes = removing quotes // around our data references which is problematic since a single data = reference // can be replaced with multiple words. If we are running in IE, we = have to call // fixUpIEInnerHTML to get around this problem. if (window.ActiveXObject && !Spry.Data.Region.disableIEInnerHTMLFixUp = && dataStr.search(/=3D\{/) !=3D -1) { if (Spry.Data.Region.debug) Spry.Debug.trace("
Performing IE innerHTML fix up of Region: " = + name + "

" + Spry.Utils.encodeEntities(dataStr)); dataStr =3D Spry.Utils.fixUpIEInnerHTML(dataStr); } if (Spry.Data.Region.debug) Spry.Debug.trace("
Region template markup for '" + name + "':

" + Spry.Utils.encodeEntities(dataStr)); if (!hasSpryContent) { // Clear the region. rgn.innerHTML =3D ""; } // Create a Spry.Data.Region object for this region. var region =3D new Spry.Data.Region(rgn, name, isDetailRegion, = dataStr, dataSets, regionStates, regionStateMap, hasBehaviorAttributes); Spry.Data.regionsArray[region.name] =3D region; newRegions.push(region); } for (var i =3D 0; i < newRegions.length; i++) newRegions[i].updateContent(); }; Spry.Data.initRegions.nextUniqueRegionID =3D 0; Spry.Data.updateRegion =3D function(regionName) { if (!regionName || !Spry.Data.regionsArray || = !Spry.Data.regionsArray[regionName]) return; try { Spry.Data.regionsArray[regionName].updateContent(); } catch(e) { Spry.Debug.reportError("Spry.Data.updateRegion(" + = regionName + ") caught an exception: " + e + "\n"); } }; Spry.Data.getRegion =3D function(regionName) { return Spry.Data.regionsArray[regionName]; }; Spry.Data.updateAllRegions =3D function() { if (!Spry.Data.regionsArray) return; for (var regionName in Spry.Data.regionsArray) Spry.Data.updateRegion(regionName); }; Spry.Data.getDataSetByName =3D function(dataSetName) { // Currently, there is no registry of mappings between // data set names and data set objects. For now, the assumption // is that the user has declared and created a data set in the // global space. // // We check for the presence of a global variable with the // specified name, and then make sure that its value is an // object with at least 2 of the data set base functions defined. var ds =3D Spry.Utils.getObjectByName(dataSetName); if (typeof ds !=3D "object" || !ds.getData || !ds.filter) return null; return ds; }; ////////////////////////////////////////////////////////////////////// // // Spry.Data.DataSet // ////////////////////////////////////////////////////////////////////// Spry.Data.DataSet =3D function(options) { Spry.Utils.Notifier.call(this); this.name =3D ""; this.internalID =3D Spry.Data.DataSet.nextDataSetID++; this.curRowID =3D 0; this.data =3D []; this.unfilteredData =3D null; this.dataHash =3D {}; this.columnTypes =3D {}; this.filterFunc =3D null; // non-destructive filter function this.filterDataFunc =3D null; // destructive filter function this.distinctOnLoad =3D false; this.distinctFieldsOnLoad =3D null; this.sortOnLoad =3D null; this.sortOrderOnLoad =3D "ascending"; this.keepSorted =3D false; this.dataWasLoaded =3D false; this.pendingRequest =3D null; this.lastSortColumns =3D []; this.lastSortOrder =3D ""; this.loadIntervalID =3D 0; Spry.Utils.setOptions(this, options); }; Spry.Data.DataSet.prototype =3D new Spry.Utils.Notifier(); Spry.Data.DataSet.prototype.constructor =3D Spry.Data.DataSet; Spry.Data.DataSet.prototype.getData =3D function(unfiltered) { return (unfiltered && this.unfilteredData) ? this.unfilteredData : = this.data; }; Spry.Data.DataSet.prototype.getUnfilteredData =3D function() { // XXX: Deprecated. return this.getData(true); }; Spry.Data.DataSet.prototype.getLoadDataRequestIsPending =3D function() { return this.pendingRequest !=3D null; }; Spry.Data.DataSet.prototype.getDataWasLoaded =3D function() { return this.dataWasLoaded; }; Spry.Data.DataSet.prototype.getValue =3D function(valueName, rowContext) { var result =3D undefined; // If a rowContext is not defined, we default to // using the current row. if (!rowContext) rowContext =3D this.getCurrentRow(); switch(valueName) { case "ds_RowNumber": result =3D this.getRowNumber(rowContext); break; case "ds_RowNumberPlus1": result =3D this.getRowNumber(rowContext) + 1; break; case "ds_RowCount": result =3D this.getRowCount(); break; case "ds_UnfilteredRowCount": result =3D this.getRowCount(true); break; case "ds_CurrentRowNumber": result =3D this.getCurrentRowNumber(); break; case "ds_CurrentRowID": result =3D this.getCurrentRowID(); break; case "ds_EvenOddRow": result =3D (this.getRowNumber(rowContext) % 2) ? = Spry.Data.Region.evenRowClassName : Spry.Data.Region.oddRowClassName; break; case "ds_SortOrder": result =3D this.getSortOrder(); break; case "ds_SortColumn": result =3D this.getSortColumn(); break; default: // We have an unknown value, check to see if the current // row has column value that matches the valueName. if (rowContext) result =3D rowContext[valueName]; break; } return result; }; Spry.Data.DataSet.prototype.setDataFromArray =3D function(arr, = fireSyncLoad) { this.notifyObservers("onPreLoad"); this.unfilteredData =3D null; this.filteredData =3D null; this.data =3D []; this.dataHash =3D {}; var arrLen =3D arr.length; for (var i =3D 0; i < arrLen; i++) { var row =3D arr[i]; if (row.ds_RowID =3D=3D undefined) row.ds_RowID =3D i; this.dataHash[row.ds_RowID] =3D row; this.data.push(row); } this.loadData(fireSyncLoad); }; Spry.Data.DataSet.prototype.loadData =3D function(syncLoad) { // The idea here is that folks using the base class DataSet directly // would change the data in the DataSet manually and then call = loadData() // to fire off an async notifications to say that it was ready for = consumption. // // Firing off data changed notificataions synchronously from this = method // can wreak havoc with complicated master/detail regions that use data = sets // that have master/detail relationships with other data sets. Our data = set // logic already handles async data loading nicely so we use a timer to = fire // off the data changed notification to insure that it happens after = this // function is finished and the JS stack unwinds. // // Other classes that derive from this class and load data = synchronously // inside their loadData() implementation should also fire off an async // notification in this same manner to avoid this same problem. var self =3D this; this.pendingRequest =3D new Object; this.dataWasLoaded =3D false; var loadCallbackFunc =3D function() { self.pendingRequest =3D null; self.dataWasLoaded =3D true; self.applyColumnTypes(); self.disableNotifications(); self.filterAndSortData(); self.enableNotifications(); self.notifyObservers("onPostLoad"); self.notifyObservers("onDataChanged"); }; if (syncLoad) loadCallbackFunc(); else this.pendingRequest.timer =3D setTimeout(loadCallbackFunc, 0); }; Spry.Data.DataSet.prototype.filterAndSortData =3D function() { // If there is a data filter installed, run it. if (this.filterDataFunc) this.filterData(this.filterDataFunc, true); // If the distinct flag was set, run through all the records in the = recordset // and toss out any that are duplicates. if (this.distinctOnLoad) this.distinct(this.distinctFieldsOnLoad); // If sortOnLoad was set, sort the data based on the columns // specified in sortOnLoad. if (this.keepSorted && this.getSortColumn()) this.sort(this.lastSortColumns, this.lastSortOrder); else if (this.sortOnLoad) this.sort(this.sortOnLoad, this.sortOrderOnLoad); // If there is a view filter installed, run it. if (this.filterFunc) this.filter(this.filterFunc, true); // The default "current" row is the first row of the data set. if (this.data && this.data.length > 0) this.curRowID =3D this.data[0]['ds_RowID']; else this.curRowID =3D 0; }; Spry.Data.DataSet.prototype.cancelLoadData =3D function() { if (this.pendingRequest && this.pendingRequest.timer) clearTimeout(this.pendingRequest.timer); this.pendingRequest =3D null; }; Spry.Data.DataSet.prototype.getRowCount =3D function(unfiltered) { var rows =3D this.getData(unfiltered); return rows ? rows.length : 0; }; Spry.Data.DataSet.prototype.getRowByID =3D function(rowID) { if (!this.data) return null; return this.dataHash[rowID]; }; Spry.Data.DataSet.prototype.getRowByRowNumber =3D function(rowNumber, = unfiltered) { var rows =3D this.getData(unfiltered); if (rows && rowNumber >=3D 0 && rowNumber < rows.length) return rows[rowNumber]; return null; }; Spry.Data.DataSet.prototype.getCurrentRow =3D function() { return this.getRowByID(this.curRowID); }; Spry.Data.DataSet.prototype.setCurrentRow =3D function(rowID) { if (this.curRowID =3D=3D rowID) return; var nData =3D { oldRowID: this.curRowID, newRowID: rowID }; this.curRowID =3D rowID; this.notifyObservers("onCurrentRowChanged", nData); }; Spry.Data.DataSet.prototype.getRowNumber =3D function(row, unfiltered) { if (row) { var rows =3D this.getData(unfiltered); if (rows && rows.length) { var numRows =3D rows.length; for (var i =3D 0; i < numRows; i++) { if (rows[i] =3D=3D row) return i; } } } return -1; }; Spry.Data.DataSet.prototype.getCurrentRowNumber =3D function() { return this.getRowNumber(this.getCurrentRow()); }; Spry.Data.DataSet.prototype.getCurrentRowID =3D function() { return this.curRowID; }; Spry.Data.DataSet.prototype.setCurrentRowNumber =3D function(rowNumber) { if (!this.data || rowNumber >=3D this.data.length) { Spry.Debug.trace("Invalid row number: " + rowNumber + "\n"); return; } var rowID =3D this.data[rowNumber]["ds_RowID"]; if (rowID =3D=3D undefined || this.curRowID =3D=3D rowID) return; this.setCurrentRow(rowID); }; Spry.Data.DataSet.prototype.findRowsWithColumnValues =3D = function(valueObj, firstMatchOnly, unfiltered) { var results =3D []; var rows =3D this.getData(unfiltered); if (rows) { var numRows =3D rows.length; for (var i =3D 0; i < numRows; i++) { var row =3D rows[i]; var matched =3D true; for (var colName in valueObj) { if (valueObj[colName] !=3D row[colName]) { matched =3D false; break; } } if (matched) { if (firstMatchOnly) return row; results.push(row); } } } return firstMatchOnly ? null : results; }; Spry.Data.DataSet.prototype.setColumnType =3D function(columnNames, = columnType) { if (columnNames) { if (typeof columnNames =3D=3D "string") columnNames =3D [ columnNames ]; for (var i =3D 0; i < columnNames.length; i++) this.columnTypes[columnNames[i]] =3D columnType; } }; Spry.Data.DataSet.prototype.getColumnType =3D function(columnName) { if (this.columnTypes[columnName]) return this.columnTypes[columnName]; return "string"; }; Spry.Data.DataSet.prototype.applyColumnTypes =3D function() { var rows =3D this.getData(true); var numRows =3D rows.length; var colNames =3D []; if (numRows < 1) return; for (var cname in this.columnTypes) { var ctype =3D this.columnTypes[cname]; if (ctype !=3D "string") { for (var i =3D 0; i < numRows; i++) { var row =3D rows[i]; var val =3D row[cname]; if (val !=3D undefined) { if (ctype =3D=3D "number") row[cname] =3D new Number(val); else if (ctype =3D=3D "html") row[cname] =3D Spry.Utils.decodeEntities(val); } } } } }; Spry.Data.DataSet.prototype.distinct =3D function(columnNames) { if (this.data) { var oldData =3D this.data; this.data =3D []; this.dataHash =3D {}; var dataChanged =3D false; var alreadySeenHash =3D {}; var i =3D 0; var keys =3D []; if (typeof columnNames =3D=3D "string") keys =3D [columnNames]; else if (columnNames) keys =3D columnNames; else for (var recField in oldData[0]) keys[i++] =3D recField; for (var i =3D 0; i < oldData.length; i++) { var rec =3D oldData[i]; var hashStr =3D ""; for (var j=3D0; j < keys.length; j++) { recField =3D keys[j]; if (recField !=3D "ds_RowID") { if (hashStr) hashStr +=3D ","; hashStr +=3D recField + ":" + "\"" + rec[recField] + "\""; } } if (!alreadySeenHash[hashStr]) { this.data.push(rec); this.dataHash[rec['ds_RowID']] =3D rec; alreadySeenHash[hashStr] =3D true; } else dataChanged =3D true; } if (dataChanged) this.notifyObservers('onDataChanged'); } }; Spry.Data.DataSet.prototype.getSortColumn =3D function() { return (this.lastSortColumns && this.lastSortColumns.length > 0) ? = this.lastSortColumns[0] : ""; }; Spry.Data.DataSet.prototype.getSortOrder =3D function() { return this.lastSortOrder ? this.lastSortOrder : ""; }; Spry.Data.DataSet.prototype.sort =3D function(columnNames, sortOrder) { // columnNames can be either the name of a column to // sort on, or an array of column names, but it can't be // null/undefined. if (!columnNames) return; // If only one column name was specified for sorting, do a // secondary sort on ds_RowID so we get a stable sort order. if (typeof columnNames =3D=3D "string") columnNames =3D [ columnNames, "ds_RowID" ]; else if (columnNames.length < 2 && columnNames[0] !=3D "ds_RowID") columnNames.push("ds_RowID"); if (!sortOrder) sortOrder =3D "toggle"; if (sortOrder =3D=3D "toggle") { if (this.lastSortColumns.length > 0 && this.lastSortColumns[0] =3D=3D = columnNames[0] && this.lastSortOrder =3D=3D "ascending") sortOrder =3D "descending"; else sortOrder =3D "ascending"; } if (sortOrder !=3D "ascending" && sortOrder !=3D "descending") { Spry.Debug.reportError("Invalid sort order type specified: " + = sortOrder + "\n"); return; } var nData =3D { oldSortColumns: this.lastSortColumns, oldSortOrder: this.lastSortOrder, newSortColumns: columnNames, newSortOrder: sortOrder }; this.notifyObservers("onPreSort", nData); var cname =3D columnNames[columnNames.length - 1]; var sortfunc =3D Spry.Data.DataSet.prototype.sort.getSortFunc(cname, = this.getColumnType(cname), sortOrder); for (var i =3D columnNames.length - 2; i >=3D 0; i--) { cname =3D columnNames[i]; sortfunc =3D = Spry.Data.DataSet.prototype.sort.buildSecondarySortFunc(Spry.Data.DataSet= .prototype.sort.getSortFunc(cname, this.getColumnType(cname), = sortOrder), sortfunc); } if (this.unfilteredData) { this.unfilteredData.sort(sortfunc); if (this.filterFunc) this.filter(this.filterFunc, true); } else this.data.sort(sortfunc); this.lastSortColumns =3D columnNames.slice(0); // Copy the array. this.lastSortOrder =3D sortOrder; this.notifyObservers("onPostSort", nData); }; Spry.Data.DataSet.prototype.sort.getSortFunc =3D function(prop, type, = order) { var sortfunc =3D null; if (type =3D=3D "number") { if (order =3D=3D "ascending") sortfunc =3D function(a, b) { a =3D a[prop]; b =3D b[prop]; if (a =3D=3D undefined || b =3D=3D undefined) return (a =3D=3D b) ? 0 : (a ? 1 : -1); return a-b; }; else // order =3D=3D "descending" sortfunc =3D function(a, b) { a =3D a[prop]; b =3D b[prop]; if (a =3D=3D undefined || b =3D=3D undefined) return (a =3D=3D b) ? 0 : (a ? -1 : 1); return b-a; }; } else if (type =3D=3D "date") { if (order =3D=3D "ascending") sortfunc =3D function(a, b) { var dA =3D a[prop]; var dB =3D b[prop]; dA =3D dA ? (new Date(dA)) : 0; dB =3D dB ? (new Date(dB)) : 0; return dA - dB; }; else // order =3D=3D "descending" sortfunc =3D function(a, b) { var dA =3D a[prop]; var dB =3D b[prop]; dA =3D dA ? (new Date(dA)) : 0; dB =3D dB ? (new Date(dB)) : 0; return dB - dA; }; } else // type =3D=3D "string" || type =3D=3D "html" { if (order =3D=3D "ascending") sortfunc =3D function(a, b){ a =3D a[prop]; b =3D b[prop]; if (a =3D=3D undefined || b =3D=3D undefined) return (a =3D=3D b) ? 0 : (a ? 1 : -1); var tA =3D a.toString(); var tB =3D b.toString(); var tA_l =3D tA.toLowerCase(); var tB_l =3D tB.toLowerCase(); var min_len =3D tA.length > tB.length ? tB.length : tA.length; for (var i=3D0; i < min_len; i++) { var a_l_c =3D tA_l.charAt(i); var b_l_c =3D tB_l.charAt(i); var a_c =3D tA.charAt(i); var b_c =3D tB.charAt(i); if (a_l_c > b_l_c) return 1; else if (a_l_c < b_l_c) return -1; else if (a_c > b_c) return 1; else if (a_c < b_c) return -1; } if(tA.length =3D=3D tB.length) return 0; else if (tA.length > tB.length) return 1; return -1; }; else // order =3D=3D "descending" sortfunc =3D function(a, b){ a =3D a[prop]; b =3D b[prop]; if (a =3D=3D undefined || b =3D=3D undefined) return (a =3D=3D b) ? 0 : (a ? -1 : 1); var tA =3D a.toString(); var tB =3D b.toString(); var tA_l =3D tA.toLowerCase(); var tB_l =3D tB.toLowerCase(); var min_len =3D tA.length > tB.length ? tB.length : tA.length; for (var i=3D0; i < min_len; i++) { var a_l_c =3D tA_l.charAt(i); var b_l_c =3D tB_l.charAt(i); var a_c =3D tA.charAt(i); var b_c =3D tB.charAt(i); if (a_l_c > b_l_c) return -1; else if (a_l_c < b_l_c) return 1; else if (a_c > b_c) return -1; else if (a_c < b_c) return 1; } if(tA.length =3D=3D tB.length) return 0; else if (tA.length > tB.length) return -1; return 1; }; } return sortfunc; }; Spry.Data.DataSet.prototype.sort.buildSecondarySortFunc =3D = function(funcA, funcB) { return function(a, b) { var ret =3D funcA(a, b); if (ret =3D=3D 0) ret =3D funcB(a, b); return ret; }; }; Spry.Data.DataSet.prototype.filterData =3D function(filterFunc, = filterOnly) { // This is a destructive filter function. var dataChanged =3D false; if (!filterFunc) { // Caller wants to remove the filter. this.filterDataFunc =3D null; dataChanged =3D true; } else { this.filterDataFunc =3D filterFunc; if (this.dataWasLoaded && ((this.unfilteredData && = this.unfilteredData.length) || (this.data && this.data.length))) { if (this.unfilteredData) { this.data =3D this.unfilteredData; this.unfilteredData =3D null; } var oldData =3D this.data; this.data =3D []; this.dataHash =3D {}; for (var i =3D 0; i < oldData.length; i++) { var newRow =3D filterFunc(this, oldData[i], i); if (newRow) { this.data.push(newRow); this.dataHash[newRow["ds_RowID"]] =3D newRow; } } dataChanged =3D true; } } if (dataChanged) { if (!filterOnly) { this.disableNotifications(); if (this.filterFunc) this.filter(this.filterFunc, true); this.enableNotifications(); } this.notifyObservers("onDataChanged"); } }; Spry.Data.DataSet.prototype.filter =3D function(filterFunc, filterOnly) { // This is a non-destructive filter function. var dataChanged =3D false; if (!filterFunc) { if (this.filterFunc && this.unfilteredData) { // Caller wants to remove the filter. Restore the unfiltered // data and trigger a data changed notification. this.data =3D this.unfilteredData; this.unfilteredData =3D null; this.filterFunc =3D null; dataChanged =3D true; } } else { this.filterFunc =3D filterFunc; if (this.dataWasLoaded && (this.unfilteredData || (this.data && = this.data.length))) { if (!this.unfilteredData) this.unfilteredData =3D this.data; var udata =3D this.unfilteredData; this.data =3D []; for (var i =3D 0; i < udata.length; i++) { var newRow =3D filterFunc(this, udata[i], i); if (newRow) this.data.push(newRow); } dataChanged =3D true; } } if (dataChanged) this.notifyObservers("onDataChanged"); }; Spry.Data.DataSet.prototype.startLoadInterval =3D function(interval) { this.stopLoadInterval(); if (interval > 0) { var self =3D this; this.loadInterval =3D interval; this.loadIntervalID =3D setInterval(function() { self.loadData(); }, = interval); } }; Spry.Data.DataSet.prototype.stopLoadInterval =3D function() { if (this.loadIntervalID) clearInterval(this.loadIntervalID); this.loadInterval =3D 0; this.loadIntervalID =3D null; }; Spry.Data.DataSet.nextDataSetID =3D 0; ////////////////////////////////////////////////////////////////////// // // Spry.Data.HTTPSourceDataSet // base class for any DataSet that uses external // ////////////////////////////////////////////////////////////////////// Spry.Data.HTTPSourceDataSet =3D function(dataSetURL, dataSetOptions) { // Call the constructor for our DataSet base class so that // our base class properties get defined. We'll call setOptions // manually after we set up our HTTPSourceDataSet properties. Spry.Data.DataSet.call(this); // HTTPSourceDataSet Properties: this.url =3D dataSetURL; this.dataSetsForDataRefStrings =3D new Array; this.hasDataRefStrings =3D false; this.useCache =3D true; this.setRequestInfo(dataSetOptions, true); Spry.Utils.setOptions(this, dataSetOptions, true); this.recalculateDataSetDependencies(); if (this.loadInterval > 0) this.startLoadInterval(this.loadInterval); }; // End of Spry.Data.HTTPSourceDataSet() constructor. Spry.Data.HTTPSourceDataSet.prototype =3D new Spry.Data.DataSet(); Spry.Data.HTTPSourceDataSet.prototype.constructor =3D = Spry.Data.HTTPSourceDataSet; Spry.Data.HTTPSourceDataSet.prototype.setRequestInfo =3D = function(requestInfo, undefineRequestProps) { // Create a loadURL request object to store any load options // the caller specified. We'll fill in the URL at the last minute // before we make the actual load request because our URL needs // to be processed at the last possible minute in case it contains // data references. this.requestInfo =3D new Spry.Utils.loadURL.Request(); this.requestInfo.extractRequestOptions(requestInfo, = undefineRequestProps); // If the caller wants to use "POST" to fetch the data, but didn't // provide the content type, default to x-www-form-urlencoded. if (this.requestInfo.method =3D=3D "POST") { if (!this.requestInfo.headers) this.requestInfo.headers =3D {}; if (!this.requestInfo.headers['Content-Type']) this.requestInfo.headers['Content-Type'] =3D = "application/x-www-form-urlencoded; charset=3DUTF-8"; } }; Spry.Data.HTTPSourceDataSet.prototype.recalculateDataSetDependencies =3D = function() { this.hasDataRefStrings =3D false; // Clear all old callbacks that may have been registered. var i =3D 0; for (i =3D 0; i < this.dataSetsForDataRefStrings.length; i++) { var ds =3D this.dataSetsForDataRefStrings[i]; if (ds) ds.removeObserver(this); } // Now run through the strings that may contain data references and = figure // out what data sets they require. Note that the data references in = these // strings must be fully qualified with a data set name. (ex: = {dsDataSetName::columnName}) this.dataSetsForDataRefStrings =3D new Array(); var regionStrs =3D this.getDataRefStrings(); var dsCount =3D 0; for (var n =3D 0; n < regionStrs.length; n++) { var tokens =3D Spry.Data.Region.getTokensFromStr(regionStrs[n]); for (i =3D 0; tokens && i < tokens.length; i++) { if (tokens[i].search(/{[^}:]+::[^}]+}/) !=3D -1) { var dsName =3D tokens[i].replace(/^\{|::.*\}/g, ""); var ds =3D null; if (!this.dataSetsForDataRefStrings[dsName]) { ds =3D Spry.Data.getDataSetByName(dsName); if (dsName && ds) { // The dataSetsForDataRefStrings array serves as both an // array of data sets and a hash lookup by name. this.dataSetsForDataRefStrings[dsName] =3D ds; this.dataSetsForDataRefStrings[dsCount++] =3D ds; this.hasDataRefStrings =3D true; } } } } } // Set up observers on any data sets our URL depends on. for (i =3D 0; i < this.dataSetsForDataRefStrings.length; i++) { var ds =3D this.dataSetsForDataRefStrings[i]; ds.addObserver(this); } }; Spry.Data.HTTPSourceDataSet.prototype.getDataRefStrings =3D function() { var strArr =3D []; if (this.url) strArr.push(this.url); if (this.requestInfo && this.requestInfo.postData) = strArr.push(this.requestInfo.postData); return strArr; }; Spry.Data.HTTPSourceDataSet.prototype.attemptLoadData =3D function() { // We only want to trigger a load when all of our data sets have data! for (var i =3D 0; i < this.dataSetsForDataRefStrings.length; i++) { var ds =3D this.dataSetsForDataRefStrings[i]; if (ds.getLoadDataRequestIsPending() || !ds.getDataWasLoaded()) return; } this.loadData(); }; Spry.Data.HTTPSourceDataSet.prototype.onCurrentRowChanged =3D = function(ds, data) { this.attemptLoadData(); }; Spry.Data.HTTPSourceDataSet.prototype.onPostSort =3D function(ds, data) { this.attemptLoadData(); }; Spry.Data.HTTPSourceDataSet.prototype.onDataChanged =3D function(ds, = data) { this.attemptLoadData(); }; Spry.Data.HTTPSourceDataSet.prototype.loadData =3D function() { if (!this.url) return; this.cancelLoadData(); var url =3D this.url; var postData =3D this.requestInfo.postData; if (this.hasDataRefStrings) { var allDataSetsReady =3D true; for (var i =3D 0; i < this.dataSetsForDataRefStrings.length; i++) { var ds =3D this.dataSetsForDataRefStrings[i]; if (ds.getLoadDataRequestIsPending()) allDataSetsReady =3D false; else if (!ds.getDataWasLoaded()) { // Kick off the load of this data set! ds.loadData(); allDataSetsReady =3D false; } } // If our data sets aren't ready, just return. We'll // get called back to load our data when they are all // done. if (!allDataSetsReady) return; url =3D Spry.Data.Region.processDataRefString(null, this.url, = this.dataSetsForDataRefStrings); if (!url) return; if (postData && (typeof postData) =3D=3D "string") postData =3D Spry.Data.Region.processDataRefString(null, postData, = this.dataSetsForDataRefStrings); } this.notifyObservers("onPreLoad"); this.data =3D null; this.dataWasLoaded =3D false; this.unfilteredData =3D null; this.dataHash =3D null; this.curRowID =3D 0; // At this point the url should've been processed if it contained any // data references. Set the url of the requestInfo structure and pass = it // to LoadManager.loadData(). var req =3D this.requestInfo.clone(); req.url =3D url; req.postData =3D postData; this.pendingRequest =3D new Object; this.pendingRequest.data =3D = Spry.Data.HTTPSourceDataSet.LoadManager.loadData(req, this, = this.useCache); }; Spry.Data.HTTPSourceDataSet.prototype.cancelLoadData =3D function() { if (this.pendingRequest) { = Spry.Data.HTTPSourceDataSet.LoadManager.cancelLoadData(this.pendingReques= t.data, this); this.pendingRequest =3D null; } }; Spry.Data.HTTPSourceDataSet.prototype.getURL =3D function() { return = this.url; }; Spry.Data.HTTPSourceDataSet.prototype.setURL =3D function(url, = requestOptions) { if (this.url =3D=3D url) { // The urls match so we may not have to do anything, but // before we bail early, check to see if the method and // postData that was last used was the same. If there is a // difference, we need to process the new URL. if (!requestOptions || (this.requestInfo.method =3D=3D = requestOptions.method && (requestOptions.method !=3D "POST" || = this.requestInfo.postData =3D=3D requestOptions.postData))) return; } this.url =3D url; this.setRequestInfo(requestOptions); this.cancelLoadData(); this.recalculateDataSetDependencies(); this.dataWasLoaded =3D false; }; Spry.Data.HTTPSourceDataSet.prototype.setDataFromDoc =3D = function(rawDataDoc) { this.pendingRequest =3D null; this.loadDataIntoDataSet(rawDataDoc); this.applyColumnTypes(); this.disableNotifications(); this.filterAndSortData(); this.enableNotifications(); this.notifyObservers("onPostLoad"); this.notifyObservers("onDataChanged"); }; Spry.Data.HTTPSourceDataSet.prototype.loadDataIntoDataSet =3D = function(rawDataDoc) { // this method needs to be overwritten by the descendent classes; // internal data structures (data & dataHash) have to load data from = the source document (ResponseText | ResponseDoc); this.dataHash =3D new Object; this.data =3D new Array; this.dataWasLoaded =3D true; }; Spry.Data.HTTPSourceDataSet.prototype.xhRequestProcessor =3D = function(xhRequest) { // This method needs to be overwritten by the descendent classes if = other objects (like responseXML) // are going to be used as a data source // This implementation returns the responseText from xhRequest var resp =3D xhRequest.responseText; if (xhRequest.status =3D=3D 200 || xhRequest.status =3D=3D 0) return resp; return null; }; Spry.Data.HTTPSourceDataSet.prototype.sessionExpiredChecker =3D = function(req) { if (req.xhRequest.responseText =3D=3D 'session expired') return true; return false; }; Spry.Data.HTTPSourceDataSet.prototype.setSessionExpiredChecker =3D = function(checker) { this.sessionExpiredChecker =3D checker; }; Spry.Data.HTTPSourceDataSet.prototype.onRequestResponse =3D = function(cachedRequest, req) { this.setDataFromDoc(cachedRequest.rawData); }; Spry.Data.HTTPSourceDataSet.prototype.onRequestError =3D = function(cachedRequest, req) { this.notifyObservers("onLoadError", req); // = Spry.Debug.reportError("Spry.Data.HTTPSourceDataSet.LoadManager.CachedReq= uest.loadDataCallback(" + req.xhRequest.status + ") failed to load: " + = req.url + "\n"); }; Spry.Data.HTTPSourceDataSet.prototype.onRequestSessionExpired =3D = function(cachedRequest, req) { this.notifyObservers("onSessionExpired", req); = //Spry.Debug.reportError("Spry.Data.HTTPSourceDataSet.LoadManager.CachedR= equest.loadDataCallback(" + req.xhRequest.status + ") failed to load: " = + req.url + "\n"); }; Spry.Data.HTTPSourceDataSet.LoadManager =3D {}; Spry.Data.HTTPSourceDataSet.LoadManager.cache =3D []; Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest =3D = function(reqInfo, xhRequestProcessor, sessionExpiredChecker) { Spry.Utils.Notifier.call(this); this.reqInfo =3D reqInfo; this.rawData =3D null; this.timer =3D null; this.state =3D = Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.NOT_LOADED; this.xhRequestProcessor =3D xhRequestProcessor; this.sessionExpiredChecker =3D sessionExpiredChecker; }; Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.prototype =3D new = Spry.Utils.Notifier(); Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.prototype.construct= or =3D Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest; Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.NOT_LOADED = =3D 1; Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_REQUESTED = =3D 2; Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_FAILED = =3D 3; Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_SUCCESSFUL = =3D 4; Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.prototype.loadDataC= allback =3D function(req) { if (req.xhRequest.readyState !=3D 4) return; var rawData =3D null; if (this.xhRequestProcessor) rawData =3D = this.xhRequestProcessor(req.xhRequest); if (this.sessionExpiredChecker) { Spry.Utils.setOptions(req, {'rawData': rawData}, false); if (this.sessionExpiredChecker(req)) { this.state =3D = Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_FAILED; this.notifyObservers("onRequestSessionExpired", req); this.observers.length =3D 0; return; } } if (!rawData) { this.state =3D = Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_FAILED; this.notifyObservers("onRequestError", req); this.observers.length =3D 0; // Clear the observers list. return; } this.rawData =3D rawData; this.state =3D = Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_SUCCESSFUL; // Notify all of the cached request's observers! this.notifyObservers("onRequestResponse", req); // Clear the observers list. this.observers.length =3D 0; }; Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.prototype.loadData = =3D function() { // IE will synchronously fire our loadDataCallback() during the call // to an async Spry.Utils.loadURL() if the data for the url is already // in the browser's local cache. This can wreak havoc with complicated = master/detail // regions that use data sets that have master/detail relationships = with other // data sets. Our data set logic already handles async data loading = nicely so we // use a timer to fire off the async Spry.Utils.loadURL() call to = insure that any // data loading happens asynchronously after this function is finished. var self =3D this; this.cancelLoadData(); this.rawData =3D null; this.state =3D = Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_REQUESTED; var reqInfo =3D this.reqInfo.clone(); reqInfo.successCallback =3D function(req) { self.loadDataCallback(req); = }; reqInfo.errorCallback =3D reqInfo.successCallback; this.timer =3D setTimeout(function() { self.timer =3D null; Spry.Utils.loadURL(reqInfo.method, reqInfo.url, reqInfo.async, = reqInfo.successCallback, reqInfo); }, 0); }; Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.prototype.cancelLoa= dData =3D function() { if (this.state =3D=3D = Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_REQUESTED) { if (this.timer) { this.timer.clearTimeout(); this.timer =3D null; } this.rawData =3D null; this.state =3D = Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.NOT_LOADED; } }; Spry.Data.HTTPSourceDataSet.LoadManager.getCacheKey =3D = function(reqInfo) { return reqInfo.method + "::" + reqInfo.url + "::" + reqInfo.postData + = "::" + reqInfo.username; }; Spry.Data.HTTPSourceDataSet.LoadManager.loadData =3D function(reqInfo, = ds, useCache) { if (!reqInfo) return null; var cacheObj =3D null; var cacheKey =3D null; if (useCache) { cacheKey =3D = Spry.Data.HTTPSourceDataSet.LoadManager.getCacheKey(reqInfo); cacheObj =3D Spry.Data.HTTPSourceDataSet.LoadManager.cache[cacheKey]; } if (cacheObj) { if (cacheObj.state =3D=3D = Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_REQUESTED) { if (ds) cacheObj.addObserver(ds); return cacheObj; } else if (cacheObj.state =3D=3D = Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest.LOAD_SUCCESSFUL) { // Data is already cached so if we have a data set, trigger an async = call // that tells it to load its data. if (ds) setTimeout(function() { ds.setDataFromDoc(cacheObj.rawData); }, 0); return cacheObj; } } // We're either loading this url for the first time, or an error = occurred when // we last tried to load it, or the caller requested a forced load. if (!cacheObj) { cacheObj =3D new = Spry.Data.HTTPSourceDataSet.LoadManager.CachedRequest(reqInfo, (ds ? = ds.xhRequestProcessor : null), (ds ? ds.sessionExpiredChecker : null)); if (useCache) { Spry.Data.HTTPSourceDataSet.LoadManager.cache[cacheKey] =3D cacheObj; // Add an observer that will remove the cacheObj from the cache // if there is a load request failure. cacheObj.addObserver({ onRequestError: function() { = Spry.Data.HTTPSourceDataSet.LoadManager.cache[cacheKey] =3D undefined; = }}); } } if (ds) cacheObj.addObserver(ds); cacheObj.loadData(); return cacheObj; }; Spry.Data.HTTPSourceDataSet.LoadManager.cancelLoadData =3D = function(cacheObj, ds) { if (cacheObj) { if (ds) cacheObj.removeObserver(ds); else cacheObj.cancelLoadData(); } }; ////////////////////////////////////////////////////////////////////// // // Spry.Data.XMLDataSet // ////////////////////////////////////////////////////////////////////// Spry.Data.XMLDataSet =3D function(dataSetURL, dataSetPath, = dataSetOptions) { // Call the constructor for our HTTPSourceDataSet base class so that // our base class properties get defined. this.xpath =3D dataSetPath; this.doc =3D null; this.subPaths =3D []; this.entityEncodeStrings =3D true; Spry.Data.HTTPSourceDataSet.call(this, dataSetURL, dataSetOptions); // Callers are allowed to pass either a string, an object or an array = of // strings and/or objects for the 'subPaths' option, so make sure we = normalize // the subPaths value to be an array. var jwType =3D typeof this.subPaths; if (jwType =3D=3D "string" || (jwType =3D=3D "object" && = this.subPaths.constructor !=3D Array)) this.subPaths =3D [ this.subPaths ]; }; // End of Spry.Data.XMLDataSet() constructor. Spry.Data.XMLDataSet.prototype =3D new Spry.Data.HTTPSourceDataSet(); Spry.Data.XMLDataSet.prototype.constructor =3D Spry.Data.XMLDataSet; Spry.Data.XMLDataSet.prototype.getDataRefStrings =3D function() { var strArr =3D []; if (this.url) strArr.push(this.url); if (this.xpath) strArr.push(this.xpath); if (this.requestInfo && this.requestInfo.postData) = strArr.push(this.requestInfo.postData); return strArr; }; Spry.Data.XMLDataSet.prototype.getDocument =3D function() { return = this.doc; }; Spry.Data.XMLDataSet.prototype.getXPath =3D function() { return = this.xpath; }; Spry.Data.XMLDataSet.prototype.setXPath =3D function(path) { if (this.xpath !=3D path) { this.xpath =3D path; if (this.dataWasLoaded && this.doc) { this.notifyObservers("onPreLoad"); this.setDataFromDoc(this.doc); } } }; Spry.Data.XMLDataSet.nodeContainsElementNode =3D function(node) { if (node) { node =3D node.firstChild; while (node) { if (node.nodeType =3D=3D 1 /* Node.ELEMENT_NODE */) return true; node =3D node.nextSibling; } } return false; }; Spry.Data.XMLDataSet.getNodeText =3D function(node, encodeText, = encodeCData) { var txt =3D ""; if (!node) return; try { var child =3D node.firstChild; while (child) { try { if (child.nodeType =3D=3D 3 /* TEXT_NODE */) txt +=3D encodeText ? Spry.Utils.encodeEntities(child.data) : = child.data; else if (child.nodeType =3D=3D 4 /* CDATA_SECTION_NODE */) txt +=3D encodeCData ? Spry.Utils.encodeEntities(child.data) : = child.data; } catch (e) { = Spry.Debug.reportError("Spry.Data.XMLDataSet.getNodeText() exception = caught: " + e + "\n"); } child =3D child.nextSibling; } } catch (e) { Spry.Debug.reportError("Spry.Data.XMLDataSet.getNodeText() = exception caught: " + e + "\n"); } return txt; }; Spry.Data.XMLDataSet.createObjectForNode =3D function(node, encodeText, = encodeCData) { if (!node) return null; var obj =3D new Object(); var i =3D 0; var attr =3D null; try { for (i =3D 0; i < node.attributes.length; i++) { attr =3D node.attributes[i]; if (attr && attr.nodeType =3D=3D 2 /* Node.ATTRIBUTE_NODE */) obj["@" + attr.name] =3D attr.value; } } catch (e) { Spry.Debug.reportError("Spry.Data.XMLDataSet.createObjectForNode() = caught exception while accessing attributes: " + e + "\n"); } var child =3D node.firstChild; if (child && !child.nextSibling && child.nodeType !=3D 1 /* = Node.ELEMENT_NODE */) { // We have a single child and it's not an element. It must // be the text value for this node. Add it to the record set and // give it the column the same name as the node. obj[node.nodeName] =3D Spry.Data.XMLDataSet.getNodeText(node, = encodeText, encodeCData); } while (child) { // Add the text value for each child element. Note that // We skip elements that have element children (sub-elements) // because we don't handle multi-level data sets right now. if (child.nodeType =3D=3D 1 /* Node.ELEMENT_NODE */) { if (!Spry.Data.XMLDataSet.nodeContainsElementNode(child)) { obj[child.nodeName] =3D Spry.Data.XMLDataSet.getNodeText(child, = encodeText, encodeCData); // Now add properties for any attributes on the child. The property // name will be of the form "/@". try { var namePrefix =3D child.nodeName + "/@"; for (i =3D 0; i < child.attributes.length; i++) { attr =3D child.attributes[i]; if (attr && attr.nodeType =3D=3D 2 /* Node.ATTRIBUTE_NODE */) obj[namePrefix + attr.name] =3D attr.value; } } catch (e) { Spry.Debug.reportError("Spry.Data.XMLDataSet.createObjectForNode() = caught exception while accessing attributes: " + e + "\n"); } } } child =3D child.nextSibling; } return obj; }; Spry.Data.XMLDataSet.getRecordSetFromXMLDoc =3D function(xmlDoc, path, = suppressColumns, entityEncodeStrings) { if (!xmlDoc || !path) return null; var recordSet =3D new Object(); recordSet.xmlDoc =3D xmlDoc; recordSet.xmlPath =3D path; recordSet.dataHash =3D new Object; recordSet.data =3D new Array; recordSet.getData =3D function() { return this.data; }; // Use the XPath library to find the nodes that will // make up our data set. The result should be an array // of subtrees that we need to flatten. var ctx =3D new ExprContext(xmlDoc); var pathExpr =3D xpathParse(path); var e =3D pathExpr.evaluate(ctx); // XXX: Note that we should check the result type of the evaluation // just in case it's a boolean, string, or number value instead of // a node set. var nodeArray =3D e.nodeSetValue(); var isDOMNodeArray =3D true; if (nodeArray && nodeArray.length > 0) isDOMNodeArray =3D nodeArray[0].nodeType !=3D 2 /* Node.ATTRIBUTE_NODE = */; var nextID =3D 0; var encodeText =3D true; var encodeCData =3D false; if (typeof entityEncodeStrings =3D=3D "boolean") encodeText =3D encodeCData =3D entityEncodeStrings; // We now have the set of nodes that make up our data set // so process each one. for (var i =3D 0; i < nodeArray.length; i++) { var rowObj =3D null; if (suppressColumns) rowObj =3D new Object; else { if (isDOMNodeArray) rowObj =3D Spry.Data.XMLDataSet.createObjectForNode(nodeArray[i], = encodeText, encodeCData); else // Must be a Node.ATTRIBUTE_NODE array. { rowObj =3D new Object; rowObj["@" + nodeArray[i].name] =3D nodeArray[i].value; } } if (rowObj) { // We want to make sure that every row has a unique ID and since we // we don't know which column, if any, in this recordSet is a unique // identifier, we generate a unique ID ourselves and store it under // the ds_RowID column in the row object. rowObj['ds_RowID'] =3D nextID++; rowObj['ds_XMLNode'] =3D nodeArray[i]; recordSet.dataHash[rowObj['ds_RowID']] =3D rowObj; recordSet.data.push(rowObj); } } return recordSet; }; Spry.Data.XMLDataSet.PathNode =3D function(path) { this.path =3D path; this.subPaths =3D []; this.xpath =3D ""; }; Spry.Data.XMLDataSet.PathNode.prototype.addSubPath =3D function(path) { var node =3D this.findSubPath(path); if (!node) { node =3D new Spry.Data.XMLDataSet.PathNode(path); this.subPaths.push(node); } return node; }; Spry.Data.XMLDataSet.PathNode.prototype.findSubPath =3D function(path) { var numSubPaths =3D this.subPaths.length; for (var i =3D 0; i < numSubPaths; i++) { var subPath =3D this.subPaths[i]; if (path =3D=3D subPath.path) return subPath; } return null; }; Spry.Data.XMLDataSet.PathNode.prototype.consolidate =3D function() { // This method recursively runs through the path tree and // tries to flatten any nodes that have no XPath and one child. // The flattening involves merging the parent's path component // with its child path component. var numSubPaths =3D this.subPaths.length; if (!this.xpath && numSubPaths =3D=3D 1) { // Consolidate! var subPath =3D this.subPaths[0]; this.path +=3D ((subPath[0] !=3D "/") ? "/" : "") + subPath.path; this.xpath =3D subPath.xpath; this.subPaths =3D subPath.subPaths; this.consolidate(); return; } for (var i =3D 0; i < numSubPaths; i++) this.subPaths[i].consolidate(); }; /* This method is commented out so that it gets stripped when the file is minimized. Please do not remove this from the full version of the file! It is needed for debugging. Spry.Data.XMLDataSet.PathNode.prototype.dump =3D function(indentStr) { var didPre =3D false; var result =3D ""; if (!indentStr) { indentStr =3D ""; didPre =3D true; result =3D "
";
	}
	result +=3D indentStr + "" + this.path + "" + =
(this.xpath ? " -- xpath(" + Spry.Utils.encodeEntities(this.xpath) + =
")" : "") + "\n";
	var numSubPaths =3D this.subPaths.length;
	indentStr +=3D "    ";
	for (var i =3D 0; i < numSubPaths; i++)
		result +=3D this.subPaths[i].dump(indentStr);
	if (didPre)
		result +=3D "
"; return result; }; */ Spry.Data.XMLDataSet.prototype.convertXPathsToPathTree =3D = function(xpathArray) { var xpaLen =3D xpathArray.length; var root =3D new Spry.Data.XMLDataSet.PathNode(""); for (var i =3D 0; i < xpaLen; i++) { // Convert any "//" in the XPath to our placeholder value. // We need to do that so they don't get removed when we split the // path into components. var xpath =3D xpathArray[i]; var cleanXPath =3D xpath.replace(/\/\//g, "/__SPRYDS__"); cleanXPath =3D cleanXPath.replace(/^\//, ""); // Strip any leading = slash. var pathItems =3D cleanXPath.split(/\//); var pathItemsLen =3D pathItems.length; // Now add each path component to our tree. var node =3D root; for (var j =3D 0; j < pathItemsLen; j++) { // If this path component has a placeholder in it, convert it // back to a double slash. var path =3D pathItems[j].replace(/__SPRYDS__/, "//"); node =3D node.addSubPath(path); } // Now add the full xpath to the node that represents the // last path component in our path. node.xpath =3D xpath; } // Now that we have a tree of nodes. Tell the root to consolidate // itself so we get a tree that is as flat as possible. This reduces // the number of XPaths we will have to flatten. root.consolidate(); return root; }; Spry.Data.XMLDataSet.prototype.flattenSubPaths =3D function(rs, = subPaths) { if (!rs || !subPaths) return; var numSubPaths =3D subPaths.length; if (numSubPaths < 1) return; var data =3D rs.data; var dataHash =3D {}; // Convert all of the templated subPaths to XPaths with real values. // We also need a "cleaned" version of the XPath which contains no // expressions in it, so that we can pre-pend it to the column names // of any nested data we find. var xpathArray =3D []; var cleanedXPathArray =3D []; for (var i =3D 0; i < numSubPaths; i++) { // The elements of the subPaths array can be XPath strings, // or objects that describe a path with nested sub-paths below // it, so make sure we properly extract out the XPath to use. var subPath =3D subPaths[i]; if (typeof subPath =3D=3D "object") subPath =3D subPath.path; if (!subPath) subPath =3D ""; // Convert any data references in the XPath to real values! xpathArray[i] =3D Spry.Data.Region.processDataRefString(null, subPath, = this.dataSetsForDataRefStrings); // Create a clean version of the XPath by stripping out any // expressions it may contain. cleanedXPathArray[i] =3D xpathArray[i].replace(/\[.*\]/g, ""); } // For each row of the base record set passed in, generate a flattened // recordset from each subPath, and then join the results with the base // row. The row from the base data set will be duplicated to match the // number of rows matched by the subPath. The results are then merged. var row; var numRows =3D data.length; var newData =3D []; // Iterate over each row of the base record set. for (var i =3D 0; i < numRows; i++) { row =3D data[i]; var newRows =3D [ row ]; // Iterate over every subPath passed into this function. for (var j =3D 0; j < numSubPaths; j++) { // Search for all nodes that match the given XPath underneath // the XML node for the base row and flatten the data into // a tabular recordset structure. var newRS =3D = Spry.Data.XMLDataSet.getRecordSetFromXMLDoc(row.ds_XMLNode, = xpathArray[j], (subPaths[j].xpath ? false : true), = this.entityEncodeStrings); // If this subPath has additional subPaths beneath it, // flatten and join them with the recordset we just created. if (newRS && newRS.data && newRS.data.length) { if (typeof subPaths[j] =3D=3D "object" && subPaths[j].subPaths) { // The subPaths property can be either an XPath string, // an Object describing a subPath and paths beneath it, // or an Array of XPath strings or objects. We need to // normalize these variations into an array to simplify // our processing. var sp =3D subPaths[j].subPaths; spType =3D typeof sp; if (spType =3D=3D "string") sp =3D [ sp ]; else if (spType =3D=3D "object" && spType.constructor =3D=3D = Object) sp =3D [ sp ]; // Now that we have a normalized array of sub paths, flatten // them and join them to the recordSet we just calculated. this.flattenSubPaths(newRS, sp); } var newRSData =3D newRS.data; var numRSRows =3D newRSData.length; var cleanedXPath =3D cleanedXPathArray[j] + "/"; var numNewRows =3D newRows.length; var joinedRows =3D []; // Iterate over all rows in our newRows array. Note that the // contents of newRows changes after the execution of this // loop, allowing us to perform more joins when more than // one subPath is specified. for (var k =3D 0; k < numNewRows; k++) { var newRow =3D newRows[k]; // Iterate over all rows in the record set generated // from the current subPath. We are going to create // m*n rows for the joined table, where m is the number // of rows in the newRows array, and n is the number of // rows in the current subPath recordset. for (var l =3D 0; l < numRSRows; l++) { // Create a new row that will house the join result. var newRowObj =3D new Object; var newRSRow =3D newRSData[l]; // Copy the columns from the newRow into our row // object. for (prop in newRow) newRowObj[prop] =3D newRow[prop]; // Copy the data from the current row of the record set // into our new row object, but make sure to store the // data in columns that have the subPath prepended to // it so that it doesn't collide with any columns from // the newRows row data. for (var prop in newRSRow) { // The new propery name will have the subPath used prepended to = it. var newPropName =3D cleanedXPath + prop; // We need to handle the case where the tag name of the node = matched // by the XPath has a value. In that specific case, the name of = the // property should be the cleanedXPath itself. For example: // // // Bob // Joe // // // XPath: /employees/employee // // The property name that contains "Bob" and "Joe" will be = "employee". // So in our new row, we need to call this column = "/employees/employee" // instead of "/employees/employee/employee" which would be = incorrect. if (cleanedXPath =3D=3D (prop + "/") || cleanedXPath.search(new = RegExp("\\/" + prop + "\\/$")) !=3D -1) newPropName =3D cleanedXPathArray[j]; // Copy the props to the new object using the new property name. newRowObj[newPropName] =3D newRSRow[prop]; } // Now add this row to the array that tracks all of the new // rows we've just created. joinedRows.push(newRowObj); } } // Set the newRows array equal to our joinedRows we just created, // so that when we flatten the data for the next subPath, it gets // joined with our new set of rows. newRows =3D joinedRows; } } newData =3D newData.concat(newRows); } // Now that we have a new set of joined rows, we need to run through // all of the rows and make sure they all have a unique row ID and // rebuild our dataHash. data =3D newData; numRows =3D data.length; for (i =3D 0; i < numRows; i++) { row =3D data[i]; row.ds_RowID =3D i; dataHash[row.ds_RowID] =3D row; } // We're all done, so stuff the new data and dataHash // back into the base recordSet. rs.data =3D data; rs.dataHash =3D dataHash; }; Spry.Data.XMLDataSet.prototype.loadDataIntoDataSet =3D = function(rawDataDoc) { var rs =3D null; var mainXPath =3D Spry.Data.Region.processDataRefString(null, = this.xpath, this.dataSetsForDataRefStrings); var subPaths =3D this.subPaths; var suppressColumns =3D false; if (this.subPaths && this.subPaths.length > 0) { // Some subPaths were specified. Convert any data references in each = subPath // to real data. While we're at it, convert any subPaths that are = relative // to our main XPath to absolute paths. var processedSubPaths =3D []; var numSubPaths =3D subPaths.length; for (var i =3D 0; i < numSubPaths; i++) { var subPathStr =3D Spry.Data.Region.processDataRefString(null, = subPaths[i], this.dataSetsForDataRefStrings); if (subPathStr.charAt(0) !=3D '/') subPathStr =3D mainXPath + "/" + subPathStr; processedSubPaths.push(subPathStr); } // We need to add our main XPath to the set of subPaths and generate a = path // tree so we can find the XPath to the common parent of all the = paths, just // in case the user specified a path that was outside of our main = XPath. processedSubPaths.unshift(mainXPath); var commonParent =3D this.convertXPathsToPathTree(processedSubPaths); // The root node of the resulting path tree should contain the XPath // to the common parent. Make this the XPath we generate our initial // set of rows from so we can group the results of flattening the = other // subPaths in predictable/expected manner. mainXPath =3D commonParent.path; subPaths =3D commonParent.subPaths; // If the XPath to the common parent we calculated isn't our main = XPath // or any of the subPaths specified by the user, it is used purely for // grouping and joining the data we will flatten. We don't want to = include // any of the columns for the rows created for the common parent XPath = since // the user did not ask for it. suppressColumns =3D commonParent.xpath ? false : true; } rs =3D Spry.Data.XMLDataSet.getRecordSetFromXMLDoc(rawDataDoc, = mainXPath, suppressColumns, this.entityEncodeStrings); if (!rs) { Spry.Debug.reportError("Spry.Data.XMLDataSet.loadDataIntoDataSet() = failed to create dataSet '" + this.name + "'for '" + this.xpath + "' - " = + this.url + "\n"); return; } // Now that we have our base set of rows, flatten any additional = subPaths // specified by the user. this.flattenSubPaths(rs, subPaths); this.doc =3D rs.xmlDoc; this.data =3D rs.data; this.dataHash =3D rs.dataHash; this.dataWasLoaded =3D (this.doc !=3D null); }; Spry.Data.XMLDataSet.prototype.xhRequestProcessor =3D = function(xhRequest) { // XMLDataSet uses the responseXML from the xhRequest var resp =3D xhRequest.responseXML; var manualParseRequired =3D false; if (xhRequest.status !=3D 200) { if (xhRequest.status =3D=3D 0) { // The page that is attempting to load data was probably loaded with // a file:// url. Mozilla based browsers will actually provide the = complete DOM // tree for the data, but IE provides an empty document node so try = to parse // the xml text manually to create a dom tree we can use. if (xhRequest.responseText && (!resp || !resp.firstChild)) manualParseRequired =3D true; } } else if (!resp) { // The server said it sent us data, but for some reason we don't have // an XML DOM document. Some browsers won't auto-create an XML DOM // unless the server used a content-type of "text/xml" or = "application/xml". // Try to manually parse the XML string, just in case the server // gave us an unexpected Content-Type. manualParseRequired =3D true; } if (manualParseRequired) resp =3D Spry.Utils.stringToXMLDoc(xhRequest.responseText); if (!resp || !resp.firstChild || resp.firstChild.nodeName =3D=3D = "parsererror") return null; return resp; }; Spry.Data.XMLDataSet.prototype.sessionExpiredChecker =3D function(req) { if (req.xhRequest.responseText =3D=3D 'session expired') return true; else { if (req.rawData) { var firstChild =3D req.rawData.documentElement.firstChild; if (firstChild && firstChild.nodeValue =3D=3D "session expired") return true; } } return false; }; ////////////////////////////////////////////////////////////////////// // // Spry.Data.Region // ////////////////////////////////////////////////////////////////////// Spry.Data.Region =3D function(regionNode, name, isDetailRegion, data, = dataSets, regionStates, regionStateMap, hasBehaviorAttributes) { this.regionNode =3D regionNode; this.name =3D name; this.isDetailRegion =3D isDetailRegion; this.data =3D data; this.dataSets =3D dataSets; this.hasBehaviorAttributes =3D hasBehaviorAttributes; this.tokens =3D null; this.currentState =3D null; this.states =3D { ready: true }; this.stateMap =3D {}; Spry.Utils.setOptions(this.states, regionStates); Spry.Utils.setOptions(this.stateMap, regionStateMap); // Add the region as an observer to the dataSet! for (var i =3D 0; i < this.dataSets.length; i++) { var ds =3D this.dataSets[i]; try { if (ds) ds.addObserver(this); } catch(e) { Spry.Debug.reportError("Failed to add '" + this.name + "' = as a dataSet observer!\n"); } } }; // End of Spry.Data.Region() constructor. Spry.Data.Region.hiddenRegionClassName =3D "SpryHiddenRegion"; Spry.Data.Region.evenRowClassName =3D "even"; Spry.Data.Region.oddRowClassName =3D "odd"; Spry.Data.Region.notifiers =3D {}; Spry.Data.Region.evalScripts =3D true; Spry.Data.Region.addObserver =3D function(regionID, observer) { var n =3D Spry.Data.Region.notifiers[regionID]; if (!n) { n =3D new Spry.Utils.Notifier(); Spry.Data.Region.notifiers[regionID] =3D n; } n.addObserver(observer); }; Spry.Data.Region.removeObserver =3D function(regionID, observer) { var n =3D Spry.Data.Region.notifiers[regionID]; if (n) n.removeObserver(observer); }; Spry.Data.Region.notifyObservers =3D function(methodName, region, data) { var n =3D Spry.Data.Region.notifiers[region.name]; if (n) { var dataObj =3D {}; if (data && typeof data =3D=3D "object") dataObj =3D data; else dataObj.data =3D data; dataObj.region =3D region; dataObj.regionID =3D region.name; dataObj.regionNode =3D region.regionNode; n.notifyObservers(methodName, dataObj); } }; Spry.Data.Region.RS_Error =3D 0x01; Spry.Data.Region.RS_LoadingData =3D 0x02; Spry.Data.Region.RS_PreUpdate =3D 0x04; Spry.Data.Region.RS_PostUpdate =3D 0x08; Spry.Data.Region.prototype.getState =3D function() { return this.currentState; }; Spry.Data.Region.prototype.mapState =3D function(stateName, = newStateName) { this.stateMap[stateName] =3D newStateName; }; Spry.Data.Region.prototype.getMappedState =3D function(stateName) { var mappedState =3D this.stateMap[stateName]; return mappedState ? mappedState : stateName; }; Spry.Data.Region.prototype.setState =3D function(stateName, = suppressNotfications) { var stateObj =3D { state: stateName, mappedState: = this.getMappedState(stateName) }; if (!suppressNotfications) Spry.Data.Region.notifyObservers("onPreStateChange", this, stateObj); this.currentState =3D stateObj.mappedState ? stateObj.mappedState : = stateName; // If the region has content that is specific to this // state, regenerate the region so that its markup is updated. if (this.states[stateName]) { var notificationData =3D { state: this.currentState }; if (!suppressNotfications) Spry.Data.Region.notifyObservers("onPreUpdate", this, = notificationData); // Make the region transform the xml data. The result is // a string that we need to parse and insert into the document. var str =3D this.transform(); // Clear out any previous transformed content. // this.clearContent(); if (Spry.Data.Region.debug) Spry.Debug.trace("
Generated region markup for '" + this.name + = "':

" + Spry.Utils.encodeEntities(str)); // Now insert the new transformed content into the document. Spry.Utils.setInnerHTML(this.regionNode, str, = !Spry.Data.Region.evalScripts); // Now run through the content looking for attributes // that tell us what behaviors to attach to each element. if (this.hasBehaviorAttributes) this.attachBehaviors(); if (!suppressNotfications) Spry.Data.Region.notifyObservers("onPostUpdate", this, = notificationData); } if (!suppressNotfications) Spry.Data.Region.notifyObservers("onPostStateChange", this, stateObj); }; Spry.Data.Region.prototype.getDataSets =3D function() { return this.dataSets; }; Spry.Data.Region.prototype.addDataSet =3D function(aDataSet) { if (!aDataSet) return; if (!this.dataSets) this.dataSets =3D new Array; // Check to see if the data set is already in our list. for (var i =3D 0; i < this.dataSets.length; i++) { if (this.dataSets[i] =3D=3D aDataSet) return; // It's already in our list! } this.dataSets.push(aDataSet); aDataSet.addObserver(this); }; Spry.Data.Region.prototype.removeDataSet =3D function(aDataSet) { if (!aDataSet || this.dataSets) return; for (var i =3D 0; i < this.dataSets.length; i++) { if (this.dataSets[i] =3D=3D aDataSet) { this.dataSets.splice(i, 1); aDataSet.removeObserver(this); return; } } }; Spry.Data.Region.prototype.onPreLoad =3D function(dataSet) { if (this.currentState !=3D "loading") this.setState("loading"); }; Spry.Data.Region.prototype.onLoadError =3D function(dataSet) { if (this.currentState !=3D "error") this.setState("error"); Spry.Data.Region.notifyObservers("onError", this); }; Spry.Data.Region.prototype.onSessionExpired =3D function(dataSet) { if (this.currentState !=3D "expired") this.setState("expired"); Spry.Data.Region.notifyObservers("onExpired", this); }; Spry.Data.Region.prototype.onCurrentRowChanged =3D function(dataSet, = data) { if (this.isDetailRegion) this.updateContent(); }; Spry.Data.Region.prototype.onPostSort =3D function(dataSet, data) { this.updateContent(); }; Spry.Data.Region.prototype.onDataChanged =3D function(dataSet, data) { this.updateContent(); }; Spry.Data.Region.enableBehaviorAttributes =3D true; Spry.Data.Region.behaviorAttrs =3D {}; Spry.Data.Region.behaviorAttrs["spry:select"] =3D { attach: function(rgn, node, value) { var selectGroupName =3D null; try { selectGroupName =3D = node.attributes.getNamedItem("spry:selectgroup").value; } catch (e) {} if (!selectGroupName) selectGroupName =3D "default"; Spry.Utils.addEventListener(node, "click", function(event) { = Spry.Utils.SelectionManager.select(selectGroupName, node, value); }, = false); if (node.attributes.getNamedItem("spry:selected")) Spry.Utils.SelectionManager.select(selectGroupName, node, value); } }; Spry.Data.Region.behaviorAttrs["spry:hover"] =3D { attach: function(rgn, node, value) { Spry.Utils.addEventListener(node, "mouseover", function(event){ = Spry.Utils.addClassName(node, value); }, false); Spry.Utils.addEventListener(node, "mouseout", function(event){ = Spry.Utils.removeClassName(node, value); }, false); } }; Spry.Data.Region.setUpRowNumberForEvenOddAttr =3D function(node, attr, = value, rowNumAttrName) { // The format for the spry:even and spry:odd attributes are as follows: // //
// // The dataSetName is optional, and if not specified, the first data = set // listed for the region is used. // // cssEvenClassName and cssOddClassName are required and *must* be = specified. They can be // any user defined CSS class name. if (!value) { Spry.Debug.showError("The " + attr + " attribute requires a CSS class = name as its value!"); node.attributes.removeNamedItem(attr); return; } var dsName =3D ""; var valArr =3D value.split(/\s/); if (valArr.length > 1) { // Extract out the data set name and reset the attribute so // that it only contains the CSS class name to use. dsName =3D valArr[0]; node.setAttribute(attr, valArr[1]); } // Tag the node with an attribute that will allow us to fetch the row // number used when it is written out during the re-generation process. node.setAttribute(rowNumAttrName, "{" + (dsName ? (dsName + "::") : "") = + "ds_RowNumber}"); }; Spry.Data.Region.behaviorAttrs["spry:even"] =3D { setup: function(node, value) { Spry.Data.Region.setUpRowNumberForEvenOddAttr(node, "spry:even", = value, "spryevenrownumber"); }, attach: function(rgn, node, value) { if (value) { rowNumAttr =3D node.attributes.getNamedItem("spryevenrownumber"); if (rowNumAttr && rowNumAttr.value) { var rowNum =3D parseInt(rowNumAttr.value); if (rowNum % 2) Spry.Utils.addClassName(node, value); } } node.removeAttribute("spry:even"); node.removeAttribute("spryevenrownumber"); } }; Spry.Data.Region.behaviorAttrs["spry:odd"] =3D { setup: function(node, value) { Spry.Data.Region.setUpRowNumberForEvenOddAttr(node, "spry:odd", value, = "spryoddrownumber"); }, attach: function(rgn, node, value) { if (value) { rowNumAttr =3D node.attributes.getNamedItem("spryoddrownumber"); if (rowNumAttr && rowNumAttr.value) { var rowNum =3D parseInt(rowNumAttr.value); if (rowNum % 2 =3D=3D 0) Spry.Utils.addClassName(node, value); } } node.removeAttribute("spry:odd"); node.removeAttribute("spryoddrownumber"); } }; Spry.Data.Region.setRowAttrClickHandler =3D function(node, dsName, = rowAttr, funcName) { if (dsName) { var ds =3D Spry.Data.getDataSetByName(dsName); if (ds) { rowIDAttr =3D node.attributes.getNamedItem(rowAttr); if (rowIDAttr) { var rowAttrVal =3D rowIDAttr.value; if (rowAttrVal) Spry.Utils.addEventListener(node, "click", function(event){ = ds[funcName](rowAttrVal); }, false); } } } }; Spry.Data.Region.behaviorAttrs["spry:setrow"] =3D { setup: function(node, value) { if (!value) { Spry.Debug.reportError("The spry:setrow attribute requires a data set = name as its value!"); node.removeAttribute("spry:setrow"); return; } // Tag the node with an attribute that will allow us to fetch the id = of the // row used when it is written out during the re-generation process. node.setAttribute("spryrowid", "{" + value + "::ds_RowID}"); }, attach: function(rgn, node, value) { Spry.Data.Region.setRowAttrClickHandler(node, value, "spryrowid", = "setCurrentRow"); node.removeAttribute("spry:setrow"); node.removeAttribute("spryrowid"); } }; Spry.Data.Region.behaviorAttrs["spry:setrownumber"] =3D { setup: function(node, value) { if (!value) { Spry.Debug.reportError("The spry:setrownumber attribute requires a = data set name as its value!"); node.removeAttribute("spry:setrownumber"); return; } // Tag the node with an attribute that will allow us to fetch the row = number // of the row used when it is written out during the re-generation = process. node.setAttribute("spryrownumber", "{" + value + "::ds_RowID}"); }, attach: function(rgn, node, value) { Spry.Data.Region.setRowAttrClickHandler(node, value, "spryrownumber", = "setCurrentRowNumber"); node.removeAttribute("spry:setrownumber"); node.removeAttribute("spryrownumber"); } }; Spry.Data.Region.behaviorAttrs["spry:sort"] =3D { attach: function(rgn, node, value) { if (!value) return; // The format of a spry:sort attribute is as follows: // //
// // The dataSetName and sortOrderName are optional, but when specified, = they // must appear in the order mentioned above. If the dataSetName is not = specified, // the first data set listed for the region is used. If the = sortOrderName is not // specified, the sort defaults to "toggle". // // The user *must* specify at least one column name. var ds =3D rgn.getDataSets()[0]; var sortOrder =3D "toggle"; var colArray =3D value.split(/\s/); if (colArray.length > 1) { // Check the first string in the attribute to see if a data set was // specified. If so, make sure we use it for the sort. var specifiedDS =3D Spry.Data.getDataSetByName(colArray[0]); if (specifiedDS) { ds =3D specifiedDS; colArray.shift(); } // Check to see if the last string in the attribute is the name of // a sort order. If so, use that sort order during the sort. if (colArray.length > 1) { var str =3D colArray[colArray.length - 1]; if (str =3D=3D "ascending" || str =3D=3D "descending" || str =3D=3D = "toggle") { sortOrder =3D str; colArray.pop(); } } } // If we have a data set and some column names, add a non-destructive // onclick handler that will perform a toggle sort on the data set. if (ds && colArray.length > 0) Spry.Utils.addEventListener(node, "click", function(event){ = ds.sort(colArray, sortOrder); }, false); node.removeAttribute("spry:sort"); } }; Spry.Data.Region.prototype.attachBehaviors =3D function() { var rgn =3D this; Spry.Utils.getNodesByFunc(this.regionNode, function(node) { if (!node || node.nodeType !=3D 1 /* Node.ELEMENT_NODE */) return false; try { var bAttrs =3D Spry.Data.Region.behaviorAttrs; for (var bAttrName in bAttrs) { var attr =3D node.attributes.getNamedItem(bAttrName); if (attr) { var behavior =3D bAttrs[bAttrName]; if (behavior && behavior.attach) behavior.attach(rgn, node, attr.value); } } } catch(e) {} return false; }); }; Spry.Data.Region.prototype.updateContent =3D function() { var allDataSetsReady =3D true; var dsArray =3D this.getDataSets(); if (!dsArray || dsArray.length < 1) { Spry.Debug.reportError("updateContent(): Region '" + this.name + "' = has no data set!\n"); return; } for (var i =3D 0; i < dsArray.length; i++) { var ds =3D dsArray[i]; if (ds) { if (ds.getLoadDataRequestIsPending()) allDataSetsReady =3D false; else if (!ds.getDataWasLoaded()) { // Kick off the loading of the data if it hasn't happened yet. ds.loadData(); allDataSetsReady =3D false; } } } if (!allDataSetsReady) { Spry.Data.Region.notifyObservers("onLoadingData", this); // Just return, this method will get called again automatically // as each data set load completes! return; } this.setState("ready"); }; Spry.Data.Region.prototype.clearContent =3D function() { this.regionNode.innerHTML =3D ""; }; Spry.Data.Region.processContentPI =3D function(inStr) { var outStr =3D ""; var regexp =3D //mg; var searchStartIndex =3D 0; var processingContentTag =3D 0; while (inStr.length) { var results =3D regexp.exec(inStr); if (!results || !results[0]) { outStr +=3D inStr.substr(searchStartIndex, inStr.length - = searchStartIndex); break; } if (!processingContentTag && results.index !=3D searchStartIndex) { // We found a match but it's not at the start of the inStr. // Create a string token for everything that precedes the match. outStr +=3D inStr.substr(searchStartIndex, results.index - = searchStartIndex); } if (results[0].search(/<\//) !=3D -1) { --processingContentTag; if (processingContentTag) Spry.Debug.reportError("Nested spry:content regions are not = allowed!\n"); } else { ++processingContentTag; var dataRefStr =3D results[0].replace(/.*\bdataref=3D"/, ""); outStr +=3D dataRefStr.replace(/".*$/, ""); } searchStartIndex =3D regexp.lastIndex; } return outStr; }; Spry.Data.Region.prototype.tokenizeData =3D function(dataStr) { // If there is no data, there's nothing to do. if (!dataStr) return null; var rootToken =3D new = Spry.Data.Region.Token(Spry.Data.Region.Token.LIST_TOKEN, null, null, = null); var tokenStack =3D new Array; var parseStr =3D Spry.Data.Region.processContentPI(dataStr); tokenStack.push(rootToken); // Create a regular expression that will match one of the following: // // // // {valueReference} var regexp =3D = /((){0,1})|((\{|%7[bB])[^\}\s%]+(\= }|%7[dD]))/mg; var searchStartIndex =3D 0; while(parseStr.length) { var results =3D regexp.exec(parseStr); var token =3D null; if (!results || !results[0]) { // If we get here, the rest of the parseStr should be // just a plain string. Create a token for it and then // break out of the list. var str =3D parseStr.substr(searchStartIndex, parseStr.length - = searchStartIndex); token =3D new = Spry.Data.Region.Token(Spry.Data.Region.Token.STRING_TOKEN, null, str, = str); tokenStack[tokenStack.length - 1].addChild(token); break; } if (results.index !=3D searchStartIndex) { // We found a match but it's not at the start of the parseStr. // Create a string token for everything that precedes the match. var str =3D parseStr.substr(searchStartIndex, results.index - = searchStartIndex); token =3D new = Spry.Data.Region.Token(Spry.Data.Region.Token.STRING_TOKEN, null, str, = str); tokenStack[tokenStack.length - 1].addChild(token); } // We found a string that needs to be turned into a token. Create a = token // for it and then update parseStr for the next iteration. if (results[0].search(/^({|%7[bB])/) !=3D -1 /* results[0].charAt(0) = =3D=3D '{' */) { var valueName =3D results[0]; var regionStr =3D results[0]; // Strip off brace and url encode brace chars inside the valueName. valueName =3D valueName.replace(/^({|%7[bB])/, ""); valueName =3D valueName.replace(/(}|%7[dD])$/, ""); // Check to see if our value begins with the name of a data set. // For example: {dataSet:tokenValue}. If it is, we need to save // the data set name so we know which data set to use to get the // value for the token during the region transform. var dataSetName =3D null; var splitArray =3D valueName.split(/::/); if (splitArray.length > 1) { dataSetName =3D splitArray[0]; valueName =3D splitArray[1]; } // Convert any url encoded braces to regular brace chars. regionStr =3D regionStr.replace(/^%7[bB]/, "{"); regionStr =3D regionStr.replace(/%7[dD]$/, "}"); // Now create a token for the placeholder. token =3D new = Spry.Data.Region.Token(Spry.Data.Region.Token.VALUE_TOKEN, dataSetName, = valueName, new String(regionStr)); tokenStack[tokenStack.length - 1].addChild(token); } else if (results[0].charAt(0) =3D=3D '<') { // Extract out the name of the processing instruction. var piName =3D results[0].replace(/^(){0,1}|\s.*$/, ""); if (results[0].search(/<\//) !=3D -1 /* results[0].charAt(1) =3D=3D = '/' */) { // We found a processing instruction close tag. Pop the top of the // token stack! // // XXX: We need to make sure that the close tag name matches the one // on the top of the token stack! if (tokenStack[tokenStack.length - 1].tokenType !=3D = Spry.Data.Region.Token.PROCESSING_INSTRUCTION_TOKEN) { Spry.Debug.reportError("Invalid processing instruction close tag: " = + piName + " -- " + results[0] + "\n"); return null; } tokenStack.pop(); } else { // Create the processing instruction token, add it as a child of the = token // at the top of the token stack, and then push it on the stack so = that it // becomes the parent of any tokens between it and its close tag. var piDesc =3D Spry.Data.Region.PI.instructions[piName]; if (piDesc) { var dataSet =3D null; var selectedDataSetName =3D ""; if (results[0].search(/^.*\bselect=3D\"/) !=3D -1) { selectedDataSetName =3D results[0].replace(/^.*\bselect=3D\"/, = ""); selectedDataSetName =3D selectedDataSetName.replace(/".*$/, ""); if (selectedDataSetName) { dataSet =3D Spry.Data.getDataSetByName(selectedDataSetName); if (!dataSet) { Spry.Debug.reportError("Failed to retrieve data set (" + = selectedDataSetName + ") for " + piName + "\n"); selectedDataSetName =3D ""; } } } // Check if the repeat has a test attribute. var jsExpr =3D null; if (results[0].search(/^.*\btest=3D\"/) !=3D -1) { jsExpr =3D results[0].replace(/^.*\btest=3D\"/, ""); jsExpr =3D jsExpr.replace(/".*$/, ""); jsExpr =3D Spry.Utils.decodeEntities(jsExpr); } // Check if the instruction has a state name specified. var regionState =3D null; if (results[0].search(/^.*\bname=3D\"/) !=3D -1) { regionState =3D results[0].replace(/^.*\bname=3D\"/, ""); regionState =3D regionState.replace(/".*$/, ""); regionState =3D Spry.Utils.decodeEntities(regionState); } var piData =3D new Spry.Data.Region.Token.PIData(piName, = selectedDataSetName, jsExpr, regionState); token =3D new = Spry.Data.Region.Token(Spry.Data.Region.Token.PROCESSING_INSTRUCTION_TOKE= N, dataSet, piData, new String(results[0])); tokenStack[tokenStack.length - 1].addChild(token); tokenStack.push(token); } else { Spry.Debug.reportError("Unsupported region processing instruction: = " + results[0] + "\n"); return null; } } } else { Spry.Debug.reportError("Invalid region token: " + results[0] + "\n"); return null; } searchStartIndex =3D regexp.lastIndex; } return rootToken; }; Spry.Data.Region.prototype.callScriptFunction =3D function(funcName, = processContext) { var result =3D undefined; funcName =3D funcName.replace(/^\s*\{?\s*function::\s*|\s*\}?\s*$/g, = ""); var func =3D Spry.Utils.getObjectByName(funcName); if (func) result =3D func(this.name, function() { return = processContext.getValueFromDataSet.apply(processContext, arguments); }); return result; }; Spry.Data.Region.prototype.evaluateExpression =3D function(exprStr, = processContext) { var result =3D undefined; try { if (exprStr.search(/^\s*function::/) !=3D -1) result =3D this.callScriptFunction(exprStr, processContext); else result =3D = Spry.Utils.eval(Spry.Data.Region.processDataRefString(processContext, = exprStr, null, true)); } catch(e) { Spry.Debug.trace("Caught exception in = Spry.Data.Region.prototype.evaluateExpression() while evaluating: " + = Spry.Utils.encodeEntities(exprStr) + "\n Exception:" + e + "\n"); } return result; }; Spry.Data.Region.prototype.processTokenChildren =3D function(outputArr, = token, processContext) { var children =3D token.children; var len =3D children.length; for (var i =3D 0; i < len; i++) this.processTokens(outputArr, children[i], processContext); }; Spry.Data.Region.prototype.processTokens =3D function(outputArr, token, = processContext) { var i =3D 0; switch(token.tokenType) { case Spry.Data.Region.Token.LIST_TOKEN: this.processTokenChildren(outputArr, token, processContext); break; case Spry.Data.Region.Token.STRING_TOKEN: outputArr.push(token.data); break; case Spry.Data.Region.Token.PROCESSING_INSTRUCTION_TOKEN: if (token.data.name =3D=3D "spry:repeat") { var dataSet =3D null; if (token.dataSet) dataSet =3D token.dataSet; else dataSet =3D this.dataSets[0]; if (dataSet) { var dsContext =3D processContext.getDataSetContext(dataSet); if (!dsContext) { Spry.Debug.reportError("processTokens() failed to get a data set = context!\n"); break; } dsContext.pushState(); var dataSetRows =3D dsContext.getData(); var numRows =3D dataSetRows.length; for (i =3D 0; i < numRows; i++) { dsContext.setRowIndex(i); var testVal =3D true; if (token.data.jsExpr) testVal =3D this.evaluateExpression(token.data.jsExpr, = processContext); if (testVal) this.processTokenChildren(outputArr, token, processContext); } dsContext.popState(); } } else if (token.data.name =3D=3D "spry:if") { var testVal =3D true; if (token.data.jsExpr) testVal =3D this.evaluateExpression(token.data.jsExpr, = processContext); if (testVal) this.processTokenChildren(outputArr, token, processContext); } else if (token.data.name =3D=3D "spry:choose") { var defaultChild =3D null; var childToProcess =3D null; var testVal =3D false; var j =3D 0; // All of the children of the spry:choose token should be of the = type spry:when or spry:default. // Run through all of the spry:when children and see if any of their = test expressions return true. // If one does, then process its children tokens. If none of the = test expressions return true, // process the spry:default token's children, if it exists. for (j =3D 0; j < token.children.length; j++) { var child =3D token.children[j]; if (child.tokenType =3D=3D = Spry.Data.Region.Token.PROCESSING_INSTRUCTION_TOKEN) { if (child.data.name =3D=3D "spry:when") { if (child.data.jsExpr) { testVal =3D this.evaluateExpression(child.data.jsExpr, = processContext); if (testVal) { childToProcess =3D child; break; } } } else if (child.data.name =3D=3D "spry:default") defaultChild =3D child; } } // If we didn't find a match, use the token for the default case. if (!childToProcess && defaultChild) childToProcess =3D defaultChild; if (childToProcess) this.processTokenChildren(outputArr, childToProcess, = processContext); } else if (token.data.name =3D=3D "spry:state") { var testVal =3D true; if (!token.data.regionState || token.data.regionState =3D=3D = this.currentState) this.processTokenChildren(outputArr, token, processContext); } else { Spry.Debug.reportError("processTokens(): Unknown processing = instruction: " + token.data.name + "\n"); return ""; } break; case Spry.Data.Region.Token.VALUE_TOKEN: var dataSet =3D token.dataSet; var val =3D undefined; if (dataSet && dataSet =3D=3D "function") { // This value token doesn't contain a data set data reference, it // contains a function call, so call it. val =3D this.callScriptFunction(token.data, processContext); } else { if (!dataSet && this.dataSets && this.dataSets.length > 0 && = this.dataSets[0]) { // No dataSet was specified by the token, so use whatever the first // data set specified in the region. =09 dataSet =3D this.dataSets[0]; } if (!dataSet) { Spry.Debug.reportError("processTokens(): Value reference has no = data set specified: " + token.regionStr + "\n"); return ""; } =09 val =3D processContext.getValueFromDataSet(dataSet, token.data); } if (typeof val !=3D "undefined") outputArr.push(val + ""); break; default: Spry.Debug.reportError("processTokens(): Invalid token type: " + = token.regionStr + "\n"); break; } }; Spry.Data.Region.prototype.transform =3D function() { if (this.data && !this.tokens) this.tokens =3D this.tokenizeData(this.data); if (!this.tokens) return ""; processContext =3D new Spry.Data.Region.ProcessingContext(this); if (!processContext) return ""; // Now call processTokens to transform our tokens into real data = strings. // We use an array to gather the strings during processing as a = performance // enhancement for IE to avoid n-square problems of adding to an = existing // string. For example: // // for (var i =3D 0; i < token.children.length; i++) // outputStr +=3D this.processTokens(token.children[i], = processContext); // // Using an array with a final join reduced one of our test cases from = over // a minute to about 15 seconds. var outputArr =3D [ "" ]; this.processTokens(outputArr, this.tokens, processContext); return outputArr.join(""); }; Spry.Data.Region.PI =3D {}; Spry.Data.Region.PI.instructions =3D {}; Spry.Data.Region.PI.buildOpenTagForValueAttr =3D function(ele, piName, = attrName) { if (!ele || !piName) return ""; var jsExpr =3D ""; try { var testAttr =3D ele.attributes.getNamedItem(piName); if (testAttr && testAttr.value) jsExpr =3D Spry.Utils.encodeEntities(testAttr.value); } catch (e) { jsExpr =3D ""; } if (!jsExpr) { Spry.Debug.reportError(piName + " attribute requires a JavaScript = expression that returns true or false!\n"); return ""; } return "<" + Spry.Data.Region.PI.instructions[piName].tagName + " " + = attrName +"=3D\"" + jsExpr + "\">"; }; Spry.Data.Region.PI.buildOpenTagForTest =3D function(ele, piName) { return Spry.Data.Region.PI.buildOpenTagForValueAttr(ele, piName, = "test"); }; Spry.Data.Region.PI.buildOpenTagForState =3D function(ele, piName) { return Spry.Data.Region.PI.buildOpenTagForValueAttr(ele, piName, = "name"); }; Spry.Data.Region.PI.buildOpenTagForRepeat =3D function(ele, piName) { if (!ele || !piName) return ""; var selectAttrStr =3D ""; try { var selectAttr =3D ele.attributes.getNamedItem(piName); if (selectAttr && selectAttr.value) { selectAttrStr =3D selectAttr.value; selectAttrStr =3D selectAttrStr.replace(/\s/g, ""); } } catch (e) { selectAttrStr =3D ""; } if (!selectAttrStr) { Spry.Debug.reportError(piName + " attribute requires a data set = name!\n"); return ""; } var testAttrStr =3D ""; try { var testAttr =3D ele.attributes.getNamedItem("spry:test"); if (testAttr) { if (testAttr.value) testAttrStr =3D " test=3D\"" + = Spry.Utils.encodeEntities(testAttr.value) + "\""; ele.attributes.removeNamedItem(testAttr.nodeName); } } catch (e) { testAttrStr =3D ""; } return "<" + Spry.Data.Region.PI.instructions[piName].tagName + " = select=3D\"" + selectAttrStr + "\"" + testAttrStr + ">"; }; Spry.Data.Region.PI.buildOpenTagForContent =3D function(ele, piName) { if (!ele || !piName) return ""; var dataRefStr =3D ""; try { var contentAttr =3D ele.attributes.getNamedItem(piName); if (contentAttr && contentAttr.value) dataRefStr =3D Spry.Utils.encodeEntities(contentAttr.value); } catch (e) { dataRefStr =3D ""; } if (!dataRefStr) { Spry.Debug.reportError(piName + " attribute requires a data = reference!\n"); return ""; } return "<" + Spry.Data.Region.PI.instructions[piName].tagName + " = dataref=3D\"" + dataRefStr + "\">"; }; Spry.Data.Region.PI.buildOpenTag =3D function(ele, piName) { return "<" + Spry.Data.Region.PI.instructions[piName].tagName + ">"; }; Spry.Data.Region.PI.buildCloseTag =3D function(ele, piName) { return ""; }; Spry.Data.Region.PI.instructions["spry:state"] =3D { tagName: = "spry:state", childrenOnly: false, getOpenTag: = Spry.Data.Region.PI.buildOpenTagForState, getCloseTag: = Spry.Data.Region.PI.buildCloseTag }; Spry.Data.Region.PI.instructions["spry:if"] =3D { tagName: "spry:if", = childrenOnly: false, getOpenTag: = Spry.Data.Region.PI.buildOpenTagForTest, getCloseTag: = Spry.Data.Region.PI.buildCloseTag }; Spry.Data.Region.PI.instructions["spry:repeat"] =3D { tagName: = "spry:repeat", childrenOnly: false, getOpenTag: = Spry.Data.Region.PI.buildOpenTagForRepeat, getCloseTag: = Spry.Data.Region.PI.buildCloseTag }; Spry.Data.Region.PI.instructions["spry:repeatchildren"] =3D { tagName: = "spry:repeat", childrenOnly: true, getOpenTag: = Spry.Data.Region.PI.buildOpenTagForRepeat, getCloseTag: = Spry.Data.Region.PI.buildCloseTag }; Spry.Data.Region.PI.instructions["spry:choose"] =3D { tagName: = "spry:choose", childrenOnly: true, getOpenTag: = Spry.Data.Region.PI.buildOpenTag, getCloseTag: = Spry.Data.Region.PI.buildCloseTag }; Spry.Data.Region.PI.instructions["spry:when"] =3D { tagName: = "spry:when", childrenOnly: false, getOpenTag: = Spry.Data.Region.PI.buildOpenTagForTest, getCloseTag: = Spry.Data.Region.PI.buildCloseTag }; Spry.Data.Region.PI.instructions["spry:default"] =3D { tagName: = "spry:default", childrenOnly: false, getOpenTag: = Spry.Data.Region.PI.buildOpenTag, getCloseTag: = Spry.Data.Region.PI.buildCloseTag }; Spry.Data.Region.PI.instructions["spry:content"] =3D { tagName: = "spry:content", childrenOnly: true, getOpenTag: = Spry.Data.Region.PI.buildOpenTagForContent, getCloseTag: = Spry.Data.Region.PI.buildCloseTag }; Spry.Data.Region.PI.orderedInstructions =3D [ "spry:state", "spry:if", = "spry:repeat", "spry:repeatchildren", "spry:choose", "spry:when", = "spry:default", "spry:content" ]; Spry.Data.Region.getTokensFromStr =3D function(str) { // XXX: This will need to be modified if we support // tokens that use javascript between the braces! if (!str) return null; return str.match(/{[^}]+}/g); }; Spry.Data.Region.processDataRefString =3D function(processingContext, = regionStr, dataSetsToUse, isJSExpr) { if (!regionStr) return ""; if (!processingContext && !dataSetsToUse) return regionStr; var resultStr =3D ""; var re =3D new RegExp("\\{([^\\}:]+::)?[^\\}]+\\}", "g"); var startSearchIndex =3D 0; while (startSearchIndex < regionStr.length) { var reArray =3D re.exec(regionStr); if (!reArray || !reArray[0]) { resultStr +=3D regionStr.substr(startSearchIndex, regionStr.length - = startSearchIndex); return resultStr; } if (reArray.index !=3D startSearchIndex) resultStr +=3D regionStr.substr(startSearchIndex, reArray.index - = startSearchIndex); var dsName =3D ""; if (reArray[0].search(/^\{[^}:]+::/) !=3D -1) dsName =3D reArray[0].replace(/^\{|::.*/g, ""); var fieldName =3D reArray[0].replace(/^\{|.*::|\}/g, ""); var row =3D null; var val =3D ""; if (processingContext) val =3D processingContext.getValueFromDataSet(dsName, fieldName); else { var ds =3D dsName ? dataSetsToUse[dsName] : dataSetsToUse[0]; if (ds) val =3D ds.getValue(fieldName); } if (typeof val !=3D "undefined") { val +=3D ""; // Make sure val is converted to a string. resultStr +=3D isJSExpr ? Spry.Utils.escapeQuotesAndLineBreaks(val) : = val; } if (startSearchIndex =3D=3D re.lastIndex) { // On IE if there was a match near the end of the string, it = sometimes // leaves re.lastIndex pointing to the value it had before the last = time // we called re.exec. We check for this case to prevent an infinite = loop! // We need to write out any text in regionStr that comes after the = last // match. var leftOverIndex =3D reArray.index + reArray[0].length; if (leftOverIndex < regionStr.length) resultStr +=3D regionStr.substr(leftOverIndex); break; } startSearchIndex =3D re.lastIndex; } return resultStr; }; Spry.Data.Region.strToDataSetsArray =3D function(str, returnRegionNames) { var dataSetsArr =3D new Array; var foundHash =3D {}; if (!str) return dataSetsArr; str =3D str.replace(/\s+/g, " "); str =3D str.replace(/^\s|\s$/g, ""); var arr =3D str.split(/ /); for (var i =3D 0; i < arr.length; i++) { if (arr[i] && !Spry.Data.Region.PI.instructions[arr[i]]) { try { var dataSet =3D Spry.Data.getDataSetByName(arr[i]); if (!foundHash[arr[i]]) { if (returnRegionNames) dataSetsArr.push(arr[i]); else dataSetsArr.push(dataSet); foundHash[arr[i]] =3D true; } } catch (e) { /* Spry.Debug.trace("Caught exception: " + e + "\n"); */ = } } } return dataSetsArr; }; Spry.Data.Region.DSContext =3D function(dataSet, processingContext) { var m_dataSet =3D dataSet; var m_processingContext =3D processingContext; var m_curRowIndexArray =3D [ { rowIndex: -1 } ]; // -1 means return = whatever the current row is inside the data set. var m_parent =3D null; var m_children =3D []; // Private Methods: var getInternalRowIndex =3D function() { return = m_curRowIndexArray[m_curRowIndexArray.length - 1].rowIndex; }; // Public Methods: this.resetAll =3D function() { m_curRowIndexArray =3D [ { rowIndex: = m_dataSet.getCurrentRow() } ] }; this.getDataSet =3D function() { return m_dataSet; }; this.getNumRows =3D function(unfiltered) { var data =3D this.getCurrentState().data; return data ? data.length : m_dataSet.getRowCount(unfiltered); }; this.getData =3D function() { var data =3D this.getCurrentState().data; return data ? data : m_dataSet.getData(); }; this.setData =3D function(data) { this.getCurrentState().data =3D data; }; this.getValue =3D function(valueName, rowContext) { var result =3D ""; var curState =3D this.getCurrentState(); var ds =3D curState.nestedDS ? curState.nestedDS : this.getDataSet(); if (ds) result =3D ds.getValue(valueName, rowContext); return result; }; this.getCurrentRow =3D function() { if (m_curRowIndexArray.length < 2 || getInternalRowIndex() < 0) return m_dataSet.getCurrentRow(); var data =3D this.getData(); var curRowIndex =3D getInternalRowIndex(); if (curRowIndex < 0 || curRowIndex > data.length) { Spry.Debug.reportError("Invalid index used in = Spry.Data.Region.DSContext.getCurrentRow()!\n"); return null; } return data[curRowIndex]; }; this.getRowIndex =3D function() { var curRowIndex =3D getInternalRowIndex(); if (curRowIndex >=3D 0) return curRowIndex; return m_dataSet.getRowNumber(m_dataSet.getCurrentRow()); }; this.setRowIndex =3D function(rowIndex) { this.getCurrentState().rowIndex =3D rowIndex; var data =3D this.getData(); var numChildren =3D m_children.length; for (var i =3D 0; i < numChildren; i++) m_children[i].syncDataWithParentRow(this, rowIndex, data); }; this.syncDataWithParentRow =3D function(parentDSContext, rowIndex, = parentData) { var row =3D parentData[rowIndex]; if (row) { nestedDS =3D m_dataSet.getNestedDataSetForParentRow(row); if (nestedDS) { var currentState =3D this.getCurrentState(); currentState.nestedDS =3D nestedDS; currentState.data =3D nestedDS.getData(); currentState.rowIndex =3D nestedDS.getCurrentRowNumber(); // getCurrentRowNumber() will return a -1 if the nestedDS has // no data in it. If the rowIndex is -1, we need to reset it back to // zero so the dsContext doesn't attempt to use the *real* current // row of the data set. currentState.rowIndex =3D currentState.rowIndex < 0 ? 0 : = currentState.rowIndex; var numChildren =3D m_children.length; for (var i =3D 0; i < numChildren; i++) m_children[i].syncDataWithParentRow(this, currentState.rowIndex, = currentState.data); } } }; this.pushState =3D function() { var curState =3D this.getCurrentState(); var newState =3D new Object; newState.rowIndex =3D curState.rowIndex; newState.data =3D curState.data; newState.nestedDS =3D curState.nestedDS; m_curRowIndexArray.push(newState); var numChildren =3D m_children.length; for (var i =3D 0; i < numChildren; i++) m_children[i].pushState(); }; this.popState =3D function() { if (m_curRowIndexArray.length < 2) { // Our array should always have at least one element in it! Spry.Debug.reportError("Stack underflow in = Spry.Data.Region.DSContext.popState()!\n"); return; } var numChildren =3D m_children.length; for (var i =3D 0; i < numChildren; i++) m_children[i].popState(); m_curRowIndexArray.pop(); }; this.getCurrentState =3D function() { return m_curRowIndexArray[m_curRowIndexArray.length - 1]; }; this.addChild =3D function(childDSContext) { var numChildren =3D m_children.length; for (var i =3D 0; i < numChildren; i++) { if (m_children[i] =3D=3D childDSContext) return; } m_children.push(childDSContext); }; }; Spry.Data.Region.ProcessingContext =3D function(region) { this.region =3D region; this.dataSetContexts =3D []; if (region && region.dataSets) { // Run through each data set in the list and check to see if we need // to add its parent to the list of data sets we track. var dsArray =3D region.dataSets.slice(0); var dsArrayLen =3D dsArray.length; for (var i =3D 0; i < dsArrayLen; i++) { var ds =3D region.dataSets[i]; while (ds && ds.getParentDataSet) { var doesExist =3D false; ds =3D ds.getParentDataSet(); if (ds && this.indexOf(dsArray, ds) =3D=3D -1) dsArray.push(ds); } } // Create a data set context for every data set in our list. for (i =3D 0; i < dsArray.length; i++) this.dataSetContexts.push(new Spry.Data.Region.DSContext(dsArray[i], = this)); // Now run through the list of data set contexts and wire up the = parent/child // relationships so that notifications get dispatched as expected. var dsContexts =3D this.dataSetContexts; var numDSContexts =3D dsContexts.length; for (i =3D 0; i < numDSContexts; i++) { var dsc =3D dsContexts[i]; var ds =3D dsc.getDataSet(); if (ds.getParentDataSet) { var parentDS =3D ds.getParentDataSet(); if (parentDS) { var pdsc =3D this.getDataSetContext(parentDS); if (pdsc) pdsc.addChild(dsc); } } } } }; Spry.Data.Region.ProcessingContext.prototype.indexOf =3D function(arr, = item) { // Given an array, return the index of item in that array // or -1 if it doesn't exist. if (arr) { var arrLen =3D arr.length; for (var i =3D 0; i < arrLen; i++) if (arr[i] =3D=3D item) return i; } return -1; }; Spry.Data.Region.ProcessingContext.prototype.getDataSetContext =3D = function(dataSet) { if (!dataSet) { // We were called without a specified data set or // data set name. Assume the caller wants the first // data set in the processing context. if (this.dataSetContexts.length > 0) return this.dataSetContexts[0]; return null; } if (typeof dataSet =3D=3D 'string') { dataSet =3D Spry.Data.getDataSetByName(dataSet); if (!dataSet) return null; } for (var i =3D 0; i < this.dataSetContexts.length; i++) { var dsc =3D this.dataSetContexts[i]; if (dsc.getDataSet() =3D=3D dataSet) return dsc; } return null; }; Spry.Data.Region.ProcessingContext.prototype.getValueFromDataSet =3D = function() { var dsName =3D ""; var columnName =3D ""; if (arguments.length > 1) { // The caller is passing in the data set name and the // name of the data reference separately. dsName =3D arguments[0]; columnName =3D arguments[1]; } else { // The caller is passing a single string which can be in one // of the following forms: // // "columnName" // "dsName::columnName" // "{columnName}" // "{dsName::columnName}" var dataRef =3D arguments[0].replace(/\s*{\s*|\s*}\s*/g, ""); if (dataRef.search("::") !=3D -1) { dsName =3D dataRef.replace(/::.*/, ""); columnName =3D dataRef.replace(/.*::/, ""); } else columnName =3D dataRef; } var result =3D ""; var dsContext =3D this.getDataSetContext(dsName); if (dsContext) result =3D dsContext.getValue(columnName, dsContext.getCurrentRow()); else Spry.Debug.reportError("getValueFromDataSet: Failed to get " + dsName = + " context for the " + this.region.regionNode.id + " region.\n"); return result; }; // Define a short-hand name for developers. Spry.Data.Region.ProcessingContext.prototype.$v =3D = Spry.Data.Region.ProcessingContext.prototype.getValueFromDataSet; Spry.Data.Region.ProcessingContext.prototype.getCurrentRowForDataSet =3D = function(dataSet) { var dsc =3D this.getDataSetContext(dataSet); if (dsc) return dsc.getCurrentRow(); return null; }; Spry.Data.Region.Token =3D function(tokenType, dataSet, data, regionStr) { var self =3D this; this.tokenType =3D tokenType; this.dataSet =3D dataSet; this.data =3D data; this.regionStr =3D regionStr; this.parent =3D null; this.children =3D null; }; Spry.Data.Region.Token.prototype.addChild =3D function(child) { if (!child) return; if (!this.children) this.children =3D new Array; this.children.push(child); child.parent =3D this; }; Spry.Data.Region.Token.LIST_TOKEN =3D 0; Spry.Data.Region.Token.STRING_TOKEN =3D 1; Spry.Data.Region.Token.PROCESSING_INSTRUCTION_TOKEN =3D 2; Spry.Data.Region.Token.VALUE_TOKEN =3D 3; Spry.Data.Region.Token.PIData =3D function(piName, data, jsExpr, = regionState) { var self =3D this; this.name =3D piName; this.data =3D data; this.jsExpr =3D jsExpr; this.regionState =3D regionState; }; Spry.Utils.addLoadListener(function() { setTimeout(function() { if = (Spry.Data.initRegionsOnLoad) Spry.Data.initRegions(); }, 0); }); ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: application/octet-stream Content-Transfer-Encoding: quoted-printable Content-Location: http://www.marquette.edu/academicsenate/_js/SpryJSONDataSet.js // SpryJSONDataSet.js - version 0.6 - Spry Pre-Release 1.6.1 // // Copyright (c) 2007. Adobe Systems Incorporated. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions = are met: // // * Redistributions of source code must retain the above copyright = notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright = notice, // this list of conditions and the following disclaimer in the = documentation // and/or other materials provided with the distribution. // * Neither the name of Adobe Systems Incorporated nor the names of = its // contributors may be used to endorse or promote products derived = from this // software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS = "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, = THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR = PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS = BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR = BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER = IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR = OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED = OF THE // POSSIBILITY OF SUCH DAMAGE. Spry.Data.JSONDataSet =3D function(dataSetURL, dataSetOptions) { // Call the constructor for our HTTPSourceDataSet base class so that // our base class properties get defined. this.path =3D ""; this.pathIsObjectOfArrays =3D false; this.doc =3D null; this.subPaths =3D []; this.useParser =3D false; this.preparseFunc =3D null; Spry.Data.HTTPSourceDataSet.call(this, dataSetURL, dataSetOptions); // Callers are allowed to pass either a string, an object or an array = of // strings and/or objects for the 'subPaths' option, so make sure we = normalize // the subPaths value to be an array. var jwType =3D typeof this.subPaths; if (jwType =3D=3D "string" || (jwType =3D=3D "object" && = this.subPaths.constructor !=3D Array)) this.subPaths =3D [ this.subPaths ]; }; // End of Spry.Data.JSONDataSet() constructor. Spry.Data.JSONDataSet.prototype =3D new Spry.Data.HTTPSourceDataSet(); Spry.Data.JSONDataSet.prototype.constructor =3D Spry.Data.JSONDataSet; // Override the inherited version of getDataRefStrings() with our // own version that returns the strings memebers we maintain that // may have data references in them. Spry.Data.JSONDataSet.prototype.getDataRefStrings =3D function() { var strArr =3D []; if (this.url) strArr.push(this.url); if (this.path) strArr.push(this.path); if (this.requestInfo && this.requestInfo.postData) = strArr.push(this.requestInfo.postData); return strArr; }; Spry.Data.JSONDataSet.prototype.getDocument =3D function() { return = this.doc; }; Spry.Data.JSONDataSet.prototype.getPath =3D function() { return = this.path; }; Spry.Data.JSONDataSet.prototype.setPath =3D function(path) { if (this.path !=3D path) { this.path =3D path; if (this.dataWasLoaded && this.doc) { this.notifyObservers("onPreLoad"); this.setDataFromDoc(this.doc); } } }; // A recursive method that returns all objects that match the given = object path. Spry.Data.JSONDataSet.getMatchingObjects =3D function(path, jsonObj) { var results =3D []; if (path && jsonObj) { var prop =3D ""; var leftOverPath =3D ""; var offset =3D path.search(/\./); if (offset !=3D -1) { prop =3D path.substring(0, offset); leftOverPath =3D path.substring(offset + 1); } else prop =3D path; var matches =3D []; if (prop && typeof jsonObj =3D=3D "object") { var obj =3D jsonObj[prop]; var objType =3D typeof obj; if (objType !=3D undefined && objType !=3D null) { if (obj && objType =3D=3D "object" && obj.constructor =3D=3D Array) matches =3D matches.concat(obj); else matches.push(obj); } } var numMatches =3D matches.length; if (leftOverPath) { for (var i =3D 0; i < numMatches; i++) results =3D = results.concat(Spry.Data.JSONDataSet.getMatchingObjects(leftOverPath, = matches[i])); } else results =3D matches; } return results; }; // Flatten the specified object into a row object that can be added // to a record set. Spry.Data.JSONDataSet.flattenObject =3D function(obj, basicColumnName) { // If obj is a basic type (null, string, boolean, or number), we need // to store it under a column name in our row object. If the caller = supplied // a column name, use that, if not use our default "column0". var basicName =3D basicColumnName ? basicColumnName : "column0"; // If obj is an object, copy its properties into our row object. If obj // is a basic type, then store it in the row under the column name = specified // by basicName. var row =3D new Object; var objType =3D typeof obj; if (objType =3D=3D "object") Spry.Data.JSONDataSet.copyProps(row, obj); else row[basicName] =3D obj; // Make sure we note the original JSON object we used to create // this row. It may be needed if we need to flatten other sub-paths. row.ds_JSONObject =3D obj; return row; }; // Utility routine for copying properties from one object to another. Spry.Data.JSONDataSet.copyProps =3D function(dstObj, srcObj, = suppressObjProps) { if (srcObj && dstObj) { for (var prop in srcObj) { if (suppressObjProps && typeof srcObj[prop] =3D=3D "object") continue; dstObj[prop] =3D srcObj[prop]; } } return dstObj; }; // Given an object created from JSON data, and an object path, find all = the // matching objects and flatten them into rows of data. Spry.Data.JSONDataSet.flattenDataIntoRecordSet =3D function(jsonObj, = path, pathIsObjectOfArrays) { var rs =3D new Object; rs.data =3D []; rs.dataHash =3D {}; if (!path) path =3D ""; var obj =3D jsonObj; var objType =3D typeof obj; var basicColName =3D ""; // Handle the basic non-object data types. if (objType !=3D "object" || !obj) { // JSON has a null data type which we translate // into a data set with no rows. All other data types // translate into a data set with a single row with a // column named "column0" which contains the actual // data. if (obj !=3D null) { var row =3D new Object; row.column0 =3D obj; row.ds_RowID =3D 0; rs.data.push(row); rs.dataHash[row.ds_RowID] =3D row; } return rs; } var matches =3D []; if (obj.constructor =3D=3D Array) { var arrLen =3D obj.length; // We have a top-level array. If the array is empty, // then there's nothing for us to do. if (arrLen < 1) return rs; // XXX: We are making a big assumption here that all of the // elements within the array are of the same type! // // If the elements are of a basic data type, we create // a row for each element and add it as a row to the data set. var eleType =3D typeof obj[0]; if (eleType !=3D "object") { for (var i =3D 0; i < arrLen; i++) { var row =3D new Object; row.column0 =3D obj[i]; row.ds_RowID =3D i; rs.data.push(row); rs.dataHash[row.ds_RowID] =3D row; } return rs; } =09 // The elements within the array are objects. // // XXX: If they are arrays, bail, because we don't handle // arrays within arrays right now! if (obj[0].constructor =3D=3D Array) return rs; // We have an array of objects. If we have a path, use it // to fetch the data the user is interested in from each element // in the array and append the results to our matches array. // If no path was specified, just add the element to the matches // array. if (path) { for (var i =3D 0; i < arrLen; i++) matches =3D = matches.concat(Spry.Data.JSONDataSet.getMatchingObjects(path, obj[i])); } else { for (var i =3D 0; i < arrLen; i++) matches.push(obj[i]); } } else { // We have a top-level object. If the user has specified a path, // use it to extract out the data they are interested in. If no // path was specified, then just copy=20 =09 if (path) matches =3D Spry.Data.JSONDataSet.getMatchingObjects(path, obj); else matches.push(obj); } var numMatches =3D matches.length; if (path && numMatches >=3D 1 && typeof matches[0] !=3D "object") basicColName =3D path.replace(/.*\./, ""); if (!pathIsObjectOfArrays) { for (var i =3D 0; i < numMatches; i++) { var row =3D Spry.Data.JSONDataSet.flattenObject(matches[i], = basicColName, pathIsObjectOfArrays); row.ds_RowID =3D i; rs.dataHash[i] =3D row; rs.data.push(row); } } else { // Each object that was matched contains properties that are the = column names // of our rows. The value of each property is an array of values for = that column. This // means the data for each row is inverted and spread across multiple = arrays. We expect arrays of // objects, so run through all of the arrays and build up row objects = and add them // to our record set. var rowID =3D 0; for (var i =3D 0; i < numMatches; i++) { var obj =3D matches[i]; var colNames =3D []; var maxNumRows =3D 0; for (var propName in obj) { var prop =3D obj[propName]; var propyType =3D typeof prop; if (propyType =3D=3D 'object' && prop.constructor =3D=3D Array) { colNames.push(propName); maxNumRows =3D Math.max(maxNumRows, obj[propName].length); } } var numColNames =3D colNames.length; for (var j =3D 0; j < maxNumRows; j++) { var row =3D new Object; for (var k =3D 0; k < numColNames; k++) { var colName =3D colNames[k]; row[colName] =3D obj[colName][j]; } row.ds_RowID =3D rowID++; rs.dataHash[row.ds_RowID] =3D row; rs.data.push(row); } } } return rs; }; // For each JSON object used to create the rows in the specified = recordset, // find the data the matches the specified subPaths, flatten them, and = append // them to the rows of the record set. Spry.Data.JSONDataSet.prototype.flattenSubPaths =3D function(rs, = subPaths) { if (!rs || !subPaths) return; var numSubPaths =3D subPaths.length; if (numSubPaths < 1) return; var data =3D rs.data; var dataHash =3D {}; // Convert all of the templated subPaths to object paths with real = values. // We also need a "cleaned" version of the object path which contains = no // expressions in it, so that we can pre-pend it to the column names // of any nested data we find. var pathArray =3D []; var cleanedPathArray =3D []; var isObjectOfArraysArr =3D []; for (var i =3D 0; i < numSubPaths; i++) { // The elements of the subPaths array can be path strings, // or objects that describe a path with nested sub-paths below // it, so make sure we properly extract out the object path to use. var subPath =3D subPaths[i]; if (typeof subPath =3D=3D "object") { isObjectOfArraysArr[i] =3D subPath.pathIsObjectOfArrays; subPath =3D subPath.path; } if (!subPath) subPath =3D ""; // Convert any data references in the object path to real values! pathArray[i] =3D Spry.Data.Region.processDataRefString(null, subPath, = this.dataSetsForDataRefStrings); // Create a clean version of the object path by stripping out any // expressions it may contain. cleanedPathArray[i] =3D pathArray[i].replace(/\[.*\]/g, ""); } // For each row of the base record set passed in, generate a flattened // recordset from each subPath, and then join the results with the base // row. The row from the base data set will be duplicated to match the // number of rows matched by the subPath. The results are then merged. var row; var numRows =3D data.length; var newData =3D []; // Iterate over each row of the base record set. for (var i =3D 0; i < numRows; i++) { row =3D data[i]; var newRows =3D [ row ]; // Iterate over every subPath passed into this function. for (var j =3D 0; j < numSubPaths; j++) { // Search for all nodes that match the given path underneath // the JSON Object for the base row and flatten the data into // a tabular recordset structure. var newRS =3D = Spry.Data.JSONDataSet.flattenDataIntoRecordSet(row.ds_JSONObject, = pathArray[j], isObjectOfArraysArr[j]); // If this subPath has additional subPaths beneath it, // flatten and join them with the recordset we just created. if (newRS && newRS.data && newRS.data.length) { if (typeof subPaths[j] =3D=3D "object" && subPaths[j].subPaths) { // The subPaths property can be either an object path string, // an Object describing a subPath and paths beneath it, // or an Array of object path strings or objects. We need to // normalize these variations into an array to simplify // our processing. =09 var sp =3D subPaths[j].subPaths; spType =3D typeof sp; if (spType =3D=3D "string") sp =3D [ sp ]; else if (spType =3D=3D "object" && spType.constructor =3D=3D = Object) sp =3D [ sp ]; =09 // Now that we have a normalized array of sub paths, flatten // them and join them to the recordSet we just calculated. =09 this.flattenSubPaths(newRS, sp); } =09 var newRSData =3D newRS.data; var numRSRows =3D newRSData.length; =09 var cleanedPath =3D cleanedPathArray[j] + "."; =09 var numNewRows =3D newRows.length; var joinedRows =3D []; =09 // Iterate over all rows in our newRows array. Note that the // contents of newRows changes after the execution of this // loop, allowing us to perform more joins when more than // one subPath is specified. =09 for (var k =3D 0; k < numNewRows; k++) { var newRow =3D newRows[k]; =09 // Iterate over all rows in the record set generated // from the current subPath. We are going to create // m*n rows for the joined table, where m is the number // of rows in the newRows array, and n is the number of // rows in the current subPath recordset. =09 for (var l =3D 0; l < numRSRows; l++) { // Create a new row that will house the join result. =09 var newRowObj =3D new Object; var newRSRow =3D newRSData[l]; =09 // Copy the data from the current row of the record set // into our new row object, but make sure to store the // data in columns that have the subPath prepended to // it so that it doesn't collide with any columns from // the newRows row data. =09 // Copy the props to the new object using the new property name. for (var prop in newRSRow)=09 { // The new propery name will have the subPath used prepended to = it. var newPropName =3D cleanedPath + prop; =09 // We need to handle the case where the property name of the = object matched // by the object path has a value. In that specific case, the = name of the // property should be the cleanedPath itself. For example: // // { // "employees": // { // "employee": // [ // "Bob", // "Joe" // ] // } // } // // Object Path: employees.employee // // The property name that contains "Bob" and "Joe" will be = "employee". // So in our new row, we need to call this column = "employees.employee" // instead of "employees.employee.employee" which would be = incorrect. =09 if (cleanedPath =3D=3D prop || cleanedPath.search(new = RegExp("\\." + prop + "\\.$")) !=3D -1) newPropName =3D cleanedPathArray[j]; =09 // Copy the props to the new object using the new property name. newRowObj[newPropName] =3D newRSRow[prop]; } =09 // Now copy the columns from the newRow into our row // object. Spry.Data.JSONDataSet.copyProps(newRowObj, newRow); =09 // Now add this row to the array that tracks all of the new // rows we've just created. =09 joinedRows.push(newRowObj); } } // Set the newRows array equal to our joinedRows we just created, // so that when we flatten the data for the next subPath, it gets // joined with our new set of rows. newRows =3D joinedRows; } } newData =3D newData.concat(newRows); } // Now that we have a new set of joined rows, we need to run through // all of the rows and make sure they all have a unique row ID and // rebuild our dataHash. data =3D newData; numRows =3D data.length; for (i =3D 0; i < numRows; i++) { row =3D data[i]; row.ds_RowID =3D i; dataHash[row.ds_RowID] =3D row; } // We're all done, so stuff the new data and dataHash // back into the base recordSet. rs.data =3D data; rs.dataHash =3D dataHash; }; Spry.Data.JSONDataSet.prototype.parseJSON =3D function(str, filter) { // The implementation of this JSON Parser is from the json.js = (2007-03-20) // reference implementation from json.org. It was modified to accept = the // JSON string as an arg, and throw a generic Error. // // Parsing happens in three stages. In the first stage, we run the text = against // a regular expression which looks for non-JSON characters. We are = especially // concerned with '()' and 'new' because they can cause invocation, and = '=3D' // because it can cause mutation. But just to be safe, we will reject = all // unexpected characters. try { if (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u = \n\r\t])+?$/.test(str)) { // In the second stage we use the eval function to compile the text = into a // JavaScript structure. The '{' operator is subject to a syntactic = ambiguity // in JavaScript: it can begin a block or an object literal. We wrap = the text // in parens to eliminate the ambiguity. var j =3D eval('(' + str + ')'); // In the optional third stage, we recursively walk the new = structure, passing // each name/value pair to a filter function for possible = transformation. if (typeof filter =3D=3D=3D 'function') { function walk(k, v) { if (v && typeof v =3D=3D=3D 'object') { for (var i in v) { if (v.hasOwnProperty(i)) { v[i] =3D walk(i, v[i]); } } } return filter(k, v); } j =3D walk('', j); } return j; } } catch (e) { // Fall through if the regexp test fails. } throw new Error("Failed to parse JSON string."); }; Spry.Data.JSONDataSet.prototype.syncColumnTypesToData =3D function() { // Run through every column in the first row and set the column type // to match the type of the value currently in the column, but only // if the column type is not already set. // // For the sake of performance, there are a couple of big assumptions // being made here. Specifically, we are assuming that *every* row in = the // data set has the same set of column names defined, and that the = value // for a specific column has the same type as a value in the same = column // in any other row. var row =3D this.getData()[0]; for (var colName in row) { if (!this.columnTypes[colName]) { var type =3D typeof row[colName]; if (type =3D=3D "number") this.setColumnType(colName, type); } } }; // Translate the raw JSON string (rawDataDoc) into an object, find the // data within the object we are interested in, and flatten it into // a set of rows for our data set. Spry.Data.JSONDataSet.prototype.loadDataIntoDataSet =3D = function(rawDataDoc) { if (this.preparseFunc) rawDataDoc =3D this.preparseFunc(this, rawDataDoc); var jsonObj; try { jsonObj =3D this.useParser ? this.parseJSON(rawDataDoc) : = eval("(" + rawDataDoc + ")"); } catch(e) { Spry.Debug.reportError("Caught exception in = JSONDataSet.loadDataIntoDataSet: " + e); jsonObj =3D {}; } if (jsonObj =3D=3D null) jsonObj =3D "null"; var rs =3D Spry.Data.JSONDataSet.flattenDataIntoRecordSet(jsonObj, = Spry.Data.Region.processDataRefString(null, this.path, = this.dataSetsForDataRefStrings), this.pathIsObjectOfArrays); this.flattenSubPaths(rs, this.subPaths); this.doc =3D rawDataDoc; this.docObj =3D jsonObj; this.data =3D rs.data; this.dataHash =3D rs.dataHash; this.dataWasLoaded =3D (this.doc !=3D null); this.syncColumnTypesToData(); }; ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: application/octet-stream Content-Transfer-Encoding: quoted-printable Content-Location: http://www.marquette.edu/academicsenate/_js/SpryHTMLDataSet.js // SpryHTMLDataSet.js - version 0.20 - Spry Pre-Release 1.6.1 // // Copyright (c) 2006. Adobe Systems Incorporated. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions = are met: // // * Redistributions of source code must retain the above copyright = notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright = notice, // this list of conditions and the following disclaimer in the = documentation // and/or other materials provided with the distribution. // * Neither the name of Adobe Systems Incorporated nor the names of = its // contributors may be used to endorse or promote products derived = from this // software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS = "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, = THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR = PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS = BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR = BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER = IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR = OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED = OF THE // POSSIBILITY OF SUCH DAMAGE. ////////////////////////////////////////////////////////////////////// // // Spry.Data.HTMLDataSet // ////////////////////////////////////////////////////////////////////// Spry.Data.HTMLDataSet =3D function(dataSetURL, sourceElementID, = dataSetOptions) { this.sourceElementID =3D sourceElementID; // ID of the html element to = be used as a data source this.sourceElement =3D null; // The actual html element to be = used as a data source this.sourceWasInitialized =3D false; this.usesExternalFile =3D (dataSetURL !=3D null) ? true : false; =09 this.firstRowAsHeaders =3D true; this.useColumnsAsRows =3D false; this.columnNames =3D null; this.hideDataSourceElement =3D true; =09 this.rowSelector =3D null; this.dataSelector =3D null; this.tableModeEnabled =3D true; Spry.Data.HTTPSourceDataSet.call(this, dataSetURL, dataSetOptions); }; Spry.Data.HTMLDataSet.prototype =3D new Spry.Data.HTTPSourceDataSet(); Spry.Data.HTMLDataSet.prototype.constructor =3D Spry.Data.HTMLDataSet; Spry.Data.HTMLDataSet.prototype.getDataRefStrings =3D function()=20 { var dep =3D []; if (this.url)=20 dep.push(this.url); if (typeof this.sourceElementID =3D=3D "string")=20 dep.push(this.sourceElementID); =09 return dep; }; Spry.Data.HTMLDataSet.prototype.setDisplay =3D function(ele, display) { if( ele ) ele.style.display =3D display; }; Spry.Data.HTMLDataSet.prototype.initDataSource =3D = function(callLoadData) { if (!this.loadDependentDataSets()) return; if (!this.usesExternalFile) { this.setSourceElement(); if (this.hideDataSourceElement) this.setDisplay(this.sourceElement, "none"); } //this.sourceWasInitialized =3D true; }; Spry.Data.HTMLDataSet.prototype.setSourceElement =3D function = (externalDataElement) { // externalDataElement is the container that holds the data imported = from the external file. this.sourceElement =3D null; if (!this.sourceElementID)=20 { if (externalDataElement) this.sourceElement =3D externalDataElement; else { this.hideDataSourceElement =3D false; this.sourceElement =3D document.body; } return;=20 } =09 var sourceElementID =3D Spry.Data.Region.processDataRefString(null, = this.sourceElementID, this.dataSetsForDataRefStrings); if (!this.usesExternalFile) this.sourceElement =3D Spry.$(sourceElementID); else if (externalDataElement)=20 { var foundElement =3D false; // looking for the specified ID in the current element node var sources =3D Spry.Utils.getNodesByFunc(externalDataElement, = function(node) { if (foundElement)=20 return false; if (node.nodeType !=3D 1) return false; if (node.id && node.id.toLowerCase() =3D=3D = sourceElementID.toLowerCase()) { foundElement =3D true; return true; } }); this.sourceElement =3D sources[0]; } =20 if (!this.sourceElement)=20 Spry.Debug.reportError("Spry.Data.HTMLDataSet: '" + sourceElementID + = "' is not a valid element ID"); }; Spry.Data.HTMLDataSet.prototype.getSourceElement =3D function() { return = this.sourceElement; }; Spry.Data.HTMLDataSet.prototype.getSourceElementID =3D function() { = return this.sourceElementID; }; Spry.Data.HTMLDataSet.prototype.setSourceElementID =3D = function(sourceElementID) { if (this.sourceElementID !=3D sourceElementID) { this.sourceElementID =3D sourceElementID; this.recalculateDataSetDependencies(); this.dataWasLoaded =3D false; } }; Spry.Data.HTMLDataSet.prototype.getDataSelector =3D function() { return = this.dataSelector; }; Spry.Data.HTMLDataSet.prototype.setDataSelector =3D = function(dataSelector) {=20 if (this.dataSelector !=3D dataSelector) { this.dataSelector =3D dataSelector; this.dataWasLoaded =3D false; } }; Spry.Data.HTMLDataSet.prototype.getRowSelector =3D function() { return = this.rowSelector; }; Spry.Data.HTMLDataSet.prototype.setRowSelector =3D function(rowSelector) {=20 if (this.rowSelector !=3D rowSelector) { this.rowSelector =3D rowSelector; this.dataWasLoaded =3D false; } }; Spry.Data.HTMLDataSet.prototype.loadDataIntoDataSet =3D = function(rawDataDoc) { var responseText =3D rawDataDoc; responseText =3D Spry.Data.HTMLDataSet.cleanupSource(responseText); var div =3D document.createElement("div"); div.id =3D "htmlsource" + this.internalID; div.innerHTML =3D responseText; this.setSourceElement(div); if (this.sourceElement) { var parsedStructure =3D this.getDataFromSourceElement(); if (parsedStructure)=20 { this.dataHash =3D parsedStructure.dataHash; this.data =3D parsedStructure.data; } =09 } this.dataWasLoaded =3D true; div =3D null; }; Spry.Data.HTMLDataSet.prototype.loadDependentDataSets =3D function()=20 { if (this.hasDataRefStrings) { var allDataSetsReady =3D true; for (var i =3D 0; i < this.dataSetsForDataRefStrings.length; i++) { var ds =3D this.dataSetsForDataRefStrings[i]; if (ds.getLoadDataRequestIsPending()) allDataSetsReady =3D false; else if (!ds.getDataWasLoaded()) { // Kick off the load of this data set! ds.loadData(); allDataSetsReady =3D false; } } // If our data sets aren't ready, just return. We'll // get called back to load our data when they are all // done. if (!allDataSetsReady) return false; } return true; }; Spry.Data.HTMLDataSet.prototype.loadData =3D function() { this.cancelLoadData(); this.initDataSource(); =09 var self =3D this; if (!this.usesExternalFile)=20 { this.notifyObservers("onPreLoad"); =09 this.dataHash =3D new Object; this.data =3D new Array; this.dataWasLoaded =3D false; this.unfilteredData =3D null; this.curRowID =3D 0; =09 this.pendingRequest =3D new Object; this.pendingRequest.timer =3D setTimeout(function() { self.pendingRequest =3D null; var parsedStructure =3D self.getDataFromSourceElement(); if (parsedStructure)=20 { self.dataHash =3D parsedStructure.dataHash; self.data =3D parsedStructure.data; } self.dataWasLoaded =3D true; =09 self.disableNotifications(); self.filterAndSortData(); self.enableNotifications(); =09 self.notifyObservers("onPostLoad"); self.notifyObservers("onDataChanged");=09 }, 0);=20 } else=20 { var url =3D Spry.Data.Region.processDataRefString(null, this.url, = this.dataSetsForDataRefStrings); var postData =3D this.requestInfo.postData; if (postData && (typeof postData) =3D=3D "string")=20 postData =3D Spry.Data.Region.processDataRefString(null, postData, = this.dataSetsForDataRefStrings); this.notifyObservers("onPreLoad"); =09 =09 this.dataHash =3D new Object; this.data =3D new Array; this.dataWasLoaded =3D false; this.unfilteredData =3D null; this.curRowID =3D 0; var req =3D this.requestInfo.clone(); req.url =3D url; req.postData =3D postData; =09 this.pendingRequest =3D new Object; this.pendingRequest.data =3D = Spry.Data.HTTPSourceDataSet.LoadManager.loadData(req, this, = this.useCache); } }; Spry.Data.HTMLDataSet.cleanupSource =3D function (source) { // Cleans the content by replacing the src/href with spry_src=20 // This prevents browser to load the external resources. source =3D = source.replace(/<(img|script|link|frame|iframe|input)([^>]+)>/gi, = function(a,b,c) { //b=3Dtag name,c=3Dtag attributes return '<' + b + c.replace(/\b(src|href)\s*=3D/gi, function(a, b) { //b=3Dattribute name return 'spry_'+ b + '=3D'; }) + '>'; }); return source; }; Spry.Data.HTMLDataSet.undoCleanupSource =3D function (source) { // Undo cleanup. See the cleanupSource function source =3D = source.replace(/<(img|script|link|frame|iframe|input)([^>]+)>/gi, = function(a,b,c) { //b=3Dtag name,c=3Dtag attributes return '<' + b + c.replace(/\bspry_(src|href)\s*=3D/gi, function(a, = b) { //b=3Dattribute name return b + '=3D'; }) + '>'; }); return source; }; Spry.Data.HTMLDataSet.normalizeColumnName =3D function(colName)=20 { // Removes the tags from column names values // Replaces spaces with underscore colName =3D colName.replace(/(?:^[\s\t]+|[\s\t]+$)/gi, ""); colName =3D colName.replace(/<\/?([a-z]+)([^>]+)>/gi, ""); colName =3D colName.replace(/[\s\t]+/gi, "_"); return colName; }; Spry.Data.HTMLDataSet.prototype.getDataFromSourceElement =3D function()=20 { if (!this.sourceElement)=20 return null; var extractedData; var usesTable =3D (this.tableModeEnabled && = this.sourceElement.nodeName.toLowerCase() =3D=3D "table"); if (usesTable) extractedData =3D this.getDataFromHTMLTable(); else extractedData =3D this.getDataFromNestedStructure(); if (!extractedData) return null; // Flip Columns / Rows if (this.useColumnsAsRows)=20 { var flipedData =3D new Array; // Get columns and put them as rows=20 for (var rowIdx =3D 0; rowIdx < extractedData.length; rowIdx++) { var row =3D extractedData[rowIdx]; for (var cellIdx =3D 0; cellIdx < row.length; cellIdx++)=20 { if (!flipedData[cellIdx]) flipedData[cellIdx] =3D new Array; flipedData[cellIdx][rowIdx]=3D row[cellIdx]; } } extractedData =3D flipedData; } // Build the data structure for the DataSet var parsedStructure =3D new Object(); parsedStructure.dataHash =3D new Object; parsedStructure.data =3D new Array; =09 if (extractedData.length =3D=3D 0)=20 return parsedStructure; =20 =20 // Get the column names // this.firstRowAsHeaders is used only if the source of data is a TABLE var columnNames =3D new Array; var firstRowOfData =3D extractedData[0]; for (var cellIdx=3D0; cellIdx < firstRowOfData.length; cellIdx++) { if (usesTable && this.firstRowAsHeaders) columnNames[cellIdx] =3D = Spry.Data.HTMLDataSet.normalizeColumnName(firstRowOfData[cellIdx]); else columnNames[cellIdx] =3D "column" + cellIdx; } =20 // Check if column names are being overwritten using the optional = columnNames parameter if (this.columnNames && this.columnNames.length)=20 { if (this.columnNames.length < columnNames.length)=20 Spry.Debug.reportError("Too few elements in the columnNames = array. The columNames length must match the actual number of columns." = ); else for (var i=3D0; i < columnNames.length; i++) { if (this.columnNames[i]) columnNames[i] =3D = this.columnNames[i]; } } =20 // Place the extracted data into a dataset kind of structure var nextID =3D 0; var firstDataRowIndex =3D (usesTable && this.firstRowAsHeaders) ? 1: 0; for (var rowIdx =3D firstDataRowIndex; rowIdx < extractedData.length; = rowIdx++) { var row =3D extractedData[rowIdx]; if (columnNames.length !=3D row.length) { Spry.Debug.reportError("Unbalanced column names for row #" + = (rowIdx+1) + ". Skipping row." ); continue; } var rowObj =3D {}; for (var cellIdx =3D 0; cellIdx < row.length; cellIdx++) rowObj[columnNames[cellIdx]] =3D row[cellIdx]; rowObj['ds_RowID'] =3D nextID++; parsedStructure.dataHash[rowObj['ds_RowID']] =3D rowObj; parsedStructure.data.push(rowObj); } return parsedStructure; }; Spry.Data.HTMLDataSet.getElementChildren =3D function(element) { var children =3D []; var child =3D element.firstChild; while (child) { if (child.nodeType =3D=3D 1) children.push(child); child =3D child.nextSibling; } return children; }; // This method extracts data from a TABLE structure // It knows how to handle both colspan and rowspan Spry.Data.HTMLDataSet.prototype.getDataFromHTMLTable =3D function() { var tHead =3D this.sourceElement.tHead; var tBody =3D this.sourceElement.tBodies[0]; =20 var rowsHead =3D []; var rowsBody =3D []; if (tHead) rowsHead =3D = Spry.Data.HTMLDataSet.getElementChildren(tHead); if (tBody) rowsBody =3D = Spry.Data.HTMLDataSet.getElementChildren(tBody); =20 var extractedData =3D new Array; var rows =3D rowsHead.concat(rowsBody); if (this.rowSelector) rows =3D = Spry.Data.HTMLDataSet.applySelector(rows, this.rowSelector); for (var rowIdx =3D 0; rowIdx < rows.length; rowIdx++) { var row =3D rows[rowIdx]; =20 var dataRow; if (extractedData[rowIdx]) dataRow =3D extractedData[rowIdx]; else dataRow =3D new Array; =20 var offset =3D 0; var cells =3D row.cells; if (this.dataSelector) cells =3D = Spry.Data.HTMLDataSet.applySelector(cells, this.dataSelector); for (var cellIdx=3D0; cellIdx < cells.length; cellIdx++) { var cell =3D cells[cellIdx]; var nextCellIndex =3D cellIdx + offset; =20 // Find the next available position while (dataRow[nextCellIndex]) { offset ++; nextCellIndex ++; } var cellValue =3D = Spry.Data.HTMLDataSet.undoCleanupSource(cell.innerHTML); dataRow[nextCellIndex] =3D cellValue; =20 // Handle collspan var colspan =3D cell.colSpan; if (colspan =3D=3D 0) colspan =3D 1; var startOffset =3D offset; for (var offIdx =3D 1; offIdx < colspan; offIdx++) { offset ++; nextCellIndex =3D cellIdx + offset; dataRow[nextCellIndex] =3D cellValue; } =20 // Handle rowspan var rowspan =3D cell.rowSpan; if (rowspan =3D=3D 0) rowspan =3D 1; for (var rowOffIdx =3D 1; rowOffIdx < rowspan; rowOffIdx++) { nextRowIndex =3D rowIdx + rowOffIdx; var nextDataRow; if (extractedData[nextRowIndex]) nextDataRow =3D = extractedData[nextRowIndex]; else nextDataRow =3D new Array; =20 var rowSpanCellOffset =3D startOffset; for (var offIdx =3D 0; offIdx < colspan; offIdx++) { nextCellIndex =3D cellIdx + rowSpanCellOffset; nextDataRow[nextCellIndex] =3D cellValue; rowSpanCellOffset ++; } extractedData[nextRowIndex] =3D nextDataRow; } } extractedData[rowIdx] =3D dataRow; } return extractedData; }; // This method extracts data from any HTML structure // It uses rowSelector and dataSelector in order to build a three level = nested structure -=20 // Either one: rowSelector or dataSelector can miss Spry.Data.HTMLDataSet.prototype.getDataFromNestedStructure =3D = function() { var extractedData =3D new Array; =20 if (this.sourceElementID && !this.rowSelector && !this.dataSelector)=20 { // The whole sourceElementID is a single row, single cell = structure; extractedData[0] =3D = [Spry.Data.HTMLDataSet.undoCleanupSource(this.sourceElement.innerHTML)]; return extractedData; } =20 var self =3D this; // Get the rows var rows =3D []; if (!this.rowSelector) // If no rowSelector, there will be only one row rows =3D [this.sourceElement]; else rows =3D Spry.Utils.getNodesByFunc(this.sourceElement, = function(node) {=20 return Spry.Data.HTMLDataSet.evalSelector(node, = self.sourceElement, self.rowSelector);=20 });=20 =20 // Get the data columns for (var rowIdx =3D 0; rowIdx < rows.length; rowIdx++) { var row =3D rows[rowIdx]; // Get the cells that actually hold the data for each row var cells =3D []; if (!this.dataSelector) // If no dataSelector, the whole row is extracted as one cell row. cells =3D [row]; else cells =3D Spry.Utils.getNodesByFunc(row, function(node) {=20 return Spry.Data.HTMLDataSet.evalSelector(node, row, = self.dataSelector);=20 }); =20 extractedData[rowIdx] =3D new Array; for (var cellIdx =3D 0; cellIdx < cells.length; cellIdx ++) extractedData[rowIdx][cellIdx] =3D = Spry.Data.HTMLDataSet.undoCleanupSource(cells[cellIdx].innerHTML); } return extractedData; }; // Applies a css selector on a collection and returns the resulting = elements Spry.Data.HTMLDataSet.applySelector =3D function(collection, selector, = root) { var newCollection =3D []; for (var idx =3D 0; idx < collection.length; idx++) { var node =3D collection[idx]; if (Spry.Data.HTMLDataSet.evalSelector(node, = root?root:node.parentNode, selector)) newCollection.push(node); } return newCollection; }; // Checks if a specified node matches the specified css selector Spry.Data.HTMLDataSet.evalSelector =3D function (node, root, selector) { if (node.nodeType !=3D 1) return false; if (node =3D=3D root) return false; =20 // Comma delimited selectors can be passed in // The node is selected if it matches one of the selectors // #myID1, div#myID2, #myID3 var selectors =3D selector.split(","); for (var idx =3D 0; idx < selectors.length; idx ++) { var currentSelector =3D selectors[idx].replace(/^\s+/, = "").replace(/\s+$/, ""); var tagName =3D null; var className =3D null; var id =3D null; =09 // Accepted values for the selector: // DIV.myClass | DIV | .myClass | *.myClass // DIV#myID | #myID // > DIV.myClass : > points to the direct descendents =09 var selected =3D true; if (currentSelector.substring(0,1) =3D=3D ">")=20 { // Looking for direct descendants only if (node.parentNode !=3D root)=20 selected =3D false; else currentSelector =3D = currentSelector.substring(1).replace(/^\s+/, ""); } if (selected)=20 { tagName =3D currentSelector.toLowerCase(); if (currentSelector.indexOf(".") !=3D -1) { var parts =3D currentSelector.split("."); tagName =3D parts[0]; className =3D parts[1]; } else if (currentSelector.indexOf("#") !=3D -1) { var parts =3D currentSelector.split("#"); tagName =3D parts[0]; id =3D parts[1]; } } if (selected && tagName !=3D '' && tagName !=3D '*') if (node.nodeName.toLowerCase() !=3D tagName)=20 selected =3D false; if (selected && id && node.id !=3D id) selected =3D false; if (selected && className && node.className.search(new RegExp('\\b' = + className + '\\b', 'i')) =3D=3D-1)=20 selected =3D false; if (selected) return true; } return false; }; ------=_NextPart_000_0000_01CBD2B6.E7122D00 Content-Type: application/octet-stream Content-Transfer-Encoding: quoted-printable Content-Location: http://www.marquette.edu/academicsenate/_js/SpryAutoSuggest.js // SpryAutoSuggest.js - version 0.91 - Spry Pre-Release 1.6.1=0A= //=0A= // Copyright (c) 2006. Adobe Systems Incorporated.=0A= // All rights reserved.=0A= //=0A= // Redistribution and use in source and binary forms, with or without=0A= // modification, are permitted provided that the following conditions = are met:=0A= //=0A= // * Redistributions of source code must retain the above copyright = notice,=0A= // this list of conditions and the following disclaimer.=0A= // * Redistributions in binary form must reproduce the above copyright = notice,=0A= // this list of conditions and the following disclaimer in the = documentation=0A= // and/or other materials provided with the distribution.=0A= // * Neither the name of Adobe Systems Incorporated nor the names of = its=0A= // contributors may be used to endorse or promote products derived = from this=0A= // software without specific prior written permission.=0A= //=0A= // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS = "AS IS"=0A= // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, = THE=0A= // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR = PURPOSE=0A= // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS = BE=0A= // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR=0A= // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF=0A= // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR = BUSINESS=0A= // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER = IN=0A= // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR = OTHERWISE)=0A= // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED = OF THE=0A= // POSSIBILITY OF SUCH DAMAGE.=0A= =0A= var Spry;=0A= if (!Spry) Spry =3D {};=0A= if (!Spry.Widget) Spry.Widget =3D {};=0A= =0A= Spry.Widget.BrowserSniff =3D function()=0A= {=0A= var b =3D navigator.appName.toString();=0A= var up =3D navigator.platform.toString();=0A= var ua =3D navigator.userAgent.toString();=0A= =0A= this.mozilla =3D this.ie =3D this.opera =3D this.safari =3D false;=0A= var re_opera =3D /Opera.([0-9\.]*)/i;=0A= var re_msie =3D /MSIE.([0-9\.]*)/i;=0A= var re_gecko =3D /gecko/i;=0A= var re_safari =3D /(applewebkit|safari)\/([\d\.]*)/i;=0A= var r =3D false;=0A= =0A= if ( (r =3D ua.match(re_opera))) {=0A= this.opera =3D true;=0A= this.version =3D parseFloat(r[1]);=0A= } else if ( (r =3D ua.match(re_msie))) {=0A= this.ie =3D true;=0A= this.version =3D parseFloat(r[1]);=0A= } else if ( (r =3D ua.match(re_safari))) {=0A= this.safari =3D true;=0A= this.version =3D parseFloat(r[2]);=0A= } else if (ua.match(re_gecko)) {=0A= var re_gecko_version =3D /rv:\s*([0-9\.]+)/i;=0A= r =3D ua.match(re_gecko_version);=0A= this.mozilla =3D true;=0A= this.version =3D parseFloat(r[1]);=0A= }=0A= this.windows =3D this.mac =3D this.linux =3D false;=0A= =0A= this.Platform =3D ua.match(/windows/i) ? "windows" :=0A= (ua.match(/linux/i) ? "linux" :=0A= (ua.match(/mac/i) ? "mac" :=0A= ua.match(/unix/i)? "unix" : "unknown"));=0A= this[this.Platform] =3D true;=0A= this.v =3D this.version;=0A= =0A= if (this.safari && this.mac && this.mozilla) {=0A= this.mozilla =3D false;=0A= }=0A= };=0A= =0A= Spry.is =3D new Spry.Widget.BrowserSniff();=0A= =0A= Spry.Widget.AutoSuggest =3D function(region, sRegion, dataset, field, = options)=0A= {=0A= if (!this.isBrowserSupported())=0A= return;=0A= =0A= options =3D options || {};=0A= =0A= this.init(region, sRegion, dataset, field);=0A= Spry.Widget.Utils.setOptions(this, options);=0A= =0A= if (Spry.Widget.AutoSuggest.onloadDidFire)=0A= this.attachBehaviors();=0A= else =0A= Spry.Widget.AutoSuggest.loadQueue.push(this);=0A= =0A= // when data is changing we will decide if we will have to show the = suggestions=0A= this.dataset.addObserver(this);=0A= =0A= // Set up an observer so we can attach our click behaviors whenever=0A= // the region is regenerated.=0A= var regionID =3D Spry.Widget.Utils.getElementID(sRegion);=0A= =0A= var self =3D this;=0A= this._notifyDataset =3D { onPostUpdate: function() {=0A= self.attachClickBehaviors();=0A= }, onPreUpdate: function(){=0A= self.removeClickBehaviours();=0A= }};=0A= =0A= Spry.Data.Region.addObserver(regionID,this._notifyDataset);=0A= =0A= // clean up the widget when on page unload=0A= Spry.Widget.Utils.addEventListener(window, 'unload', = function(){self.destroy()}, false);=0A= =0A= // make the first computation in case the textfield is not empty=0A= this.attachClickBehaviors();=0A= this.handleKeyUp(null);=0A= this.showSuggestions(false);=0A= };=0A= =0A= Spry.Widget.AutoSuggest.prototype.init =3D function(region, sRegion, = dataset, field)=0A= {=0A= this.region =3D Spry.Widget.Utils.getElement(region);=0A= =0A= if (!this.region)=0A= return;=0A= =0A= this.minCharsType =3D false;=0A= this.containsString =3D false;=0A= this.loadFromServer =3D false;=0A= this.urlParam =3D '';=0A= this.suggestionIsVisible =3D false;=0A= this.stopFocus =3D false;=0A= this.hasFocus =3D false;=0A= this.showSuggestClass =3D 'showSuggestClass';=0A= this.hideSuggestClass =3D 'hideSuggestClass';=0A= this.hoverSuggestClass =3D 'hoverSuggestClass';=0A= this.movePrevKeyCode =3D Spry.Widget.AutoSuggest.KEY_UP;=0A= this.moveNextKeyCode =3D Spry.Widget.AutoSuggest.KEY_DOWN;=0A= =0A= this.textElement =3D = Spry.Widget.Utils.getFirstChildWithNodeNameAtAnyLevel(this.region, = "INPUT");=0A= this.textElement.setAttribute('AutoComplete', 'off');=0A= =0A= this.suggestRegion =3D Spry.Widget.Utils.getElement(sRegion);=0A= // prepare the suggest region=0A= Spry.Widget.Utils.makePositioned(this.suggestRegion);=0A= Spry.Widget.Utils.addClassName(this.suggestRegion, = this.hideSuggestClass);=0A= =0A= this.timerID =3D null;=0A= if (typeof dataset =3D=3D "string"){=0A= this.dataset =3D window[dataset];=0A= }else{=0A= this.dataset =3D dataset;=0A= }=0A= this.field =3D field;=0A= if (typeof field =3D=3D 'string' && field.indexOf(',') !=3D -1)=0A= {=0A= field =3D field.replace(/\s*,\s*/ig, ',');=0A= this.field =3D field.split(',');=0A= }=0A= };=0A= =0A= Spry.Widget.AutoSuggest.prototype.isBrowserSupported =3D function()=0A= {=0A= return Spry.is.ie && Spry.is.v >=3D 5 && Spry.is.windows=0A= ||=0A= Spry.is.mozilla && Spry.is.v >=3D 1.4=0A= ||=0A= Spry.is.safari=0A= ||=0A= Spry.is.opera && Spry.is.v >=3D 9;=0A= };=0A= =0A= Spry.Widget.AutoSuggest.prototype.getValue =3D function()=0A= {=0A= if (!this.textElement)=0A= return '';=0A= return this.textElement.value;=0A= };=0A= =0A= Spry.Widget.AutoSuggest.prototype.setValue =3D function(str)=0A= {=0A= if (!this.textElement)=0A= return;=0A= this.textElement.value =3D str;=0A= this.showSuggestions(false);=0A= };=0A= =0A= Spry.Widget.AutoSuggest.prototype.focus =3D function()=0A= {=0A= if (!this.textElement)=0A= return;=0A= this.textElement.focus();=0A= };=0A= =0A= Spry.Widget.AutoSuggest.prototype.showSuggestions =3D function(doShow)=0A= {=0A= if (this.region && this.isVisibleSuggestion() !=3D doShow)=0A= {=0A= if (doShow && this.hasFocus)=0A= {=0A= Spry.Widget.Utils.addClassName(this.region, this.showSuggestClass);=0A= if (Spry.is.ie && Spry.is.version < 7)=0A= this.createIframeLayer(this.suggestRegion);=0A= }=0A= else=0A= {=0A= if (Spry.is.ie && Spry.is.version < 7)=0A= this.removeIframeLayer();=0A= Spry.Widget.Utils.removeClassName(this.region, = this.showSuggestClass);=0A= }=0A= }=0A= this.suggestionIsVisible =3D = Spry.Widget.Utils.hasClassName(this.region, this.showSuggestClass);=0A= };=0A= =0A= Spry.Widget.AutoSuggest.prototype.isVisibleSuggestion =3D function()=0A= {=0A= return this.suggestionIsVisible;=0A= };=0A= =0A= Spry.Widget.AutoSuggest.prototype.onDataChanged =3D function(el)=0A= {=0A= var data =3D el.getData(true);=0A= var val =3D this.getValue();=0A= this.showSuggestions(data && (!this.minCharsType || val.length >=3D = this.minCharsType) && (data.length > 1 || (data.length =3D=3D 1 && = this.childs[0] && = this.childs[0].attributes.getNamedItem("spry:suggest").value !=3D = this.getValue())));=0A= };=0A= Spry.Widget.AutoSuggest.prototype.nodeMouseOver =3D function(e, node)=0A= {=0A= var l =3D this.childs.length;=0A= for (var i=3D0; i this.scrolParent.scrollTop + = h)=0A= {=0A= // the 5 pixels make the latest option more visible.=0A= this.scrolParent.scrollTop =3D el.offsetTop + el.offsetHeight - h + 5;=0A= if (this.scrolParent.scrollTop < 0)=0A= this.scrolParent.scrollTop =3D 0; =0A= }=0A= =0A= }=0A= };=0A= =0A= Spry.Widget.AutoSuggest.KEY_UP =3D 38;=0A= Spry.Widget.AutoSuggest.KEY_DOWN =3D 40;=0A= =0A= Spry.Widget.AutoSuggest.prototype.handleSpecialKeys =3D function(e){=0A= =0A= switch (e.keyCode)=0A= {=0A= case this.moveNextKeyCode: // Down key =0A= case this.movePrevKeyCode: // Up Key=0A= if (!(this.childs.length > 0) || !this.getValue())=0A= return; =0A= =0A= var prev =3D this.childs.length-1;=0A= var next =3D false;=0A= var found =3D false;=0A= var data =3D this.dataset.getData();=0A= if (this.childs.length > 1 || (data && data.length =3D=3D 1 && = this.childs[0] && = this.childs[0].attributes.getNamedItem('spry:suggest').value !=3D = this.getValue()))=0A= {=0A= this.showSuggestions(true);=0A= }=0A= else=0A= return; =0A= =0A= var utils =3D Spry.Widget.Utils;=0A= for (var k=3D0; k < this.childs.length; k++)=0A= {=0A= if (next)=0A= {=0A= utils.addClassName(this.childs[k], this.hoverSuggestClass);=0A= this.scrollVisible(this.childs[k]);=0A= break;=0A= }=0A= if (utils.hasClassName(this.childs[k], this.hoverSuggestClass))=0A= {=0A= utils.removeClassName(this.childs[k], this.hoverSuggestClass);=0A= found =3D true;=0A= if (e.keyCode =3D=3D this.moveNextKeyCode)=0A= {=0A= next =3D true;=0A= continue;=0A= }=0A= else=0A= {=0A= utils.addClassName(this.childs[prev], this.hoverSuggestClass);=0A= this.scrollVisible(this.childs[prev]);=0A= break;=0A= }=0A= }=0A= prev =3D k;=0A= }=0A= if (!found || (next && k =3D=3D this.childs.length))=0A= {=0A= utils.addClassName(this.childs[0], this.hoverSuggestClass);=0A= this.scrollVisible(this.childs[0]);=0A= }=0A= utils.stopEvent(e);=0A= break;=0A= case 27: // ESC key=0A= this.showSuggestions(false);=0A= break;=0A= case 13: //Enter Key=0A= if (!this.isVisibleSuggestion())=0A= return;=0A= for (var k=3D0; k < this.childs.length; k++)=0A= if (Spry.Widget.Utils.hasClassName(this.childs[k], = this.hoverSuggestClass))=0A= {=0A= var attr =3D this.childs[k].attributes.getNamedItem('spry:suggest');=0A= if (attr){=0A= var link =3D = Spry.Widget.Utils.getFirstChildWithNodeNameAtAnyLevel(this.childs[k], = 'a');=0A= if (link)=0A= window.location =3D link.href;=0A= this.setValue(attr.value);=0A= this.handleKeyUp(null);=0A= }=0A= // stop form submission=0A= Spry.Widget.Utils.stopEvent(e);=0A= return false;=0A= }=0A= break; =0A= case 9: //Tab Key=0A= this.showSuggestions(false);=0A= }=0A= return;=0A= };=0A= =0A= Spry.Widget.AutoSuggest.prototype.filterDataSet =3D function()=0A= {=0A= var contains =3D this.containsString;=0A= var columnName =3D this.field;=0A= var val =3D this.getValue();=0A= =0A= if (this.previousString && this.previousString =3D=3D val)=0A= return;=0A= =0A= this.previousString =3D val;=0A= =0A= if (!val || (this.minCharsType && this.minCharsType > val.length))=0A= {=0A= this.dataset.filter(function(ds, row, rowNumber) {return null;});=0A= this.showSuggestions(false);=0A= return;=0A= }=0A= =0A= var regExpStr =3D Spry.Widget.Utils.escapeRegExp(val);=0A= =0A= if (!contains)=0A= regExpStr =3D "^" + regExpStr;=0A= =0A= var regExp =3D new RegExp(regExpStr, "ig");=0A= =0A= if (this.maxListItems > 0)=0A= this.dataset.maxItems =3D this.maxListItems;=0A= =0A= var filterFunc =3D function(ds, row, rowNumber)=0A= {=0A= if (ds.maxItems >0 && ds.maxItems <=3D ds.data.length)=0A= return null;=0A= =0A= if (typeof columnName =3D=3D 'object')=0A= {=0A= var l =3D columnName.length;=0A= for (var i=3D0; i < l; i++)=0A= {=0A= var str =3D row[columnName[i]];=0A= if (str && str.search(regExp) !=3D -1)=0A= return row;=0A= }=0A= }=0A= else=0A= {=0A= var str =3D row[columnName];=0A= if (str && str.search(regExp) !=3D -1)=0A= return row;=0A= }=0A= return null; =0A= };=0A= =0A= this.dataset.filter(filterFunc);=0A= var data =3D this.dataset.getData();=0A= this.showSuggestions(data && (!this.minCharsType || val.length >=3D = this.minCharsType) && (data.length > 1 || (data.length =3D=3D 1 && = this.childs[0] && = this.childs[0].attributes.getNamedItem('spry:suggest').value !=3D val = )));=0A= };=0A= =0A= Spry.Widget.AutoSuggest.prototype.loadDataSet =3D function()=0A= {=0A= var val =3D this.getValue();=0A= var ds =3D this.dataset;=0A= ds.cancelLoadData();=0A= ds.useCache =3D false;=0A= =0A= if (!val || (this.minCharsType && this.minCharsType > val.length))=0A= {=0A= this.showSuggestions(false);=0A= return;=0A= }=0A= =0A= if (this.previousString && this.previousString =3D=3D val)=0A= {=0A= var data =3D ds.getData();=0A= this.showSuggestions(data && (data.length > 1 || (data.length =3D=3D 1 = && this.childs[0].attributes.getNamedItem("spry:suggest").value !=3D = val)));=0A= return;=0A= }=0A= =0A= this.previousString =3D val;=0A= =0A= var url =3D Spry.Widget.Utils.addReplaceParam(ds.url, this.urlParam, = val);=0A= ds.setURL(url);=0A= ds.loadData();=0A= };=0A= =0A= Spry.Widget.AutoSuggest.prototype.addMouseListener =3D function(node, = value)=0A= {=0A= var self =3D this;=0A= var addListener =3D Spry.Widget.Utils.addEventListener;=0A= addListener(node, "click", function(e){ return self.nodeClick(e, = value); self.handleKeyUp(null);}, false); =0A= addListener(node, "mouseover", function(e){ = Spry.Widget.Utils.addClassName(node, self.hoverSuggestClass); = self.nodeMouseOver(e, node)}, false); =0A= addListener(node, "mouseout", function(e){ = Spry.Widget.Utils.removeClassName(node, self.hoverSuggestClass); = self.nodeMouseOver(e, node)}, false); =0A= };=0A= Spry.Widget.AutoSuggest.prototype.removeMouseListener =3D = function(node, value)=0A= {=0A= var self =3D this;=0A= var removeListener =3D Spry.Widget.Utils.removeEventListener;=0A= removeListener(node, "click", function (e){ self.nodeClick(e, value); = self.handleKeyUp(null);}, false); =0A= removeListener(node, "mouseover", function(e){ = Spry.Widget.Utils.addClassName(node, self.hoverSuggestClass); = self.nodeMouseOver(e, node)}, false); =0A= removeListener(node, "mouseout", function(e){ = Spry.Widget.Utils.removeClassName(node, self.hoverSuggestClass); = self.nodeMouseOver(e, node)}, false); =0A= };=0A= Spry.Widget.AutoSuggest.prototype.attachClickBehaviors =3D function()=0A= {=0A= var self =3D this;=0A= var valNodes =3D Spry.Utils.getNodesByFunc(this.region, function(node)=0A= {=0A= if (node.nodeType =3D=3D 1) /* Node.ELEMENT_NODE */=0A= {=0A= var attr =3D node.attributes.getNamedItem("spry:suggest");=0A= if (attr){=0A= self.addMouseListener(node, attr.value);=0A= return true;=0A= }=0A= }=0A= return false;=0A= });=0A= this.childs =3D valNodes;=0A= };=0A= Spry.Widget.AutoSuggest.prototype.removeClickBehaviours =3D function()=0A= {=0A= var self =3D this;=0A= var valNodes =3D Spry.Utils.getNodesByFunc(this.region, function(node)=0A= {=0A= if (node.nodeType =3D=3D 1) /* Node.ELEMENT_NODE */=0A= {=0A= var attr =3D node.attributes.getNamedItem("spry:suggest");=0A= if (attr){=0A= self.removeMouseListener(node, attr.value);=0A= return true;=0A= }=0A= }=0A= return false;=0A= });=0A= };=0A= Spry.Widget.AutoSuggest.prototype.destroy =3D function(){=0A= =0A= this.removeClickBehaviours();=0A= = Spry.Data.Region.removeObserver(Spry.Widget.Utils.getElementID(this.sugge= stRegion),this._notifyDataset);=0A= =0A= if (this.event_handlers)=0A= for (var i=3D0; i0)=0A= {=0A= if(isFirstEntry)=0A= {=0A= camelizedString =3D oStringList[i];=0A= isFirstEntry =3D false;=0A= }=0A= else=0A= {=0A= var s =3D oStringList[i];=0A= camelizedString +=3D s.charAt(0).toUpperCase() + s.substring(1);=0A= }=0A= }=0A= }=0A= =0A= return camelizedString;=0A= };=0A= =0A= Spry.Widget.Utils.getStyleProp =3D function(element, prop)=0A= {=0A= var value;=0A= var camel =3D Spry.Widget.Utils.camelize(prop);=0A= try=0A= {=0A= value =3D element.style[camel];=0A= if (!value)=0A= {=0A= if (document.defaultView && document.defaultView.getComputedStyle)=0A= {=0A= var css =3D document.defaultView.getComputedStyle(element, null);=0A= value =3D css ? css.getPropertyValue(prop) : null;=0A= }=0A= else=0A= if (element.currentStyle)=0A= value =3D element.currentStyle[camel];=0A= }=0A= }=0A= catch (e) {}=0A= =0A= return value =3D=3D 'auto' ? null : value;=0A= };=0A= Spry.Widget.Utils.makePositioned =3D function(element)=0A= {=0A= var pos =3D Spry.Widget.Utils.getStyleProp(element, 'position');=0A= if (!pos || pos =3D=3D 'static')=0A= {=0A= element.style.position =3D 'absolute';=0A= =0A= // Opera returns the offset relative to the positioning context, when = an=0A= // element is position relative but top and left have not been defined=0A= if (window.opera)=0A= {=0A= element.style.top =3D 0;=0A= element.style.left =3D 0;=0A= }=0A= }=0A= };=0A= Spry.Widget.Utils.escapeRegExp =3D function(rexp)=0A= {=0A= return rexp.replace(/([\.\/\]\[\{\}\(\)\\\$\^\?\*\|\!\=3D\+\-])/g, = '\\$1');=0A= };=0A= Spry.Widget.Utils.getFirstChildWithNodeNameAtAnyLevel =3D function(node, = nodeName)=0A= {=0A= var elements =3D node.getElementsByTagName(nodeName);=0A= if (elements)=0A= return elements[0];=0A= =0A= return null;=0A= };=0A= ------=_NextPart_000_0000_01CBD2B6.E7122D00--