Checked in new UI code
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@6485 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
17
xCAT-UI/.project
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>xCat UI</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
17
xCAT-UI/configure.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* Configure page
|
||||
*/
|
||||
require_once "lib/functions.php";
|
||||
require_once "lib/ui.php";
|
||||
|
||||
/* Load page */
|
||||
loadPage();
|
||||
|
||||
/* Login user */
|
||||
if (!isAuthenticated()) {
|
||||
login();
|
||||
} else {
|
||||
loadContent();
|
||||
}
|
||||
?>
|
BIN
xCAT-UI/css/images/ui-bg_flat_0_aaaaaa_40x100.png
Normal file
After Width: | Height: | Size: 180 B |
BIN
xCAT-UI/css/images/ui-bg_glass_55_fbf9ee_1x400.png
Normal file
After Width: | Height: | Size: 120 B |
BIN
xCAT-UI/css/images/ui-bg_glass_65_ffffff_1x400.png
Normal file
After Width: | Height: | Size: 105 B |
BIN
xCAT-UI/css/images/ui-bg_glass_75_dadada_1x400.png
Normal file
After Width: | Height: | Size: 111 B |
BIN
xCAT-UI/css/images/ui-bg_glass_75_e6e6e6_1x400.png
Normal file
After Width: | Height: | Size: 110 B |
BIN
xCAT-UI/css/images/ui-bg_glass_75_ffffff_1x400.png
Normal file
After Width: | Height: | Size: 107 B |
BIN
xCAT-UI/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png
Normal file
After Width: | Height: | Size: 101 B |
BIN
xCAT-UI/css/images/ui-bg_inset-soft_95_fef1ec_1x100.png
Normal file
After Width: | Height: | Size: 123 B |
BIN
xCAT-UI/css/images/ui-icons_222222_256x240.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
xCAT-UI/css/images/ui-icons_2e83ff_256x240.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
xCAT-UI/css/images/ui-icons_454545_256x240.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
xCAT-UI/css/images/ui-icons_888888_256x240.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
xCAT-UI/css/images/ui-icons_cd0a0a_256x240.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
1769
xCAT-UI/css/jquery-ui-1.8.custom.css
vendored
Normal file
48
xCAT-UI/css/jquery.autocomplete.css
Normal file
@ -0,0 +1,48 @@
|
||||
.ac_results {
|
||||
padding: 0px;
|
||||
border: 1px solid black;
|
||||
background-color: white;
|
||||
overflow: hidden;
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
.ac_results ul {
|
||||
width: 100%;
|
||||
list-style-position: outside;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.ac_results li {
|
||||
margin: 0px;
|
||||
padding: 2px 5px;
|
||||
cursor: default;
|
||||
display: block;
|
||||
/*
|
||||
if width will be 100% horizontal scrollbar will apear
|
||||
when scroll mode will be used
|
||||
*/
|
||||
/*width: 100%;*/
|
||||
font: menu;
|
||||
font-size: 12px;
|
||||
/*
|
||||
it is very important, if line-height not setted or setted
|
||||
in relative units scroll will be broken in firefox
|
||||
*/
|
||||
line-height: 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ac_loading {
|
||||
background: white url('indicator.gif') right center no-repeat;
|
||||
}
|
||||
|
||||
.ac_odd {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.ac_over {
|
||||
background-color: #0A246A;
|
||||
color: white;
|
||||
}
|
475
xCAT-UI/css/jquery.dataTables.css
Normal file
@ -0,0 +1,475 @@
|
||||
/*
|
||||
* File: demo_table.css
|
||||
* CVS: $Id$
|
||||
* Description: CSS descriptions for DataTables demo pages
|
||||
* Author: Allan Jardine
|
||||
* Created: Tue May 12 06:47:22 BST 2009
|
||||
* Modified: $Date$ by $Author$
|
||||
* Language: CSS
|
||||
* Project: DataTables
|
||||
*
|
||||
* Copyright 2009 Allan Jardine. All Rights Reserved.
|
||||
*
|
||||
* ***************************************************************************
|
||||
* DESCRIPTION
|
||||
*
|
||||
* The styles given here are suitable for the demos that are used with the standard DataTables
|
||||
* distribution (see www.datatables.net). You will most likely wish to modify these styles to
|
||||
* meet the layout requirements of your site.
|
||||
*
|
||||
* Common issues:
|
||||
* 'full_numbers' pagination - I use an extra selector on the body tag to ensure that there is
|
||||
* no conflict between the two pagination types. If you want to use full_numbers pagination
|
||||
* ensure that you either have "example_alt_pagination" as a body class name, or better yet,
|
||||
* modify that selector.
|
||||
* Note that the path used for Images is relative. All images are by default located in
|
||||
* ../images/ - relative to this CSS file.
|
||||
*/
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* DataTables features
|
||||
*/
|
||||
.dataTables_wrapper {
|
||||
position: relative;
|
||||
min-height: 302px;
|
||||
clear: both;
|
||||
_height: 302px;
|
||||
zoom: 1; /* Feeling sorry for IE */
|
||||
}
|
||||
|
||||
.dataTables_processing {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 250px;
|
||||
height: 30px;
|
||||
margin-left: -125px;
|
||||
margin-top: -15px;
|
||||
padding: 14px 0 2px 0;
|
||||
border: 1px solid #ddd;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.dataTables_length {
|
||||
width: 40%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.dataTables_filter {
|
||||
width: 50%;
|
||||
float: right;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.dataTables_info {
|
||||
width: 60%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.dataTables_paginate {
|
||||
width: 44px; *
|
||||
width: 50px;
|
||||
float: right;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* Pagination nested */
|
||||
.paginate_disabled_previous,.paginate_enabled_previous,.paginate_disabled_next,.paginate_enabled_next
|
||||
{
|
||||
height: 19px;
|
||||
width: 19px;
|
||||
margin-left: 3px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.paginate_disabled_previous {
|
||||
background-image: url('../images/back_disabled.jpg');
|
||||
}
|
||||
|
||||
.paginate_enabled_previous {
|
||||
background-image: url('../images/back_enabled.jpg');
|
||||
}
|
||||
|
||||
.paginate_disabled_next {
|
||||
background-image: url('../images/forward_disabled.jpg');
|
||||
}
|
||||
|
||||
.paginate_enabled_next {
|
||||
background-image: url('../images/forward_enabled.jpg');
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* DataTables display
|
||||
*/
|
||||
table.display {
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
table.display thead th {
|
||||
padding: 3px 18px 3px 10px;
|
||||
border-bottom: 1px solid black;
|
||||
font-weight: bold;
|
||||
cursor: pointer; *
|
||||
cursor: hand;
|
||||
}
|
||||
|
||||
table.display tfoot th {
|
||||
padding: 3px 10px;
|
||||
border-top: 1px solid black;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
table.display tr.heading2 td {
|
||||
border-bottom: 1px solid #aaa;
|
||||
}
|
||||
|
||||
table.display td {
|
||||
padding: 3px 10px;
|
||||
}
|
||||
|
||||
table.display td.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* DataTables sorting
|
||||
*/
|
||||
.sorting_asc {
|
||||
background: url('../images/sort_asc.png') no-repeat center right;
|
||||
}
|
||||
|
||||
.sorting_desc {
|
||||
background: url('../images/sort_desc.png') no-repeat center right;
|
||||
}
|
||||
|
||||
.sorting {
|
||||
background: url('../images/sort_both.png') no-repeat center right;
|
||||
}
|
||||
|
||||
.sorting_asc_disabled {
|
||||
background: url('../images/sort_asc_disabled.png') no-repeat center
|
||||
right;
|
||||
}
|
||||
|
||||
.sorting_desc_disabled {
|
||||
background: url('../images/sort_desc_disabled.png') no-repeat center
|
||||
right;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* DataTables row classes
|
||||
*/
|
||||
table.display tr.odd.gradeA {
|
||||
background-color: #ddffdd;
|
||||
}
|
||||
|
||||
table.display tr.even.gradeA {
|
||||
background-color: #eeffee;
|
||||
}
|
||||
|
||||
table.display tr.odd.gradeA {
|
||||
background-color: #ddffdd;
|
||||
}
|
||||
|
||||
table.display tr.even.gradeA {
|
||||
background-color: #eeffee;
|
||||
}
|
||||
|
||||
table.display tr.odd.gradeC {
|
||||
background-color: #ddddff;
|
||||
}
|
||||
|
||||
table.display tr.even.gradeC {
|
||||
background-color: #eeeeff;
|
||||
}
|
||||
|
||||
table.display tr.odd.gradeX {
|
||||
background-color: #ffdddd;
|
||||
}
|
||||
|
||||
table.display tr.even.gradeX {
|
||||
background-color: #ffeeee;
|
||||
}
|
||||
|
||||
table.display tr.odd.gradeU {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
table.display tr.even.gradeU {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
tr.odd {
|
||||
background-color: #E2E4FF;
|
||||
}
|
||||
|
||||
tr.even {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Misc
|
||||
*/
|
||||
.top,.bottom {
|
||||
padding: 15px;
|
||||
background-color: #F5F5F5;
|
||||
border: 1px solid #CCCCCC;
|
||||
}
|
||||
|
||||
.top .dataTables_info {
|
||||
float: none;
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.dataTables_empty {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
tfoot input {
|
||||
margin: 0.5em 0;
|
||||
width: 100%;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
tfoot input.search_init {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
td.group {
|
||||
background-color: #d1cfd0;
|
||||
border-bottom: 2px solid #A19B9E;
|
||||
border-top: 2px solid #A19B9E;
|
||||
}
|
||||
|
||||
td.details {
|
||||
background-color: #d1cfd0;
|
||||
border: 2px solid #A19B9E;
|
||||
}
|
||||
|
||||
.example_alt_pagination div.dataTables_info {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.paging_full_numbers {
|
||||
width: 400px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.paging_full_numbers span.paginate_button,.paging_full_numbers span.paginate_active
|
||||
{
|
||||
border: 1px solid #aaa;
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
padding: 2px 5px;
|
||||
margin: 0 3px;
|
||||
cursor: pointer; *
|
||||
cursor: hand;
|
||||
}
|
||||
|
||||
.paging_full_numbers span.paginate_button {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
.paging_full_numbers span.paginate_button:hover {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
.paging_full_numbers span.paginate_active {
|
||||
background-color: #99B3FF;
|
||||
}
|
||||
|
||||
table.display tr.even.row_selected td {
|
||||
background-color: #B0BED9;
|
||||
}
|
||||
|
||||
table.display tr.odd.row_selected td {
|
||||
background-color: #9FAFD1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sorting classes for columns
|
||||
*/ /* For the standard odd/even */
|
||||
tr.odd td.sorting_1 {
|
||||
background-color: #D3D6FF;
|
||||
}
|
||||
|
||||
tr.odd td.sorting_2 {
|
||||
background-color: #DADCFF;
|
||||
}
|
||||
|
||||
tr.odd td.sorting_3 {
|
||||
background-color: #E0E2FF;
|
||||
}
|
||||
|
||||
tr.even td.sorting_1 {
|
||||
background-color: #EAEBFF;
|
||||
}
|
||||
|
||||
tr.even td.sorting_2 {
|
||||
background-color: #F2F3FF;
|
||||
}
|
||||
|
||||
tr.even td.sorting_3 {
|
||||
background-color: #F9F9FF;
|
||||
}
|
||||
|
||||
/* For the Conditional-CSS grading rows */ /*
|
||||
Colour calculations (based off the main row colours)
|
||||
Level 1:
|
||||
dd > c4
|
||||
ee > d5
|
||||
Level 2:
|
||||
dd > d1
|
||||
ee > e2
|
||||
*/
|
||||
tr.odd.gradeA td.sorting_1 {
|
||||
background-color: #c4ffc4;
|
||||
}
|
||||
|
||||
tr.odd.gradeA td.sorting_2 {
|
||||
background-color: #d1ffd1;
|
||||
}
|
||||
|
||||
tr.odd.gradeA td.sorting_3 {
|
||||
background-color: #d1ffd1;
|
||||
}
|
||||
|
||||
tr.even.gradeA td.sorting_1 {
|
||||
background-color: #d5ffd5;
|
||||
}
|
||||
|
||||
tr.even.gradeA td.sorting_2 {
|
||||
background-color: #e2ffe2;
|
||||
}
|
||||
|
||||
tr.even.gradeA td.sorting_3 {
|
||||
background-color: #e2ffe2;
|
||||
}
|
||||
|
||||
tr.odd.gradeC td.sorting_1 {
|
||||
background-color: #c4c4ff;
|
||||
}
|
||||
|
||||
tr.odd.gradeC td.sorting_2 {
|
||||
background-color: #d1d1ff;
|
||||
}
|
||||
|
||||
tr.odd.gradeC td.sorting_3 {
|
||||
background-color: #d1d1ff;
|
||||
}
|
||||
|
||||
tr.even.gradeC td.sorting_1 {
|
||||
background-color: #d5d5ff;
|
||||
}
|
||||
|
||||
tr.even.gradeC td.sorting_2 {
|
||||
background-color: #e2e2ff;
|
||||
}
|
||||
|
||||
tr.even.gradeC td.sorting_3 {
|
||||
background-color: #e2e2ff;
|
||||
}
|
||||
|
||||
tr.odd.gradeX td.sorting_1 {
|
||||
background-color: #ffc4c4;
|
||||
}
|
||||
|
||||
tr.odd.gradeX td.sorting_2 {
|
||||
background-color: #ffd1d1;
|
||||
}
|
||||
|
||||
tr.odd.gradeX td.sorting_3 {
|
||||
background-color: #ffd1d1;
|
||||
}
|
||||
|
||||
tr.even.gradeX td.sorting_1 {
|
||||
background-color: #ffd5d5;
|
||||
}
|
||||
|
||||
tr.even.gradeX td.sorting_2 {
|
||||
background-color: #ffe2e2;
|
||||
}
|
||||
|
||||
tr.even.gradeX td.sorting_3 {
|
||||
background-color: #ffe2e2;
|
||||
}
|
||||
|
||||
tr.odd.gradeU td.sorting_1 {
|
||||
background-color: #c4c4c4;
|
||||
}
|
||||
|
||||
tr.odd.gradeU td.sorting_2 {
|
||||
background-color: #d1d1d1;
|
||||
}
|
||||
|
||||
tr.odd.gradeU td.sorting_3 {
|
||||
background-color: #d1d1d1;
|
||||
}
|
||||
|
||||
tr.even.gradeU td.sorting_1 {
|
||||
background-color: #d5d5d5;
|
||||
}
|
||||
|
||||
tr.even.gradeU td.sorting_2 {
|
||||
background-color: #e2e2e2;
|
||||
}
|
||||
|
||||
tr.even.gradeU td.sorting_3 {
|
||||
background-color: #e2e2e2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Row highlighting example
|
||||
*/
|
||||
.ex_highlight #example tbody tr.even:hover,#example tbody tr.even td.highlighted
|
||||
{
|
||||
background-color: #ECFFB3;
|
||||
}
|
||||
|
||||
.ex_highlight #example tbody tr.odd:hover,#example tbody tr.odd td.highlighted
|
||||
{
|
||||
background-color: #E6FF99;
|
||||
}
|
||||
|
||||
/*
|
||||
* KeyTable
|
||||
*/
|
||||
table.KeyTable td {
|
||||
border: 3px solid transparent;
|
||||
}
|
||||
|
||||
table.KeyTable td.focus {
|
||||
border: 3px solid #3366FF;
|
||||
}
|
||||
|
||||
table.display tr.gradeA {
|
||||
background-color: #eeffee;
|
||||
}
|
||||
|
||||
table.display tr.gradeC {
|
||||
background-color: #ddddff;
|
||||
}
|
||||
|
||||
table.display tr.gradeX {
|
||||
background-color: #ffdddd;
|
||||
}
|
||||
|
||||
table.display tr.gradeU {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
div.box {
|
||||
height: 100px;
|
||||
padding: 10px;
|
||||
overflow: auto;
|
||||
border: 1px solid #8080FF;
|
||||
background-color: #E5E5FF;
|
||||
}
|
703
xCAT-UI/css/style.css
Normal file
@ -0,0 +1,703 @@
|
||||
/***************** Login dialog *****************/
|
||||
#logdialog {
|
||||
margin: 0px 10px 20px 10px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
#logdialog label,input,p {
|
||||
font: 14px verdana, arial, helvetica, sans-serif;
|
||||
}
|
||||
|
||||
#logdialog input {
|
||||
border: solid 1px #BDBDBD;
|
||||
font: 14px verdana, arial, helvetica, sans-serif;
|
||||
}
|
||||
|
||||
/****************** Header ******************/
|
||||
#header {
|
||||
width: 1000px;
|
||||
margin: 0px auto;
|
||||
background: url(../images/header-gloss-wave.png) 50% 50% repeat-x;
|
||||
-moz-border-radius: .5em;
|
||||
-webkit-border-radius: .5em;
|
||||
border-radius: .5em;
|
||||
margin: 0px auto;
|
||||
}
|
||||
|
||||
#header ul {
|
||||
list-style: none;
|
||||
padding: 0 0 0 30px;
|
||||
margin: 0;
|
||||
height: 39px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#header ul li {
|
||||
display: block;
|
||||
float: left;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#header ul li a {
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
float: left;
|
||||
font: 14px verdana, arial, helvetica, sans-serif;
|
||||
color: #424242;;
|
||||
padding: 11px 30px;
|
||||
}
|
||||
|
||||
#header ul a:hover {
|
||||
background-color: #A9D0F5;
|
||||
}
|
||||
|
||||
/****************** Content section ******************/
|
||||
body {
|
||||
background-color: #1C1C1C;
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
}
|
||||
|
||||
.content {
|
||||
-moz-border-radius: .5em;
|
||||
-webkit-border-radius: .5em;
|
||||
border-radius: .5em;
|
||||
width: 1000px;
|
||||
margin: 10px auto;
|
||||
background-color: white;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/****************** Groups section ******************/
|
||||
#groups {
|
||||
width: 150px;
|
||||
vertical-align: top;
|
||||
float: left;
|
||||
position: relative;
|
||||
margin: 15px 0px 15px 15px;
|
||||
}
|
||||
|
||||
#groups ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#groups ul h3 {
|
||||
text-transform: uppercase;
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
#groups a {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
color: #0000FF;
|
||||
display: block;
|
||||
padding: 5px 15px 15px 5px;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#groups a:hover {
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
/****************** Nodes section ******************/
|
||||
#nodes {
|
||||
width: 700px;
|
||||
margin: 20px;
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
/****************** Info bar ******************/
|
||||
.info {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
}
|
||||
|
||||
span.ui-icon-info {
|
||||
float: left;
|
||||
margin-right: 0.3em;
|
||||
}
|
||||
|
||||
.ui-button {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
padding: 0;
|
||||
margin: 5px;
|
||||
text-decoration: none !important;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
zoom: 1;
|
||||
overflow: visible;
|
||||
text-align: center
|
||||
}
|
||||
|
||||
.ui-button:hover {
|
||||
background: url(../images/header-gloss-wave.png) 50% 50% repeat-x;
|
||||
}
|
||||
|
||||
/****************** Tabs section ******************/
|
||||
.tab {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
border-style: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tab p {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
}
|
||||
|
||||
.tab .ui-icon-close {
|
||||
float: left;
|
||||
margin: 0.4em 0.2em 0 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/****************** Inventory and user entry ******************/
|
||||
.tab table {
|
||||
border-width: 1px;
|
||||
border-spacing: 0px;
|
||||
border-style: solid;
|
||||
border-color: #BDBDBD;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.tab th {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
color: #424242;
|
||||
padding: 10px;
|
||||
background-color: #F2F2F2;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #BDBDBD;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.tab td {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
color: #424242;
|
||||
padding: 5px 15px;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #BDBDBD;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.tab span a {
|
||||
text-decoration: none;
|
||||
color: #0000FF;
|
||||
}
|
||||
|
||||
.tab fieldset {
|
||||
margin-bottom: 5px;
|
||||
border-width: 1px 0 0 0;
|
||||
border-style: solid none none none;
|
||||
border-color: #D8D8D8;
|
||||
}
|
||||
|
||||
.tab label {
|
||||
color: #424242;
|
||||
display: inline-block;
|
||||
line-height: 1.5;
|
||||
vertical-align: top;
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
.tab legend {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
color: #424242;
|
||||
font-weight: bold;
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.tab ol {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.tab li {
|
||||
list-style: none;
|
||||
padding: 5px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.tab a {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
text-decoration: none;
|
||||
color: #0000FF;
|
||||
}
|
||||
|
||||
.tab a:hover {
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
.tab textarea {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
border: solid 0px #BDBDBD;
|
||||
padding: 5px;
|
||||
display: inline-table;
|
||||
width: 400px;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
/****************** Action bar (on nodes tab) ******************/
|
||||
.actionBar {
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
.actionBar div {
|
||||
padding: 10px 0px;
|
||||
}
|
||||
|
||||
.actionBar span {
|
||||
padding: 0px 10px;
|
||||
}
|
||||
|
||||
/****************** Status bar ******************/
|
||||
.statusBar {
|
||||
border: solid 1px #F5D0A9;
|
||||
-moz-border-radius: .5em;
|
||||
-webkit-border-radius: .5em;
|
||||
border-radius: .5em;
|
||||
padding: 10px;
|
||||
background: #F8ECE0;
|
||||
}
|
||||
|
||||
.statusBar p {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
}
|
||||
|
||||
/****************** Info bar ******************/
|
||||
.infoBar {
|
||||
border: solid 1px #D8D8D8;
|
||||
padding: 0px 10px;
|
||||
background: #E0ECF8;
|
||||
}
|
||||
|
||||
.infoBar span {
|
||||
width: 20px;
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
.infoBar p {
|
||||
padding: 0px 10px;
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
/****************** Data table ******************/
|
||||
.dataTables_wrapper {
|
||||
overflow: auto;
|
||||
width: 700px;
|
||||
margin: 0px auto;
|
||||
}
|
||||
|
||||
/*** Show X entries ***/
|
||||
.dataTables_length {
|
||||
width: 40%;
|
||||
float: left;
|
||||
padding: 10px 20px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/*** Search ***/
|
||||
.dataTables_filter {
|
||||
width: 50%;
|
||||
display: block;
|
||||
float: right;
|
||||
text-align: right;
|
||||
padding: 10px 10px;
|
||||
}
|
||||
|
||||
.tab input,select {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
border: solid 1px #BDBDBD;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
/*** Showing X to X of X entries ***/
|
||||
.dataTables_info {
|
||||
padding: 10px 20px;
|
||||
width: 40%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
/*** < > buttons ***/
|
||||
.paginate_disabled_previous,.paginate_enabled_previous,.paginate_disabled_next,.paginate_enabled_next
|
||||
{
|
||||
height: 19px;
|
||||
width: 19px;
|
||||
margin-left: 2px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
/*** Table ***/
|
||||
.datatable {
|
||||
width: 660px;
|
||||
border-width: 1px;
|
||||
border-spacing: 0px;
|
||||
border-style: solid;
|
||||
border-color: #BDBDBD;
|
||||
border-collapse: collapse;
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
.datatable th {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
color: #424242;
|
||||
padding: 10px;
|
||||
background-color: #F2F2F2;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #BDBDBD;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
min-width: 30px;
|
||||
}
|
||||
|
||||
.datatable td {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
color: #424242;
|
||||
padding: 6px 12px;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #BDBDBD;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/*** Row color (odd) ***/
|
||||
.datatable tr.odd {
|
||||
background-color: #E0ECF8;
|
||||
}
|
||||
|
||||
.datatable tr.odd td.sorting_1 {
|
||||
background-color: #A9D0F5;
|
||||
}
|
||||
|
||||
/*** Row color (even) ***/
|
||||
.datatable tr.even {
|
||||
background-color: #EFF5FB;
|
||||
}
|
||||
|
||||
.datatable tr.even td.sorting_1 {
|
||||
background-color: #CEE3F6;
|
||||
}
|
||||
|
||||
.datatable a {
|
||||
text-decoration: none;
|
||||
color: #000FF;
|
||||
}
|
||||
|
||||
.datatable a:hover {
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
/****************** Editable column ******************/
|
||||
.tab .datatable textarea {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
border: solid 1px #BDBDBD;
|
||||
}
|
||||
|
||||
.tab .datatable button {
|
||||
border: solid 1px #BDBDBD;
|
||||
-moz-border-radius: .5em;
|
||||
-webkit-border-radius: .5em;
|
||||
padding: 5px 10px;
|
||||
margin: 0 10px;
|
||||
background-color: #D8D8D8;
|
||||
color: #424242;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.tab .datatable button:hover {
|
||||
background-color: #E6E6E6;
|
||||
}
|
||||
|
||||
/****************** Prompts ******************/
|
||||
.cleanbluewarning .cleanblue {
|
||||
background-color: #acb4c4;
|
||||
}
|
||||
|
||||
.cleanbluefade {
|
||||
position: absolute;
|
||||
background-color: #aaaaaa;
|
||||
}
|
||||
|
||||
div.cleanblue {
|
||||
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
|
||||
position: absolute;
|
||||
background-color: #ffffff;
|
||||
width: 400px;
|
||||
font-size: 11px;
|
||||
text-align: left;
|
||||
border: solid 1px #213e80;
|
||||
}
|
||||
|
||||
div.cleanblue .cleanbluecontainer {
|
||||
background-color: #ffffff;
|
||||
border-top: solid 14px #213e80;
|
||||
padding: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.cleanblue .cleanblueclose {
|
||||
float: right;
|
||||
width: 18px;
|
||||
cursor: default;
|
||||
margin: -19px -12px 0 0;
|
||||
color: #ffffff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.cleanblue .cleanbluemessage {
|
||||
padding: 10px;
|
||||
line-height: 20px;
|
||||
font-size: 11px;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
div.cleanblue .cleanbluebuttons {
|
||||
text-align: right;
|
||||
padding: 5px 0 5px 0;
|
||||
border: solid 1px #eeeeee;
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
|
||||
div.cleanblue button {
|
||||
padding: 3px 10px;
|
||||
margin: 0 10px;
|
||||
background-color: #314e90;
|
||||
border: solid 1px #f4f4f4;
|
||||
color: #ffffff;
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
div.cleanblue button:hover {
|
||||
border: solid 1px #d4d4d4;
|
||||
}
|
||||
|
||||
/****************** Context menu ******************/
|
||||
.context-menu-theme-vista {
|
||||
background: #FAFAFA url(../images/context-menu-bg.gif) repeat-y left top
|
||||
;
|
||||
border: 1px solid #868686;
|
||||
}
|
||||
|
||||
.context-menu-theme-vista .context-menu-item {
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
color: black;
|
||||
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.context-menu-theme-vista .context-menu-separator {
|
||||
margin: 0px 0px 0px 32px;
|
||||
font-size: 0px;
|
||||
border-top: 1px solid #C5C5C5;
|
||||
border-bottom: 1px solid #F5F5F5;
|
||||
}
|
||||
|
||||
.context-menu-theme-vista .context-menu-item-hover {
|
||||
background: transparent url(../images/context-menu-item-hover.gif)
|
||||
repeat-x left center;
|
||||
border: 1px solid #D7D0B3;
|
||||
}
|
||||
|
||||
.context-menu-theme-vista .context-menu-item .context-menu-item-inner {
|
||||
padding: 4px 16px 4px 35px;
|
||||
margin-left: 1px;
|
||||
background-color: none;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 3px center;
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.context-menu-theme-vista .context-menu-item-hover .context-menu-item-inner
|
||||
{
|
||||
padding: 3px 15px 3px 35px;
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.context-menu-theme-vista .context-menu-item-disabled {
|
||||
color: #A7A7A7;
|
||||
}
|
||||
|
||||
/****************** Forms ******************/
|
||||
.form label {
|
||||
color: #424242;
|
||||
line-height: 1.5;
|
||||
vertical-align: top;
|
||||
width: 120px;
|
||||
padding: 0px 0px 0px 20px;
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
.form div {
|
||||
margin: 10px 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.form input {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
border: solid 1px #BDBDBD;
|
||||
padding: 5px;
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
.form textarea {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
border: solid 1px #BDBDBD;
|
||||
padding: 5px;
|
||||
display: inline-table;
|
||||
width: 350px;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.button {
|
||||
padding: 3px 10px;
|
||||
margin: 0 10px;
|
||||
background-color: #314e90;
|
||||
border: solid 1px #f4f4f4;
|
||||
color: #ffffff;
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
border: solid 1px #d4d4d4;
|
||||
}
|
||||
|
||||
.form a {
|
||||
text-decoration: none;
|
||||
color: #0000FF;
|
||||
}
|
||||
|
||||
.form a:hover {
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
/****************** Provision disk table ******************/
|
||||
.provision table {
|
||||
border-width: 1px;
|
||||
border-spacing: 0px;
|
||||
border-style: solid;
|
||||
border-color: #BDBDBD;
|
||||
border-collapse: collapse;
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
.provision input {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
border: solid 1px #BDBDBD;
|
||||
padding: 3px;
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
/****************** Provision and clone new nodes table ******************/
|
||||
.special table {
|
||||
border-width: 1px;
|
||||
border-spacing: 0px;
|
||||
border-style: solid;
|
||||
border-color: #BDBDBD;
|
||||
border-collapse: collapse;
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
.special input {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
border: solid 1px #BDBDBD;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
/****************** Provision form ******************/
|
||||
.provision label {
|
||||
color: #424242;
|
||||
line-height: 1.5;
|
||||
vertical-align: top;
|
||||
padding: 0px 0px 0px 20px;
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
.provision div {
|
||||
margin: 10px 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.provision input {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
border: solid 1px #BDBDBD;
|
||||
padding: 5px;
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
.provision select {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
border: solid 1px #BDBDBD;
|
||||
padding: 5px;
|
||||
margin: 10px;
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
.provision textarea {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
border: solid 1px #BDBDBD;
|
||||
padding: 5px;
|
||||
display: inline-table;
|
||||
width: 350px;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.provision a {
|
||||
text-decoration: none;
|
||||
color: #0000FF;
|
||||
}
|
||||
|
||||
.provision a:hover {
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
/****************** Monitor form ******************/
|
||||
.monitor label {
|
||||
color: #424242;
|
||||
line-height: 1.5;
|
||||
vertical-align: top;
|
||||
padding: 0px 0px 0px 20px;
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
.monitor div {
|
||||
margin: 10px 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.monitor input {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
border: solid 1px #BDBDBD;
|
||||
padding: 5px;
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
.monitor select {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
border: solid 1px #BDBDBD;
|
||||
padding: 5px;
|
||||
margin: 10px;
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
.monitor textarea {
|
||||
font: 12px verdana, arial, helvetica, sans-serif;
|
||||
border: solid 1px #BDBDBD;
|
||||
padding: 5px;
|
||||
display: inline-table;
|
||||
width: 350px;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.monitor a {
|
||||
text-decoration: none;
|
||||
color: #0000FF;
|
||||
}
|
||||
|
||||
.monitor a:hover {
|
||||
color: #FF0000;
|
||||
}
|
149
xCAT-UI/css/superfish.css
Normal file
@ -0,0 +1,149 @@
|
||||
.sf-menu,.sf-menu * {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.sf-menu {
|
||||
line-height: 1.0;
|
||||
}
|
||||
|
||||
.sf-menu ul {
|
||||
position: absolute;
|
||||
top: -999em;
|
||||
width: 10em; /* left offset of submenus need to match (see below) */
|
||||
}
|
||||
|
||||
.sf-menu ul li {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sf-menu li {
|
||||
float: left;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sf-menu a {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sf-menu li:hover ul,.sf-menu li.sfHover ul {
|
||||
left: 0;
|
||||
top: 2.5em; /* match top ul list item height */
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
ul.sf-menu li:hover li ul,ul.sf-menu li.sfHover li ul {
|
||||
top: -999em;
|
||||
}
|
||||
|
||||
ul.sf-menu li li:hover ul,ul.sf-menu li li.sfHover ul {
|
||||
left: 10em; /* match ul width */
|
||||
top: 0;
|
||||
}
|
||||
|
||||
ul.sf-menu li li:hover li ul,ul.sf-menu li li.sfHover li ul {
|
||||
top: -999em;
|
||||
}
|
||||
|
||||
ul.sf-menu li li li:hover ul,ul.sf-menu li li li.sfHover ul {
|
||||
left: 10em; /* match ul width */
|
||||
top: 0;
|
||||
}
|
||||
|
||||
/****************** Skin ******************/
|
||||
.sf-menu {
|
||||
float: left;
|
||||
margin-bottom: .5em;
|
||||
border: solid 1px #BDBDBD;
|
||||
-moz-border-radius: .5em;
|
||||
-webkit-border-radius: .5em;
|
||||
font-size: 12px;
|
||||
background: #E6E6E6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50%
|
||||
repeat-x;
|
||||
}
|
||||
|
||||
/*** Sub menu ***/
|
||||
.sf-menu .sf-menu {
|
||||
float: left;
|
||||
margin-bottom: .5em;
|
||||
border: solid 1px #BDBDBD;
|
||||
-moz-border-radius: .5em;
|
||||
-webkit-border-radius: .5em;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.sf-menu a {
|
||||
padding: .3em 1em;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.sf-menu a,.sf-menu a:visited {
|
||||
color: #424242;
|
||||
}
|
||||
|
||||
/*** Hover ***/
|
||||
.sf-menu li:hover,.sf-menu li.sfHover {
|
||||
background: url(../images/header-gloss-wave.png) 50% 50% repeat-x;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.sf-menu li a:hover {
|
||||
color: #424242;
|
||||
}
|
||||
|
||||
/*** Arrows ***/
|
||||
.sf-menu a.sf-with-ul {
|
||||
padding-right: 2.25em;
|
||||
min-width: 1px;
|
||||
}
|
||||
|
||||
.sf-sub-indicator {
|
||||
position: absolute;
|
||||
display: block;
|
||||
right: .75em;
|
||||
top: 1.05em; /* IE6 only */
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
text-indent: -999em;
|
||||
overflow: hidden;
|
||||
background: url('../images/arrows-ffffff.png') no-repeat -10px -100px;
|
||||
}
|
||||
|
||||
a>.sf-sub-indicator { /* give all except IE6 the correct values */
|
||||
top: .8em;
|
||||
background-position: 0 -100px;
|
||||
/* Use translucent arrow for modern browsers */
|
||||
}
|
||||
|
||||
/*** Apply hovers to modern browsers ***/
|
||||
a:focus>.sf-sub-indicator,a:hover>.sf-sub-indicator,a:active>.sf-sub-indicator,li:hover>a>.sf-sub-indicator,li.sfHover>a>.sf-sub-indicator
|
||||
{
|
||||
background-position: -10px -100px;
|
||||
/* Arrow hovers for modern browsers */
|
||||
}
|
||||
|
||||
/*** Point right for anchors in subs ***/
|
||||
.sf-menu ul .sf-sub-indicator {
|
||||
background-position: -10px 0;
|
||||
}
|
||||
|
||||
.sf-menu ul a>.sf-sub-indicator {
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
/*** Apply hovers to modern browsers ***/
|
||||
.sf-menu ul a:focus>.sf-sub-indicator,.sf-menu ul a:hover>.sf-sub-indicator,.sf-menu ul a:active>.sf-sub-indicator,.sf-menu ul li:hover>a>.sf-sub-indicator,.sf-menu ul li.sfHover>a>.sf-sub-indicator
|
||||
{
|
||||
background-position: -10px 0; /* Arrow hovers for modern browsers */
|
||||
}
|
||||
|
||||
/*** Shadows ***/
|
||||
.sf-shadow ul {
|
||||
padding: 0 9px 9px 0;
|
||||
}
|
||||
|
||||
.sf-shadow ul.sf-shadow-off {
|
||||
background: transparent;
|
||||
}
|
115
xCAT-UI/css/tree.css
Normal file
@ -0,0 +1,115 @@
|
||||
/*** LOCKED ***/
|
||||
.tree-default .locked li a {
|
||||
color: gray;
|
||||
}
|
||||
|
||||
/*** DOTS ***/
|
||||
.tree-default ul {
|
||||
background-position: 6px 1px;
|
||||
background-repeat: repeat-y;
|
||||
background-image:
|
||||
url(data:image/gif;base64,R0lGODlhAgACAIAAAB4dGf///yH5BAEAAAEALAAAAAACAAIAAAICRF4AOw==)
|
||||
;
|
||||
_background-image: url("../images/dot_for_ie.gif"); *
|
||||
background-image: url("../images/dot_for_ie.gif");
|
||||
}
|
||||
|
||||
.tree-default li {
|
||||
background-position: -64px -16px;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url("../images/icons.png");
|
||||
}
|
||||
|
||||
/*** NO DOTS ***/
|
||||
.tree-default .no_dots,.tree-default .no_dots ul {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.tree-default .no_dots li.leaf {
|
||||
background-image: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
/*** OPEN or CLOSED ***/
|
||||
.tree-default li.open {
|
||||
background: url("../images/icons.png") -32px -48px no-repeat;
|
||||
}
|
||||
|
||||
.tree-default li.closed,#jstree-dragged.tree-default li li.open {
|
||||
background: url("../images/icons.png") -48px -32px no-repeat;
|
||||
}
|
||||
|
||||
#jstree-marker {
|
||||
background-image: url("../images/icons.png");
|
||||
}
|
||||
|
||||
/*** DEFAULT, HOVER, CLICKED, LOADING STATES ***/
|
||||
.tree-default li a,.tree-default li span {
|
||||
border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
}
|
||||
|
||||
.tree-default li a:hover,.tree-default li a.hover,.tree-default li span
|
||||
{
|
||||
background: #EFF5FB;
|
||||
border: 1px solid #d8f0fa;
|
||||
padding: 0px 3px 0px 3px;
|
||||
}
|
||||
|
||||
.tree-default li a.clicked,.tree-default li a.clicked:hover,.tree-default li span.clicked
|
||||
{
|
||||
background: #A9D0F5;
|
||||
border: 1px solid #99defd;
|
||||
padding: 0px 3px 0px 3px;
|
||||
}
|
||||
|
||||
/*** ICONS ***/
|
||||
.tree-default ins {
|
||||
background-image: url("../images/icons.png");
|
||||
background-position: 0 0;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.tree-default ul li a.loading ins {
|
||||
background-image: url("../images/throbber.gif") !important;
|
||||
background-position: 0 0 !important;
|
||||
} /* UL is added to make selector stronger */
|
||||
.tree-default li a ins.forbidden {
|
||||
background-position: -16px -16px;
|
||||
}
|
||||
|
||||
.tree-default .locked li a ins {
|
||||
background-position: 0 -48px;
|
||||
}
|
||||
|
||||
.tree-default li span ins {
|
||||
background-position: -16px 0;
|
||||
}
|
||||
|
||||
#jstree-dragged.tree-default ins {
|
||||
background: url("../images/icons.png") -16px -32px no-repeat;
|
||||
}
|
||||
|
||||
#jstree-dragged.tree-default ins.forbidden {
|
||||
background: url("../images/icons.png") -16px -16px no-repeat;
|
||||
}
|
||||
|
||||
/*** CONTEXT MENU ***/
|
||||
.tree-default-context a ins {
|
||||
background-image: url("../images/icons.png");
|
||||
background-repeat: no-repeat;
|
||||
background-position: -64px -64px;
|
||||
}
|
||||
|
||||
.tree-default-context a ins.create {
|
||||
background-position: 0 -16px;
|
||||
}
|
||||
|
||||
.tree-default-context a ins.rename {
|
||||
background-position: -16px 0px;
|
||||
}
|
||||
|
||||
.tree-default-context a ins.remove {
|
||||
background-position: 0 -32px;
|
||||
}
|
7
xCAT-UI/etc/apache2/conf.d/xcat-ui.conf
Normal file
@ -0,0 +1,7 @@
|
||||
Alias /xcat "/opt/xcat/ui"
|
||||
<Directory "/opt/xcat/ui">
|
||||
Options FollowSymLinks
|
||||
AllowOverride None
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
</Directory>
|
BIN
xCAT-UI/images/arrows-ffffff.png
Normal file
After Width: | Height: | Size: 244 B |
BIN
xCAT-UI/images/back_disabled.jpg
Normal file
After Width: | Height: | Size: 612 B |
BIN
xCAT-UI/images/back_enabled.jpg
Normal file
After Width: | Height: | Size: 807 B |
BIN
xCAT-UI/images/context-menu-bg.gif
Normal file
After Width: | Height: | Size: 64 B |
BIN
xCAT-UI/images/context-menu-item-hover.gif
Normal file
After Width: | Height: | Size: 347 B |
BIN
xCAT-UI/images/dot_for_ie.gif
Normal file
After Width: | Height: | Size: 43 B |
BIN
xCAT-UI/images/forward_disabled.jpg
Normal file
After Width: | Height: | Size: 635 B |
BIN
xCAT-UI/images/forward_enabled.jpg
Normal file
After Width: | Height: | Size: 852 B |
BIN
xCAT-UI/images/header-gloss-wave.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
xCAT-UI/images/icons.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
BIN
xCAT-UI/images/loader.gif
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
xCAT-UI/images/logo.gif
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
xCAT-UI/images/sort_asc.png
Normal file
After Width: | Height: | Size: 263 B |
BIN
xCAT-UI/images/sort_asc_disabled.png
Normal file
After Width: | Height: | Size: 252 B |
BIN
xCAT-UI/images/sort_both.png
Normal file
After Width: | Height: | Size: 282 B |
BIN
xCAT-UI/images/sort_desc.png
Normal file
After Width: | Height: | Size: 260 B |
BIN
xCAT-UI/images/sort_desc_disabled.png
Normal file
After Width: | Height: | Size: 251 B |
BIN
xCAT-UI/images/throbber.gif
Normal file
After Width: | Height: | Size: 1.8 KiB |
35
xCAT-UI/index.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* Main xCAT page
|
||||
*/
|
||||
require_once "lib/functions.php";
|
||||
require_once "lib/ui.php";
|
||||
require_once "lib/jsonwrapper.php";
|
||||
|
||||
/* Load page */
|
||||
loadPage();
|
||||
|
||||
/* Login user */
|
||||
if (!isAuthenticated()) {
|
||||
login();
|
||||
} else {
|
||||
loadContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test lib/cmd.php
|
||||
*/
|
||||
function testCmdPhp() {
|
||||
$xml = docmd('lsdef', NULL, array('all'));
|
||||
$rsp = array();
|
||||
|
||||
foreach ($xml->children() as $child) {
|
||||
foreach ($child->children() as $data) {
|
||||
array_push($rsp, "$data");
|
||||
}
|
||||
}
|
||||
|
||||
$rtn = array("rsp" => $rsp, "msg" => '');
|
||||
echo json_encode($rtn);
|
||||
}
|
||||
?>
|
494
xCAT-UI/js/configure.js
Normal file
@ -0,0 +1,494 @@
|
||||
/**
|
||||
* Global variables
|
||||
*/
|
||||
var configTabs; // Config tabs
|
||||
var configDataTables = new Object(); // Datatables on the config page
|
||||
|
||||
/**
|
||||
* Set the datatable
|
||||
*
|
||||
* @param id
|
||||
* The ID of the datatable
|
||||
* @param obj
|
||||
* Datatable object
|
||||
* @return Nothing
|
||||
*/
|
||||
function setConfigDatatable(id, obj) {
|
||||
configDataTables[id] = obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the datatable with the given ID
|
||||
*
|
||||
* @param id
|
||||
* The ID of the datatable
|
||||
* @return Datatable object
|
||||
*/
|
||||
function getConfigDatatable(id) {
|
||||
return configDataTables[id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the configure tab
|
||||
*
|
||||
* @param obj
|
||||
* Tab object
|
||||
* @return Nothing
|
||||
*/
|
||||
function setConfigTab(obj) {
|
||||
configTabs = obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the configure tab
|
||||
*
|
||||
* @param Nothing
|
||||
* @return Tab object
|
||||
*/
|
||||
function getConfigTab() {
|
||||
return configTabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load configure page
|
||||
*
|
||||
* @return Nothing
|
||||
*/
|
||||
function loadConfigPage() {
|
||||
// If the configure page has already been loaded
|
||||
if ($('#configure_page').children().length) {
|
||||
// Do not reload configure page
|
||||
return;
|
||||
}
|
||||
|
||||
// Create configure tab
|
||||
var tab = new Tab();
|
||||
setConfigTab(tab);
|
||||
tab.init();
|
||||
$('#configure_page').append(tab.object());
|
||||
|
||||
// Create loader
|
||||
var loader = createLoader();
|
||||
loader = $('<center></center>').append(loader);
|
||||
|
||||
// Configure xCAT tables
|
||||
tab.add('configTablesTab', 'Tables', loader);
|
||||
|
||||
// Get list of tables and their descriptions
|
||||
$.ajax( {
|
||||
url : 'lib/cmd.php',
|
||||
dataType : 'json',
|
||||
data : {
|
||||
cmd : 'tabdump',
|
||||
tgt : '',
|
||||
args : '-d',
|
||||
msg : ''
|
||||
},
|
||||
|
||||
success : loadTableNames
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Load xCAT table names and their descriptions
|
||||
*
|
||||
* @param data
|
||||
* Data returned from HTTP request
|
||||
* @return Nothing
|
||||
*/
|
||||
function loadTableNames(data) {
|
||||
// Get output
|
||||
var tables = data.rsp;
|
||||
|
||||
// Remove loader
|
||||
var tabId = 'configTablesTab';
|
||||
$('#' + tabId).find('img').hide();
|
||||
|
||||
// Create a groups division
|
||||
var tablesDIV = $('<div id="configure_table"></div>');
|
||||
$('#' + tabId).append(tablesDIV);
|
||||
|
||||
// Create info bar
|
||||
var infoBar = createInfoBar('Select a table to edit');
|
||||
tablesDIV.append(infoBar);
|
||||
|
||||
// Create a list for the tables
|
||||
var list = $('<ul></ul>');
|
||||
// Loop through each table
|
||||
for ( var i = 0; i < tables.length; i++) {
|
||||
// Create a link for each table
|
||||
var args = tables[i].split(':');
|
||||
var link = $('<a href="#" id="' + args[0] + '">' + args[0] + '</a>');
|
||||
|
||||
// Open table on click
|
||||
link.bind('click', function(e) {
|
||||
// Get table ID that was clicked
|
||||
var id = (e.target) ? e.target.id : e.srcElement.id;
|
||||
|
||||
// Create loader
|
||||
var loader = createLoader();
|
||||
loader = $('<center></center>').append(loader);
|
||||
|
||||
// Add a new tab for this table
|
||||
var configTab = getConfigTab();
|
||||
if (!$('#' + id + 'Tab').length) {
|
||||
configTab.add(id + 'Tab', id, loader);
|
||||
|
||||
// Get contents of selected table
|
||||
$.ajax( {
|
||||
url : 'lib/cmd.php',
|
||||
dataType : 'json',
|
||||
data : {
|
||||
cmd : 'tabdump',
|
||||
tgt : '',
|
||||
args : id,
|
||||
msg : id
|
||||
},
|
||||
|
||||
success : loadTable
|
||||
});
|
||||
}
|
||||
|
||||
// Select new tab
|
||||
configTab.select(id + 'Tab');
|
||||
});
|
||||
|
||||
var item = $('<li></li>');
|
||||
item.append(link);
|
||||
|
||||
// Append the table description
|
||||
item.append(': ' + args[1]);
|
||||
|
||||
// Append item to list
|
||||
list.append(item);
|
||||
}
|
||||
|
||||
tablesDIV.append(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a given table
|
||||
*
|
||||
* @param data
|
||||
* Data returned from HTTP request
|
||||
* @return Nothing
|
||||
*/
|
||||
function loadTable(data) {
|
||||
// Get response
|
||||
var rsp = data.rsp;
|
||||
// Get table ID
|
||||
var id = data.msg;
|
||||
|
||||
// Remove loader
|
||||
var tabId = id + 'Tab';
|
||||
$('#' + tabId).find('img').remove();
|
||||
|
||||
// Create info bar
|
||||
var infoBar = createInfoBar('Click on a cell to edit. Click outside the table to write to the cell.<br>Once you are satisfied with how the table looks, click on Save.');
|
||||
$('#' + tabId).append(infoBar);
|
||||
|
||||
// Create action bar
|
||||
var actionBar = $('<div></div>');
|
||||
$('#' + tabId).append(actionBar);
|
||||
|
||||
// Get table headers
|
||||
var args = rsp[0].replace('#', '');
|
||||
var headers = args.split(',');
|
||||
|
||||
// Create container for original table contents
|
||||
var origCont = new Array(); // Original table content
|
||||
origCont[0] = rsp[0].split(','); // Headers
|
||||
|
||||
// Create container for new table contents
|
||||
var newCont = new Object();
|
||||
var tmp = new Object();
|
||||
tmp[0] = '#' + headers[0]; // Put a # in front of the header
|
||||
for ( var i = 1; i < headers.length; i++) {
|
||||
tmp[i] = headers[i];
|
||||
}
|
||||
newCont[0] = tmp;
|
||||
|
||||
// Create a new datatable
|
||||
var tableId = id + 'DataTable';
|
||||
var table = new DataTable(tableId);
|
||||
|
||||
// Add column for the remove button
|
||||
headers.unshift('');
|
||||
table.init(headers);
|
||||
headers.shift();
|
||||
|
||||
// Append datatable to tab
|
||||
$('#' + tabId).append(table.object());
|
||||
|
||||
// Data table
|
||||
var dTable;
|
||||
|
||||
// Add table rows
|
||||
// Start with the 2nd row (1st row is the headers)
|
||||
for ( var i = 1; i < rsp.length; i++) {
|
||||
// Split into columns
|
||||
var cols = rsp[i].split(',');
|
||||
|
||||
// Go through each column
|
||||
for ( var j = 0; j < cols.length; j++) {
|
||||
|
||||
// If the column is not complete
|
||||
if (cols[j].count('"') == 1) {
|
||||
while (cols[j].count('"') != 2) {
|
||||
// Merge this column with the adjacent one
|
||||
cols[j] = cols[j] + "," + cols[j + 1];
|
||||
|
||||
// Remove merged row
|
||||
cols.splice(j + 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Replace quote
|
||||
cols[j] = cols[j].replace(new RegExp('"', 'g'), '');
|
||||
}
|
||||
|
||||
// Add remove button
|
||||
cols
|
||||
.unshift('<span class="ui-icon ui-icon-close" onclick="deleteRow(this)"></span>');
|
||||
|
||||
// Add row
|
||||
table.add(cols);
|
||||
|
||||
// Save original table content
|
||||
origCont[i] = cols;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable editable columns
|
||||
*/
|
||||
// Do not make 1st column editable
|
||||
$('#' + tableId + ' td:not(td:nth-child(1))').editable(
|
||||
function(value, settings) {
|
||||
// Get column index
|
||||
var colPos = this.cellIndex;
|
||||
// Get row index
|
||||
var rowPos = dTable.fnGetPosition(this.parentNode);
|
||||
|
||||
// Update datatable
|
||||
dTable.fnUpdate(value, rowPos, colPos);
|
||||
|
||||
return (value);
|
||||
}, {
|
||||
onblur : 'submit', // Clicking outside editable area submits
|
||||
// changes
|
||||
type : 'textarea',
|
||||
height : '30px' // The height of the text area
|
||||
});
|
||||
|
||||
// Turn table into datatable
|
||||
dTable = $('#' + id + 'DataTable').dataTable();
|
||||
setConfigDatatable(id + 'DataTable', dTable);
|
||||
|
||||
// Create add row button
|
||||
var addBar = $('<div></div>');
|
||||
$('#' + tabId).append(addBar);
|
||||
var addRowBtn = createButton('Add row');
|
||||
addBar.append(addRowBtn);
|
||||
|
||||
// Create save and undo buttons
|
||||
var saveBtn = createButton('Save');
|
||||
var undoBtn = createButton('Undo');
|
||||
actionBar.append(saveBtn);
|
||||
actionBar.append(undoBtn);
|
||||
|
||||
/**
|
||||
* Add row
|
||||
*/
|
||||
addRowBtn
|
||||
.bind(
|
||||
'click',
|
||||
function(event) {
|
||||
// Create an empty row
|
||||
var row = new Array();
|
||||
|
||||
/**
|
||||
* Remove button
|
||||
*/
|
||||
row
|
||||
.push('<span class="ui-icon ui-icon-close" onclick="deleteRow(this)"></span>');
|
||||
for ( var i = 0; i < headers.length; i++) {
|
||||
row.push('');
|
||||
}
|
||||
|
||||
// Get tab ID
|
||||
var tabId = $(this).parent().parent().attr('id');
|
||||
// Get table name
|
||||
var tableName = tabId.replace('Tab', '');
|
||||
// Get table ID
|
||||
var tableId = tableName + 'DataTable';
|
||||
|
||||
// Get datatable
|
||||
var dTable = getConfigDatatable(tableId);
|
||||
// Add the row to the data table
|
||||
dTable.fnAddData(row);
|
||||
|
||||
// Enable editable columns (again)
|
||||
// Do not make 1st column editable
|
||||
$('#' + tabId + ' td:not(td:nth-child(1))').editable(
|
||||
function(value, settings) {
|
||||
// Get column index
|
||||
var colPos = this.cellIndex;
|
||||
// Get row index
|
||||
var rowPos = dTable.fnGetPosition(this.parentNode);
|
||||
|
||||
// Update datatable
|
||||
dTable.fnUpdate(value, rowPos, colPos);
|
||||
|
||||
return (value);
|
||||
}, {
|
||||
onblur : 'submit', // Clicking outside editable area
|
||||
// submits changes
|
||||
type : 'textarea',
|
||||
height : '30px' // The height of the text area
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Save changes
|
||||
*/
|
||||
saveBtn.bind('click', function(event) {
|
||||
// Get tab ID
|
||||
var tabId = $(this).parent().parent().attr('id');
|
||||
// Get table name
|
||||
var tableName = tabId.replace('Tab', '');
|
||||
// Get table ID
|
||||
var tableId = tableName + 'DataTable';
|
||||
|
||||
// Get datatable
|
||||
var dTable = getConfigDatatable(tableId);
|
||||
// Get the nodes from the table
|
||||
var dRows = dTable.fnGetNodes();
|
||||
|
||||
// Go through each row
|
||||
for ( var i = 0; i < dRows.length; i++) {
|
||||
// If there is row with values
|
||||
if (dRows[i]) {
|
||||
// Go through each column
|
||||
// Ignore the 1st column because it is a button
|
||||
var cols = dRows[i].childNodes;
|
||||
var vals = new Object();
|
||||
for ( var j = 1; j < cols.length; j++) {
|
||||
var val = cols.item(j).firstChild.nodeValue;
|
||||
|
||||
// Insert quotes
|
||||
if (val == 'Click to edit') {
|
||||
vals[j - 1] = '';
|
||||
} else {
|
||||
vals[j - 1] = val;
|
||||
}
|
||||
}
|
||||
|
||||
// Save row
|
||||
newCont[i + 1] = vals;
|
||||
}
|
||||
}
|
||||
|
||||
// Update datatable
|
||||
setConfigDatatable(tableId, dTable);
|
||||
|
||||
// Update xCAT table
|
||||
$.ajax( {
|
||||
type : 'POST',
|
||||
url : 'lib/tabRestore.php',
|
||||
dataType : 'json',
|
||||
data : {
|
||||
table : tableName,
|
||||
cont : newCont
|
||||
},
|
||||
success : function(data) {
|
||||
alert('Changes saved');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Undo changes
|
||||
*/
|
||||
undoBtn.bind('click', function(event) {
|
||||
// Get tab ID
|
||||
var tabId = $(this).parent().parent().attr('id');
|
||||
// Get table name
|
||||
var tableName = tabId.replace('Tab', '');
|
||||
// Get table ID
|
||||
var tableId = tableName + 'DataTable';
|
||||
|
||||
// Get datatable
|
||||
var dTable = getConfigDatatable(tableId);
|
||||
// Get the nodes from the table
|
||||
|
||||
// Clear entire datatable
|
||||
dTable.fnClearTable();
|
||||
|
||||
// Add original content back into datatable
|
||||
for ( var i = 1; i < origCont.length; i++) {
|
||||
dTable.fnAddData(origCont[i], true);
|
||||
}
|
||||
|
||||
// Enable editable columns (again)
|
||||
// Do not make 1st column editable
|
||||
$('#' + tableId + ' td:not(td:nth-child(1))').editable(
|
||||
function(value, settings) {
|
||||
// Get column index
|
||||
var colPos = this.cellIndex;
|
||||
// Get row index
|
||||
var rowPos = dTable.fnGetPosition(this.parentNode);
|
||||
|
||||
// Update datatable
|
||||
dTable.fnUpdate(value, rowPos, colPos);
|
||||
|
||||
return (value);
|
||||
}, {
|
||||
onblur : 'submit', // Clicking outside editable area submits
|
||||
// changes
|
||||
type : 'textarea',
|
||||
height : '30px' // The height of the text area
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a row in the data table
|
||||
*
|
||||
* @param obj
|
||||
* The object that was clicked
|
||||
* @return Nothing
|
||||
*/
|
||||
function deleteRow(obj) {
|
||||
// Get table ID
|
||||
var tableId = $(obj).parent().parent().parent().parent().attr('id');
|
||||
|
||||
// Get datatable
|
||||
var dTable = getConfigDatatable(tableId);
|
||||
|
||||
// Get all nodes within the datatable
|
||||
var rows = dTable.fnGetNodes();
|
||||
// Get target row
|
||||
var tgtRow = $(obj).parent().parent().get(0);
|
||||
|
||||
// Find the target row in the datatable
|
||||
for ( var i in rows) {
|
||||
// If the row matches the target row
|
||||
if (rows[i] == tgtRow) {
|
||||
// Remove row
|
||||
dTable.fnDeleteRow(i, null, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of occurrences of a specific character in a string
|
||||
*
|
||||
* @param char
|
||||
* Character to count
|
||||
* @return The number of occurrences
|
||||
*/
|
||||
String.prototype.count = function(char) {
|
||||
return (this.length - this.replace(new RegExp(char, "g"), '').length)
|
||||
/ char.length;
|
||||
};
|
117
xCAT-UI/js/hoverIntent.js
Normal file
@ -0,0 +1,117 @@
|
||||
(function($) {
|
||||
/* hoverIntent by Brian Cherne */
|
||||
$.fn.hoverIntent = function(f, g) {
|
||||
// default configuration options
|
||||
var cfg = {
|
||||
sensitivity : 7,
|
||||
interval : 100,
|
||||
timeout : 0
|
||||
};
|
||||
// override configuration options with user supplied object
|
||||
cfg = $.extend(cfg, g ? {
|
||||
over : f,
|
||||
out : g
|
||||
} : f);
|
||||
|
||||
// instantiate variables
|
||||
// cX, cY = current X and Y position of mouse, updated by mousemove
|
||||
// event
|
||||
// pX, pY = previous X and Y position of mouse, set by mouseover and
|
||||
// polling interval
|
||||
var cX, cY, pX, pY;
|
||||
|
||||
// A private function for getting mouse position
|
||||
var track = function(ev) {
|
||||
cX = ev.pageX;
|
||||
cY = ev.pageY;
|
||||
};
|
||||
|
||||
// A private function for comparing current and previous mouse position
|
||||
var compare = function(ev, ob) {
|
||||
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
|
||||
// compare mouse positions to see if they've crossed the threshold
|
||||
if ((Math.abs(pX - cX) + Math.abs(pY - cY)) < cfg.sensitivity) {
|
||||
$(ob).unbind("mousemove", track);
|
||||
// set hoverIntent state to true (so mouseOut can be called)
|
||||
ob.hoverIntent_s = 1;
|
||||
return cfg.over.apply(ob, [ ev ]);
|
||||
} else {
|
||||
// set previous coordinates for next time
|
||||
pX = cX;
|
||||
pY = cY;
|
||||
// use self-calling timeout, guarantees intervals are spaced out
|
||||
// properly (avoids JavaScript timer bugs)
|
||||
ob.hoverIntent_t = setTimeout(function() {
|
||||
compare(ev, ob);
|
||||
}, cfg.interval);
|
||||
}
|
||||
};
|
||||
|
||||
// A private function for delaying the mouseOut function
|
||||
var delay = function(ev, ob) {
|
||||
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
|
||||
ob.hoverIntent_s = 0;
|
||||
return cfg.out.apply(ob, [ ev ]);
|
||||
};
|
||||
|
||||
// A private function for handling mouse 'hovering'
|
||||
var handleHover = function(e) {
|
||||
// next three lines copied from jQuery.hover, ignore children
|
||||
// onMouseOver/onMouseOut
|
||||
var p = (e.type == "mouseover" ? e.fromElement : e.toElement)
|
||||
|| e.relatedTarget;
|
||||
while (p && p != this) {
|
||||
try {
|
||||
p = p.parentNode;
|
||||
} catch (e) {
|
||||
p = this;
|
||||
}
|
||||
}
|
||||
if (p == this) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// copy objects to be passed into t (required for event object to be
|
||||
// passed in IE)
|
||||
var ev = jQuery.extend( {}, e);
|
||||
var ob = this;
|
||||
|
||||
// cancel hoverIntent timer if it exists
|
||||
if (ob.hoverIntent_t) {
|
||||
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
|
||||
}
|
||||
|
||||
// else e.type == "onmouseover"
|
||||
if (e.type == "mouseover") {
|
||||
// set "previous" X and Y position based on initial entry point
|
||||
pX = ev.pageX;
|
||||
pY = ev.pageY;
|
||||
// update "current" X and Y position based on mousemove
|
||||
$(ob).bind("mousemove", track);
|
||||
// start polling interval (self-calling timeout) to compare
|
||||
// mouse coordinates over time
|
||||
if (ob.hoverIntent_s != 1) {
|
||||
ob.hoverIntent_t = setTimeout(function() {
|
||||
compare(ev, ob);
|
||||
}, cfg.interval);
|
||||
}
|
||||
|
||||
// else e.type == "onmouseout"
|
||||
} else {
|
||||
// unbind expensive mousemove event
|
||||
$(ob).unbind("mousemove", track);
|
||||
// if hoverIntent state is true, then call the mouseOut function
|
||||
// after the specified delay
|
||||
if (ob.hoverIntent_s == 1) {
|
||||
ob.hoverIntent_t = setTimeout(function() {
|
||||
delay(ev, ob);
|
||||
}, cfg.timeout);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// bind the function to the two event listeners
|
||||
return this.mouseover(handleHover).mouseout(handleHover);
|
||||
};
|
||||
|
||||
})(jQuery);
|
154
xCAT-UI/js/jquery-1.4.2.min.js
vendored
Normal file
@ -0,0 +1,154 @@
|
||||
/*!
|
||||
* jQuery JavaScript Library v1.4.2
|
||||
* http://jquery.com/
|
||||
*
|
||||
* Copyright 2010, John Resig
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* Includes Sizzle.js
|
||||
* http://sizzlejs.com/
|
||||
* Copyright 2010, The Dojo Foundation
|
||||
* Released under the MIT, BSD, and GPL Licenses.
|
||||
*
|
||||
* Date: Sat Feb 13 22:33:48 2010 -0500
|
||||
*/
|
||||
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
|
||||
e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
|
||||
j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
|
||||
"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
|
||||
true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
|
||||
Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
|
||||
(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
|
||||
a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
|
||||
"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
|
||||
function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
|
||||
c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
|
||||
L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
|
||||
"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
|
||||
a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
|
||||
d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
|
||||
a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
|
||||
!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
|
||||
true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
|
||||
var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
|
||||
parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
|
||||
false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
|
||||
s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
|
||||
applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
|
||||
else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
|
||||
a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
|
||||
w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
|
||||
cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
|
||||
i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
|
||||
" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
|
||||
this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
|
||||
e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
|
||||
c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
|
||||
a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
|
||||
function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
|
||||
k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
|
||||
C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
|
||||
null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
|
||||
e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
|
||||
f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
|
||||
if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
|
||||
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
|
||||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
|
||||
"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
|
||||
a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
|
||||
isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
|
||||
{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
|
||||
if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
|
||||
e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
|
||||
"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
|
||||
d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
|
||||
!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
|
||||
toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
|
||||
u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
|
||||
function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
|
||||
if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
|
||||
e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
|
||||
t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
|
||||
g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
|
||||
for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
|
||||
1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
|
||||
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
|
||||
relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
|
||||
l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
|
||||
h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
|
||||
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
|
||||
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
|
||||
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
|
||||
setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
|
||||
h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
|
||||
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
|
||||
"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
|
||||
h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
|
||||
!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
|
||||
h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
|
||||
q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
|
||||
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
|
||||
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
|
||||
function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
|
||||
gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
|
||||
c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
|
||||
{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
|
||||
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
|
||||
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
|
||||
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
|
||||
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
|
||||
a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
|
||||
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
|
||||
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
|
||||
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
|
||||
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
|
||||
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
|
||||
""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
|
||||
this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
|
||||
u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
|
||||
1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
|
||||
return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
|
||||
""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
|
||||
c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
|
||||
c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
|
||||
function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
|
||||
Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
|
||||
"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
|
||||
a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
|
||||
a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
|
||||
"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
|
||||
serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
|
||||
function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
|
||||
global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
|
||||
e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
|
||||
"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
|
||||
false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
|
||||
false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
|
||||
c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
|
||||
d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
|
||||
g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
|
||||
1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
|
||||
"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
|
||||
if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
|
||||
this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
|
||||
"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
|
||||
animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
|
||||
j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
|
||||
this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
|
||||
"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
|
||||
c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
|
||||
this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
|
||||
this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
|
||||
e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
|
||||
c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
|
||||
function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
|
||||
this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
|
||||
k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
|
||||
f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
|
||||
a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
|
||||
c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
|
||||
d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
|
||||
f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
|
||||
"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
|
||||
e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
|
318
xCAT-UI/js/jquery-impromptu.3.0.min.js
vendored
Normal file
@ -0,0 +1,318 @@
|
||||
/*
|
||||
* jQuery Impromptu
|
||||
* By: Trent Richardson [http://trentrichardson.com]
|
||||
* Version 3.0
|
||||
* Last Modified: 2/15/2010
|
||||
*
|
||||
* Copyright 2010 Trent Richardson
|
||||
* Dual licensed under the MIT and GPL licenses.
|
||||
* http://trentrichardson.com/Impromptu/GPL-LICENSE.txt
|
||||
* http://trentrichardson.com/Impromptu/MIT-LICENSE.txt
|
||||
*
|
||||
*/
|
||||
(function($) {
|
||||
$.prompt = function(message, options) {
|
||||
options = $.extend( {}, $.prompt.defaults, options);
|
||||
$.prompt.currentPrefix = options.prefix;
|
||||
var ie6 = ($.browser.msie && $.browser.version < 7);
|
||||
var $body = $(document.body);
|
||||
var $window = $(window);
|
||||
options.classes = $.trim(options.classes);
|
||||
if (options.classes != '')
|
||||
options.classes = ' ' + options.classes;
|
||||
var msgbox = '<div class="' + options.prefix + 'box' + options.classes + '" id="' + options.prefix + 'box">';
|
||||
if (options.useiframe && (($('object, applet').length > 0) || ie6)) {
|
||||
msgbox += '<iframe src="javascript:false;" style="display:block;position:absolute;z-index:-1;" class="' + options.prefix + 'fade" id="' + options.prefix + 'fade"></iframe>';
|
||||
} else {
|
||||
if (ie6) {
|
||||
$('select').css('visibility', 'hidden');
|
||||
}
|
||||
msgbox += '<div class="' + options.prefix + 'fade" id="' + options.prefix + 'fade"></div>';
|
||||
}
|
||||
msgbox += '<div class="' + options.prefix + '" id="' + options.prefix + '"><div class="' + options.prefix + 'container"><div class="';
|
||||
msgbox += options.prefix + 'close">X</div><div id="' + options.prefix + 'states"></div>';
|
||||
msgbox += '</div></div></div>';
|
||||
var $jqib = $(msgbox).appendTo($body);
|
||||
var $jqi = $jqib.children('#' + options.prefix);
|
||||
var $jqif = $jqib.children('#' + options.prefix + 'fade');
|
||||
if (message.constructor == String) {
|
||||
message = {
|
||||
state0 : {
|
||||
html : message,
|
||||
buttons : options.buttons,
|
||||
focus : options.focus,
|
||||
submit : options.submit
|
||||
}
|
||||
};
|
||||
}
|
||||
var states = "";
|
||||
$
|
||||
.each(
|
||||
message,
|
||||
function(statename, stateobj) {
|
||||
stateobj = $.extend( {}, $.prompt.defaults.state, stateobj);
|
||||
message[statename] = stateobj;
|
||||
states += '<div id="' + options.prefix + '_state_' + statename + '" class="' + options.prefix + '_state" style="display:none;"><div class="' + options.prefix + 'message">' + stateobj.html + '</div><div class="' + options.prefix + 'buttons">';
|
||||
$
|
||||
.each(
|
||||
stateobj.buttons,
|
||||
function(k, v) {
|
||||
states += '<button name="' + options.prefix + '_' + statename + '_button' + k + '" id="' + options.prefix + '_' + statename + '_button' + k + '" value="' + v + '">' + k + '</button>';
|
||||
});
|
||||
states += '</div></div>';
|
||||
});
|
||||
$jqi.find('#' + options.prefix + 'states').html(states).children(
|
||||
'.' + options.prefix + '_state:first').css('display', 'block');
|
||||
$jqi.find('.' + options.prefix + 'buttons:empty')
|
||||
.css('display', 'none');
|
||||
$
|
||||
.each(
|
||||
message,
|
||||
function(statename, stateobj) {
|
||||
var $state = $jqi
|
||||
.find('#' + options.prefix + '_state_' + statename);
|
||||
$state
|
||||
.children('.' + options.prefix + 'buttons')
|
||||
.children('button')
|
||||
.click(
|
||||
function() {
|
||||
var msg = $state
|
||||
.children('.' + options.prefix + 'message');
|
||||
var clicked = stateobj.buttons[$(this).text()];
|
||||
var forminputs = {};
|
||||
$
|
||||
.each(
|
||||
$jqi
|
||||
.find(
|
||||
'#' + options.prefix + 'states :input')
|
||||
.serializeArray(),
|
||||
function(i, obj) {
|
||||
if (forminputs[obj.name] === undefined) {
|
||||
forminputs[obj.name] = obj.value;
|
||||
} else if (typeof forminputs[obj.name] == Array || typeof forminputs[obj.name] == 'object') {
|
||||
forminputs[obj.name]
|
||||
.push(obj.value);
|
||||
} else {
|
||||
forminputs[obj.name] = [
|
||||
forminputs[obj.name],
|
||||
obj.value ];
|
||||
}
|
||||
});
|
||||
var close = stateobj.submit(clicked, msg,
|
||||
forminputs);
|
||||
if (close === undefined || close) {
|
||||
removePrompt(true, clicked, msg, forminputs);
|
||||
}
|
||||
});
|
||||
$state
|
||||
.find(
|
||||
'.' + options.prefix + 'buttons button:eq(' + stateobj.focus + ')')
|
||||
.addClass(options.prefix + 'defaultbutton');
|
||||
});
|
||||
var ie6scroll = function() {
|
||||
$jqib.css( {
|
||||
top : $window.scrollTop()
|
||||
});
|
||||
};
|
||||
var fadeClicked = function() {
|
||||
if (options.persistent) {
|
||||
var i = 0;
|
||||
$jqib.addClass(options.prefix + 'warning');
|
||||
var intervalid = setInterval(function() {
|
||||
$jqib.toggleClass(options.prefix + 'warning');
|
||||
if (i++ > 1) {
|
||||
clearInterval(intervalid);
|
||||
$jqib.removeClass(options.prefix + 'warning');
|
||||
}
|
||||
}, 100);
|
||||
} else {
|
||||
removePrompt();
|
||||
}
|
||||
};
|
||||
var keyPressEventHandler = function(e) {
|
||||
var key = (window.event) ? event.keyCode : e.keyCode;
|
||||
if (key == 27) {
|
||||
fadeClicked();
|
||||
}
|
||||
if (key == 9) {
|
||||
var $inputels = $(':input:enabled:visible', $jqib);
|
||||
var fwd = !e.shiftKey && e.target == $inputels[$inputels.length - 1];
|
||||
var back = e.shiftKey && e.target == $inputels[0];
|
||||
if (fwd || back) {
|
||||
setTimeout(
|
||||
function() {
|
||||
if (!$inputels)
|
||||
return;
|
||||
var el = $inputels[back === true ? $inputels.length - 1 : 0];
|
||||
if (el)
|
||||
el.focus();
|
||||
}, 10);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
var positionPrompt = function() {
|
||||
$jqib.css( {
|
||||
position : (ie6) ? "absolute" : "fixed",
|
||||
height : $window.height(),
|
||||
width : "100%",
|
||||
top : (ie6) ? $window.scrollTop() : 0,
|
||||
left : 0,
|
||||
right : 0,
|
||||
bottom : 0
|
||||
});
|
||||
$jqif.css( {
|
||||
position : "absolute",
|
||||
height : $window.height(),
|
||||
width : "100%",
|
||||
top : 0,
|
||||
left : 0,
|
||||
right : 0,
|
||||
bottom : 0
|
||||
});
|
||||
$jqi.css( {
|
||||
position : "absolute",
|
||||
top : options.top,
|
||||
left : "50%",
|
||||
marginLeft : (($jqi.outerWidth() / 2) * -1)
|
||||
});
|
||||
};
|
||||
var stylePrompt = function() {
|
||||
$jqif.css( {
|
||||
zIndex : options.zIndex,
|
||||
display : "none",
|
||||
opacity : options.opacity
|
||||
});
|
||||
$jqi.css( {
|
||||
zIndex : options.zIndex + 1,
|
||||
display : "none"
|
||||
});
|
||||
$jqib.css( {
|
||||
zIndex : options.zIndex
|
||||
});
|
||||
};
|
||||
var removePrompt = function(callCallback, clicked, msg, formvals) {
|
||||
$jqi.remove();
|
||||
if (ie6) {
|
||||
$body.unbind('scroll', ie6scroll);
|
||||
}
|
||||
$window.unbind('resize', positionPrompt);
|
||||
$jqif.fadeOut(options.overlayspeed, function() {
|
||||
$jqif.unbind('click', fadeClicked);
|
||||
$jqif.remove();
|
||||
if (callCallback) {
|
||||
options.callback(clicked, msg, formvals);
|
||||
}
|
||||
$jqib.unbind('keypress', keyPressEventHandler);
|
||||
$jqib.remove();
|
||||
if (ie6 && !options.useiframe) {
|
||||
$('select').css('visibility', 'visible');
|
||||
}
|
||||
});
|
||||
};
|
||||
positionPrompt();
|
||||
stylePrompt();
|
||||
if (ie6) {
|
||||
$window.scroll(ie6scroll);
|
||||
}
|
||||
$jqif.click(fadeClicked);
|
||||
$window.resize(positionPrompt);
|
||||
$jqib.bind("keydown keypress", keyPressEventHandler);
|
||||
$jqi.find('.' + options.prefix + 'close').click(removePrompt);
|
||||
$jqif.fadeIn(options.overlayspeed);
|
||||
$jqi[options.show](options.promptspeed, options.loaded);
|
||||
$jqi
|
||||
.find(
|
||||
'#' + options.prefix + 'states .' + options.prefix + '_state:first .' + options.prefix + 'defaultbutton')
|
||||
.focus();
|
||||
if (options.timeout > 0)
|
||||
setTimeout($.prompt.close, options.timeout);
|
||||
return $jqib;
|
||||
};
|
||||
$.prompt.defaults = {
|
||||
prefix : 'jqi',
|
||||
classes : '',
|
||||
buttons : {
|
||||
Ok : true
|
||||
},
|
||||
loaded : function() {
|
||||
},
|
||||
submit : function() {
|
||||
return true;
|
||||
},
|
||||
callback : function() {
|
||||
},
|
||||
opacity : 0.6,
|
||||
zIndex : 999,
|
||||
overlayspeed : 'slow',
|
||||
promptspeed : 'fast',
|
||||
show : 'fadeIn',
|
||||
focus : 0,
|
||||
useiframe : false,
|
||||
top : "15%",
|
||||
persistent : true,
|
||||
timeout : 0,
|
||||
state : {
|
||||
html : '',
|
||||
buttons : {
|
||||
Ok : true
|
||||
},
|
||||
focus : 0,
|
||||
submit : function() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
$.prompt.currentPrefix = $.prompt.defaults.prefix;
|
||||
$.prompt.setDefaults = function(o) {
|
||||
$.prompt.defaults = $.extend( {}, $.prompt.defaults, o);
|
||||
};
|
||||
$.prompt.setStateDefaults = function(o) {
|
||||
$.prompt.defaults.state = $.extend( {}, $.prompt.defaults.state, o);
|
||||
};
|
||||
$.prompt.getStateContent = function(state) {
|
||||
return $('#' + $.prompt.currentPrefix + '_state_' + state);
|
||||
};
|
||||
$.prompt.getCurrentState = function() {
|
||||
return $('.' + $.prompt.currentPrefix + '_state:visible');
|
||||
};
|
||||
$.prompt.getCurrentStateName = function() {
|
||||
var stateid = $.prompt.getCurrentState().attr('id');
|
||||
return stateid.replace($.prompt.currentPrefix + '_state_', '');
|
||||
};
|
||||
$.prompt.goToState = function(state) {
|
||||
$('.' + $.prompt.currentPrefix + '_state').slideUp('slow');
|
||||
$('#' + $.prompt.currentPrefix + '_state_' + state).slideDown(
|
||||
'slow',
|
||||
function() {
|
||||
$(this).find('.' + $.prompt.currentPrefix + 'defaultbutton')
|
||||
.focus();
|
||||
});
|
||||
};
|
||||
$.prompt.nextState = function() {
|
||||
var $next = $('.' + $.prompt.currentPrefix + '_state:visible').next();
|
||||
$('.' + $.prompt.currentPrefix + '_state').slideUp('slow');
|
||||
$next.slideDown('slow', function() {
|
||||
$next.find('.' + $.prompt.currentPrefix + 'defaultbutton').focus();
|
||||
});
|
||||
};
|
||||
$.prompt.prevState = function() {
|
||||
var $next = $('.' + $.prompt.currentPrefix + '_state:visible').prev();
|
||||
$('.' + $.prompt.currentPrefix + '_state').slideUp('slow');
|
||||
$next.slideDown('slow', function() {
|
||||
$next.find('.' + $.prompt.currentPrefix + 'defaultbutton').focus();
|
||||
});
|
||||
};
|
||||
$.prompt.close = function() {
|
||||
$('#' + $.prompt.currentPrefix + 'box').fadeOut('fast', function() {
|
||||
$(this).remove();
|
||||
});
|
||||
};
|
||||
$.fn.prompt = function(options) {
|
||||
if (options == undefined)
|
||||
options = {};
|
||||
if (options.withDataAndEvents == undefined)
|
||||
options.withDataAndEvents = false;
|
||||
$.prompt($(this).clone(withDataAndEvents).html(), options);
|
||||
}
|
||||
})(jQuery);
|
234
xCAT-UI/js/jquery-ui-1.8.custom.min.js
vendored
Normal file
852
xCAT-UI/js/jquery.autocomplete.js
Normal file
@ -0,0 +1,852 @@
|
||||
/*
|
||||
* jQuery Autocomplete plugin 1.1
|
||||
*
|
||||
* Copyright (c) 2009 Jörn Zaefferer
|
||||
*
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* Revision: $Id: jquery.autocomplete.js 15 2009-08-22 10:30:27Z joern.zaefferer $
|
||||
*/
|
||||
|
||||
;
|
||||
(function($) {
|
||||
|
||||
$.fn.extend( {
|
||||
autocomplete : function(urlOrData, options) {
|
||||
var isUrl = typeof urlOrData == "string";
|
||||
options = $.extend( {}, $.Autocompleter.defaults, {
|
||||
url : isUrl ? urlOrData : null,
|
||||
data : isUrl ? null : urlOrData,
|
||||
delay : isUrl ? $.Autocompleter.defaults.delay : 10,
|
||||
max : options && !options.scroll ? 10 : 150
|
||||
}, options);
|
||||
|
||||
// if highlight is set to false, replace it with a do-nothing
|
||||
// function
|
||||
options.highlight = options.highlight || function(value) {
|
||||
return value;
|
||||
};
|
||||
|
||||
// if the formatMatch option is not specified, then use formatItem for
|
||||
// backwards compatibility
|
||||
options.formatMatch = options.formatMatch || options.formatItem;
|
||||
|
||||
return this.each(function() {
|
||||
new $.Autocompleter(this, options);
|
||||
});
|
||||
},
|
||||
result : function(handler) {
|
||||
return this.bind("result", handler);
|
||||
},
|
||||
search : function(handler) {
|
||||
return this.trigger("search", [ handler ]);
|
||||
},
|
||||
flushCache : function() {
|
||||
return this.trigger("flushCache");
|
||||
},
|
||||
setOptions : function(options) {
|
||||
return this.trigger("setOptions", [ options ]);
|
||||
},
|
||||
unautocomplete : function() {
|
||||
return this.trigger("unautocomplete");
|
||||
}
|
||||
});
|
||||
|
||||
$.Autocompleter = function(input, options) {
|
||||
|
||||
var KEY = {
|
||||
UP : 38,
|
||||
DOWN : 40,
|
||||
DEL : 46,
|
||||
TAB : 9,
|
||||
RETURN : 13,
|
||||
ESC : 27,
|
||||
COMMA : 188,
|
||||
PAGEUP : 33,
|
||||
PAGEDOWN : 34,
|
||||
BACKSPACE : 8
|
||||
};
|
||||
|
||||
// Create $ object for input element
|
||||
var $input = $(input).attr("autocomplete", "off")
|
||||
.addClass(options.inputClass);
|
||||
|
||||
var timeout;
|
||||
var previousValue = "";
|
||||
var cache = $.Autocompleter.Cache(options);
|
||||
var hasFocus = 0;
|
||||
var lastKeyPressCode;
|
||||
var config = {
|
||||
mouseDownOnSelect : false
|
||||
};
|
||||
var select = $.Autocompleter
|
||||
.Select(options, input, selectCurrent, config);
|
||||
|
||||
var blockSubmit;
|
||||
|
||||
// prevent form submit in opera when selecting with return key
|
||||
$.browser.opera &&
|
||||
$(input.form).bind("submit.autocomplete", function() {
|
||||
if (blockSubmit) {
|
||||
blockSubmit = false;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// only opera doesn't trigger keydown multiple times while pressed,
|
||||
// others don't work with keypress at all
|
||||
$input.bind(($.browser.opera ? "keypress" : "keydown") +
|
||||
".autocomplete", function(event) {
|
||||
// a keypress means the input has focus
|
||||
// avoids issue where input had focus before the autocomplete
|
||||
// was applied
|
||||
hasFocus = 1;
|
||||
// track last key pressed
|
||||
lastKeyPressCode = event.keyCode;
|
||||
switch (event.keyCode) {
|
||||
|
||||
case KEY.UP:
|
||||
event.preventDefault();
|
||||
if (select.visible()) {
|
||||
select.prev();
|
||||
} else {
|
||||
onChange(0, true);
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY.DOWN:
|
||||
event.preventDefault();
|
||||
if (select.visible()) {
|
||||
select.next();
|
||||
} else {
|
||||
onChange(0, true);
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY.PAGEUP:
|
||||
event.preventDefault();
|
||||
if (select.visible()) {
|
||||
select.pageUp();
|
||||
} else {
|
||||
onChange(0, true);
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY.PAGEDOWN:
|
||||
event.preventDefault();
|
||||
if (select.visible()) {
|
||||
select.pageDown();
|
||||
} else {
|
||||
onChange(0, true);
|
||||
}
|
||||
break;
|
||||
|
||||
// matches also semicolon
|
||||
case options.multiple && $.trim(options.multipleSeparator) == "," &&
|
||||
KEY.COMMA:
|
||||
case KEY.TAB:
|
||||
case KEY.RETURN:
|
||||
if (selectCurrent()) {
|
||||
// stop default to prevent a form submit, Opera needs special handling
|
||||
event.preventDefault();
|
||||
blockSubmit = true;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY.ESC:
|
||||
select.hide();
|
||||
break;
|
||||
|
||||
default:
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(onChange, options.delay);
|
||||
break;
|
||||
}
|
||||
}).focus(function() {
|
||||
// track whether the field has focus, we shouldn't process any
|
||||
// results if the field no longer has focus
|
||||
hasFocus++;
|
||||
}).blur(function() {
|
||||
hasFocus = 0;
|
||||
if (!config.mouseDownOnSelect) {
|
||||
hideResults();
|
||||
}
|
||||
}).click(function() {
|
||||
// show select when clicking in a focused field
|
||||
if (hasFocus++ > 1 && !select.visible()) {
|
||||
onChange(0, true);
|
||||
}
|
||||
}).bind("search", function() {
|
||||
// TODO why not just specifying both arguments?
|
||||
var fn = (arguments.length > 1) ? arguments[1] : null;
|
||||
function findValueCallback(q, data) {
|
||||
var result;
|
||||
if (data && data.length) {
|
||||
for ( var i = 0; i < data.length; i++) {
|
||||
if (data[i].result.toLowerCase() == q.toLowerCase()) {
|
||||
result = data[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeof fn == "function")
|
||||
fn(result);
|
||||
else
|
||||
$input.trigger("result", result &&
|
||||
[ result.data, result.value ]);
|
||||
}
|
||||
$.each(trimWords($input.val()), function(i, value) {
|
||||
request(value, findValueCallback, findValueCallback);
|
||||
});
|
||||
}).bind("flushCache", function() {
|
||||
cache.flush();
|
||||
}).bind("setOptions", function() {
|
||||
$.extend(options, arguments[1]);
|
||||
// if we've updated the data, repopulate
|
||||
if ("data" in arguments[1])
|
||||
cache.populate();
|
||||
}).bind("unautocomplete", function() {
|
||||
select.unbind();
|
||||
$input.unbind();
|
||||
$(input.form).unbind(".autocomplete");
|
||||
});
|
||||
|
||||
function selectCurrent() {
|
||||
var selected = select.selected();
|
||||
if (!selected)
|
||||
return false;
|
||||
|
||||
var v = selected.result;
|
||||
previousValue = v;
|
||||
|
||||
if (options.multiple) {
|
||||
var words = trimWords($input.val());
|
||||
if (words.length > 1) {
|
||||
var seperator = options.multipleSeparator.length;
|
||||
var cursorAt = $(input).selection().start;
|
||||
var wordAt, progress = 0;
|
||||
$.each(words, function(i, word) {
|
||||
progress += word.length;
|
||||
if (cursorAt <= progress) {
|
||||
wordAt = i;
|
||||
return false;
|
||||
}
|
||||
progress += seperator;
|
||||
});
|
||||
words[wordAt] = v;
|
||||
// TODO this should set the cursor to the right position,
|
||||
// but it gets overriden somewhere
|
||||
// $.Autocompleter.Selection(input, progress + seperator,
|
||||
// progress + seperator);
|
||||
v = words.join(options.multipleSeparator);
|
||||
}
|
||||
v += options.multipleSeparator;
|
||||
}
|
||||
|
||||
$input.val(v);
|
||||
hideResultsNow();
|
||||
$input.trigger("result", [ selected.data, selected.value ]);
|
||||
return true;
|
||||
}
|
||||
|
||||
function onChange(crap, skipPrevCheck) {
|
||||
if (lastKeyPressCode == KEY.DEL) {
|
||||
select.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
var currentValue = $input.val();
|
||||
|
||||
if (!skipPrevCheck && currentValue == previousValue)
|
||||
return;
|
||||
|
||||
previousValue = currentValue;
|
||||
|
||||
currentValue = lastWord(currentValue);
|
||||
if (currentValue.length >= options.minChars) {
|
||||
$input.addClass(options.loadingClass);
|
||||
if (!options.matchCase)
|
||||
currentValue = currentValue.toLowerCase();
|
||||
request(currentValue, receiveData, hideResultsNow);
|
||||
} else {
|
||||
stopLoading();
|
||||
select.hide();
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
function trimWords(value) {
|
||||
if (!value)
|
||||
return [ "" ];
|
||||
if (!options.multiple)
|
||||
return [ $.trim(value) ];
|
||||
return $
|
||||
.map(value.split(options.multipleSeparator), function(word) {
|
||||
return $.trim(value).length ? $.trim(word) : null;
|
||||
});
|
||||
}
|
||||
|
||||
function lastWord(value) {
|
||||
if (!options.multiple)
|
||||
return value;
|
||||
var words = trimWords(value);
|
||||
if (words.length == 1)
|
||||
return words[0];
|
||||
var cursorAt = $(input).selection().start;
|
||||
if (cursorAt == value.length) {
|
||||
words = trimWords(value)
|
||||
} else {
|
||||
words = trimWords(value.replace(value.substring(cursorAt), ""));
|
||||
}
|
||||
return words[words.length - 1];
|
||||
}
|
||||
|
||||
// fills in the input box w/the first match (assumed to be the best match)
|
||||
// q: the term entered
|
||||
// sValue: the first matching result
|
||||
function autoFill(q, sValue) {
|
||||
// autofill in the complete box w/the first match as long as the user hasn't entered in more data
|
||||
// if the last user key pressed was backspace, don't autofill
|
||||
if (options.autoFill &&
|
||||
(lastWord($input.val()).toLowerCase() == q.toLowerCase()) &&
|
||||
lastKeyPressCode != KEY.BACKSPACE) {
|
||||
// fill in the value (keep the case the user has typed)
|
||||
$input.val($input.val() +
|
||||
sValue.substring(lastWord(previousValue).length));
|
||||
// select the portion of the value not typed by the user (so the
|
||||
// next character will erase)
|
||||
$(input).selection(previousValue.length, previousValue.length +
|
||||
sValue.length);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
function hideResults() {
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(hideResultsNow, 200);
|
||||
}
|
||||
;
|
||||
|
||||
function hideResultsNow() {
|
||||
var wasVisible = select.visible();
|
||||
select.hide();
|
||||
clearTimeout(timeout);
|
||||
stopLoading();
|
||||
if (options.mustMatch) {
|
||||
// call search and run callback
|
||||
$input.search(function(result) {
|
||||
// if no value found, clear the input box
|
||||
if (!result) {
|
||||
if (options.multiple) {
|
||||
var words = trimWords($input.val()).slice(0, -1);
|
||||
$input
|
||||
.val(words.join(options.multipleSeparator) +
|
||||
(words.length ? options.multipleSeparator : ""));
|
||||
} else {
|
||||
$input.val("");
|
||||
$input.trigger("result", null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
function receiveData(q, data) {
|
||||
if (data && data.length && hasFocus) {
|
||||
stopLoading();
|
||||
select.display(data, q);
|
||||
autoFill(q, data[0].value);
|
||||
select.show();
|
||||
} else {
|
||||
hideResultsNow();
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
function request(term, success, failure) {
|
||||
if (!options.matchCase)
|
||||
term = term.toLowerCase();
|
||||
var data = cache.load(term);
|
||||
// recieve the cached data
|
||||
if (data && data.length) {
|
||||
success(term, data);
|
||||
// if an AJAX url has been supplied, try loading the data now
|
||||
} else if ((typeof options.url == "string") &&
|
||||
(options.url.length > 0)) {
|
||||
|
||||
var extraParams = {
|
||||
timestamp : +new Date()
|
||||
};
|
||||
$
|
||||
.each(options.extraParams, function(key, param) {
|
||||
extraParams[key] = typeof param == "function" ? param() : param;
|
||||
});
|
||||
|
||||
$.ajax( {
|
||||
// try to leverage ajaxQueue plugin to abort previous requests
|
||||
mode : "abort",
|
||||
// limit abortion to this input
|
||||
port : "autocomplete" + input.name,
|
||||
dataType : options.dataType,
|
||||
url : options.url,
|
||||
data : $.extend( {
|
||||
q : lastWord(term), limit : options.max
|
||||
}, extraParams),
|
||||
success : function(data) {
|
||||
var parsed = options.parse && options.parse(data) ||
|
||||
parse(data);
|
||||
cache.add(term, parsed);
|
||||
success(term, parsed);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the
|
||||
// last successful match
|
||||
select.emptyList();
|
||||
failure(term);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
function parse(data) {
|
||||
var parsed = [];
|
||||
var rows = data.split("\n");
|
||||
for ( var i = 0; i < rows.length; i++) {
|
||||
var row = $.trim(rows[i]);
|
||||
if (row) {
|
||||
row = row.split("|");
|
||||
parsed[parsed.length] = {
|
||||
data : row,
|
||||
value : row[0],
|
||||
result : options.formatResult &&
|
||||
options.formatResult(row, row[0]) || row[0]
|
||||
};
|
||||
}
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
;
|
||||
|
||||
function stopLoading() {
|
||||
$input.removeClass(options.loadingClass);
|
||||
}
|
||||
;
|
||||
|
||||
};
|
||||
|
||||
$.Autocompleter.defaults = {
|
||||
inputClass : "ac_input",
|
||||
resultsClass : "ac_results",
|
||||
loadingClass : "ac_loading",
|
||||
minChars : 1,
|
||||
delay : 400,
|
||||
matchCase : false,
|
||||
matchSubset : true,
|
||||
matchContains : false,
|
||||
cacheLength : 10,
|
||||
max : 100,
|
||||
mustMatch : false,
|
||||
extraParams : {},
|
||||
selectFirst : true,
|
||||
formatItem : function(row) {
|
||||
return row[0];
|
||||
},
|
||||
formatMatch : null,
|
||||
autoFill : false,
|
||||
width : 0,
|
||||
multiple : false,
|
||||
multipleSeparator : ", ",
|
||||
highlight : function(value, term) {
|
||||
return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" +
|
||||
term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") +
|
||||
")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
|
||||
},
|
||||
scroll : true,
|
||||
scrollHeight : 180
|
||||
};
|
||||
|
||||
$.Autocompleter.Cache = function(options) {
|
||||
|
||||
var data = {};
|
||||
var length = 0;
|
||||
|
||||
function matchSubset(s, sub) {
|
||||
if (!options.matchCase)
|
||||
s = s.toLowerCase();
|
||||
var i = s.indexOf(sub);
|
||||
if (options.matchContains == "word") {
|
||||
i = s.toLowerCase().search("\\b" + sub.toLowerCase());
|
||||
}
|
||||
if (i == -1)
|
||||
return false;
|
||||
return i == 0 || options.matchContains;
|
||||
}
|
||||
;
|
||||
|
||||
function add(q, value) {
|
||||
if (length > options.cacheLength) {
|
||||
flush();
|
||||
}
|
||||
if (!data[q]) {
|
||||
length++;
|
||||
}
|
||||
data[q] = value;
|
||||
}
|
||||
|
||||
function populate() {
|
||||
if (!options.data)
|
||||
return false;
|
||||
// track the matches
|
||||
var stMatchSets = {}, nullData = 0;
|
||||
|
||||
// no url was specified, we need to adjust the cache length to make
|
||||
// sure it fits the local data store
|
||||
if (!options.url)
|
||||
options.cacheLength = 1;
|
||||
|
||||
// track all options for minChars = 0
|
||||
stMatchSets[""] = [];
|
||||
|
||||
// loop through the array and create a lookup structure
|
||||
for ( var i = 0, ol = options.data.length; i < ol; i++) {
|
||||
var rawValue = options.data[i];
|
||||
// if rawValue is a string, make an array otherwise just
|
||||
// reference the array
|
||||
rawValue = (typeof rawValue == "string") ? [ rawValue ] : rawValue;
|
||||
|
||||
var value = options
|
||||
.formatMatch(rawValue, i + 1, options.data.length);
|
||||
if (value === false)
|
||||
continue;
|
||||
|
||||
var firstChar = value.charAt(0).toLowerCase();
|
||||
// if no lookup array for this character exists, look it up now
|
||||
if (!stMatchSets[firstChar])
|
||||
stMatchSets[firstChar] = [];
|
||||
|
||||
// if the match is a string
|
||||
var row = {
|
||||
value : value,
|
||||
data : rawValue,
|
||||
result : options.formatResult &&
|
||||
options.formatResult(rawValue) || value
|
||||
};
|
||||
|
||||
// push the current match into the set list
|
||||
stMatchSets[firstChar].push(row);
|
||||
|
||||
// keep track of minChars zero items
|
||||
if (nullData++ < options.max) {
|
||||
stMatchSets[""].push(row);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
// add the data items to the cache
|
||||
$.each(stMatchSets, function(i, value) {
|
||||
// increase the cache size
|
||||
options.cacheLength++;
|
||||
// add to the cache
|
||||
add(i, value);
|
||||
});
|
||||
}
|
||||
|
||||
// populate any existing data
|
||||
setTimeout(populate, 25);
|
||||
|
||||
function flush() {
|
||||
data = {};
|
||||
length = 0;
|
||||
}
|
||||
|
||||
return {
|
||||
flush : flush, add : add, populate : populate, load : function(q) {
|
||||
if (!options.cacheLength || !length)
|
||||
return null;
|
||||
/*
|
||||
* if dealing w/local data and matchContains than we must make sure to loop through all the data
|
||||
* collections looking for matches
|
||||
*/
|
||||
if (!options.url && options.matchContains) {
|
||||
// track all matches
|
||||
var csub = [];
|
||||
// loop through all the data grids for matches
|
||||
for ( var k in data) {
|
||||
// don't search through the stMatchSets[""] (minChars: 0) cache
|
||||
// this prevents duplicates
|
||||
if (k.length > 0) {
|
||||
var c = data[k];
|
||||
$.each(c, function(i, x) {
|
||||
// if we've got a match, add it to the array
|
||||
if (matchSubset(x.value, q)) {
|
||||
csub.push(x);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return csub;
|
||||
} else
|
||||
// if the exact item exists, use it
|
||||
if (data[q]) {
|
||||
return data[q];
|
||||
} else if (options.matchSubset) {
|
||||
for ( var i = q.length - 1; i >= options.minChars; i--) {
|
||||
var c = data[q.substr(0, i)];
|
||||
if (c) {
|
||||
var csub = [];
|
||||
$.each(c, function(i, x) {
|
||||
if (matchSubset(x.value, q)) {
|
||||
csub[csub.length] = x;
|
||||
}
|
||||
});
|
||||
return csub;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
$.Autocompleter.Select = function(options, input, select, config) {
|
||||
var CLASSES = {
|
||||
ACTIVE : "ac_over"
|
||||
};
|
||||
|
||||
var listItems, active = -1, data, term = "", needsInit = true, element, list;
|
||||
|
||||
// Create results
|
||||
function init() {
|
||||
if (!needsInit)
|
||||
return;
|
||||
element = $("<div/>").hide().addClass(options.resultsClass)
|
||||
.css("position", "absolute").appendTo(document.body);
|
||||
|
||||
list = $("<ul/>").appendTo(element).mouseover(function(event) {
|
||||
if (target(event).nodeName &&
|
||||
target(event).nodeName.toUpperCase() == 'LI') {
|
||||
active = $("li", list).removeClass(CLASSES.ACTIVE)
|
||||
.index(target(event));
|
||||
$(target(event)).addClass(CLASSES.ACTIVE);
|
||||
}
|
||||
}).click(function(event) {
|
||||
$(target(event)).addClass(CLASSES.ACTIVE);
|
||||
select();
|
||||
// TODO provide option to avoid setting focus again after
|
||||
// selection? useful for cleanup-on-focus
|
||||
input.focus();
|
||||
return false;
|
||||
}).mousedown(function() {
|
||||
config.mouseDownOnSelect = true;
|
||||
}).mouseup(function() {
|
||||
config.mouseDownOnSelect = false;
|
||||
});
|
||||
|
||||
if (options.width > 0)
|
||||
element.css("width", options.width);
|
||||
|
||||
needsInit = false;
|
||||
}
|
||||
|
||||
function target(event) {
|
||||
var element = event.target;
|
||||
while (element && element.tagName != "LI")
|
||||
element = element.parentNode;
|
||||
// more fun with IE, sometimes event.target is empty, just ignore it
|
||||
// then
|
||||
if (!element)
|
||||
return [];
|
||||
return element;
|
||||
}
|
||||
|
||||
function moveSelect(step) {
|
||||
listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
|
||||
movePosition(step);
|
||||
var activeItem = listItems.slice(active, active + 1)
|
||||
.addClass(CLASSES.ACTIVE);
|
||||
if (options.scroll) {
|
||||
var offset = 0;
|
||||
listItems.slice(0, active).each(function() {
|
||||
offset += this.offsetHeight;
|
||||
});
|
||||
if ((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
|
||||
list.scrollTop(offset + activeItem[0].offsetHeight -
|
||||
list.innerHeight());
|
||||
} else if (offset < list.scrollTop()) {
|
||||
list.scrollTop(offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
function movePosition(step) {
|
||||
active += step;
|
||||
if (active < 0) {
|
||||
active = listItems.size() - 1;
|
||||
} else if (active >= listItems.size()) {
|
||||
active = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function limitNumberOfItems(available) {
|
||||
return options.max && options.max < available ? options.max : available;
|
||||
}
|
||||
|
||||
function fillList() {
|
||||
list.empty();
|
||||
var max = limitNumberOfItems(data.length);
|
||||
for ( var i = 0; i < max; i++) {
|
||||
if (!data[i])
|
||||
continue;
|
||||
var formatted = options
|
||||
.formatItem(data[i].data, i + 1, max, data[i].value, term);
|
||||
if (formatted === false)
|
||||
continue;
|
||||
var li = $("<li/>").html(options.highlight(formatted, term))
|
||||
.addClass(i % 2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
|
||||
$.data(li, "ac_data", data[i]);
|
||||
}
|
||||
listItems = list.find("li");
|
||||
if (options.selectFirst) {
|
||||
listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
|
||||
active = 0;
|
||||
}
|
||||
// apply bgiframe if available
|
||||
if ($.fn.bgiframe)
|
||||
list.bgiframe();
|
||||
}
|
||||
|
||||
return {
|
||||
display : function(d, q) {
|
||||
init();
|
||||
data = d;
|
||||
term = q;
|
||||
fillList();
|
||||
},
|
||||
next : function() {
|
||||
moveSelect(1);
|
||||
},
|
||||
prev : function() {
|
||||
moveSelect(-1);
|
||||
},
|
||||
pageUp : function() {
|
||||
if (active != 0 && active - 8 < 0) {
|
||||
moveSelect(-active);
|
||||
} else {
|
||||
moveSelect(-8);
|
||||
}
|
||||
},
|
||||
pageDown : function() {
|
||||
if (active != listItems.size() - 1 &&
|
||||
active + 8 > listItems.size()) {
|
||||
moveSelect(listItems.size() - 1 - active);
|
||||
} else {
|
||||
moveSelect(8);
|
||||
}
|
||||
},
|
||||
hide : function() {
|
||||
element && element.hide();
|
||||
listItems && listItems.removeClass(CLASSES.ACTIVE);
|
||||
active = -1;
|
||||
},
|
||||
visible : function() {
|
||||
return element && element.is(":visible");
|
||||
},
|
||||
current : function() {
|
||||
return this.visible() &&
|
||||
(listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst &&
|
||||
listItems[0]);
|
||||
},
|
||||
show : function() {
|
||||
var offset = $(input).offset();
|
||||
element.css( {
|
||||
width : typeof options.width == "string" ||
|
||||
options.width > 0 ? options.width : $(input).width(),
|
||||
top : offset.top + input.offsetHeight,
|
||||
left : offset.left
|
||||
}).show();
|
||||
if (options.scroll) {
|
||||
list.scrollTop(0);
|
||||
list.css( {
|
||||
maxHeight : options.scrollHeight, overflow : 'auto'
|
||||
});
|
||||
|
||||
if ($.browser.msie &&
|
||||
typeof document.body.style.maxHeight === "undefined") {
|
||||
var listHeight = 0;
|
||||
listItems.each(function() {
|
||||
listHeight += this.offsetHeight;
|
||||
});
|
||||
var scrollbarsVisible = listHeight > options.scrollHeight;
|
||||
list
|
||||
.css('height', scrollbarsVisible ? options.scrollHeight : listHeight);
|
||||
if (!scrollbarsVisible) {
|
||||
// IE doesn't recalculate width when scrollbar disappears
|
||||
listItems.width(list.width() -
|
||||
parseInt(listItems.css("padding-left")) -
|
||||
parseInt(listItems.css("padding-right")));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
selected : function() {
|
||||
var selected = listItems &&
|
||||
listItems.filter("." + CLASSES.ACTIVE)
|
||||
.removeClass(CLASSES.ACTIVE);
|
||||
return selected && selected.length &&
|
||||
$.data(selected[0], "ac_data");
|
||||
},
|
||||
emptyList : function() {
|
||||
list && list.empty();
|
||||
},
|
||||
unbind : function() {
|
||||
element && element.remove();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
$.fn.selection = function(start, end) {
|
||||
if (start !== undefined) {
|
||||
return this.each(function() {
|
||||
if (this.createTextRange) {
|
||||
var selRange = this.createTextRange();
|
||||
if (end === undefined || start == end) {
|
||||
selRange.move("character", start);
|
||||
selRange.select();
|
||||
} else {
|
||||
selRange.collapse(true);
|
||||
selRange.moveStart("character", start);
|
||||
selRange.moveEnd("character", end);
|
||||
selRange.select();
|
||||
}
|
||||
} else if (this.setSelectionRange) {
|
||||
this.setSelectionRange(start, end);
|
||||
} else if (this.selectionStart) {
|
||||
this.selectionStart = start;
|
||||
this.selectionEnd = end;
|
||||
}
|
||||
});
|
||||
}
|
||||
var field = this[0];
|
||||
if (field.createTextRange) {
|
||||
var range = document.selection.createRange(), orig = field.value, teststring = "<->", textLength = range.text.length;
|
||||
range.text = teststring;
|
||||
var caretAt = field.value.indexOf(teststring);
|
||||
field.value = orig;
|
||||
this.selection(caretAt, caretAt + textLength);
|
||||
return {
|
||||
start : caretAt, end : caretAt + textLength
|
||||
}
|
||||
} else if (field.selectionStart !== undefined) {
|
||||
return {
|
||||
start : field.selectionStart, end : field.selectionEnd
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
370
xCAT-UI/js/jquery.contextmenu.js
Normal file
@ -0,0 +1,370 @@
|
||||
/**
|
||||
* Copyright (c)2005-2009 Matt Kruse (javascripttoolbox.com)
|
||||
*
|
||||
* Dual licensed under the MIT and GPL licenses.
|
||||
* This basically means you can use this code however you want for
|
||||
* free, but don't claim to have written it yourself!
|
||||
* Donations always accepted: http://www.JavascriptToolbox.com/donate/
|
||||
*
|
||||
* Please do not link to the .js files on javascripttoolbox.com from
|
||||
* your site. Copy the files locally to your server instead.
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* jquery.contextmenu.js jQuery Plugin for Context Menus http://www.JavascriptToolbox.com/lib/contextmenu/
|
||||
*
|
||||
* Copyright (c) 2008 Matt Kruse (javascripttoolbox.com) Dual licensed under the MIT and GPL licenses.
|
||||
*
|
||||
* @version 1.1
|
||||
* @history 1.1 2010-01-25 Fixed a problem with 1.4 which caused undesired show/hide animations
|
||||
* @history 1.0 2008-10-20 Initial Release
|
||||
* @todo slideUp doesn't work in IE - because of iframe?
|
||||
* @todo Hide all other menus when contextmenu is shown?
|
||||
* @todo More themes
|
||||
* @todo Nested context menus
|
||||
*/
|
||||
;
|
||||
(function($) {
|
||||
$.contextMenu = {
|
||||
shadow : true,
|
||||
shadowOffset : 0,
|
||||
shadowOffsetX : 5,
|
||||
shadowOffsetY : 5,
|
||||
shadowWidthAdjust : -3,
|
||||
shadowHeightAdjust : -3,
|
||||
shadowOpacity : .2,
|
||||
shadowClass : 'context-menu-shadow',
|
||||
shadowColor : 'black',
|
||||
|
||||
offsetX : 0,
|
||||
offsetY : 0,
|
||||
appendTo : 'body',
|
||||
direction : 'down',
|
||||
constrainToScreen : true,
|
||||
|
||||
showTransition : 'show',
|
||||
hideTransition : 'hide',
|
||||
showSpeed : null,
|
||||
hideSpeed : null,
|
||||
showCallback : null,
|
||||
hideCallback : null,
|
||||
|
||||
className : 'context-menu',
|
||||
itemClassName : 'context-menu-item',
|
||||
itemHoverClassName : 'context-menu-item-hover',
|
||||
disabledItemClassName : 'context-menu-item-disabled',
|
||||
disabledItemHoverClassName : 'context-menu-item-disabled-hover',
|
||||
separatorClassName : 'context-menu-separator',
|
||||
innerDivClassName : 'context-menu-item-inner',
|
||||
themePrefix : 'context-menu-theme-',
|
||||
theme : 'default',
|
||||
|
||||
separator : 'context-menu-separator', // A specific key to identify a separator
|
||||
target : null, // The target of the context click, to be populated when triggered
|
||||
menu : null, // The jQuery object containing the HTML object that is the menu itself
|
||||
shadowObj : null, // Shadow object
|
||||
bgiframe : null, // The iframe object for IE6
|
||||
shown : false, // Currently being shown?
|
||||
useIframe : /* @cc_on @ *//* @if (@_win32) true, @else @ */false,/* @end @ */// This is a better check than
|
||||
// looking
|
||||
// at userAgent!
|
||||
|
||||
// Create the menu instance
|
||||
create : function(menu, opts) {
|
||||
var cmenu = $.extend( {}, this, opts); // Clone all default
|
||||
// properties to created
|
||||
// object
|
||||
|
||||
// If a selector has been passed in, then use that as the menu
|
||||
if (typeof menu == "string") {
|
||||
cmenu.menu = $(menu);
|
||||
}
|
||||
// If a function has been passed in, call it each time the menu is shown to create the menu
|
||||
else if (typeof menu == "function") {
|
||||
cmenu.menuFunction = menu;
|
||||
}
|
||||
// Otherwise parse the Array passed in
|
||||
else {
|
||||
cmenu.menu = cmenu.createMenu(menu, cmenu);
|
||||
}
|
||||
if (cmenu.menu) {
|
||||
cmenu.menu.css( {
|
||||
display : 'none'
|
||||
});
|
||||
$(cmenu.appendTo).append(cmenu.menu);
|
||||
}
|
||||
|
||||
// Create the shadow object if shadow is enabled
|
||||
if (cmenu.shadow) {
|
||||
cmenu.createShadow(cmenu); // Extracted to method for
|
||||
// extensibility
|
||||
if (cmenu.shadowOffset) {
|
||||
cmenu.shadowOffsetX = cmenu.shadowOffsetY = cmenu.shadowOffset;
|
||||
}
|
||||
}
|
||||
$('body').bind('contextmenu', function() {
|
||||
cmenu.hide();
|
||||
}); // If right-clicked somewhere else in the document, hide this
|
||||
// menu
|
||||
return cmenu;
|
||||
},
|
||||
|
||||
// Create an iframe object to go behind the menu
|
||||
createIframe : function() {
|
||||
return $('<iframe frameborder="0" tabindex="-1" src="javascript:false" style="display:block;position:absolute;z-index:-1;filter:Alpha(Opacity=0);"/>');
|
||||
},
|
||||
|
||||
// Accept an Array representing a menu structure and turn it into HTML
|
||||
createMenu : function(menu, cmenu) {
|
||||
var className = cmenu.className;
|
||||
$.each(cmenu.theme.split(","), function(i, n) {
|
||||
className += ' ' + cmenu.themePrefix + n
|
||||
});
|
||||
var $t = $('<table cellspacing=0 cellpadding=0></table>')
|
||||
.click(function() {
|
||||
cmenu.hide();
|
||||
return false;
|
||||
}); // We wrap a table around it so width can be flexible
|
||||
var $tr = $('<tr></tr>');
|
||||
var $td = $('<td></td>');
|
||||
var $div = $('<div class="' + className + '"></div>');
|
||||
|
||||
// Each menu item is specified as either:
|
||||
// title:function
|
||||
// or title: { property:value ... }
|
||||
for ( var i = 0; i < menu.length; i++) {
|
||||
var m = menu[i];
|
||||
if (m == $.contextMenu.separator) {
|
||||
$div.append(cmenu.createSeparator());
|
||||
} else {
|
||||
for ( var opt in menu[i]) {
|
||||
$div.append(cmenu.createMenuItem(opt, menu[i][opt])); // Extracted
|
||||
// to
|
||||
// method
|
||||
// for
|
||||
// extensibility
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cmenu.useIframe) {
|
||||
$td.append(cmenu.createIframe());
|
||||
}
|
||||
$t.append($tr.append($td.append($div)))
|
||||
return $t;
|
||||
},
|
||||
|
||||
// Create an individual menu item
|
||||
createMenuItem : function(label, obj) {
|
||||
var cmenu = this;
|
||||
if (typeof obj == "function") {
|
||||
obj = {
|
||||
onclick : obj
|
||||
};
|
||||
} // If passed a simple function, turn it into a property of an object
|
||||
// Default properties, extended in case properties are passed
|
||||
var o = $.extend( {
|
||||
onclick : function() {
|
||||
},
|
||||
className : '',
|
||||
hoverClassName : cmenu.itemHoverClassName,
|
||||
icon : '',
|
||||
disabled : false,
|
||||
title : '',
|
||||
hoverItem : cmenu.hoverItem,
|
||||
hoverItemOut : cmenu.hoverItemOut
|
||||
}, obj);
|
||||
// If an icon is specified, hard-code the background-image style.
|
||||
// Themes that don't show images should take this into account in
|
||||
// their CSS
|
||||
var iconStyle = (o.icon) ? 'background-image:url(' + o.icon + ');' : '';
|
||||
var $div = $('<div class="' + cmenu.itemClassName + ' ' +
|
||||
o.className +
|
||||
((o.disabled) ? ' ' + cmenu.disabledItemClassName : '') +
|
||||
'" title="' + o.title + '"></div>')
|
||||
// If the item is disabled, don't do anything when it is clicked
|
||||
.click(function(e) {
|
||||
if (cmenu.isItemDisabled(this)) {
|
||||
return false;
|
||||
} else {
|
||||
return o.onclick.call(cmenu.target, this, cmenu, e)
|
||||
}
|
||||
})
|
||||
// Change the class of the item when hovered over
|
||||
.hover(function() {
|
||||
o.hoverItem
|
||||
.call(this, (cmenu.isItemDisabled(this)) ? cmenu.disabledItemHoverClassName : o.hoverClassName);
|
||||
}, function() {
|
||||
o.hoverItemOut
|
||||
.call(this, (cmenu.isItemDisabled(this)) ? cmenu.disabledItemHoverClassName : o.hoverClassName);
|
||||
});
|
||||
var $idiv = $('<div class="' + cmenu.innerDivClassName +
|
||||
'" style="' + iconStyle + '">' + label + '</div>');
|
||||
$div.append($idiv);
|
||||
return $div;
|
||||
},
|
||||
|
||||
// Create a separator row
|
||||
createSeparator : function() {
|
||||
return $('<div class="' + this.separatorClassName + '"></div>');
|
||||
},
|
||||
|
||||
// Determine if an individual item is currently disabled. This is called each time the item is hovered or
|
||||
// clicked because the disabled status may change at any time
|
||||
isItemDisabled : function(item) {
|
||||
return $(item).is('.' + this.disabledItemClassName);
|
||||
},
|
||||
|
||||
// Functions to fire on hover. Extracted to methods for extensibility
|
||||
hoverItem : function(c) {
|
||||
$(this).addClass(c);
|
||||
},
|
||||
hoverItemOut : function(c) {
|
||||
$(this).removeClass(c);
|
||||
},
|
||||
|
||||
// Create the shadow object
|
||||
createShadow : function(cmenu) {
|
||||
cmenu.shadowObj = $('<div class="' + cmenu.shadowClass + '"></div>')
|
||||
.css( {
|
||||
display : 'none',
|
||||
position : "absolute",
|
||||
zIndex : 9998,
|
||||
opacity : cmenu.shadowOpacity,
|
||||
backgroundColor : cmenu.shadowColor
|
||||
});
|
||||
$(cmenu.appendTo).append(cmenu.shadowObj);
|
||||
},
|
||||
|
||||
// Display the shadow object, given the position of the menu itself
|
||||
showShadow : function(x, y, e) {
|
||||
var cmenu = this;
|
||||
if (cmenu.shadow) {
|
||||
cmenu.shadowObj.css( {
|
||||
width : (cmenu.menu.width() + cmenu.shadowWidthAdjust) +
|
||||
"px",
|
||||
height : (cmenu.menu.height() + cmenu.shadowHeightAdjust) +
|
||||
"px",
|
||||
top : (y + cmenu.shadowOffsetY) + "px",
|
||||
left : (x + cmenu.shadowOffsetX) + "px"
|
||||
}).addClass(cmenu.shadowClass)[cmenu.showTransition]
|
||||
(cmenu.showSpeed);
|
||||
}
|
||||
},
|
||||
|
||||
// A hook to call before the menu is shown, in case special processing needs to be done.
|
||||
// Return false to cancel the default show operation
|
||||
beforeShow : function() {
|
||||
return true;
|
||||
},
|
||||
|
||||
// Show the context menu
|
||||
show : function(t, e) {
|
||||
var cmenu = this, x = e.pageX, y = e.pageY;
|
||||
cmenu.target = t; // Preserve the object that triggered this
|
||||
// context menu so menu item click methods can
|
||||
// see it
|
||||
if (cmenu.beforeShow() !== false) {
|
||||
// If the menu content is a function, call it to populate the menu each time it is displayed
|
||||
if (cmenu.menuFunction) {
|
||||
if (cmenu.menu) {
|
||||
$(cmenu.menu).remove();
|
||||
}
|
||||
cmenu.menu = cmenu
|
||||
.createMenu(cmenu.menuFunction(cmenu, t), cmenu);
|
||||
cmenu.menu.css( {
|
||||
display : 'none'
|
||||
});
|
||||
$(cmenu.appendTo).append(cmenu.menu);
|
||||
}
|
||||
var $c = cmenu.menu;
|
||||
x += cmenu.offsetX;
|
||||
y += cmenu.offsetY;
|
||||
var pos = cmenu.getPosition(x, y, cmenu, e); // Extracted to
|
||||
// method for
|
||||
// extensibility
|
||||
cmenu.showShadow(pos.x, pos.y, e);
|
||||
// Resize the iframe if needed
|
||||
if (cmenu.useIframe) {
|
||||
$c.find('iframe').css( {
|
||||
width : $c.width() + cmenu.shadowOffsetX +
|
||||
cmenu.shadowWidthAdjust,
|
||||
height : $c.height() + cmenu.shadowOffsetY +
|
||||
cmenu.shadowHeightAdjust
|
||||
});
|
||||
}
|
||||
$c.css( {
|
||||
top : pos.y + "px",
|
||||
left : pos.x + "px",
|
||||
position : "absolute",
|
||||
zIndex : 9999
|
||||
})[cmenu.showTransition]
|
||||
(cmenu.showSpeed, ((cmenu.showCallback) ? function() {
|
||||
cmenu.showCallback.call(cmenu);
|
||||
} : null));
|
||||
cmenu.shown = true;
|
||||
$(document).one('click', null, function() {
|
||||
cmenu.hide()
|
||||
}); // Handle a single click to the document to hide the menu
|
||||
}
|
||||
},
|
||||
|
||||
// Find the position where the menu should appear, given an x,y of the click event
|
||||
getPosition : function(clickX, clickY, cmenu, e) {
|
||||
var x = clickX + cmenu.offsetX;
|
||||
var y = clickY + cmenu.offsetY
|
||||
var h = $(cmenu.menu).height();
|
||||
var w = $(cmenu.menu).width();
|
||||
var dir = cmenu.direction;
|
||||
if (cmenu.constrainToScreen) {
|
||||
var $w = $(window);
|
||||
var wh = $w.height();
|
||||
var ww = $w.width();
|
||||
if (dir == "down" && (y + h - $w.scrollTop() > wh)) {
|
||||
dir = "up";
|
||||
}
|
||||
var maxRight = x + w - $w.scrollLeft();
|
||||
if (maxRight > ww) {
|
||||
x -= (maxRight - ww);
|
||||
}
|
||||
}
|
||||
if (dir == "up") {
|
||||
y -= h;
|
||||
}
|
||||
return {
|
||||
'x' : x, 'y' : y
|
||||
};
|
||||
},
|
||||
|
||||
// Hide the menu, of course
|
||||
hide : function() {
|
||||
var cmenu = this;
|
||||
if (cmenu.shown) {
|
||||
if (cmenu.iframe) {
|
||||
$(cmenu.iframe).hide();
|
||||
}
|
||||
if (cmenu.menu) {
|
||||
cmenu.menu[cmenu.hideTransition]
|
||||
(cmenu.hideSpeed, ((cmenu.hideCallback) ? function() {
|
||||
cmenu.hideCallback.call(cmenu);
|
||||
} : null));
|
||||
}
|
||||
if (cmenu.shadow) {
|
||||
cmenu.shadowObj[cmenu.hideTransition](cmenu.hideSpeed);
|
||||
}
|
||||
}
|
||||
cmenu.shown = false;
|
||||
}
|
||||
};
|
||||
|
||||
// This actually adds the .contextMenu() function to the jQuery namespace
|
||||
$.fn.contextMenu = function(menu, options) {
|
||||
var cmenu = $.contextMenu.create(menu, options);
|
||||
return this.each(function() {
|
||||
// Show menu on left click
|
||||
$(this).bind('click', function(e) {
|
||||
cmenu.show(this, e);
|
||||
return false;
|
||||
});
|
||||
});
|
||||
};
|
||||
})(jQuery);
|
110
xCAT-UI/js/jquery.cookie.js
Normal file
@ -0,0 +1,110 @@
|
||||
/**
|
||||
* Cookie plugin
|
||||
*
|
||||
* Copyright (c) 2006 Klaus Hartl (stilbuero.de)
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a cookie with the given name and value and other optional parameters.
|
||||
*
|
||||
* @example $.cookie('the_cookie', 'the_value');
|
||||
* @desc Set the value of a cookie.
|
||||
* @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
|
||||
* @desc Create a cookie with all available options.
|
||||
* @example $.cookie('the_cookie', 'the_value');
|
||||
* @desc Create a session cookie.
|
||||
* @example $.cookie('the_cookie', null);
|
||||
* @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
|
||||
* used when the cookie was set.
|
||||
*
|
||||
* @param String name The name of the cookie.
|
||||
* @param String value The value of the cookie.
|
||||
* @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
|
||||
* @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
|
||||
* If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
|
||||
* If set to null or omitted, the cookie will be a session cookie and will not be retained
|
||||
* when the the browser exits.
|
||||
* @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
|
||||
* @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
|
||||
* @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
|
||||
* require a secure protocol (like HTTPS).
|
||||
* @type undefined
|
||||
*
|
||||
* @name $.cookie
|
||||
* @cat Plugins/Cookie
|
||||
* @author Klaus Hartl/klaus.hartl@stilbuero.de
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the value of a cookie with the given name.
|
||||
*
|
||||
* @example $.cookie('the_cookie');
|
||||
* @desc Get the value of a cookie.
|
||||
*
|
||||
* @param String
|
||||
* name The name of the cookie.
|
||||
* @return The value of the cookie.
|
||||
* @type String
|
||||
*
|
||||
* @name $.cookie
|
||||
* @cat Plugins/Cookie
|
||||
* @author Klaus Hartl/klaus.hartl@stilbuero.de
|
||||
*/
|
||||
jQuery.cookie = function(name, value, options) {
|
||||
if (typeof value != 'undefined') { // name and value given, set cookie
|
||||
options = options || {};
|
||||
if (value === null) {
|
||||
value = '';
|
||||
options.expires = -1;
|
||||
}
|
||||
var expires = '';
|
||||
if (options.expires &&
|
||||
(typeof options.expires == 'number' || options.expires.toUTCString)) {
|
||||
var date;
|
||||
if (typeof options.expires == 'number') {
|
||||
date = new Date();
|
||||
date.setTime(date.getTime() +
|
||||
(options.expires * 24 * 60 * 60 * 1000));
|
||||
} else {
|
||||
date = options.expires;
|
||||
}
|
||||
expires = '; expires=' + date.toUTCString(); // use expires
|
||||
// attribute,
|
||||
// max-age is not
|
||||
// supported by IE
|
||||
}
|
||||
// CAUTION: Needed to parenthesize options.path and options.domain
|
||||
// in the following expressions, otherwise they evaluate to undefined
|
||||
// in the packed version for some reason...
|
||||
var path = options.path ? '; path=' + (options.path) : '';
|
||||
var domain = options.domain ? '; domain=' + (options.domain) : '';
|
||||
var secure = options.secure ? '; secure' : '';
|
||||
document.cookie = [
|
||||
name,
|
||||
'=',
|
||||
encodeURIComponent(value),
|
||||
expires,
|
||||
path,
|
||||
domain,
|
||||
secure ].join('');
|
||||
} else { // only name given, get cookie
|
||||
var cookieValue = null;
|
||||
if (document.cookie && document.cookie != '') {
|
||||
var cookies = document.cookie.split(';');
|
||||
for ( var i = 0; i < cookies.length; i++) {
|
||||
var cookie = jQuery.trim(cookies[i]);
|
||||
// Does this cookie string begin with the name we want?
|
||||
if (cookie.substring(0, name.length + 1) == (name + '=')) {
|
||||
cookieValue = decodeURIComponent(cookie
|
||||
.substring(name.length + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cookieValue;
|
||||
}
|
||||
};
|
2820
xCAT-UI/js/jquery.dataTables.min.js
vendored
Normal file
675
xCAT-UI/js/jquery.form.js
Normal file
@ -0,0 +1,675 @@
|
||||
/*!
|
||||
* jQuery Form Plugin
|
||||
* version: 2.43 (12-MAR-2010)
|
||||
* @requires jQuery v1.3.2 or later
|
||||
*
|
||||
* Examples and documentation at: http://malsup.com/jquery/form/
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*/
|
||||
;(function($) {
|
||||
|
||||
/*
|
||||
Usage Note:
|
||||
-----------
|
||||
Do not use both ajaxSubmit and ajaxForm on the same form. These
|
||||
functions are intended to be exclusive. Use ajaxSubmit if you want
|
||||
to bind your own submit handler to the form. For example,
|
||||
|
||||
$(document).ready(function() {
|
||||
$('#myForm').bind('submit', function() {
|
||||
$(this).ajaxSubmit({
|
||||
target: '#output'
|
||||
});
|
||||
return false; // <-- important!
|
||||
});
|
||||
});
|
||||
|
||||
Use ajaxForm when you want the plugin to manage all the event binding
|
||||
for you. For example,
|
||||
|
||||
$(document).ready(function() {
|
||||
$('#myForm').ajaxForm({
|
||||
target: '#output'
|
||||
});
|
||||
});
|
||||
|
||||
When using ajaxForm, the ajaxSubmit function will be invoked for you
|
||||
at the appropriate time.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ajaxSubmit() provides a mechanism for immediately submitting
|
||||
* an HTML form using AJAX.
|
||||
*/
|
||||
$.fn.ajaxSubmit = function(options) {
|
||||
// fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
|
||||
if (!this.length) {
|
||||
log('ajaxSubmit: skipping submit process - no element selected');
|
||||
return this;
|
||||
}
|
||||
|
||||
if (typeof options == 'function')
|
||||
options = { success: options };
|
||||
|
||||
var url = $.trim(this.attr('action'));
|
||||
if (url) {
|
||||
// clean url (don't include hash vaue)
|
||||
url = (url.match(/^([^#]+)/)||[])[1];
|
||||
}
|
||||
url = url || window.location.href || '';
|
||||
|
||||
options = $.extend({
|
||||
url: url,
|
||||
type: this.attr('method') || 'GET',
|
||||
iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
|
||||
}, options || {});
|
||||
|
||||
// hook for manipulating the form data before it is extracted;
|
||||
// convenient for use with rich editors like tinyMCE or FCKEditor
|
||||
var veto = {};
|
||||
this.trigger('form-pre-serialize', [this, options, veto]);
|
||||
if (veto.veto) {
|
||||
log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
|
||||
return this;
|
||||
}
|
||||
|
||||
// provide opportunity to alter form data before it is serialized
|
||||
if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
|
||||
log('ajaxSubmit: submit aborted via beforeSerialize callback');
|
||||
return this;
|
||||
}
|
||||
|
||||
var a = this.formToArray(options.semantic);
|
||||
if (options.data) {
|
||||
options.extraData = options.data;
|
||||
for (var n in options.data) {
|
||||
if(options.data[n] instanceof Array) {
|
||||
for (var k in options.data[n])
|
||||
a.push( { name: n, value: options.data[n][k] } );
|
||||
}
|
||||
else
|
||||
a.push( { name: n, value: options.data[n] } );
|
||||
}
|
||||
}
|
||||
|
||||
// give pre-submit callback an opportunity to abort the submit
|
||||
if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
|
||||
log('ajaxSubmit: submit aborted via beforeSubmit callback');
|
||||
return this;
|
||||
}
|
||||
|
||||
// fire vetoable 'validate' event
|
||||
this.trigger('form-submit-validate', [a, this, options, veto]);
|
||||
if (veto.veto) {
|
||||
log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
|
||||
return this;
|
||||
}
|
||||
|
||||
var q = $.param(a);
|
||||
|
||||
if (options.type.toUpperCase() == 'GET') {
|
||||
options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
|
||||
options.data = null; // data is null for 'get'
|
||||
}
|
||||
else
|
||||
options.data = q; // data is the query string for 'post'
|
||||
|
||||
var $form = this, callbacks = [];
|
||||
if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
|
||||
if (options.clearForm) callbacks.push(function() { $form.clearForm(); });
|
||||
|
||||
// perform a load on the target only if dataType is not provided
|
||||
if (!options.dataType && options.target) {
|
||||
var oldSuccess = options.success || function(){};
|
||||
callbacks.push(function(data) {
|
||||
var fn = options.replaceTarget ? 'replaceWith' : 'html';
|
||||
$(options.target)[fn](data).each(oldSuccess, arguments);
|
||||
});
|
||||
}
|
||||
else if (options.success)
|
||||
callbacks.push(options.success);
|
||||
|
||||
options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
|
||||
for (var i=0, max=callbacks.length; i < max; i++)
|
||||
callbacks[i].apply(options, [data, status, xhr || $form, $form]);
|
||||
};
|
||||
|
||||
// are there files to upload?
|
||||
var files = $('input:file', this).fieldValue();
|
||||
var found = false;
|
||||
for (var j=0; j < files.length; j++)
|
||||
if (files[j])
|
||||
found = true;
|
||||
|
||||
var multipart = false;
|
||||
// var mp = 'multipart/form-data';
|
||||
// multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
|
||||
|
||||
// options.iframe allows user to force iframe mode
|
||||
// 06-NOV-09: now defaulting to iframe mode if file input is detected
|
||||
if ((files.length && options.iframe !== false) || options.iframe || found || multipart) {
|
||||
// hack to fix Safari hang (thanks to Tim Molendijk for this)
|
||||
// see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
|
||||
if (options.closeKeepAlive)
|
||||
$.get(options.closeKeepAlive, fileUpload);
|
||||
else
|
||||
fileUpload();
|
||||
}
|
||||
else
|
||||
$.ajax(options);
|
||||
|
||||
// fire 'notify' event
|
||||
this.trigger('form-submit-notify', [this, options]);
|
||||
return this;
|
||||
|
||||
|
||||
// private function for handling file uploads (hat tip to YAHOO!)
|
||||
function fileUpload() {
|
||||
var form = $form[0];
|
||||
|
||||
if ($(':input[name=submit]', form).length) {
|
||||
alert('Error: Form elements must not be named "submit".');
|
||||
return;
|
||||
}
|
||||
|
||||
var opts = $.extend({}, $.ajaxSettings, options);
|
||||
var s = $.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts);
|
||||
|
||||
var id = 'jqFormIO' + (new Date().getTime());
|
||||
var $io = $('<iframe id="' + id + '" name="' + id + '" src="'+ opts.iframeSrc +'" onload="(jQuery(this).data(\'form-plugin-onload\'))()" />');
|
||||
var io = $io[0];
|
||||
|
||||
$io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
|
||||
|
||||
var xhr = { // mock object
|
||||
aborted: 0,
|
||||
responseText: null,
|
||||
responseXML: null,
|
||||
status: 0,
|
||||
statusText: 'n/a',
|
||||
getAllResponseHeaders: function() {},
|
||||
getResponseHeader: function() {},
|
||||
setRequestHeader: function() {},
|
||||
abort: function() {
|
||||
this.aborted = 1;
|
||||
$io.attr('src', opts.iframeSrc); // abort op in progress
|
||||
}
|
||||
};
|
||||
|
||||
var g = opts.global;
|
||||
// trigger ajax global events so that activity/block indicators work like normal
|
||||
if (g && ! $.active++) $.event.trigger("ajaxStart");
|
||||
if (g) $.event.trigger("ajaxSend", [xhr, opts]);
|
||||
|
||||
if (s.beforeSend && s.beforeSend(xhr, s) === false) {
|
||||
s.global && $.active--;
|
||||
return;
|
||||
}
|
||||
if (xhr.aborted)
|
||||
return;
|
||||
|
||||
var cbInvoked = false;
|
||||
var timedOut = 0;
|
||||
|
||||
// add submitting element to data if we know it
|
||||
var sub = form.clk;
|
||||
if (sub) {
|
||||
var n = sub.name;
|
||||
if (n && !sub.disabled) {
|
||||
opts.extraData = opts.extraData || {};
|
||||
opts.extraData[n] = sub.value;
|
||||
if (sub.type == "image") {
|
||||
opts.extraData[n+'.x'] = form.clk_x;
|
||||
opts.extraData[n+'.y'] = form.clk_y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// take a breath so that pending repaints get some cpu time before the upload starts
|
||||
function doSubmit() {
|
||||
// make sure form attrs are set
|
||||
var t = $form.attr('target'), a = $form.attr('action');
|
||||
|
||||
// update form attrs in IE friendly way
|
||||
form.setAttribute('target',id);
|
||||
if (form.getAttribute('method') != 'POST')
|
||||
form.setAttribute('method', 'POST');
|
||||
if (form.getAttribute('action') != opts.url)
|
||||
form.setAttribute('action', opts.url);
|
||||
|
||||
// ie borks in some cases when setting encoding
|
||||
if (! opts.skipEncodingOverride) {
|
||||
$form.attr({
|
||||
encoding: 'multipart/form-data',
|
||||
enctype: 'multipart/form-data'
|
||||
});
|
||||
}
|
||||
|
||||
// support timout
|
||||
if (opts.timeout)
|
||||
setTimeout(function() { timedOut = true; cb(); }, opts.timeout);
|
||||
|
||||
// add "extra" data to form if provided in options
|
||||
var extraInputs = [];
|
||||
try {
|
||||
if (opts.extraData)
|
||||
for (var n in opts.extraData)
|
||||
extraInputs.push(
|
||||
$('<input type="hidden" name="'+n+'" value="'+opts.extraData[n]+'" />')
|
||||
.appendTo(form)[0]);
|
||||
|
||||
// add iframe to doc and submit the form
|
||||
$io.appendTo('body');
|
||||
$io.data('form-plugin-onload', cb);
|
||||
form.submit();
|
||||
}
|
||||
finally {
|
||||
// reset attrs and remove "extra" input elements
|
||||
form.setAttribute('action',a);
|
||||
t ? form.setAttribute('target', t) : $form.removeAttr('target');
|
||||
$(extraInputs).remove();
|
||||
}
|
||||
};
|
||||
|
||||
if (opts.forceSync)
|
||||
doSubmit();
|
||||
else
|
||||
setTimeout(doSubmit, 10); // this lets dom updates render
|
||||
|
||||
var domCheckCount = 100;
|
||||
|
||||
function cb() {
|
||||
if (cbInvoked)
|
||||
return;
|
||||
|
||||
var ok = true;
|
||||
try {
|
||||
if (timedOut) throw 'timeout';
|
||||
// extract the server response from the iframe
|
||||
var data, doc;
|
||||
|
||||
doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
|
||||
|
||||
var isXml = opts.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
|
||||
log('isXml='+isXml);
|
||||
if (!isXml && (doc.body == null || doc.body.innerHTML == '')) {
|
||||
if (--domCheckCount) {
|
||||
// in some browsers (Opera) the iframe DOM is not always traversable when
|
||||
// the onload callback fires, so we loop a bit to accommodate
|
||||
log('requeing onLoad callback, DOM not available');
|
||||
setTimeout(cb, 250);
|
||||
return;
|
||||
}
|
||||
log('Could not access iframe DOM after 100 tries.');
|
||||
return;
|
||||
}
|
||||
|
||||
log('response detected');
|
||||
cbInvoked = true;
|
||||
xhr.responseText = doc.body ? doc.body.innerHTML : null;
|
||||
xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
|
||||
xhr.getResponseHeader = function(header){
|
||||
var headers = {'content-type': opts.dataType};
|
||||
return headers[header];
|
||||
};
|
||||
|
||||
if (opts.dataType == 'json' || opts.dataType == 'script') {
|
||||
// see if user embedded response in textarea
|
||||
var ta = doc.getElementsByTagName('textarea')[0];
|
||||
if (ta)
|
||||
xhr.responseText = ta.value;
|
||||
else {
|
||||
// account for browsers injecting pre around json response
|
||||
var pre = doc.getElementsByTagName('pre')[0];
|
||||
if (pre)
|
||||
xhr.responseText = pre.innerHTML;
|
||||
}
|
||||
}
|
||||
else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
|
||||
xhr.responseXML = toXml(xhr.responseText);
|
||||
}
|
||||
data = $.httpData(xhr, opts.dataType);
|
||||
}
|
||||
catch(e){
|
||||
log('error caught:',e);
|
||||
ok = false;
|
||||
xhr.error = e;
|
||||
$.handleError(opts, xhr, 'error', e);
|
||||
}
|
||||
|
||||
// ordering of these callbacks/triggers is odd, but that's how $.ajax does it
|
||||
if (ok) {
|
||||
opts.success(data, 'success');
|
||||
if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
|
||||
}
|
||||
if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
|
||||
if (g && ! --$.active) $.event.trigger("ajaxStop");
|
||||
if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');
|
||||
|
||||
// clean up
|
||||
setTimeout(function() {
|
||||
$io.removeData('form-plugin-onload');
|
||||
$io.remove();
|
||||
xhr.responseXML = null;
|
||||
}, 100);
|
||||
};
|
||||
|
||||
function toXml(s, doc) {
|
||||
if (window.ActiveXObject) {
|
||||
doc = new ActiveXObject('Microsoft.XMLDOM');
|
||||
doc.async = 'false';
|
||||
doc.loadXML(s);
|
||||
}
|
||||
else
|
||||
doc = (new DOMParser()).parseFromString(s, 'text/xml');
|
||||
return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* ajaxForm() provides a mechanism for fully automating form submission.
|
||||
*
|
||||
* The advantages of using this method instead of ajaxSubmit() are:
|
||||
*
|
||||
* 1: This method will include coordinates for <input type="image" /> elements (if the element
|
||||
* is used to submit the form).
|
||||
* 2. This method will include the submit element's name/value data (for the element that was
|
||||
* used to submit the form).
|
||||
* 3. This method binds the submit() method to the form for you.
|
||||
*
|
||||
* The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely
|
||||
* passes the options argument along after properly binding events for submit elements and
|
||||
* the form itself.
|
||||
*/
|
||||
$.fn.ajaxForm = function(options) {
|
||||
return this.ajaxFormUnbind().bind('submit.form-plugin', function(e) {
|
||||
e.preventDefault();
|
||||
$(this).ajaxSubmit(options);
|
||||
}).bind('click.form-plugin', function(e) {
|
||||
var target = e.target;
|
||||
var $el = $(target);
|
||||
if (!($el.is(":submit,input:image"))) {
|
||||
// is this a child element of the submit el? (ex: a span within a button)
|
||||
var t = $el.closest(':submit');
|
||||
if (t.length == 0)
|
||||
return;
|
||||
target = t[0];
|
||||
}
|
||||
var form = this;
|
||||
form.clk = target;
|
||||
if (target.type == 'image') {
|
||||
if (e.offsetX != undefined) {
|
||||
form.clk_x = e.offsetX;
|
||||
form.clk_y = e.offsetY;
|
||||
} else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
|
||||
var offset = $el.offset();
|
||||
form.clk_x = e.pageX - offset.left;
|
||||
form.clk_y = e.pageY - offset.top;
|
||||
} else {
|
||||
form.clk_x = e.pageX - target.offsetLeft;
|
||||
form.clk_y = e.pageY - target.offsetTop;
|
||||
}
|
||||
}
|
||||
// clear form vars
|
||||
setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
|
||||
});
|
||||
};
|
||||
|
||||
// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
|
||||
$.fn.ajaxFormUnbind = function() {
|
||||
return this.unbind('submit.form-plugin click.form-plugin');
|
||||
};
|
||||
|
||||
/**
|
||||
* formToArray() gathers form element data into an array of objects that can
|
||||
* be passed to any of the following ajax functions: $.get, $.post, or load.
|
||||
* Each object in the array has both a 'name' and 'value' property. An example of
|
||||
* an array for a simple login form might be:
|
||||
*
|
||||
* [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
|
||||
*
|
||||
* It is this array that is passed to pre-submit callback functions provided to the
|
||||
* ajaxSubmit() and ajaxForm() methods.
|
||||
*/
|
||||
$.fn.formToArray = function(semantic) {
|
||||
var a = [];
|
||||
if (this.length == 0) return a;
|
||||
|
||||
var form = this[0];
|
||||
var els = semantic ? form.getElementsByTagName('*') : form.elements;
|
||||
if (!els) return a;
|
||||
for(var i=0, max=els.length; i < max; i++) {
|
||||
var el = els[i];
|
||||
var n = el.name;
|
||||
if (!n) continue;
|
||||
|
||||
if (semantic && form.clk && el.type == "image") {
|
||||
// handle image inputs on the fly when semantic == true
|
||||
if(!el.disabled && form.clk == el) {
|
||||
a.push({name: n, value: $(el).val()});
|
||||
a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
var v = $.fieldValue(el, true);
|
||||
if (v && v.constructor == Array) {
|
||||
for(var j=0, jmax=v.length; j < jmax; j++)
|
||||
a.push({name: n, value: v[j]});
|
||||
}
|
||||
else if (v !== null && typeof v != 'undefined')
|
||||
a.push({name: n, value: v});
|
||||
}
|
||||
|
||||
if (!semantic && form.clk) {
|
||||
// input type=='image' are not found in elements array! handle it here
|
||||
var $input = $(form.clk), input = $input[0], n = input.name;
|
||||
if (n && !input.disabled && input.type == 'image') {
|
||||
a.push({name: n, value: $input.val()});
|
||||
a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
|
||||
}
|
||||
}
|
||||
return a;
|
||||
};
|
||||
|
||||
/**
|
||||
* Serializes form data into a 'submittable' string. This method will return a string
|
||||
* in the format: name1=value1&name2=value2
|
||||
*/
|
||||
$.fn.formSerialize = function(semantic) {
|
||||
//hand off to jQuery.param for proper encoding
|
||||
return $.param(this.formToArray(semantic));
|
||||
};
|
||||
|
||||
/**
|
||||
* Serializes all field elements in the jQuery object into a query string.
|
||||
* This method will return a string in the format: name1=value1&name2=value2
|
||||
*/
|
||||
$.fn.fieldSerialize = function(successful) {
|
||||
var a = [];
|
||||
this.each(function() {
|
||||
var n = this.name;
|
||||
if (!n) return;
|
||||
var v = $.fieldValue(this, successful);
|
||||
if (v && v.constructor == Array) {
|
||||
for (var i=0,max=v.length; i < max; i++)
|
||||
a.push({name: n, value: v[i]});
|
||||
}
|
||||
else if (v !== null && typeof v != 'undefined')
|
||||
a.push({name: this.name, value: v});
|
||||
});
|
||||
//hand off to jQuery.param for proper encoding
|
||||
return $.param(a);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the value(s) of the element in the matched set. For example, consider the following form:
|
||||
*
|
||||
* <form><fieldset>
|
||||
* <input name="A" type="text" />
|
||||
* <input name="A" type="text" />
|
||||
* <input name="B" type="checkbox" value="B1" />
|
||||
* <input name="B" type="checkbox" value="B2"/>
|
||||
* <input name="C" type="radio" value="C1" />
|
||||
* <input name="C" type="radio" value="C2" />
|
||||
* </fieldset></form>
|
||||
*
|
||||
* var v = $(':text').fieldValue();
|
||||
* // if no values are entered into the text inputs
|
||||
* v == ['','']
|
||||
* // if values entered into the text inputs are 'foo' and 'bar'
|
||||
* v == ['foo','bar']
|
||||
*
|
||||
* var v = $(':checkbox').fieldValue();
|
||||
* // if neither checkbox is checked
|
||||
* v === undefined
|
||||
* // if both checkboxes are checked
|
||||
* v == ['B1', 'B2']
|
||||
*
|
||||
* var v = $(':radio').fieldValue();
|
||||
* // if neither radio is checked
|
||||
* v === undefined
|
||||
* // if first radio is checked
|
||||
* v == ['C1']
|
||||
*
|
||||
* The successful argument controls whether or not the field element must be 'successful'
|
||||
* (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
|
||||
* The default value of the successful argument is true. If this value is false the value(s)
|
||||
* for each element is returned.
|
||||
*
|
||||
* Note: This method *always* returns an array. If no valid value can be determined the
|
||||
* array will be empty, otherwise it will contain one or more values.
|
||||
*/
|
||||
$.fn.fieldValue = function(successful) {
|
||||
for (var val=[], i=0, max=this.length; i < max; i++) {
|
||||
var el = this[i];
|
||||
var v = $.fieldValue(el, successful);
|
||||
if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
|
||||
continue;
|
||||
v.constructor == Array ? $.merge(val, v) : val.push(v);
|
||||
}
|
||||
return val;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the value of the field element.
|
||||
*/
|
||||
$.fieldValue = function(el, successful) {
|
||||
var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
|
||||
if (typeof successful == 'undefined') successful = true;
|
||||
|
||||
if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
|
||||
(t == 'checkbox' || t == 'radio') && !el.checked ||
|
||||
(t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
|
||||
tag == 'select' && el.selectedIndex == -1))
|
||||
return null;
|
||||
|
||||
if (tag == 'select') {
|
||||
var index = el.selectedIndex;
|
||||
if (index < 0) return null;
|
||||
var a = [], ops = el.options;
|
||||
var one = (t == 'select-one');
|
||||
var max = (one ? index+1 : ops.length);
|
||||
for(var i=(one ? index : 0); i < max; i++) {
|
||||
var op = ops[i];
|
||||
if (op.selected) {
|
||||
var v = op.value;
|
||||
if (!v) // extra pain for IE...
|
||||
v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
|
||||
if (one) return v;
|
||||
a.push(v);
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
return el.value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears the form data. Takes the following actions on the form's input fields:
|
||||
* - input text fields will have their 'value' property set to the empty string
|
||||
* - select elements will have their 'selectedIndex' property set to -1
|
||||
* - checkbox and radio inputs will have their 'checked' property set to false
|
||||
* - inputs of type submit, button, reset, and hidden will *not* be effected
|
||||
* - button elements will *not* be effected
|
||||
*/
|
||||
$.fn.clearForm = function() {
|
||||
return this.each(function() {
|
||||
$('input,select,textarea', this).clearFields();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears the selected form elements.
|
||||
*/
|
||||
$.fn.clearFields = $.fn.clearInputs = function() {
|
||||
return this.each(function() {
|
||||
var t = this.type, tag = this.tagName.toLowerCase();
|
||||
if (t == 'text' || t == 'password' || tag == 'textarea')
|
||||
this.value = '';
|
||||
else if (t == 'checkbox' || t == 'radio')
|
||||
this.checked = false;
|
||||
else if (tag == 'select')
|
||||
this.selectedIndex = -1;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Resets the form data. Causes all form elements to be reset to their original value.
|
||||
*/
|
||||
$.fn.resetForm = function() {
|
||||
return this.each(function() {
|
||||
// guard against an input with the name of 'reset'
|
||||
// note that IE reports the reset function as an 'object'
|
||||
if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
|
||||
this.reset();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Enables or disables any matching elements.
|
||||
*/
|
||||
$.fn.enable = function(b) {
|
||||
if (b == undefined) b = true;
|
||||
return this.each(function() {
|
||||
this.disabled = !b;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks/unchecks any matching checkboxes or radio buttons and
|
||||
* selects/deselects and matching option elements.
|
||||
*/
|
||||
$.fn.selected = function(select) {
|
||||
if (select == undefined) select = true;
|
||||
return this.each(function() {
|
||||
var t = this.type;
|
||||
if (t == 'checkbox' || t == 'radio')
|
||||
this.checked = select;
|
||||
else if (this.tagName.toLowerCase() == 'option') {
|
||||
var $sel = $(this).parent('select');
|
||||
if (select && $sel[0] && $sel[0].type == 'select-one') {
|
||||
// deselect all other options
|
||||
$sel.find('option').selected(false);
|
||||
}
|
||||
this.selected = select;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// helper fn for console logging
|
||||
// set $.fn.ajaxSubmit.debug to true to enable debug logging
|
||||
function log() {
|
||||
if ($.fn.ajaxSubmit.debug) {
|
||||
var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
|
||||
if (window.console && window.console.log)
|
||||
window.console.log(msg);
|
||||
else if (window.opera && window.opera.postError)
|
||||
window.opera.postError(msg);
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
543
xCAT-UI/js/jquery.jeditable.js
Normal file
@ -0,0 +1,543 @@
|
||||
/*
|
||||
* Jeditable - jQuery in place edit plugin
|
||||
*
|
||||
* Copyright (c) 2006-2009 Mika Tuupola, Dylan Verheul
|
||||
*
|
||||
* Licensed under the MIT license:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* Project home:
|
||||
* http://www.appelsiini.net/projects/jeditable
|
||||
*
|
||||
* Based on editable by Dylan Verheul <dylan_at_dyve.net>:
|
||||
* http://www.dyve.net/jquery/?editable
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Version 1.7.1
|
||||
*
|
||||
* ** means there is basic unit tests for this parameter.
|
||||
*
|
||||
* @name Jeditable
|
||||
* @type jQuery
|
||||
* @param String target (POST) URL or function to send edited content to **
|
||||
* @param Hash options additional options
|
||||
* @param String options[method] method to use to send edited content (POST or PUT) **
|
||||
* @param Function options[callback] Function to run after submitting edited content **
|
||||
* @param String options[name] POST parameter name of edited content
|
||||
* @param String options[id] POST parameter name of edited div id
|
||||
* @param Hash options[submitdata] Extra parameters to send when submitting edited content.
|
||||
* @param String options[type] text, textarea or select (or any 3rd party input type) **
|
||||
* @param Integer options[rows] number of rows if using textarea **
|
||||
* @param Integer options[cols] number of columns if using textarea **
|
||||
* @param Mixed options[height] 'auto', 'none' or height in pixels **
|
||||
* @param Mixed options[width] 'auto', 'none' or width in pixels **
|
||||
* @param String options[loadurl] URL to fetch input content before editing **
|
||||
* @param String options[loadtype] Request type for load url. Should be GET or POST.
|
||||
* @param String options[loadtext] Text to display while loading external content.
|
||||
* @param Mixed options[loaddata] Extra parameters to pass when fetching content before editing.
|
||||
* @param Mixed options[data] Or content given as paramameter. String or function.**
|
||||
* @param String options[indicator] indicator html to show when saving
|
||||
* @param String options[tooltip] optional tooltip text via title attribute **
|
||||
* @param String options[event] jQuery event such as 'click' of 'dblclick' **
|
||||
* @param String options[submit] submit button value, empty means no button **
|
||||
* @param String options[cancel] cancel button value, empty means no button **
|
||||
* @param String options[cssclass] CSS class to apply to input form. 'inherit' to copy from parent. **
|
||||
* @param String options[style] Style to apply to input form 'inherit' to copy from parent. **
|
||||
* @param String options[select] true or false, when true text is highlighted ??
|
||||
* @param String options[placeholder] Placeholder text or html to insert when element is empty. **
|
||||
* @param String options[onblur] 'cancel', 'submit', 'ignore' or function ??
|
||||
*
|
||||
* @param Function options[onsubmit] function(settings, original) { ... } called before submit
|
||||
* @param Function options[onreset] function(settings, original) { ... } called before reset
|
||||
* @param Function options[onerror] function(settings, original, xhr) { ... } called on error
|
||||
*
|
||||
* @param Hash options[ajaxoptions] jQuery Ajax options. See docs.jquery.com.
|
||||
*
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
$.fn.editable = function(target, options) {
|
||||
|
||||
if ('disable' == target) {
|
||||
$(this).data('disabled.editable', true);
|
||||
return;
|
||||
}
|
||||
if ('enable' == target) {
|
||||
$(this).data('disabled.editable', false);
|
||||
return;
|
||||
}
|
||||
if ('destroy' == target) {
|
||||
$(this)
|
||||
.unbind($(this).data('event.editable'))
|
||||
.removeData('disabled.editable')
|
||||
.removeData('event.editable');
|
||||
return;
|
||||
}
|
||||
|
||||
var settings = $.extend({}, $.fn.editable.defaults, {target:target}, options);
|
||||
|
||||
/* setup some functions */
|
||||
var plugin = $.editable.types[settings.type].plugin || function() { };
|
||||
var submit = $.editable.types[settings.type].submit || function() { };
|
||||
var buttons = $.editable.types[settings.type].buttons
|
||||
|| $.editable.types['defaults'].buttons;
|
||||
var content = $.editable.types[settings.type].content
|
||||
|| $.editable.types['defaults'].content;
|
||||
var element = $.editable.types[settings.type].element
|
||||
|| $.editable.types['defaults'].element;
|
||||
var reset = $.editable.types[settings.type].reset
|
||||
|| $.editable.types['defaults'].reset;
|
||||
var callback = settings.callback || function() { };
|
||||
var onedit = settings.onedit || function() { };
|
||||
var onsubmit = settings.onsubmit || function() { };
|
||||
var onreset = settings.onreset || function() { };
|
||||
var onerror = settings.onerror || reset;
|
||||
|
||||
/* show tooltip */
|
||||
if (settings.tooltip) {
|
||||
$(this).attr('title', settings.tooltip);
|
||||
}
|
||||
|
||||
settings.autowidth = 'auto' == settings.width;
|
||||
settings.autoheight = 'auto' == settings.height;
|
||||
|
||||
return this.each(function() {
|
||||
|
||||
/* save this to self because this changes when scope changes */
|
||||
var self = this;
|
||||
|
||||
/* inlined block elements lose their width and height after first edit */
|
||||
/* save them for later use as workaround */
|
||||
var savedwidth = $(self).width();
|
||||
var savedheight = $(self).height();
|
||||
|
||||
/* save so it can be later used by $.editable('destroy') */
|
||||
$(this).data('event.editable', settings.event);
|
||||
|
||||
/* if element is empty add something clickable (if requested) */
|
||||
if (!$.trim($(this).html())) {
|
||||
$(this).html(settings.placeholder);
|
||||
}
|
||||
|
||||
$(this).bind(settings.event, function(e) {
|
||||
|
||||
/* abort if disabled for this element */
|
||||
if (true === $(this).data('disabled.editable')) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* prevent throwing an exeption if edit field is clicked again */
|
||||
if (self.editing) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* abort if onedit hook returns false */
|
||||
if (false === onedit.apply(this, [settings, self])) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* prevent default action and bubbling */
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
/* remove tooltip */
|
||||
if (settings.tooltip) {
|
||||
$(self).removeAttr('title');
|
||||
}
|
||||
|
||||
/* figure out how wide and tall we are, saved width and height */
|
||||
/* are workaround for http://dev.jquery.com/ticket/2190 */
|
||||
if (0 == $(self).width()) {
|
||||
//$(self).css('visibility', 'hidden');
|
||||
settings.width = savedwidth;
|
||||
settings.height = savedheight;
|
||||
} else {
|
||||
if (settings.width != 'none') {
|
||||
settings.width =
|
||||
settings.autowidth ? $(self).width() : settings.width;
|
||||
}
|
||||
if (settings.height != 'none') {
|
||||
settings.height =
|
||||
settings.autoheight ? $(self).height() : settings.height;
|
||||
}
|
||||
}
|
||||
//$(this).css('visibility', '');
|
||||
|
||||
/* remove placeholder text, replace is here because of IE */
|
||||
if ($(this).html().toLowerCase().replace(/(;|")/g, '') ==
|
||||
settings.placeholder.toLowerCase().replace(/(;|")/g, '')) {
|
||||
$(this).html('');
|
||||
}
|
||||
|
||||
self.editing = true;
|
||||
self.revert = $(self).html();
|
||||
$(self).html('');
|
||||
|
||||
/* create the form object */
|
||||
var form = $('<form />');
|
||||
|
||||
/* apply css or style or both */
|
||||
if (settings.cssclass) {
|
||||
if ('inherit' == settings.cssclass) {
|
||||
form.attr('class', $(self).attr('class'));
|
||||
} else {
|
||||
form.attr('class', settings.cssclass);
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.style) {
|
||||
if ('inherit' == settings.style) {
|
||||
form.attr('style', $(self).attr('style'));
|
||||
/* IE needs the second line or display wont be inherited */
|
||||
form.css('display', $(self).css('display'));
|
||||
} else {
|
||||
form.attr('style', settings.style);
|
||||
}
|
||||
}
|
||||
|
||||
/* add main input element to form and store it in input */
|
||||
var input = element.apply(form, [settings, self]);
|
||||
|
||||
/* set input content via POST, GET, given data or existing value */
|
||||
var input_content;
|
||||
|
||||
if (settings.loadurl) {
|
||||
var t = setTimeout(function() {
|
||||
input.disabled = true;
|
||||
content.apply(form, [settings.loadtext, settings, self]);
|
||||
}, 100);
|
||||
|
||||
var loaddata = {};
|
||||
loaddata[settings.id] = self.id;
|
||||
if ($.isFunction(settings.loaddata)) {
|
||||
$.extend(loaddata, settings.loaddata.apply(self, [self.revert, settings]));
|
||||
} else {
|
||||
$.extend(loaddata, settings.loaddata);
|
||||
}
|
||||
$.ajax({
|
||||
type : settings.loadtype,
|
||||
url : settings.loadurl,
|
||||
data : loaddata,
|
||||
async : false,
|
||||
success: function(result) {
|
||||
window.clearTimeout(t);
|
||||
input_content = result;
|
||||
input.disabled = false;
|
||||
}
|
||||
});
|
||||
} else if (settings.data) {
|
||||
input_content = settings.data;
|
||||
if ($.isFunction(settings.data)) {
|
||||
input_content = settings.data.apply(self, [self.revert, settings]);
|
||||
}
|
||||
} else {
|
||||
input_content = self.revert;
|
||||
}
|
||||
content.apply(form, [input_content, settings, self]);
|
||||
|
||||
input.attr('name', settings.name);
|
||||
|
||||
/* add buttons to the form */
|
||||
buttons.apply(form, [settings, self]);
|
||||
|
||||
/* add created form to self */
|
||||
$(self).append(form);
|
||||
|
||||
/* attach 3rd party plugin if requested */
|
||||
plugin.apply(form, [settings, self]);
|
||||
|
||||
/* focus to first visible form element */
|
||||
$(':input:visible:enabled:first', form).focus();
|
||||
|
||||
/* highlight input contents when requested */
|
||||
if (settings.select) {
|
||||
input.select();
|
||||
}
|
||||
|
||||
/* discard changes if pressing esc */
|
||||
input.keydown(function(e) {
|
||||
if (e.keyCode == 27) {
|
||||
e.preventDefault();
|
||||
//self.reset();
|
||||
reset.apply(form, [settings, self]);
|
||||
}
|
||||
});
|
||||
|
||||
/* discard, submit or nothing with changes when clicking outside */
|
||||
/* do nothing is usable when navigating with tab */
|
||||
var t;
|
||||
if ('cancel' == settings.onblur) {
|
||||
input.blur(function(e) {
|
||||
/* prevent canceling if submit was clicked */
|
||||
t = setTimeout(function() {
|
||||
reset.apply(form, [settings, self]);
|
||||
}, 500);
|
||||
});
|
||||
} else if ('submit' == settings.onblur) {
|
||||
input.blur(function(e) {
|
||||
/* prevent double submit if submit was clicked */
|
||||
t = setTimeout(function() {
|
||||
form.submit();
|
||||
}, 200);
|
||||
});
|
||||
} else if ($.isFunction(settings.onblur)) {
|
||||
input.blur(function(e) {
|
||||
settings.onblur.apply(self, [input.val(), settings]);
|
||||
});
|
||||
} else {
|
||||
input.blur(function(e) {
|
||||
/* TODO: maybe something here */
|
||||
});
|
||||
}
|
||||
|
||||
form.submit(function(e) {
|
||||
|
||||
if (t) {
|
||||
clearTimeout(t);
|
||||
}
|
||||
|
||||
/* do no submit */
|
||||
e.preventDefault();
|
||||
|
||||
/* call before submit hook. */
|
||||
/* if it returns false abort submitting */
|
||||
if (false !== onsubmit.apply(form, [settings, self])) {
|
||||
/* custom inputs call before submit hook. */
|
||||
/* if it returns false abort submitting */
|
||||
if (false !== submit.apply(form, [settings, self])) {
|
||||
|
||||
/* check if given target is function */
|
||||
if ($.isFunction(settings.target)) {
|
||||
var str = settings.target.apply(self, [input.val(), settings]);
|
||||
$(self).html(str);
|
||||
self.editing = false;
|
||||
callback.apply(self, [self.innerHTML, settings]);
|
||||
/* TODO: this is not dry */
|
||||
if (!$.trim($(self).html())) {
|
||||
$(self).html(settings.placeholder);
|
||||
}
|
||||
} else {
|
||||
/* add edited content and id of edited element to POST */
|
||||
var submitdata = {};
|
||||
submitdata[settings.name] = input.val();
|
||||
submitdata[settings.id] = self.id;
|
||||
/* add extra data to be POST:ed */
|
||||
if ($.isFunction(settings.submitdata)) {
|
||||
$.extend(submitdata, settings.submitdata.apply(self, [self.revert, settings]));
|
||||
} else {
|
||||
$.extend(submitdata, settings.submitdata);
|
||||
}
|
||||
|
||||
/* quick and dirty PUT support */
|
||||
if ('PUT' == settings.method) {
|
||||
submitdata['_method'] = 'put';
|
||||
}
|
||||
|
||||
/* show the saving indicator */
|
||||
$(self).html(settings.indicator);
|
||||
|
||||
/* defaults for ajaxoptions */
|
||||
var ajaxoptions = {
|
||||
type : 'POST',
|
||||
data : submitdata,
|
||||
dataType: 'html',
|
||||
url : settings.target,
|
||||
success : function(result, status) {
|
||||
if (ajaxoptions.dataType == 'html') {
|
||||
$(self).html(result);
|
||||
}
|
||||
self.editing = false;
|
||||
callback.apply(self, [result, settings]);
|
||||
if (!$.trim($(self).html())) {
|
||||
$(self).html(settings.placeholder);
|
||||
}
|
||||
},
|
||||
error : function(xhr, status, error) {
|
||||
onerror.apply(form, [settings, self, xhr]);
|
||||
}
|
||||
};
|
||||
|
||||
/* override with what is given in settings.ajaxoptions */
|
||||
$.extend(ajaxoptions, settings.ajaxoptions);
|
||||
$.ajax(ajaxoptions);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* show tooltip again */
|
||||
$(self).attr('title', settings.tooltip);
|
||||
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
/* privileged methods */
|
||||
this.reset = function(form) {
|
||||
/* prevent calling reset twice when blurring */
|
||||
if (this.editing) {
|
||||
/* before reset hook, if it returns false abort reseting */
|
||||
if (false !== onreset.apply(form, [settings, self])) {
|
||||
$(self).html(self.revert);
|
||||
self.editing = false;
|
||||
if (!$.trim($(self).html())) {
|
||||
$(self).html(settings.placeholder);
|
||||
}
|
||||
/* show tooltip again */
|
||||
if (settings.tooltip) {
|
||||
$(self).attr('title', settings.tooltip);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
$.editable = {
|
||||
types: {
|
||||
defaults: {
|
||||
element : function(settings, original) {
|
||||
var input = $('<input type="hidden"></input>');
|
||||
$(this).append(input);
|
||||
return(input);
|
||||
},
|
||||
content : function(string, settings, original) {
|
||||
$(':input:first', this).val(string);
|
||||
},
|
||||
reset : function(settings, original) {
|
||||
original.reset(this);
|
||||
},
|
||||
buttons : function(settings, original) {
|
||||
var form = this;
|
||||
if (settings.submit) {
|
||||
/* if given html string use that */
|
||||
if (settings.submit.match(/>$/)) {
|
||||
var submit = $(settings.submit).click(function() {
|
||||
if (submit.attr("type") != "submit") {
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
/* otherwise use button with given string as text */
|
||||
} else {
|
||||
var submit = $('<button type="submit" />');
|
||||
submit.html(settings.submit);
|
||||
}
|
||||
$(this).append(submit);
|
||||
}
|
||||
if (settings.cancel) {
|
||||
/* if given html string use that */
|
||||
if (settings.cancel.match(/>$/)) {
|
||||
var cancel = $(settings.cancel);
|
||||
/* otherwise use button with given string as text */
|
||||
} else {
|
||||
var cancel = $('<button type="cancel" />');
|
||||
cancel.html(settings.cancel);
|
||||
}
|
||||
$(this).append(cancel);
|
||||
|
||||
$(cancel).click(function(event) {
|
||||
//original.reset();
|
||||
if ($.isFunction($.editable.types[settings.type].reset)) {
|
||||
var reset = $.editable.types[settings.type].reset;
|
||||
} else {
|
||||
var reset = $.editable.types['defaults'].reset;
|
||||
}
|
||||
reset.apply(form, [settings, original]);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
text: {
|
||||
element : function(settings, original) {
|
||||
var input = $('<input />');
|
||||
if (settings.width != 'none') { input.width(settings.width); }
|
||||
if (settings.height != 'none') { input.height(settings.height); }
|
||||
/* https://bugzilla.mozilla.org/show_bug.cgi?id=236791 */
|
||||
//input[0].setAttribute('autocomplete','off');
|
||||
input.attr('autocomplete','off');
|
||||
$(this).append(input);
|
||||
return(input);
|
||||
}
|
||||
},
|
||||
textarea: {
|
||||
element : function(settings, original) {
|
||||
var textarea = $('<textarea />');
|
||||
if (settings.rows) {
|
||||
textarea.attr('rows', settings.rows);
|
||||
} else if (settings.height != "none") {
|
||||
textarea.height(settings.height);
|
||||
}
|
||||
if (settings.cols) {
|
||||
textarea.attr('cols', settings.cols);
|
||||
} else if (settings.width != "none") {
|
||||
textarea.width(settings.width);
|
||||
}
|
||||
$(this).append(textarea);
|
||||
return(textarea);
|
||||
}
|
||||
},
|
||||
select: {
|
||||
element : function(settings, original) {
|
||||
var select = $('<select />');
|
||||
$(this).append(select);
|
||||
return(select);
|
||||
},
|
||||
content : function(data, settings, original) {
|
||||
/* If it is string assume it is json. */
|
||||
if (String == data.constructor) {
|
||||
eval ('var json = ' + data);
|
||||
} else {
|
||||
/* Otherwise assume it is a hash already. */
|
||||
var json = data;
|
||||
}
|
||||
for (var key in json) {
|
||||
if (!json.hasOwnProperty(key)) {
|
||||
continue;
|
||||
}
|
||||
if ('selected' == key) {
|
||||
continue;
|
||||
}
|
||||
var option = $('<option />').val(key).append(json[key]);
|
||||
$('select', this).append(option);
|
||||
}
|
||||
/* Loop option again to set selected. IE needed this... */
|
||||
$('select', this).children().each(function() {
|
||||
if ($(this).val() == json['selected'] ||
|
||||
$(this).text() == $.trim(original.revert)) {
|
||||
$(this).attr('selected', 'selected');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/* Add new input type */
|
||||
addInputType: function(name, input) {
|
||||
$.editable.types[name] = input;
|
||||
}
|
||||
};
|
||||
|
||||
// publicly accessible defaults
|
||||
$.fn.editable.defaults = {
|
||||
name : 'value',
|
||||
id : 'id',
|
||||
type : 'text',
|
||||
width : 'auto',
|
||||
height : 'auto',
|
||||
event : 'click.editable',
|
||||
onblur : 'cancel',
|
||||
loadtype : 'GET',
|
||||
loadtext : 'Loading...',
|
||||
placeholder: 'Click to edit',
|
||||
loaddata : {},
|
||||
submitdata : {},
|
||||
ajaxoptions: {}
|
||||
};
|
||||
|
||||
})(jQuery);
|
2064
xCAT-UI/js/jquery.tree.js
Normal file
141
xCAT-UI/js/monitor.js
Normal file
@ -0,0 +1,141 @@
|
||||
/**
|
||||
* Global variables
|
||||
*/
|
||||
var monitorTabs; // Monitor tabs
|
||||
|
||||
/**
|
||||
* Set the monitor tab
|
||||
*
|
||||
* @param o
|
||||
* Tab object
|
||||
* @return Nothing
|
||||
*/
|
||||
function setMonitorTab(o) {
|
||||
monitorTabs = o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the monitor tab
|
||||
*
|
||||
* @param Nothing
|
||||
* @return Tab object
|
||||
*/
|
||||
function getMonitorTab() {
|
||||
return monitorTabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the monitor page
|
||||
*
|
||||
* @return Nothing
|
||||
*/
|
||||
function loadMonitorPage() {
|
||||
// If the page is already loaded
|
||||
if ($('#monitor_page').children().length) {
|
||||
// Do not reload the monitor page
|
||||
return;
|
||||
}
|
||||
|
||||
// Create monitor tab
|
||||
var tab = new Tab();
|
||||
setConfigTab(tab);
|
||||
tab.init();
|
||||
$('#monitor_page').append(tab.object());
|
||||
|
||||
// Create provision tab
|
||||
var tab = new Tab();
|
||||
setMonitorTab(tab);
|
||||
tab.init();
|
||||
$('#monitor_page').append(tab.object());
|
||||
|
||||
/**
|
||||
* Monitor nodes
|
||||
*/
|
||||
var monitorForm = $('<div class="monitor"></div>');
|
||||
|
||||
// Create info bar
|
||||
var monitorInfoBar = createInfoBar('Under construction');
|
||||
monitorForm.append(monitorInfoBar);
|
||||
|
||||
// Create drop-down menu
|
||||
// Hardware available to provision - ipmi, blade, hmc, ivm, fsp, and zvm
|
||||
var div = $('<div></div>');
|
||||
monitorForm.append(div);
|
||||
tab.add('monitorTab', 'Monitor', monitorForm);
|
||||
|
||||
/**
|
||||
* Resources
|
||||
*/
|
||||
var resrcForm = $('<div class="monitor"></div>');
|
||||
|
||||
// Create info bar
|
||||
var resrcInfoBar = createInfoBar('Select a hardware to view its resources');
|
||||
resrcForm.append(resrcInfoBar);
|
||||
|
||||
// Create drop-down menu
|
||||
// Hardware available to provision - ipmi, blade, hmc, ivm, fsp, and zvm
|
||||
var div = $('<div></div>');
|
||||
var label = $('<span>Select the hardware:</span>');
|
||||
var hw = $('<select></select>');
|
||||
var ipmi = $('<option value="ipmi">ipmi</option>');
|
||||
var blade = $('<option value="blade">blade</option>');
|
||||
var hmc = $('<option value="hmc">hmc</option>');
|
||||
var ivm = $('<option value="ivm">ivm</option>');
|
||||
var fsp = $('<option value="fsp">fsp</option>');
|
||||
var zvm = $('<option value="zvm">zvm</option>');
|
||||
hw.append(ipmi);
|
||||
hw.append(blade);
|
||||
hw.append(hmc);
|
||||
hw.append(ivm);
|
||||
hw.append(fsp);
|
||||
hw.append(zvm);
|
||||
div.append(label);
|
||||
div.append(hw);
|
||||
resrcForm.append(div);
|
||||
|
||||
/**
|
||||
* Ok
|
||||
*/
|
||||
var okBtn = createButton('Ok');
|
||||
okBtn.bind('click', function(event) {
|
||||
// Get hardware that was selected
|
||||
var hw = $(this).parent().find('select').val();
|
||||
|
||||
// Generate new tab ID
|
||||
var newTabId = hw + 'ResourceTab';
|
||||
if (!$('#' + newTabId).length) {
|
||||
var loader = createLoader('zvmResourceLoader');
|
||||
loader = $('<center></center>').append(loader);
|
||||
tab.add(newTabId, hw, loader);
|
||||
|
||||
if (hw == 'zvm') {
|
||||
// Reset resource table
|
||||
setDiskDataTable('');
|
||||
setNetworkDataTable('');
|
||||
|
||||
// Get hardware control points
|
||||
$.ajax( {
|
||||
url : 'lib/cmd.php',
|
||||
dataType : 'json',
|
||||
data : {
|
||||
cmd : 'nodels',
|
||||
tgt : 'mgt==zvm',
|
||||
args : 'zvm.hcp',
|
||||
msg : ''
|
||||
},
|
||||
success : getZResources
|
||||
});
|
||||
}
|
||||
// TODO: Add other platforms to this section
|
||||
else {
|
||||
$('#' + newTabId).append();
|
||||
}
|
||||
}
|
||||
|
||||
// Select tab
|
||||
tab.select(newTabId);
|
||||
});
|
||||
resrcForm.append(okBtn);
|
||||
|
||||
tab.add('resourceTab', 'Resources', resrcForm);
|
||||
}
|
1831
xCAT-UI/js/nodes.js
Normal file
113
xCAT-UI/js/provision.js
Normal file
@ -0,0 +1,113 @@
|
||||
/**
|
||||
* Global variables
|
||||
*/
|
||||
var provisionTabs; // Provision tabs
|
||||
|
||||
/**
|
||||
* Set the provision tab
|
||||
*
|
||||
* @param obj
|
||||
* Tab object
|
||||
* @return Nothing
|
||||
*/
|
||||
function setProvisionTab(obj) {
|
||||
provisionTabs = obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the provision tab
|
||||
*
|
||||
* @param Nothing
|
||||
* @return Tab object
|
||||
*/
|
||||
function getProvisionTab() {
|
||||
return provisionTabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load provision page
|
||||
*
|
||||
* @return Nothing
|
||||
*/
|
||||
function loadProvisionPage() {
|
||||
// If the page is loaded
|
||||
if ($('#provision_page').children().length) {
|
||||
// Do not load again
|
||||
return;
|
||||
}
|
||||
|
||||
// Create status bar, hide on load
|
||||
var statBarId = 'ProvisionStatusBar';
|
||||
var statBar = $('<div class="statusBar" id="' + statBarId + '"></div>')
|
||||
.hide();
|
||||
|
||||
// Create info bar
|
||||
var infoBar = createInfoBar('Provision a node');
|
||||
$('#provision_page').append(infoBar);
|
||||
|
||||
// Create provision form
|
||||
provForm = $('<div class="provision"></div>');
|
||||
provForm.append(statBar);
|
||||
provForm.append(infoBar);
|
||||
|
||||
// Create provision tab
|
||||
var tab = new Tab();
|
||||
setProvisionTab(tab);
|
||||
tab.init();
|
||||
$('#provision_page').append(tab.object());
|
||||
|
||||
// Create drop-down menu
|
||||
// Hardware available to provision - ipmi, blade, hmc, ivm, fsp, and zvm
|
||||
var div = $('<div></div>');
|
||||
provForm.append(div);
|
||||
|
||||
var label = $('<span>Select the hardware to provision:</span>');
|
||||
var hw = $('<select></select>');
|
||||
var ipmi = $('<option value="ipmi">ipmi</option>');
|
||||
var blade = $('<option value="blade">blade</option>');
|
||||
var hmc = $('<option value="hmc">hmc</option>');
|
||||
var ivm = $('<option value="ivm">ivm</option>');
|
||||
var fsp = $('<option value="fsp">fsp</option>');
|
||||
var zvm = $('<option value="zvm">zvm</option>');
|
||||
|
||||
hw.append(ipmi);
|
||||
hw.append(blade);
|
||||
hw.append(hmc);
|
||||
hw.append(ivm);
|
||||
hw.append(fsp);
|
||||
hw.append(zvm);
|
||||
div.append(label);
|
||||
div.append(hw);
|
||||
|
||||
/**
|
||||
* Ok
|
||||
*/
|
||||
var okBtn = createButton('Ok');
|
||||
okBtn.bind('click', function(event) {
|
||||
// Get hardware that was selected
|
||||
var hw = $(this).parent().find('select').val();
|
||||
|
||||
// Generate new tab ID
|
||||
var instance = 0;
|
||||
var newTabId = hw + 'ProvisionTab' + instance;
|
||||
while ($('#' + newTabId).length) {
|
||||
// If one already exists, generate another one
|
||||
instance = instance + 1;
|
||||
newTabId = hw + 'ProvisionTab' + instance;
|
||||
}
|
||||
|
||||
tab.add(newTabId, hw, '');
|
||||
|
||||
// Select tab
|
||||
tab.select(newTabId);
|
||||
if (hw == 'zvm') {
|
||||
loadZProvisionPage(newTabId);
|
||||
} else {
|
||||
// TODO: Add other platforms to this section
|
||||
$('#' + newTabId).append('<p>Not supported</p>');
|
||||
}
|
||||
});
|
||||
provForm.append(okBtn);
|
||||
|
||||
tab.add('provisionTab', 'Provision', provForm);
|
||||
}
|
121
xCAT-UI/js/superfish.js
Normal file
@ -0,0 +1,121 @@
|
||||
|
||||
/*
|
||||
* Superfish v1.4.8 - jQuery menu widget
|
||||
* Copyright (c) 2008 Joel Birch
|
||||
*
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* CHANGELOG: http://users.tpg.com.au/j_birch/plugins/superfish/changelog.txt
|
||||
*/
|
||||
|
||||
;(function($){
|
||||
$.fn.superfish = function(op){
|
||||
|
||||
var sf = $.fn.superfish,
|
||||
c = sf.c,
|
||||
$arrow = $(['<span class="',c.arrowClass,'"> »</span>'].join('')),
|
||||
over = function(){
|
||||
var $$ = $(this), menu = getMenu($$);
|
||||
clearTimeout(menu.sfTimer);
|
||||
$$.showSuperfishUl().siblings().hideSuperfishUl();
|
||||
},
|
||||
out = function(){
|
||||
var $$ = $(this), menu = getMenu($$), o = sf.op;
|
||||
clearTimeout(menu.sfTimer);
|
||||
menu.sfTimer=setTimeout(function(){
|
||||
o.retainPath=($.inArray($$[0],o.$path)>-1);
|
||||
$$.hideSuperfishUl();
|
||||
if (o.$path.length && $$.parents(['li.',o.hoverClass].join('')).length<1){over.call(o.$path);}
|
||||
},o.delay);
|
||||
},
|
||||
getMenu = function($menu){
|
||||
var menu = $menu.parents(['ul.',c.menuClass,':first'].join(''))[0];
|
||||
sf.op = sf.o[menu.serial];
|
||||
return menu;
|
||||
},
|
||||
addArrow = function($a){ $a.addClass(c.anchorClass).append($arrow.clone()); };
|
||||
|
||||
return this.each(function() {
|
||||
var s = this.serial = sf.o.length;
|
||||
var o = $.extend({},sf.defaults,op);
|
||||
o.$path = $('li.'+o.pathClass,this).slice(0,o.pathLevels).each(function(){
|
||||
$(this).addClass([o.hoverClass,c.bcClass].join(' '))
|
||||
.filter('li:has(ul)').removeClass(o.pathClass);
|
||||
});
|
||||
sf.o[s] = sf.op = o;
|
||||
|
||||
$('li:has(ul)',this)[($.fn.hoverIntent && !o.disableHI) ? 'hoverIntent' : 'hover'](over,out).each(function() {
|
||||
if (o.autoArrows) addArrow( $('>a:first-child',this) );
|
||||
})
|
||||
.not('.'+c.bcClass)
|
||||
.hideSuperfishUl();
|
||||
|
||||
var $a = $('a',this);
|
||||
$a.each(function(i){
|
||||
var $li = $a.eq(i).parents('li');
|
||||
$a.eq(i).focus(function(){over.call($li);}).blur(function(){out.call($li);});
|
||||
});
|
||||
o.onInit.call(this);
|
||||
|
||||
}).each(function() {
|
||||
var menuClasses = [c.menuClass];
|
||||
if (sf.op.dropShadows && !($.browser.msie && $.browser.version < 7)) menuClasses.push(c.shadowClass);
|
||||
$(this).addClass(menuClasses.join(' '));
|
||||
});
|
||||
};
|
||||
|
||||
var sf = $.fn.superfish;
|
||||
sf.o = [];
|
||||
sf.op = {};
|
||||
sf.IE7fix = function(){
|
||||
var o = sf.op;
|
||||
if ($.browser.msie && $.browser.version > 6 && o.dropShadows && o.animation.opacity!=undefined)
|
||||
this.toggleClass(sf.c.shadowClass+'-off');
|
||||
};
|
||||
sf.c = {
|
||||
bcClass : 'sf-breadcrumb',
|
||||
menuClass : 'sf-js-enabled',
|
||||
anchorClass : 'sf-with-ul',
|
||||
arrowClass : 'sf-sub-indicator',
|
||||
shadowClass : 'sf-shadow'
|
||||
};
|
||||
sf.defaults = {
|
||||
hoverClass : 'sfHover',
|
||||
pathClass : 'overideThisToUse',
|
||||
pathLevels : 1,
|
||||
delay : 800,
|
||||
animation : {opacity:'show'},
|
||||
speed : 'normal',
|
||||
autoArrows : true,
|
||||
dropShadows : true,
|
||||
disableHI : false, // true disables hoverIntent detection
|
||||
onInit : function(){}, // callback functions
|
||||
onBeforeShow: function(){},
|
||||
onShow : function(){},
|
||||
onHide : function(){}
|
||||
};
|
||||
$.fn.extend({
|
||||
hideSuperfishUl : function(){
|
||||
var o = sf.op,
|
||||
not = (o.retainPath===true) ? o.$path : '';
|
||||
o.retainPath = false;
|
||||
var $ul = $(['li.',o.hoverClass].join(''),this).add(this).not(not).removeClass(o.hoverClass)
|
||||
.find('>ul').hide().css('visibility','hidden');
|
||||
o.onHide.call($ul);
|
||||
return this;
|
||||
},
|
||||
showSuperfishUl : function(){
|
||||
var o = sf.op,
|
||||
sh = sf.c.shadowClass+'-off',
|
||||
$ul = this.addClass(o.hoverClass)
|
||||
.find('>ul:hidden').css('visibility','visible');
|
||||
sf.IE7fix.call($ul);
|
||||
o.onBeforeShow.call($ul);
|
||||
$ul.animate(o.animation,o.speed,function(){ sf.IE7fix.call($ul); o.onShow.call($ul); });
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery);
|
463
xCAT-UI/js/ui.js
Normal file
@ -0,0 +1,463 @@
|
||||
/**
|
||||
* Tab constructor
|
||||
*
|
||||
* @param tabId
|
||||
* Tab ID
|
||||
* @param tabName
|
||||
* Tab name
|
||||
* @return Nothing
|
||||
*/
|
||||
var Tab = function(tabId) {
|
||||
this.tabId = tabId;
|
||||
this.tabName = null;
|
||||
this.tab = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the tab
|
||||
*
|
||||
* @param tabName
|
||||
* Tab name to initialize
|
||||
* @return Nothing
|
||||
*/
|
||||
Tab.prototype.init = function() {
|
||||
// Create a division containing the tab
|
||||
this.tab = $('<div class="tab" id="' + this.tabId + '"></div>');
|
||||
var tabList = $('<ul></ul>');
|
||||
var tabItem = $('<li><a href="#">Dummy tab item</a></li>');
|
||||
tabList.append(tabItem);
|
||||
this.tab.append(tabList);
|
||||
|
||||
// Create a template
|
||||
var $tabs = this.tab
|
||||
.tabs( {
|
||||
tabTemplate : "<li><a href=\"#{href}\">#{label}</a><span class=\"tab-close ui-icon ui-icon-close\"></span></li>"
|
||||
});
|
||||
|
||||
// Remove dummy tab
|
||||
this.tab.tabs("remove", 0);
|
||||
|
||||
// Hide tab
|
||||
this.tab.hide();
|
||||
|
||||
// Append close button to tabs
|
||||
$("#" + this.tabId + " span.tab-close").live("click", function() {
|
||||
var index = $('li', $tabs).index($(this).parent());
|
||||
|
||||
// Do not remove first tab
|
||||
if (index != 0) {
|
||||
$tabs.tabs('remove', index);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the tab object
|
||||
*
|
||||
* @param Nothing
|
||||
* @return Object representing the tab
|
||||
*/
|
||||
Tab.prototype.object = function() {
|
||||
return this.tab;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a new tab
|
||||
*
|
||||
* @param newTabId
|
||||
* New tab ID
|
||||
* @param newTabName
|
||||
* New tab name
|
||||
* @param newTabCont
|
||||
* New tab content
|
||||
* @return Nothing
|
||||
*/
|
||||
Tab.prototype.add = function(newTabId, newTabName, newTabCont) {
|
||||
// Show tab
|
||||
if (this.tab.css("display") == "none") {
|
||||
this.tab.show();
|
||||
}
|
||||
|
||||
var newTab = $('<div class="tab" id="' + newTabId + '"></div>');
|
||||
newTab.append(newTabCont);
|
||||
this.tab.append(newTab);
|
||||
this.tab.tabs("add", "#" + newTabId, newTabName);
|
||||
};
|
||||
|
||||
/**
|
||||
* Select a tab
|
||||
*
|
||||
* @param id
|
||||
* Tab ID to select
|
||||
* @return Nothing
|
||||
*/
|
||||
Tab.prototype.select = function(id) {
|
||||
this.tab.tabs("select", "#" + id);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove a tab
|
||||
*
|
||||
* @param id
|
||||
* Tab ID to remove
|
||||
* @return Nothing
|
||||
*/
|
||||
Tab.prototype.remove = function(id) {
|
||||
// To be continued
|
||||
};
|
||||
|
||||
/**
|
||||
* Table constructor
|
||||
*
|
||||
* @param tabId
|
||||
* Tab ID
|
||||
* @param tabName
|
||||
* Tab name
|
||||
* @return Nothing
|
||||
*/
|
||||
var Table = function(tableId) {
|
||||
if ($('#' + tableId).length) {
|
||||
this.tableId = tableId;
|
||||
this.table = $('#' + tableId);
|
||||
} else {
|
||||
this.tableId = tableId;
|
||||
this.table = null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the table
|
||||
*
|
||||
* @param Headers
|
||||
* Array of table headers
|
||||
* @return Nothing
|
||||
*/
|
||||
Table.prototype.init = function(headers) {
|
||||
// Create a table
|
||||
this.table = $('<table id="' + this.tableId + '"></table>');
|
||||
var thead = $('<thead></thead>');
|
||||
var headRow = $('<tr></tr>');
|
||||
|
||||
// Append headers
|
||||
for ( var i in headers) {
|
||||
headRow.append('<th>' + headers[i] + '</th>');
|
||||
}
|
||||
|
||||
thead.append(headRow);
|
||||
this.table.append(thead);
|
||||
|
||||
// Append table body
|
||||
var tableBody = $('<tbody></tbody>');
|
||||
this.table.append(tableBody);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the table object
|
||||
*
|
||||
* @param Nothing
|
||||
* @return Object representing the table
|
||||
*/
|
||||
Table.prototype.object = function() {
|
||||
return this.table;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a row to the table
|
||||
*
|
||||
* @param rowCont
|
||||
* Array of table row contents
|
||||
* @return Nothing
|
||||
*/
|
||||
Table.prototype.add = function(rowCont) {
|
||||
// Create table row
|
||||
var tableRow = $('<tr></tr>');
|
||||
|
||||
// Create a column for each content
|
||||
var tableCol;
|
||||
for ( var i in rowCont) {
|
||||
tableCol = $('<td></td>');
|
||||
tableCol.append(rowCont[i]);
|
||||
tableRow.append(tableCol);
|
||||
}
|
||||
|
||||
// Append table row to table
|
||||
this.table.find('tbody').append(tableRow);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a footer to the table
|
||||
*
|
||||
* @param rowCont
|
||||
* Array of table row contents
|
||||
* @return Nothing
|
||||
*/
|
||||
Table.prototype.addFooter = function(rowCont) {
|
||||
// Create table row
|
||||
var tableFoot = $('<tfoot></tfoot>');
|
||||
tableFoot.append(rowCont);
|
||||
|
||||
// Append table row to table
|
||||
this.table.append(tableFoot);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove a row from the table
|
||||
*
|
||||
* @return Nothing
|
||||
*/
|
||||
Table.prototype.remove = function(id) {
|
||||
// To be continued
|
||||
};
|
||||
|
||||
/**
|
||||
* Datatable class constructor
|
||||
*
|
||||
* @param tabId
|
||||
* Tab ID
|
||||
* @param tabName
|
||||
* Tab name
|
||||
* @return Nothing
|
||||
*/
|
||||
var DataTable = function(tableId) {
|
||||
this.dataTableId = tableId;
|
||||
this.dataTable = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the datatable
|
||||
*
|
||||
* @param Headers
|
||||
* Array of table headers
|
||||
* @return Nothing
|
||||
*/
|
||||
DataTable.prototype.init = function(headers) {
|
||||
// Create a table
|
||||
this.dataTable = $('<table class="datatable" id="' + this.dataTableId + '"></table>');
|
||||
var thead = $('<thead></thead>');
|
||||
var headRow = $('<tr></tr>');
|
||||
|
||||
// Append headers
|
||||
for ( var i in headers) {
|
||||
headRow.append('<th>' + headers[i] + '</th>');
|
||||
}
|
||||
|
||||
thead.append(headRow);
|
||||
this.dataTable.append(thead);
|
||||
|
||||
// Append table body
|
||||
var tableBody = $('<tbody></tbody>');
|
||||
this.dataTable.append(tableBody);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the datatable object
|
||||
*
|
||||
* @param Nothing
|
||||
* @return Object representing the table
|
||||
*/
|
||||
DataTable.prototype.object = function() {
|
||||
return this.dataTable;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a row to the datatable
|
||||
*
|
||||
* @param rowCont
|
||||
* Array of table row contents
|
||||
* @return Nothing
|
||||
*/
|
||||
DataTable.prototype.add = function(rowCont) {
|
||||
// Create table row
|
||||
var tableRow = $('<tr></tr>');
|
||||
|
||||
// Create a column for each content
|
||||
var tableCol;
|
||||
for ( var i in rowCont) {
|
||||
tableCol = $('<td></td>');
|
||||
tableCol.append(rowCont[i]);
|
||||
tableRow.append(tableCol);
|
||||
}
|
||||
|
||||
// Append table row to table
|
||||
this.dataTable.find('tbody').append(tableRow);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove a row from the datatable
|
||||
*
|
||||
* @return Nothing
|
||||
*/
|
||||
NodesTable.prototype.remove = function(id) {
|
||||
// To be continued
|
||||
};
|
||||
|
||||
/**
|
||||
* Create status bar
|
||||
*
|
||||
* @param barId
|
||||
* Status bar ID
|
||||
* @return Status bar
|
||||
*/
|
||||
function createStatusBar(barId) {
|
||||
var statusBar = $('<div class="statusBar" id="' + barId + '"><div>');
|
||||
return statusBar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create info bar
|
||||
*
|
||||
* @param msg
|
||||
* Info message
|
||||
* @return Info bar
|
||||
*/
|
||||
function createInfoBar(msg) {
|
||||
var infoBar = $('<div class="ui-state-highlight ui-corner-all">');
|
||||
var msg = $('<p class="info"><span class="ui-icon ui-icon-info"></span>' + msg + '</p>');
|
||||
infoBar.append(msg);
|
||||
|
||||
return infoBar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a loader
|
||||
*
|
||||
* @param loaderId
|
||||
* Loader ID
|
||||
* @return Nothing
|
||||
*/
|
||||
function createLoader(loaderId) {
|
||||
var loader = $('<img id="' + loaderId + '" src="images/loader.gif"></img>');
|
||||
return loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a button
|
||||
*
|
||||
* @param name
|
||||
* Name of the button
|
||||
* @return Nothing
|
||||
*/
|
||||
function createButton(name) {
|
||||
var button = $('<button aria-disabled="false" role="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" id="button"><span class="ui-button-text">' + name + '</span></button>');
|
||||
return button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a menu
|
||||
*
|
||||
* @param items
|
||||
* An array of items to go into the menu
|
||||
* @return A division containing the menu
|
||||
*/
|
||||
function createMenu(items) {
|
||||
var menu = $('<ul class="sf-menu"></ul>');
|
||||
|
||||
// Loop through each item
|
||||
for ( var i in items) {
|
||||
// Append item to menu
|
||||
var item = $('<li></li>');
|
||||
|
||||
// If it is a sub menu
|
||||
if (items[i] instanceof Array) {
|
||||
// 1st index = Sub menu title
|
||||
item.append(items[i][0]);
|
||||
// 2nd index = Sub menu
|
||||
item.append(items[i][1]);
|
||||
} else {
|
||||
item.append(items[i]);
|
||||
}
|
||||
|
||||
// Do not add border for 1st item
|
||||
if (i > 0) {
|
||||
item.css( {
|
||||
'border-left' : '1px solid #BDBDBD'
|
||||
});
|
||||
}
|
||||
|
||||
menu.append(item);
|
||||
}
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the page
|
||||
*
|
||||
* @return Nothing
|
||||
*/
|
||||
function initPage() {
|
||||
// Get the page being loaded
|
||||
var url = window.location.pathname;
|
||||
var page = url.replace('/xcat/', '');
|
||||
|
||||
var headers = $('#header ul li a');
|
||||
|
||||
// Show the page
|
||||
$('div.content').hide();
|
||||
if (page == 'index.php') {
|
||||
$("#nodes_page").show();
|
||||
headers.eq(0).css('background-color', '#A9D0F5');
|
||||
loadNodesPage();
|
||||
} else if (page == 'configure.php') {
|
||||
$('#configure_page').show();
|
||||
headers.eq(1).css('background-color', '#A9D0F5');
|
||||
loadConfigPage();
|
||||
} else if (page == 'provision.php') {
|
||||
$('#provision_page').show();
|
||||
headers.eq(2).css('background-color', '#A9D0F5');
|
||||
loadProvisionPage();
|
||||
} else if (page == 'monitor.php') {
|
||||
$('#monitor_page').show();
|
||||
headers.eq(3).css('background-color', '#A9D0F5');
|
||||
loadMonitorPage();
|
||||
} else {
|
||||
$("#nodes_page").show();
|
||||
headers.eq(0).css('background-color', '#A9D0F5');
|
||||
loadNodesPage();
|
||||
}
|
||||
|
||||
// Bind each link to open the page on click
|
||||
for ( var i = 0; i < headers.length; i++) {
|
||||
var title = headers.eq(i).text();
|
||||
var link = headers.eq(i);
|
||||
link.attr('href', '#');
|
||||
|
||||
if (title == 'Nodes') {
|
||||
link.bind('click', function(event) {
|
||||
$('div.content').hide();
|
||||
$('#nodes_page').show();
|
||||
headers.css('background-color', '');
|
||||
$(this).css('background-color', '#A9D0F5');
|
||||
|
||||
loadNodesPage();
|
||||
});
|
||||
} else if (title == 'Configure') {
|
||||
link.bind('click', function(event) {
|
||||
$('div.content').hide();
|
||||
$('#configure_page').show();
|
||||
headers.css('background-color', '');
|
||||
$(this).css('background-color', '#A9D0F5');
|
||||
|
||||
loadConfigPage();
|
||||
});
|
||||
} else if (title == 'Provision') {
|
||||
link.bind('click', function(event) {
|
||||
$('div.content').hide();
|
||||
$('#provision_page').show();
|
||||
headers.css('background-color', '');
|
||||
$(this).css('background-color', '#A9D0F5');
|
||||
|
||||
loadProvisionPage();
|
||||
});
|
||||
} else if (title == 'Monitor') {
|
||||
link.bind('click', function(event) {
|
||||
$('div.content').hide();
|
||||
$('#monitor_page').show();
|
||||
headers.css('background-color', '');
|
||||
$(this).css('background-color', '#A9D0F5');
|
||||
|
||||
loadMonitorPage();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
79
xCAT-UI/js/xcatauth.js
Normal file
@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Open login dialog
|
||||
*/
|
||||
$(document).ready(function() {
|
||||
$("#logdialog").dialog( {
|
||||
modal : true,
|
||||
closeOnEscape : false,
|
||||
closebutton : false,
|
||||
height : 300,
|
||||
width : 350,
|
||||
autoOpen : true,
|
||||
buttons : {
|
||||
"Log in" : authenticate
|
||||
},
|
||||
open : function(type, dialog) {
|
||||
if (document.location.protocol == "http:") {
|
||||
$("#logstatus").html("You are using an unencrypted session !");
|
||||
$("#logstatus").css("color", "#ff0000");
|
||||
}
|
||||
if ($("#username").val() == "") {
|
||||
$("#username").focus();
|
||||
} else {
|
||||
$("#password").focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// When enter is hit while in username, advance to password
|
||||
$("#username").keydown(function(event) {
|
||||
if (event.keyCode == 13) {
|
||||
$("#password").focus();
|
||||
}
|
||||
});
|
||||
|
||||
// Submit authentication if enter is pressed in password field
|
||||
$("#password").keydown(function(event) {
|
||||
if (event.keyCode == 13) {
|
||||
authenticate();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Update login dialog
|
||||
*
|
||||
* @param data
|
||||
* Data returned from AJAX call
|
||||
* @param textstatus
|
||||
* @return
|
||||
*/
|
||||
function onlogin(data, textstatus) {
|
||||
// Clear password field regardless of what happens
|
||||
$("#password").val("");
|
||||
if (data.authenticated == "yes") {
|
||||
$("#logstatus").text("Logged in successfully");
|
||||
$("#logdialog").dialog("close");
|
||||
|
||||
// Remembered what page they were trying to go to
|
||||
window.location = 'index.php';
|
||||
} else {
|
||||
$("#logstatus").text("Authentication failure");
|
||||
$("#logstatus").css("color", "#FF0000");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate user for new session
|
||||
*
|
||||
* @return Nothing
|
||||
*/
|
||||
function authenticate() {
|
||||
$("#logstatus").css("color", "#000000");
|
||||
$("#logstatus").html('Authenticating...');
|
||||
var passwd = $("#password").val();
|
||||
$.post("lib/log.php", {
|
||||
username : $("#username").val(),
|
||||
password : passwd
|
||||
}, onlogin, "json");
|
||||
}
|
3171
xCAT-UI/js/zUtils.js
Normal file
806
xCAT-UI/lib/JSON/JSON.php
Normal file
@ -0,0 +1,806 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Converts to and from JSON format.
|
||||
*
|
||||
* JSON (JavaScript Object Notation) is a lightweight data-interchange
|
||||
* format. It is easy for humans to read and write. It is easy for machines
|
||||
* to parse and generate. It is based on a subset of the JavaScript
|
||||
* Programming Language, Standard ECMA-262 3rd Edition - December 1999.
|
||||
* This feature can also be found in Python. JSON is a text format that is
|
||||
* completely language independent but uses conventions that are familiar
|
||||
* to programmers of the C-family of languages, including C, C++, C#, Java,
|
||||
* JavaScript, Perl, TCL, and many others. These properties make JSON an
|
||||
* ideal data-interchange language.
|
||||
*
|
||||
* This package provides a simple encoder and decoder for JSON notation. It
|
||||
* is intended for use with client-side Javascript applications that make
|
||||
* use of HTTPRequest to perform server communication functions - data can
|
||||
* be encoded into JSON notation for use in a client-side javascript, or
|
||||
* decoded from incoming Javascript requests. JSON format is native to
|
||||
* Javascript, and can be directly eval()'ed with no further parsing
|
||||
* overhead
|
||||
*
|
||||
* All strings should be in ASCII or UTF-8 format!
|
||||
*
|
||||
* LICENSE: 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``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 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.
|
||||
*
|
||||
* @category
|
||||
* @package Services_JSON
|
||||
* @author Michal Migurski <mike-json@teczno.com>
|
||||
* @author Matt Knapp <mdknapp[at]gmail[dot]com>
|
||||
* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
|
||||
* @copyright 2005 Michal Migurski
|
||||
* @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php
|
||||
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
|
||||
*/
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_SLICE', 1);
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_STR', 2);
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_ARR', 3);
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_OBJ', 4);
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_CMT', 5);
|
||||
|
||||
/**
|
||||
* Behavior switch for Services_JSON::decode()
|
||||
*/
|
||||
define('SERVICES_JSON_LOOSE_TYPE', 16);
|
||||
|
||||
/**
|
||||
* Behavior switch for Services_JSON::decode()
|
||||
*/
|
||||
define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
|
||||
|
||||
/**
|
||||
* Converts to and from JSON format.
|
||||
*
|
||||
* Brief example of use:
|
||||
*
|
||||
* <code>
|
||||
* // create a new instance of Services_JSON
|
||||
* $json = new Services_JSON();
|
||||
*
|
||||
* // convert a complexe value to JSON notation, and send it to the browser
|
||||
* $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
|
||||
* $output = $json->encode($value);
|
||||
*
|
||||
* print($output);
|
||||
* // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
|
||||
*
|
||||
* // accept incoming POST data, assumed to be in JSON notation
|
||||
* $input = file_get_contents('php://input', 1000000);
|
||||
* $value = $json->decode($input);
|
||||
* </code>
|
||||
*/
|
||||
class Services_JSON
|
||||
{
|
||||
/**
|
||||
* constructs a new JSON instance
|
||||
*
|
||||
* @param int $use object behavior flags; combine with boolean-OR
|
||||
*
|
||||
* possible values:
|
||||
* - SERVICES_JSON_LOOSE_TYPE: loose typing.
|
||||
* "{...}" syntax creates associative arrays
|
||||
* instead of objects in decode().
|
||||
* - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
|
||||
* Values which can't be encoded (e.g. resources)
|
||||
* appear as NULL instead of throwing errors.
|
||||
* By default, a deeply-nested resource will
|
||||
* bubble up with an error, so all return values
|
||||
* from encode() should be checked with isError()
|
||||
*/
|
||||
function Services_JSON($use = 0)
|
||||
{
|
||||
$this->use = $use;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert a string from one UTF-16 char to one UTF-8 char
|
||||
*
|
||||
* Normally should be handled by mb_convert_encoding, but
|
||||
* provides a slower PHP-only method for installations
|
||||
* that lack the multibye string extension.
|
||||
*
|
||||
* @param string $utf16 UTF-16 character
|
||||
* @return string UTF-8 character
|
||||
* @access private
|
||||
*/
|
||||
function utf162utf8($utf16)
|
||||
{
|
||||
// oh please oh please oh please oh please oh please
|
||||
if(function_exists('mb_convert_encoding')) {
|
||||
return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
|
||||
}
|
||||
|
||||
$bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
|
||||
|
||||
switch(true) {
|
||||
case ((0x7F & $bytes) == $bytes):
|
||||
// this case should never be reached, because we are in ASCII range
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0x7F & $bytes);
|
||||
|
||||
case (0x07FF & $bytes) == $bytes:
|
||||
// return a 2-byte UTF-8 character
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0xC0 | (($bytes >> 6) & 0x1F))
|
||||
. chr(0x80 | ($bytes & 0x3F));
|
||||
|
||||
case (0xFFFF & $bytes) == $bytes:
|
||||
// return a 3-byte UTF-8 character
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0xE0 | (($bytes >> 12) & 0x0F))
|
||||
. chr(0x80 | (($bytes >> 6) & 0x3F))
|
||||
. chr(0x80 | ($bytes & 0x3F));
|
||||
}
|
||||
|
||||
// ignoring UTF-32 for now, sorry
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* convert a string from one UTF-8 char to one UTF-16 char
|
||||
*
|
||||
* Normally should be handled by mb_convert_encoding, but
|
||||
* provides a slower PHP-only method for installations
|
||||
* that lack the multibye string extension.
|
||||
*
|
||||
* @param string $utf8 UTF-8 character
|
||||
* @return string UTF-16 character
|
||||
* @access private
|
||||
*/
|
||||
function utf82utf16($utf8)
|
||||
{
|
||||
// oh please oh please oh please oh please oh please
|
||||
if(function_exists('mb_convert_encoding')) {
|
||||
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
|
||||
}
|
||||
|
||||
switch(strlen($utf8)) {
|
||||
case 1:
|
||||
// this case should never be reached, because we are in ASCII range
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return $utf8;
|
||||
|
||||
case 2:
|
||||
// return a UTF-16 character from a 2-byte UTF-8 char
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0x07 & (ord($utf8{0}) >> 2))
|
||||
. chr((0xC0 & (ord($utf8{0}) << 6))
|
||||
| (0x3F & ord($utf8{1})));
|
||||
|
||||
case 3:
|
||||
// return a UTF-16 character from a 3-byte UTF-8 char
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr((0xF0 & (ord($utf8{0}) << 4))
|
||||
| (0x0F & (ord($utf8{1}) >> 2)))
|
||||
. chr((0xC0 & (ord($utf8{1}) << 6))
|
||||
| (0x7F & ord($utf8{2})));
|
||||
}
|
||||
|
||||
// ignoring UTF-32 for now, sorry
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* encodes an arbitrary variable into JSON format
|
||||
*
|
||||
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
||||
* see argument 1 to Services_JSON() above for array-parsing behavior.
|
||||
* if var is a strng, note that encode() always expects it
|
||||
* to be in ASCII or UTF-8 format!
|
||||
*
|
||||
* @return mixed JSON string representation of input var or an error if a problem occurs
|
||||
* @access public
|
||||
*/
|
||||
function encode($var)
|
||||
{
|
||||
switch (gettype($var)) {
|
||||
case 'boolean':
|
||||
return $var ? 'true' : 'false';
|
||||
|
||||
case 'NULL':
|
||||
return 'null';
|
||||
|
||||
case 'integer':
|
||||
return (int) $var;
|
||||
|
||||
case 'double':
|
||||
case 'float':
|
||||
return (float) $var;
|
||||
|
||||
case 'string':
|
||||
// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
|
||||
$ascii = '';
|
||||
$strlen_var = strlen($var);
|
||||
|
||||
/*
|
||||
* Iterate over every character in the string,
|
||||
* escaping with a slash or encoding to UTF-8 where necessary
|
||||
*/
|
||||
for ($c = 0; $c < $strlen_var; ++$c) {
|
||||
|
||||
$ord_var_c = ord($var{$c});
|
||||
|
||||
switch (true) {
|
||||
case $ord_var_c == 0x08:
|
||||
$ascii .= '\b';
|
||||
break;
|
||||
case $ord_var_c == 0x09:
|
||||
$ascii .= '\t';
|
||||
break;
|
||||
case $ord_var_c == 0x0A:
|
||||
$ascii .= '\n';
|
||||
break;
|
||||
case $ord_var_c == 0x0C:
|
||||
$ascii .= '\f';
|
||||
break;
|
||||
case $ord_var_c == 0x0D:
|
||||
$ascii .= '\r';
|
||||
break;
|
||||
|
||||
case $ord_var_c == 0x22:
|
||||
case $ord_var_c == 0x2F:
|
||||
case $ord_var_c == 0x5C:
|
||||
// double quote, slash, slosh
|
||||
$ascii .= '\\'.$var{$c};
|
||||
break;
|
||||
|
||||
case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
|
||||
// characters U-00000000 - U-0000007F (same as ASCII)
|
||||
$ascii .= $var{$c};
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xE0) == 0xC0):
|
||||
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c, ord($var{$c + 1}));
|
||||
$c += 1;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xF0) == 0xE0):
|
||||
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}));
|
||||
$c += 2;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xF8) == 0xF0):
|
||||
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}),
|
||||
ord($var{$c + 3}));
|
||||
$c += 3;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xFC) == 0xF8):
|
||||
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}),
|
||||
ord($var{$c + 3}),
|
||||
ord($var{$c + 4}));
|
||||
$c += 4;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xFE) == 0xFC):
|
||||
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}),
|
||||
ord($var{$c + 3}),
|
||||
ord($var{$c + 4}),
|
||||
ord($var{$c + 5}));
|
||||
$c += 5;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return '"'.$ascii.'"';
|
||||
|
||||
case 'array':
|
||||
/*
|
||||
* As per JSON spec if any array key is not an integer
|
||||
* we must treat the the whole array as an object. We
|
||||
* also try to catch a sparsely populated associative
|
||||
* array with numeric keys here because some JS engines
|
||||
* will create an array with empty indexes up to
|
||||
* max_index which can cause memory issues and because
|
||||
* the keys, which may be relevant, will be remapped
|
||||
* otherwise.
|
||||
*
|
||||
* As per the ECMA and JSON specification an object may
|
||||
* have any string as a property. Unfortunately due to
|
||||
* a hole in the ECMA specification if the key is a
|
||||
* ECMA reserved word or starts with a digit the
|
||||
* parameter is only accessible using ECMAScript's
|
||||
* bracket notation.
|
||||
*/
|
||||
|
||||
// treat as a JSON object
|
||||
if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
|
||||
$properties = array_map(array($this, 'name_value'),
|
||||
array_keys($var),
|
||||
array_values($var));
|
||||
|
||||
foreach($properties as $property) {
|
||||
if(Services_JSON::isError($property)) {
|
||||
return $property;
|
||||
}
|
||||
}
|
||||
|
||||
return '{' . join(',', $properties) . '}';
|
||||
}
|
||||
|
||||
// treat it like a regular array
|
||||
$elements = array_map(array($this, 'encode'), $var);
|
||||
|
||||
foreach($elements as $element) {
|
||||
if(Services_JSON::isError($element)) {
|
||||
return $element;
|
||||
}
|
||||
}
|
||||
|
||||
return '[' . join(',', $elements) . ']';
|
||||
|
||||
case 'object':
|
||||
$vars = get_object_vars($var);
|
||||
|
||||
$properties = array_map(array($this, 'name_value'),
|
||||
array_keys($vars),
|
||||
array_values($vars));
|
||||
|
||||
foreach($properties as $property) {
|
||||
if(Services_JSON::isError($property)) {
|
||||
return $property;
|
||||
}
|
||||
}
|
||||
|
||||
return '{' . join(',', $properties) . '}';
|
||||
|
||||
default:
|
||||
return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
|
||||
? 'null'
|
||||
: new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* array-walking function for use in generating JSON-formatted name-value pairs
|
||||
*
|
||||
* @param string $name name of key to use
|
||||
* @param mixed $value reference to an array element to be encoded
|
||||
*
|
||||
* @return string JSON-formatted name-value pair, like '"name":value'
|
||||
* @access private
|
||||
*/
|
||||
function name_value($name, $value)
|
||||
{
|
||||
$encoded_value = $this->encode($value);
|
||||
|
||||
if(Services_JSON::isError($encoded_value)) {
|
||||
return $encoded_value;
|
||||
}
|
||||
|
||||
return $this->encode(strval($name)) . ':' . $encoded_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* reduce a string by removing leading and trailing comments and whitespace
|
||||
*
|
||||
* @param $str string string value to strip of comments and whitespace
|
||||
*
|
||||
* @return string string value stripped of comments and whitespace
|
||||
* @access private
|
||||
*/
|
||||
function reduce_string($str)
|
||||
{
|
||||
$str = preg_replace(array(
|
||||
|
||||
// eliminate single line comments in '// ...' form
|
||||
'#^\s*//(.+)$#m',
|
||||
|
||||
// eliminate multi-line comments in '/* ... */' form, at start of string
|
||||
'#^\s*/\*(.+)\*/#Us',
|
||||
|
||||
// eliminate multi-line comments in '/* ... */' form, at end of string
|
||||
'#/\*(.+)\*/\s*$#Us'
|
||||
|
||||
), '', $str);
|
||||
|
||||
// eliminate extraneous space
|
||||
return trim($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* decodes a JSON string into appropriate variable
|
||||
*
|
||||
* @param string $str JSON-formatted string
|
||||
*
|
||||
* @return mixed number, boolean, string, array, or object
|
||||
* corresponding to given JSON input string.
|
||||
* See argument 1 to Services_JSON() above for object-output behavior.
|
||||
* Note that decode() always returns strings
|
||||
* in ASCII or UTF-8 format!
|
||||
* @access public
|
||||
*/
|
||||
function decode($str)
|
||||
{
|
||||
$str = $this->reduce_string($str);
|
||||
|
||||
switch (strtolower($str)) {
|
||||
case 'true':
|
||||
return true;
|
||||
|
||||
case 'false':
|
||||
return false;
|
||||
|
||||
case 'null':
|
||||
return null;
|
||||
|
||||
default:
|
||||
$m = array();
|
||||
|
||||
if (is_numeric($str)) {
|
||||
// Lookie-loo, it's a number
|
||||
|
||||
// This would work on its own, but I'm trying to be
|
||||
// good about returning integers where appropriate:
|
||||
// return (float)$str;
|
||||
|
||||
// Return float or int, as appropriate
|
||||
return ((float)$str == (integer)$str)
|
||||
? (integer)$str
|
||||
: (float)$str;
|
||||
|
||||
} elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
|
||||
// STRINGS RETURNED IN UTF-8 FORMAT
|
||||
$delim = substr($str, 0, 1);
|
||||
$chrs = substr($str, 1, -1);
|
||||
$utf8 = '';
|
||||
$strlen_chrs = strlen($chrs);
|
||||
|
||||
for ($c = 0; $c < $strlen_chrs; ++$c) {
|
||||
|
||||
$substr_chrs_c_2 = substr($chrs, $c, 2);
|
||||
$ord_chrs_c = ord($chrs{$c});
|
||||
|
||||
switch (true) {
|
||||
case $substr_chrs_c_2 == '\b':
|
||||
$utf8 .= chr(0x08);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\t':
|
||||
$utf8 .= chr(0x09);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\n':
|
||||
$utf8 .= chr(0x0A);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\f':
|
||||
$utf8 .= chr(0x0C);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\r':
|
||||
$utf8 .= chr(0x0D);
|
||||
++$c;
|
||||
break;
|
||||
|
||||
case $substr_chrs_c_2 == '\\"':
|
||||
case $substr_chrs_c_2 == '\\\'':
|
||||
case $substr_chrs_c_2 == '\\\\':
|
||||
case $substr_chrs_c_2 == '\\/':
|
||||
if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
|
||||
($delim == "'" && $substr_chrs_c_2 != '\\"')) {
|
||||
$utf8 .= $chrs{++$c};
|
||||
}
|
||||
break;
|
||||
|
||||
case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
|
||||
// single, escaped unicode character
|
||||
$utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
|
||||
. chr(hexdec(substr($chrs, ($c + 4), 2)));
|
||||
$utf8 .= $this->utf162utf8($utf16);
|
||||
$c += 5;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
|
||||
$utf8 .= $chrs{$c};
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xE0) == 0xC0:
|
||||
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
||||
//see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 2);
|
||||
++$c;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xF0) == 0xE0:
|
||||
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 3);
|
||||
$c += 2;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xF8) == 0xF0:
|
||||
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 4);
|
||||
$c += 3;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xFC) == 0xF8:
|
||||
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 5);
|
||||
$c += 4;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xFE) == 0xFC:
|
||||
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 6);
|
||||
$c += 5;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $utf8;
|
||||
|
||||
} elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
|
||||
// array, or object notation
|
||||
|
||||
if ($str{0} == '[') {
|
||||
$stk = array(SERVICES_JSON_IN_ARR);
|
||||
$arr = array();
|
||||
} else {
|
||||
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
||||
$stk = array(SERVICES_JSON_IN_OBJ);
|
||||
$obj = array();
|
||||
} else {
|
||||
$stk = array(SERVICES_JSON_IN_OBJ);
|
||||
$obj = new stdClass();
|
||||
}
|
||||
}
|
||||
|
||||
array_push($stk, array('what' => SERVICES_JSON_SLICE,
|
||||
'where' => 0,
|
||||
'delim' => false));
|
||||
|
||||
$chrs = substr($str, 1, -1);
|
||||
$chrs = $this->reduce_string($chrs);
|
||||
|
||||
if ($chrs == '') {
|
||||
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
||||
return $arr;
|
||||
|
||||
} else {
|
||||
return $obj;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//print("\nparsing {$chrs}\n");
|
||||
|
||||
$strlen_chrs = strlen($chrs);
|
||||
|
||||
for ($c = 0; $c <= $strlen_chrs; ++$c) {
|
||||
|
||||
$top = end($stk);
|
||||
$substr_chrs_c_2 = substr($chrs, $c, 2);
|
||||
|
||||
if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
|
||||
// found a comma that is not inside a string, array, etc.,
|
||||
// OR we've reached the end of the character list
|
||||
$slice = substr($chrs, $top['where'], ($c - $top['where']));
|
||||
array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
|
||||
//print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
||||
// we are in an array, so just push an element onto the stack
|
||||
array_push($arr, $this->decode($slice));
|
||||
|
||||
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
|
||||
// we are in an object, so figure
|
||||
// out the property name and set an
|
||||
// element in an associative array,
|
||||
// for now
|
||||
$parts = array();
|
||||
|
||||
if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
|
||||
// "name":value pair
|
||||
$key = $this->decode($parts[1]);
|
||||
$val = $this->decode($parts[2]);
|
||||
|
||||
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
||||
$obj[$key] = $val;
|
||||
} else {
|
||||
$obj->$key = $val;
|
||||
}
|
||||
} elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
|
||||
// name:value pair, where name is unquoted
|
||||
$key = $parts[1];
|
||||
$val = $this->decode($parts[2]);
|
||||
|
||||
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
||||
$obj[$key] = $val;
|
||||
} else {
|
||||
$obj->$key = $val;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
|
||||
// found a quote, and we are not inside a string
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
|
||||
//print("Found start of string at {$c}\n");
|
||||
|
||||
} elseif (($chrs{$c} == $top['delim']) &&
|
||||
($top['what'] == SERVICES_JSON_IN_STR) &&
|
||||
((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) {
|
||||
// found a quote, we're in a string, and it's not escaped
|
||||
// we know that it's not escaped becase there is _not_ an
|
||||
// odd number of backslashes at the end of the string so far
|
||||
array_pop($stk);
|
||||
//print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
|
||||
|
||||
} elseif (($chrs{$c} == '[') &&
|
||||
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
||||
// found a left-bracket, and we are in an array, object, or slice
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
|
||||
//print("Found start of array at {$c}\n");
|
||||
|
||||
} elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
|
||||
// found a right-bracket, and we're in an array
|
||||
array_pop($stk);
|
||||
//print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
} elseif (($chrs{$c} == '{') &&
|
||||
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
||||
// found a left-brace, and we are in an array, object, or slice
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
|
||||
//print("Found start of object at {$c}\n");
|
||||
|
||||
} elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
|
||||
// found a right-brace, and we're in an object
|
||||
array_pop($stk);
|
||||
//print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
} elseif (($substr_chrs_c_2 == '/*') &&
|
||||
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
||||
// found a comment start, and we are in an array, object, or slice
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
|
||||
$c++;
|
||||
//print("Found start of comment at {$c}\n");
|
||||
|
||||
} elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
|
||||
// found a comment end, and we're in one now
|
||||
array_pop($stk);
|
||||
$c++;
|
||||
|
||||
for ($i = $top['where']; $i <= $c; ++$i)
|
||||
$chrs = substr_replace($chrs, ' ', $i, 1);
|
||||
|
||||
//print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
||||
return $arr;
|
||||
|
||||
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
|
||||
return $obj;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Ultimately, this should just call PEAR::isError()
|
||||
*/
|
||||
function isError($data, $code = null)
|
||||
{
|
||||
if (class_exists('pear')) {
|
||||
return PEAR::isError($data, $code);
|
||||
} elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
|
||||
is_subclass_of($data, 'services_json_error'))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (class_exists('PEAR_Error')) {
|
||||
|
||||
class Services_JSON_Error extends PEAR_Error
|
||||
{
|
||||
function Services_JSON_Error($message = 'unknown error', $code = null,
|
||||
$mode = null, $options = null, $userinfo = null)
|
||||
{
|
||||
parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/**
|
||||
* @todo Ultimately, this class shall be descended from PEAR_Error
|
||||
*/
|
||||
class Services_JSON_Error
|
||||
{
|
||||
function Services_JSON_Error($message = 'unknown error', $code = null,
|
||||
$mode = null, $options = null, $userinfo = null)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
121
xCAT-UI/lib/cmd.php
Normal file
@ -0,0 +1,121 @@
|
||||
<?php
|
||||
/* Required libraries */
|
||||
$TOPDIR = '..';
|
||||
require_once "$TOPDIR/lib/functions.php";
|
||||
require_once "$TOPDIR/lib/jsonwrapper.php";
|
||||
|
||||
/**
|
||||
* Issue a xCAT command, e.g. rinv gpok123 all
|
||||
* This will handle most commands. If not, you can create your
|
||||
* own .php. Look at zCmd.php for an example.
|
||||
*
|
||||
* @param $cmd The xCAT command
|
||||
* $tgt The target node or group
|
||||
* $args The xCAT command arguments, separated by semicolons
|
||||
* @return The xCAT response. Replies are in the form of JSON
|
||||
*/
|
||||
if (isset($_GET["cmd"])) {
|
||||
// HTTP GET requests
|
||||
$cmd = $_GET["cmd"];
|
||||
$tgt = $_GET["tgt"];
|
||||
$args = $_GET["args"];
|
||||
|
||||
// Special messages put here
|
||||
// This gets sent back to the AJAX request as is.
|
||||
$msg = $_GET["msg"];
|
||||
|
||||
// If no $tgt is given, set $tgt to NULL
|
||||
if (!$tgt) {
|
||||
$tgt = NULL;
|
||||
}
|
||||
|
||||
// If no $msg is given, set $msg to NULL
|
||||
if (!$msg) {
|
||||
$msg = NULL;
|
||||
}
|
||||
|
||||
// If $args contains multiple arguments, split it into an array
|
||||
if (strpos($args,";")) {
|
||||
// Split the arguments into an array
|
||||
$arr = array();
|
||||
$arr = explode(";", $args);
|
||||
} else {
|
||||
$arr = array($args);
|
||||
}
|
||||
|
||||
// Submit request and get response
|
||||
$xml = docmd($cmd, $tgt, $arr);
|
||||
$rsp = array();
|
||||
|
||||
// webrun pping output needs special handling
|
||||
if(strncasecmp($cmd, "webrun", 6) == 0 && stristr($args, "pping")) {
|
||||
$rsp = extractWebrun($xml);
|
||||
}
|
||||
// nodels output needs special handling
|
||||
else if(strncasecmp($cmd, "nodels", 6) == 0) {
|
||||
// Handle the output the same way as webrun
|
||||
$rsp = extractWebrun($xml);
|
||||
}
|
||||
// extnoderange output needs special handling
|
||||
// This command gets the nodes and groups
|
||||
else if(strncasecmp($cmd, "extnoderange", 12) == 0) {
|
||||
$rsp = extractExtnoderange($xml);
|
||||
}
|
||||
// Handle the typical output
|
||||
else {
|
||||
foreach ($xml->children() as $child) {
|
||||
foreach ($child->children() as $data) {
|
||||
array_push($rsp, "$data");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reply in the form of JSON
|
||||
$rtn = array("rsp" => $rsp, "msg" => $msg);
|
||||
echo json_encode($rtn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the output for a webrun command
|
||||
*
|
||||
* @param $xml The XML output from docmd()
|
||||
* @return An array containing the output
|
||||
*/
|
||||
function extractWebrun($xml) {
|
||||
$rsp = array();
|
||||
$i = 0;
|
||||
|
||||
// Extract data returned
|
||||
foreach($xml->children() as $nodes){
|
||||
foreach($nodes->children() as $node){
|
||||
// Get the node name
|
||||
$name = $node->name;
|
||||
// Get the content
|
||||
$status = $node->data->contents;
|
||||
|
||||
// Add to return array
|
||||
$rsp[$i] = array("$name", "$status");
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
return $rsp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the output for a extnoderange command
|
||||
*
|
||||
* @param $xml The XML output from docmd()
|
||||
* @return The nodes and groups
|
||||
*/
|
||||
function extractExtnoderange($xml) {
|
||||
$rsp = array();
|
||||
|
||||
// Extract data returned
|
||||
foreach ($xml->xcatresponse->intersectinggroups as $group) {
|
||||
array_push($rsp, "$group");
|
||||
}
|
||||
|
||||
return $rsp;
|
||||
}
|
||||
?>
|
249
xCAT-UI/lib/functions.php
Normal file
@ -0,0 +1,249 @@
|
||||
<?php
|
||||
/**
|
||||
* Contains all common PHP functions needed by most pages
|
||||
*/
|
||||
|
||||
// Retain session variables across page requests
|
||||
session_start();
|
||||
|
||||
// The settings below display error on the screen,
|
||||
// instead of giving blank pages.
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', true);
|
||||
|
||||
/**
|
||||
* Description: Run a command using the xCAT client/server protocol
|
||||
*
|
||||
* @param $cmd The xCAT command
|
||||
* $nr Node range or group
|
||||
* $args Command arguments
|
||||
* @return A tree of SimpleXML objects.
|
||||
* See perl-xCAT/xCAT/Client.pm for the format
|
||||
*/
|
||||
function docmd($cmd, $nr, $args){
|
||||
// If we are not logged in,
|
||||
// do not try to communicate with xcatd
|
||||
if (!is_logged()) {
|
||||
echo "<p>docmd: Not logged in - cannot run command</p>";
|
||||
return simplexml_load_string('<xcat></xcat>', 'SimpleXMLElement', LIBXML_NOCDATA);
|
||||
}
|
||||
|
||||
$request = simplexml_load_string('<xcatrequest></xcatrequest>');
|
||||
$request->addChild('command', $cmd);
|
||||
if(!empty($nr)) { $request->addChild('noderange', $nr); }
|
||||
if (!empty($args)) {
|
||||
foreach ($args as $a) {
|
||||
$request->addChild('arg',$a);
|
||||
}
|
||||
}
|
||||
|
||||
$usernode=$request->addChild('becomeuser');
|
||||
$usernode->addChild('username',$_SESSION["username"]);
|
||||
$usernode->addChild('password',getpassword());
|
||||
|
||||
$xml = submit_request($request,0);
|
||||
return $xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by docmd()
|
||||
*
|
||||
* @param $req Tree of SimpleXML objects
|
||||
* @return A tree of SimpleXML objects
|
||||
*/
|
||||
function submit_request($req, $skipVerify){
|
||||
$xcathost = "localhost";
|
||||
$port = "3001";
|
||||
$rsp = FALSE;
|
||||
$response = '';
|
||||
$cleanexit = 0;
|
||||
|
||||
// Open a socket to xcatd
|
||||
if($fp = stream_socket_client('ssl://'.$xcathost.':'.$port, $errno, $errstr, 30, STREAM_CLIENT_CONNECT)){
|
||||
|
||||
// The line below makes the call async
|
||||
// stream_set_blocking($fp, 0);
|
||||
|
||||
fwrite($fp,$req->asXML()); // Send XML to xcatd
|
||||
while(!feof($fp)){ // Read until there is no more
|
||||
// Remove newlines and add it to the response
|
||||
$response .= preg_replace('/\n/', '', fread($fp, 8192));
|
||||
|
||||
// Look for serverdone response
|
||||
$fullpattern = '/<xcatresponse>\s*<serverdone>\s*<\/serverdone>\s*<\/xcatresponse>/';
|
||||
$mixedpattern = '/<serverdone>\s*<\/serverdone>.*<\/xcatresponse>/';
|
||||
if(preg_match($mixedpattern,$response)) {
|
||||
// Transaction is done,
|
||||
// Package up XML and return it
|
||||
// Remove the serverdone response and put an xcat tag around the rest
|
||||
$count = 0;
|
||||
$response = preg_replace($fullpattern,'', $response, -1, $count); // 1st try to remove the long pattern
|
||||
if (!$count) { $response = preg_replace($mixedpattern,'', $response) . '</xcatresponse>/'; } // if its not there, then remove the short pattern
|
||||
$response = "<xcat>$response</xcat>";
|
||||
$rsp = simplexml_load_string($response,'SimpleXMLElement', LIBXML_NOCDATA);
|
||||
$cleanexit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose($fp);
|
||||
}else{
|
||||
echo "<p>xCAT submit request socket error: $errno - $errstr</p>";
|
||||
}
|
||||
|
||||
if(! $cleanexit){
|
||||
if (preg_match('/^\s*<xcatresponse>.*<\/xcatresponse>\s*$/',$response)) {
|
||||
// Probably an error message
|
||||
$response = "<xcat>$response</xcat>";
|
||||
$rsp = simplexml_load_string($response,'SimpleXMLElement', LIBXML_NOCDATA);
|
||||
}
|
||||
elseif(!$skipVerify){
|
||||
echo "<p>(Error) xCAT response ended prematurely: ", htmlentities($response), "</p>";
|
||||
$rsp = FALSE;
|
||||
}
|
||||
}
|
||||
return $rsp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable password storage to split between cookie and session variable
|
||||
*
|
||||
* @param $data
|
||||
* $key
|
||||
* @return
|
||||
*/
|
||||
function xorcrypt($data,$key) {
|
||||
$datalen = strlen($data);
|
||||
$keylen = strlen($key);
|
||||
for ($i=0;$i<$datalen;$i++) {
|
||||
$data[$i] = chr(ord($data[$i])^ord($key[$i]));
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get password
|
||||
*
|
||||
* @param Nothing
|
||||
* @return
|
||||
*/
|
||||
function getpassword() {
|
||||
if (isset($GLOBALS['xcatauthsecret'])) {
|
||||
$cryptext = $GLOBALS['xcatauthsecret'];
|
||||
} else if (isset($_COOKIE["xcatauthsecret"])) {
|
||||
$cryptext = $_COOKIE["xcatauthsecret"];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return xorcrypt($_SESSION["secretkey"], base64_decode($cryptext));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the password splitting knowledge between server
|
||||
* and client side persistant storage. Caller should regenerate
|
||||
* session id when contemplating a new user/password, to preclude
|
||||
* session fixation, though fixation is limited without the secret.
|
||||
*
|
||||
* @param $password Password
|
||||
* @return Nothing
|
||||
*/
|
||||
function setpassword($password) {
|
||||
$randlen = strlen($password);
|
||||
$key = getrandchars($randlen);
|
||||
$cryptext = xorcrypt($password,$key);
|
||||
|
||||
// Non-ascii characters, encode it in base64
|
||||
$cryptext = base64_encode($cryptext);
|
||||
setcookie("xcatauthsecret",$cryptext,0,'/');
|
||||
$GLOBALS["xcatauthsecret"] = $cryptext;
|
||||
$_SESSION["secretkey"] = $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get RAND characters.
|
||||
*
|
||||
* @param $length Length of characters
|
||||
* @return RAND characters
|
||||
*/
|
||||
function getrandchars($length) {
|
||||
$charset = '0123456789abcdefghijklmnopqrstuvwxyz!@#$%^&*';
|
||||
$charsize = strlen($charset);
|
||||
srand();
|
||||
$chars = '';
|
||||
for ($i=0;$i<$length;$i++) {
|
||||
$num=rand()%$charsize;
|
||||
$chars=$chars.substr($charset,$num,1);
|
||||
}
|
||||
|
||||
return $chars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a user/password session exists
|
||||
*
|
||||
* @param Nothing
|
||||
* @return True If user has a session.
|
||||
* False Otherwise
|
||||
*/
|
||||
function is_logged() {
|
||||
if (isset($_SESSION["username"]) and !is_bool(getpassword())) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a user is currently logged in successfully
|
||||
*
|
||||
* @param Nothing
|
||||
* @return True If the user is currently logged in successfully
|
||||
* False Otherwise
|
||||
*/
|
||||
function isAuthenticated() {
|
||||
if (is_logged()) {
|
||||
if ($_SESSION["xcatpassvalid"] != 1) {
|
||||
$testcred = docmd("authcheck", "", NULL);
|
||||
if (isset($testcred->{'xcatresponse'}->{'data'})) {
|
||||
$result = "".$testcred->{'xcatresponse'}->{'data'};
|
||||
if (is_numeric(strpos("Authenticated",$result))) {
|
||||
// Logged in successfully
|
||||
$_SESSION["xcatpassvalid"] = 1;
|
||||
} else {
|
||||
// Not logged in
|
||||
$_SESSION["xcatpassvalid"] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_SESSION["xcatpassvalid"]) and $_SESSION["xcatpassvalid"]==1) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log out of the current user session
|
||||
*
|
||||
* @param Nothing
|
||||
* @return Nothing
|
||||
*/
|
||||
function logout() {
|
||||
// Clear the secret cookie from browser
|
||||
if (isset($_COOKIE["xcatauthsecret"])) {
|
||||
setcookie("xcatauthsecret",'',time()-86400*7,'/');
|
||||
}
|
||||
|
||||
// Expire session cookie
|
||||
if (isset($_COOKIE[session_name()])) {
|
||||
setcookie(session_name(),"",time()-86400*7,"/");
|
||||
}
|
||||
|
||||
// Clear server store of data
|
||||
$_SESSION=array();
|
||||
session_destroy();
|
||||
}
|
||||
?>
|
6
xCAT-UI/lib/jsonwrapper.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
// In PHP 5.2 or higher we don't need to bring this in
|
||||
if (!function_exists('json_encode')) {
|
||||
require_once 'jsonwrapper_inner.php';
|
||||
}
|
||||
?>
|
20
xCAT-UI/lib/jsonwrapper_inner.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
require_once 'JSON/JSON.php';
|
||||
|
||||
function json_encode($arg) {
|
||||
global $services_json;
|
||||
if (!isset($services_json)) {
|
||||
$services_json = new Services_JSON();
|
||||
}
|
||||
return $services_json->encode($arg);
|
||||
}
|
||||
|
||||
function json_decode($arg) {
|
||||
global $services_json;
|
||||
if (!isset($services_json)) {
|
||||
$services_json = new Services_JSON();
|
||||
}
|
||||
return $services_json->decode($arg);
|
||||
}
|
||||
|
||||
?>
|
39
xCAT-UI/lib/log.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
$TOPDIR = '..';
|
||||
require_once "$TOPDIR/lib/functions.php";
|
||||
require_once "$TOPDIR/lib/jsonwrapper.php";
|
||||
|
||||
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
|
||||
if (isset($_REQUEST["password"])) {
|
||||
// Clear data from session
|
||||
$_SESSION = array();
|
||||
|
||||
// Zap existing session entirely
|
||||
session_regenerate_id(true);
|
||||
setpassword($_REQUEST["password"]);
|
||||
|
||||
// Invalid password
|
||||
$_SESSION["xcatpassvalid"] = -1;
|
||||
}
|
||||
|
||||
if (isset($_REQUEST["username"])) {
|
||||
$_SESSION["username"] = $_REQUEST["username"];
|
||||
|
||||
// Invalid user name
|
||||
$_SESSION["xcatpassvalid"]=-1;
|
||||
}
|
||||
|
||||
$jdata = array();
|
||||
if (isAuthenticated()) {
|
||||
$jdata["authenticated"]="yes";
|
||||
} else {
|
||||
$jdata["authenticated"]="no";
|
||||
}
|
||||
|
||||
echo json_encode($jdata);
|
||||
?>
|
||||
|
10
xCAT-UI/lib/logout.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
/**
|
||||
* Allow the user to log out and log back in
|
||||
*/
|
||||
$TOPDIR = '..';
|
||||
require_once "$TOPDIR/lib/functions.php";
|
||||
|
||||
logout();
|
||||
header("Location: ../index.php");
|
||||
?>
|
81
xCAT-UI/lib/tabRestore.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/* Required libraries */
|
||||
$TOPDIR = '..';
|
||||
require_once "$TOPDIR/lib/functions.php";
|
||||
require_once "$TOPDIR/lib/jsonwrapper.php";
|
||||
|
||||
/**
|
||||
* Replace the contents of an xCAT table
|
||||
*
|
||||
* @param $tab The xCAT table
|
||||
* $cont The xCAT table contents
|
||||
* @return The xCAT response. Replies are in the form of JSON
|
||||
*/
|
||||
if (isset($_POST["table"])) {
|
||||
// HTTP POST requests
|
||||
$tab = $_POST["table"];
|
||||
$cont = $_POST["cont"];
|
||||
}
|
||||
|
||||
// Create xCAT request
|
||||
$request = simplexml_load_string('<xcatrequest></xcatrequest>');
|
||||
|
||||
// Command is tabrestore
|
||||
$request->addChild('command', 'tabrestore');
|
||||
|
||||
// Setup authentication
|
||||
$usernode=$request->addChild('becomeuser');
|
||||
$usernode->addChild('username', $_SESSION["username"]);
|
||||
$usernode->addChild('password', getpassword());
|
||||
|
||||
// Go through each table row
|
||||
$first = 0;
|
||||
foreach($cont as $line){
|
||||
if($first == 0){
|
||||
// The 1st line is the table header
|
||||
// It does not need special processing
|
||||
// Create string containing all array elements
|
||||
$str = implode(",", $line);
|
||||
$request->addChild('data', $str);
|
||||
|
||||
$first = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Go through each column
|
||||
foreach($line as &$col){
|
||||
// If the column does begins and end with a quote
|
||||
// Change quotes to "
|
||||
if(!empty($col) && !preg_match('/^".*"$/', $col)) {
|
||||
$col = '"' . $col . '"';
|
||||
}
|
||||
}
|
||||
|
||||
// Sort line
|
||||
ksort($line, SORT_NUMERIC);
|
||||
$keys = array_keys($line);
|
||||
$max = count($line) - 1;
|
||||
if($keys[$max] != $max){
|
||||
for ($i = 0; $i <= $keys[$max]; $i++) {
|
||||
if (!isset($line[$i])) {$line[$i]='';}
|
||||
}
|
||||
ksort($line, SORT_NUMERIC);
|
||||
}
|
||||
|
||||
// Create string containing all array elements
|
||||
$str = implode(",", $line);
|
||||
// Replace " with "
|
||||
$str = str_replace('"', '"', $str);
|
||||
// Replace ' with '
|
||||
$str = str_replace("'", ''', $str);
|
||||
$request->addChild('data', $str);
|
||||
}
|
||||
|
||||
// Run command
|
||||
$request->addChild('table', $tab);
|
||||
$xml = submit_request($request, 0);
|
||||
|
||||
// Reply in the form of JSON
|
||||
$rtn = array("rsp" => $xml);
|
||||
echo json_encode($rtn);
|
||||
?>
|
106
xCAT-UI/lib/ui.php
Normal file
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
/**
|
||||
* Load page
|
||||
*
|
||||
* @param Nothing
|
||||
* @return Nothing
|
||||
*/
|
||||
function loadPage(){
|
||||
// Include CSS and Javascripts
|
||||
echo
|
||||
'<html>
|
||||
<head>
|
||||
<title>xCAT Console</title>
|
||||
<link href="css/jquery.autocomplete.css" rel=stylesheet type="text/css">
|
||||
<link href="css/jquery-ui-1.8.custom.css" rel=stylesheet type="text/css">
|
||||
<link href="css/jquery.dataTables.css" rel=stylesheet type="text/css">
|
||||
<link href="css/superfish.css" rel=stylesheet type="text/css">
|
||||
<link href="css/tree.css" rel=stylesheet type="text/css">
|
||||
<link href="css/style.css" rel=stylesheet type="text/css">
|
||||
<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
|
||||
<script type="text/javascript" src="js/jquery-ui-1.8.custom.min.js"></script>
|
||||
<script type="text/javascript" src="js/jquery.dataTables.min.js"></script>
|
||||
<script type="text/javascript" src="js/jquery.form.js"></script>
|
||||
<script type="text/javascript" src="js/jquery.jeditable.js"></script>
|
||||
<script type="text/javascript" src="js/jquery.autocomplete.js"></script>
|
||||
<script type="text/javascript" src="js/jquery.contextmenu.js"></script>
|
||||
<script type="text/javascript" src="js/jquery.cookie.js"></script>
|
||||
<script type="text/javascript" src="js/jquery-impromptu.3.0.min.js"></script>
|
||||
<script type="text/javascript" src="js/superfish.js"></script>
|
||||
<script type="text/javascript" src="js/hoverIntent.js"></script>
|
||||
<script type="text/javascript" src="js/jquery.tree.js"></script>
|
||||
<script type="text/javascript" src="js/ui.js"></script>
|
||||
<script type="text/javascript" src="js/configure.js"></script>
|
||||
<script type="text/javascript" src="js/monitor.js"></script>
|
||||
<script type="text/javascript" src="js/nodes.js"></script>
|
||||
<script type="text/javascript" src="js/provision.js"></script>
|
||||
<script type="text/javascript" src="js/zUtils.js"></script>
|
||||
</head>';
|
||||
|
||||
// Header menu
|
||||
echo
|
||||
'<body>
|
||||
<div id="header">
|
||||
<ul>
|
||||
<li><img src="images/logo.gif" height="100%"/></li>
|
||||
<li><a href="index.php" class="top_link">Nodes</a></li>
|
||||
<li><a href="configure.php" class="top_link">Configure</a></li>
|
||||
<li><a href="provision.php" class="top_link">Provision</a></li>
|
||||
<li><a href="monitor.php" class="top_link">Monitor</a></li>
|
||||
</ul>
|
||||
</div>';
|
||||
|
||||
// Nodes section
|
||||
echo '<div class="content" id="nodes_page"></div>';
|
||||
// Configure section
|
||||
echo '<div class="content" id="configure_page"></div>';
|
||||
// Provision section
|
||||
echo '<div class="content" id="provision_page"></div>';
|
||||
// Monitor section
|
||||
echo '<div class="content" id="monitor_page"></div>';
|
||||
|
||||
// End of page
|
||||
echo
|
||||
'</body>
|
||||
</html>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Load page content
|
||||
*
|
||||
* @param Nothing
|
||||
* @return Nothing
|
||||
*/
|
||||
function loadContent() {
|
||||
// Initialize page
|
||||
echo
|
||||
'<script language="JavaScript" type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
initPage();
|
||||
});
|
||||
</script>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Login user into a new session
|
||||
*
|
||||
* @param Nothing
|
||||
* @return Nothing
|
||||
*/
|
||||
function login() {
|
||||
// xcatauth.js will open a dialog box
|
||||
// asking for the user name and password
|
||||
echo
|
||||
'<script src="js/xcatauth.js" type="text/javascript"></script>
|
||||
<div id=logdialog>
|
||||
<p>Give the username and password configured in the passwd table</p>
|
||||
<form id=loginform>
|
||||
<table cellspacing=3>
|
||||
<tr><td align=right><label for=username>User name:</label></td><td align=left><input id=username type=text name=username></td></tr>
|
||||
<tr><td align=right><label for=password>Password:</label></td><td align=left><input id=password type=password name=password></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
<p><span id=logstatus></span></p>
|
||||
</div>';
|
||||
}
|
||||
?>
|
29
xCAT-UI/lib/upload.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* Upload a given file into /var/tmp
|
||||
*/
|
||||
$type = $_FILES["file"]["type"];
|
||||
if ($type == "text/plain" || $type == "application/octet-stream") {
|
||||
$error = $_FILES["file"]["error"];
|
||||
if ($error) {
|
||||
echo "Return Code: " . $error;
|
||||
} else {
|
||||
$file = $_FILES["file"]["name"];
|
||||
$path = "/var/tmp/" . $file;
|
||||
move_uploaded_file($_FILES["file"]["tmp_name"], $path);
|
||||
|
||||
// Open and read given file
|
||||
$handler = fopen($path, "r");
|
||||
$data = fread($handler, filesize($path));
|
||||
fclose($handler);
|
||||
|
||||
// Print out file contents
|
||||
echo $data;
|
||||
|
||||
// Remove this file
|
||||
unlink($path);
|
||||
}
|
||||
} else {
|
||||
echo "(Error) File type not supported";
|
||||
}
|
||||
?>
|
134
xCAT-UI/lib/zCmd.php
Normal file
@ -0,0 +1,134 @@
|
||||
<?php
|
||||
/* Required libraries */
|
||||
$TOPDIR = '..';
|
||||
require_once "$TOPDIR/lib/functions.php";
|
||||
require_once "$TOPDIR/lib/jsonwrapper.php";
|
||||
|
||||
/**
|
||||
* Issue an xCAT command (only for z)
|
||||
*
|
||||
* @param $cmd The xCAT command
|
||||
* $tgt The target node or group
|
||||
* $args The xCAT command arguments, separated by semicolons
|
||||
* @return The xCAT response. Replies are in the form of JSON
|
||||
*/
|
||||
if (isset($_GET["cmd"])) {
|
||||
// HTTP GET requests
|
||||
$cmd = $_GET["cmd"];
|
||||
$tgt = $_GET["tgt"];
|
||||
$args = $_GET["args"];
|
||||
|
||||
// Attachments are put here
|
||||
$att = $_GET["att"];
|
||||
|
||||
// Special messages put here
|
||||
$msg = $_GET["msg"];
|
||||
|
||||
// If no $tgt is given, set $tgt to NULL
|
||||
if (!$tgt) {
|
||||
$tgt = NULL;
|
||||
}
|
||||
|
||||
// If no $args is given, set $args to NULL
|
||||
if (!$args) {
|
||||
$args = NULL;
|
||||
}
|
||||
|
||||
// If no $msg is given, set $msg to NULL
|
||||
if (!$msg) {
|
||||
$msg = NULL;
|
||||
}
|
||||
|
||||
// If no $att is given, set $att to NULL
|
||||
if (!$att) {
|
||||
$att = NULL;
|
||||
}
|
||||
|
||||
// If $args contains multiple arguments, split it into an array
|
||||
if (strpos($args,";")) {
|
||||
// Split the arguments into an array
|
||||
$arr = array();
|
||||
$arr = explode(";", $args);
|
||||
} else {
|
||||
$arr = array($args);
|
||||
}
|
||||
|
||||
$rsp = array();
|
||||
|
||||
// Replace user entry
|
||||
if(strncasecmp($cmd, "chvm", 4) == 0 && strncasecmp($arr[0], "--replacevs", 11) == 0) {
|
||||
// Directory /var/tmp permissions = 777
|
||||
// You can write anything to that directory
|
||||
$userEntry = "/var/tmp/$tgt.txt";
|
||||
$handle = fopen($userEntry, 'w') or die("Cannot open $userEntry");
|
||||
fwrite($handle, $att);
|
||||
fclose($handle);
|
||||
|
||||
// CLI command: chvm gpok249 --replacevs /tmp/dirEntry.txt
|
||||
// Replace user entry
|
||||
array_push($arr, $userEntry);
|
||||
$xml = docmd($cmd, $tgt, $arr);
|
||||
foreach ($xml->children() as $child) {
|
||||
foreach ($child->children() as $data) {
|
||||
array_push($rsp, "$data");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create virtual server
|
||||
else if(strncasecmp($cmd, "mkvm", 4) == 0) {
|
||||
// Directory /var/tmp permissions = 777
|
||||
// You can write anything to that directory
|
||||
$userEntry = "/var/tmp/$tgt.txt";
|
||||
$handle = fopen($userEntry, 'w') or die("Cannot open $userEntry");
|
||||
fwrite($handle, $att);
|
||||
fclose($handle);
|
||||
|
||||
// CLI command: mkvm gpok3 /tmp/gpok3.txt
|
||||
// Create user entry
|
||||
array_unshift($arr, $userEntry);
|
||||
$xml = docmd($cmd, $tgt, $arr);
|
||||
foreach ($xml->children() as $child) {
|
||||
foreach ($child->children() as $data) {
|
||||
array_push($rsp, "$data");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock virtual server
|
||||
// This is a typical command used by all platforms. It is put here because
|
||||
// most of the code needed are already here
|
||||
else if (strncasecmp($cmd, "xdsh", 4) == 0) {
|
||||
// Directory /var/tmp permissions = 777
|
||||
// You can write anything to that directory
|
||||
$msgArgs = explode(";", $msg);
|
||||
$inst = str_replace("out=scriptStatusBar", "", $msgArgs[0]);
|
||||
$script = "/var/tmp/script$inst.sh";
|
||||
|
||||
// Write to file
|
||||
$handle = fopen($script, 'w') or die("Cannot open $script");
|
||||
fwrite($handle, $att);
|
||||
fclose($handle);
|
||||
|
||||
// Change it to executable
|
||||
chmod($script, 0777);
|
||||
|
||||
// CLI command: xdsh gpok3 -e /var/tmp/gpok3.sh
|
||||
// Create user entry
|
||||
array_push($arr, $script);
|
||||
$xml = docmd($cmd, $tgt, $arr);
|
||||
foreach ($xml->children() as $child) {
|
||||
foreach ($child->children() as $data) {
|
||||
array_push($rsp, "$data");
|
||||
}
|
||||
}
|
||||
|
||||
// Remove this file
|
||||
unlink($script);
|
||||
}
|
||||
|
||||
// Reply in the form of JSON
|
||||
$rtn = array("rsp" => $rsp, "msg" => $msg);
|
||||
echo json_encode($rtn);
|
||||
}
|
||||
?>
|
17
xCAT-UI/monitor.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* Monitor page
|
||||
*/
|
||||
require_once "lib/functions.php";
|
||||
require_once "lib/ui.php";
|
||||
|
||||
/* Load page */
|
||||
loadPage();
|
||||
|
||||
/* Login user */
|
||||
if (!isAuthenticated()) {
|
||||
login();
|
||||
} else {
|
||||
loadContent();
|
||||
}
|
||||
?>
|
17
xCAT-UI/provision.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* Provision page
|
||||
*/
|
||||
require_once "lib/functions.php";
|
||||
require_once "lib/ui.php";
|
||||
|
||||
/* Load page */
|
||||
loadPage();
|
||||
|
||||
/* Login user */
|
||||
if (!isAuthenticated()) {
|
||||
login();
|
||||
} else {
|
||||
loadContent();
|
||||
}
|
||||
?>
|